mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
Merge pull request #42 from pengzhanbo/RC-23
feat: (试验性)代码高亮支持 twoslash
This commit is contained in:
commit
a83e665cbd
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -72,6 +72,7 @@
|
||||
"taze",
|
||||
"Tongji",
|
||||
"tsbuildinfo",
|
||||
"twoslash",
|
||||
"vite",
|
||||
"vuepress",
|
||||
"vueuse",
|
||||
|
||||
@ -124,6 +124,56 @@ const obj = {
|
||||
}
|
||||
```
|
||||
|
||||
**Code Blocks TwoSlash**
|
||||
|
||||
```ts twoslash
|
||||
// @errors: 2339
|
||||
const welcome = "Tudo bem gente?"
|
||||
const words = welcome.contains(" ")
|
||||
```
|
||||
|
||||
```ts twoslash
|
||||
import express from "express"
|
||||
const app = express()
|
||||
app.get("/", function (req, res) {
|
||||
res.send
|
||||
})
|
||||
app.listen(3000)
|
||||
```
|
||||
|
||||
```ts twoslash
|
||||
import { getHighlighterCore } from 'shikiji/core'
|
||||
|
||||
const highlighter = await getHighlighterCore({})
|
||||
// @log: Custom log message
|
||||
const a = 1
|
||||
// @error: Custom error message
|
||||
const b = 1
|
||||
// @warn: Custom warning message
|
||||
const c = 1
|
||||
// @annotate: Custom annotation message
|
||||
```
|
||||
|
||||
```ts twoslash
|
||||
// @errors: 2540
|
||||
interface Todo {
|
||||
title: string
|
||||
}
|
||||
|
||||
const todo: Readonly<Todo> = {
|
||||
title: 'Delete inactive users'.toUpperCase(),
|
||||
// ^?
|
||||
}
|
||||
|
||||
todo.title = 'Hello'
|
||||
|
||||
Number.parseInt('123', 10)
|
||||
// ^|
|
||||
|
||||
//
|
||||
//
|
||||
```
|
||||
|
||||
**代码分组**
|
||||
|
||||
::: code-tabs
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
"anywhere": "^1.6.0",
|
||||
"sass": "^1.69.7",
|
||||
"sass-loader": "^13.3.3",
|
||||
"vue": "^3.4.7",
|
||||
"vue": "^3.4.10",
|
||||
"vuepress-theme-plume": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,6 +60,11 @@
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.11"
|
||||
},
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@vuepress/markdown@2.0.0-rc.0": "patches/@vuepress__markdown@2.0.0-rc.0.patch"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*": "eslint --fix"
|
||||
},
|
||||
|
||||
13
patches/@vuepress__markdown@2.0.0-rc.0.patch
Normal file
13
patches/@vuepress__markdown@2.0.0-rc.0.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/dist/index.js b/dist/index.js
|
||||
index 996b0d16dac39667cc25496e52adcc9dd2b2befa..a4c9f5ba3a20967d9a561fcc73178d9e84f48279 100644
|
||||
--- a/dist/index.js
|
||||
+++ b/dist/index.js
|
||||
@@ -245,7 +245,7 @@ var codePlugin = (md, {
|
||||
const info = token.info ? md.utils.unescapeAll(token.info).trim() : "";
|
||||
const language = resolveLanguage(info);
|
||||
const languageClass = `${options.langPrefix}${language.name}`;
|
||||
- const code = options.highlight?.(token.content, language.name, "") || md.utils.escapeHtml(token.content);
|
||||
+ const code = options.highlight?.(token.content, language.name, info || "") || md.utils.escapeHtml(token.content);
|
||||
token.attrJoin("class", languageClass);
|
||||
let result = code.startsWith("<pre") ? code : `<pre${slf.renderAttrs(token)}><code>${code}</code></pre>`;
|
||||
const useVPre = resolveVPre(info) ?? vPreBlock;
|
||||
@ -42,7 +42,7 @@
|
||||
"@vuepress/utils": "2.0.0-rc.0",
|
||||
"chokidar": "^3.5.3",
|
||||
"create-filter": "^1.0.1",
|
||||
"vue": "^3.4.7"
|
||||
"vue": "^3.4.10"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
"@vuepress/client": "2.0.0-rc.0",
|
||||
"@vuepress/core": "2.0.0-rc.0",
|
||||
"@vuepress/utils": "2.0.0-rc.0",
|
||||
"vue": "^3.4.7",
|
||||
"vue": "^3.4.10",
|
||||
"vue-router": "4.2.5"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
"@vuepress/core": "2.0.0-rc.0",
|
||||
"@vuepress/shared": "2.0.0-rc.0",
|
||||
"@vuepress/utils": "2.0.0-rc.0",
|
||||
"vue": "^3.4.7"
|
||||
"vue": "^3.4.10"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -8,7 +8,7 @@ const options = __COPY_CODE_OPTIONS__
|
||||
const RE_LANGUAGE = /language-([\w]+)/
|
||||
const RE_START_CODE = /^ *(\$|>)/gm
|
||||
const shells = ['shellscript', 'shell', 'bash', 'sh', 'zsh']
|
||||
const ignoredNodes = ['.diff.remove']
|
||||
const ignoredNodes = ['.diff.remove', '.vp-copy-ignore']
|
||||
|
||||
function isMobile(): boolean {
|
||||
return navigator
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
"@vuepress/core": "2.0.0-rc.0",
|
||||
"@vuepress/shared": "2.0.0-rc.0",
|
||||
"@vuepress/utils": "2.0.0-rc.0",
|
||||
"vue": "^3.4.7"
|
||||
"vue": "^3.4.10"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -51,11 +51,11 @@
|
||||
"dotenv": "^16.3.1",
|
||||
"esbuild": "^0.19.11",
|
||||
"execa": "^8.0.1",
|
||||
"netlify-cli": "^17.13.0",
|
||||
"netlify-cli": "^17.13.1",
|
||||
"portfinder": "^1.0.32"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.10.8"
|
||||
"@types/node": "^20.11.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
"@vuepress/utils": "2.0.0-rc.0",
|
||||
"chokidar": "^3.5.3",
|
||||
"create-filter": "^1.0.1",
|
||||
"vue": "^3.4.7"
|
||||
"vue": "^3.4.10"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"@vuepress/shared": "2.0.0-rc.0",
|
||||
"@vuepress/utils": "2.0.0-rc.0",
|
||||
"leancloud-storage": "^4.15.2",
|
||||
"vue": "^3.4.7",
|
||||
"vue": "^3.4.10",
|
||||
"vue-router": "4.2.5",
|
||||
"vuepress-plugin-netlify-functions": "workspace:*"
|
||||
},
|
||||
|
||||
@ -37,7 +37,8 @@
|
||||
"nanoid": "^5.0.4",
|
||||
"picocolors": "^1.0.0",
|
||||
"shikiji": "^0.9.18",
|
||||
"shikiji-transformers": "^0.9.18"
|
||||
"shikiji-transformers": "^0.9.18",
|
||||
"shikiji-twoslash": "^0.9.18"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -15,7 +15,9 @@ import {
|
||||
transformerNotationFocus,
|
||||
transformerNotationHighlight,
|
||||
} from 'shikiji-transformers'
|
||||
import { rendererRich, transformerTwoSlash } from 'shikiji-twoslash'
|
||||
import type { HighlighterOptions, ThemeOptions } from './types.js'
|
||||
import { resolveAttrs } from './resolveAttrs.js'
|
||||
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10)
|
||||
|
||||
@ -88,9 +90,7 @@ export async function highlight(
|
||||
lang = defaultLang
|
||||
}
|
||||
}
|
||||
|
||||
// const lineOptions = attrsToLines(attrs)
|
||||
|
||||
const { attrs: attributes, rawAttrs } = resolveAttrs(attrs || '')
|
||||
const mustaches = new Map<string, string>()
|
||||
|
||||
const removeMustache = (s: string) => {
|
||||
@ -110,32 +110,75 @@ export async function highlight(
|
||||
mustaches.forEach((marker, match) => {
|
||||
s = s.replaceAll(marker, match)
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
const fillEmptyHighlightedLine = (s: string) => {
|
||||
return `${s.replace(
|
||||
/(<span class="line highlighted">)(<\/span>)/g,
|
||||
'$1<wbr>$2',
|
||||
).replace(/(\/\/\s*?\[)\\(!code.*?\])/g, '$1$2')}\n`
|
||||
return `${s}\n`
|
||||
}
|
||||
|
||||
str = removeMustache(str).trimEnd()
|
||||
|
||||
const highlighted = highlighter.codeToHtml(str, {
|
||||
lang,
|
||||
transformers: [
|
||||
...transformers,
|
||||
...userTransformers,
|
||||
],
|
||||
meta: {
|
||||
__raw: attrs,
|
||||
const inlineTransformers: ShikijiTransformer[] = [
|
||||
{
|
||||
name: 'vuepress-shikiji:empty-line',
|
||||
pre(hast) {
|
||||
hast.children.forEach((code) => {
|
||||
if (code.type === 'element' && code.tagName === 'code') {
|
||||
code.children.forEach((span) => {
|
||||
if (
|
||||
span.type === 'element'
|
||||
&& span.tagName === 'span'
|
||||
&& Array.isArray(span.properties.class)
|
||||
&& span.properties.class.includes('line')
|
||||
&& span.children.length === 0
|
||||
) {
|
||||
span.children.push({
|
||||
type: 'element',
|
||||
tagName: 'wbr',
|
||||
properties: {},
|
||||
children: [],
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
...(typeof theme === 'object' && 'light' in theme && 'dark' in theme
|
||||
? { themes: theme, defaultColor: false }
|
||||
: { theme }),
|
||||
})
|
||||
{
|
||||
name: 'vuepress-shikiji:remove-escape',
|
||||
postprocess(code) {
|
||||
return code.replace(/\[\\\!code/g, '[!code')
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
return fillEmptyHighlightedLine(restoreMustache(highlighted))
|
||||
if (attributes.twoslash) {
|
||||
inlineTransformers.push(transformerTwoSlash({
|
||||
renderer: rendererRich({
|
||||
classExtra: 'vp-copy-ignore',
|
||||
}),
|
||||
}))
|
||||
}
|
||||
|
||||
try {
|
||||
const highlighted = highlighter.codeToHtml(str, {
|
||||
lang,
|
||||
transformers: [
|
||||
...transformers,
|
||||
...inlineTransformers,
|
||||
...userTransformers,
|
||||
],
|
||||
meta: {
|
||||
__raw: rawAttrs,
|
||||
},
|
||||
...(typeof theme === 'object' && 'light' in theme && 'dark' in theme
|
||||
? { themes: theme, defaultColor: false }
|
||||
: { theme }),
|
||||
})
|
||||
|
||||
return restoreMustache(highlighted)
|
||||
}
|
||||
catch (e) {
|
||||
logger.error(e)
|
||||
return str
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
43
plugins/plugin-shikiji/src/node/resolveAttrs.ts
Normal file
43
plugins/plugin-shikiji/src/node/resolveAttrs.ts
Normal file
@ -0,0 +1,43 @@
|
||||
const RE_ATTR_VALUE = /(?:^|\s+)(?<attr>[\w\d-]+)(?:=\s*(?<quote>['"])(?<value>.+?)\k<quote>)?(?:\s+|$)/
|
||||
const RE_CODE_BLOCKS = /^[\w\d-]*(\s*:[\w\d-]*)?(\s*\{[\d\w-,\s]+\})?\s*/
|
||||
|
||||
export function resolveAttrs(info: string): {
|
||||
attrs: Record<string, string | boolean>
|
||||
rawAttrs: string
|
||||
} {
|
||||
if (!info)
|
||||
return { rawAttrs: '', attrs: {} }
|
||||
info = info.replace(RE_CODE_BLOCKS, '').trim()
|
||||
if (!info)
|
||||
return { rawAttrs: '', attrs: {} }
|
||||
|
||||
const attrs: Record<string, string | boolean> = {}
|
||||
const rawAttrs = info
|
||||
|
||||
let matched: RegExpMatchArray | null
|
||||
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
while (matched = info.match(RE_ATTR_VALUE)) {
|
||||
const { attr, value } = matched.groups || {}
|
||||
attrs[attr] = value ?? true
|
||||
info = info.slice(matched[0].length)
|
||||
}
|
||||
|
||||
Object.keys(attrs).forEach((key) => {
|
||||
let value = attrs[key]
|
||||
value = typeof value === 'string' ? value.trim() : value
|
||||
if (value === 'true')
|
||||
value = true
|
||||
else if (value === 'false')
|
||||
value = false
|
||||
|
||||
attrs[key] = value
|
||||
|
||||
if (key.includes('-')) {
|
||||
const _key = key.replace(/-(\w)/g, (_, c) => c.toUpperCase())
|
||||
attrs[_key] = value
|
||||
}
|
||||
})
|
||||
|
||||
return { attrs, rawAttrs }
|
||||
}
|
||||
@ -2,9 +2,6 @@ import type { Plugin } from '@vuepress/core'
|
||||
import { highlight } from './highlight.js'
|
||||
import type { HighlighterOptions } from './types'
|
||||
|
||||
/**
|
||||
* Options of @vuepress/plugin-shiki
|
||||
*/
|
||||
export type ShikijiPluginOptions = HighlighterOptions
|
||||
|
||||
export function shikijiPlugin(options: ShikijiPluginOptions = {}): Plugin {
|
||||
|
||||
1213
pnpm-lock.yaml
generated
1213
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -82,7 +82,7 @@
|
||||
"katex": "^0.16.9",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"nanoid": "^5.0.4",
|
||||
"vue": "^3.4.7",
|
||||
"vue": "^3.4.10",
|
||||
"vue-router": "4.2.5",
|
||||
"vuepress-plugin-comment2": "2.0.0-rc.10",
|
||||
"vuepress-plugin-md-enhance": "2.0.0-rc.10",
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
@import "utils";
|
||||
@import "content";
|
||||
@import "code";
|
||||
|
||||
@import "twoslash";
|
||||
@import "md-enhance";
|
||||
@import "search";
|
||||
@import "@vuepress/plugin-palette/style";
|
||||
|
||||
225
theme/src/client/styles/twoslash.scss
Normal file
225
theme/src/client/styles/twoslash.scss
Normal file
@ -0,0 +1,225 @@
|
||||
/* stylelint-disable no-descending-specificity */
|
||||
|
||||
/* ===== Basic ===== */
|
||||
:root {
|
||||
--twoslash-border-color: var(--vp-c-divider);
|
||||
--twoslash-jsdoc-color: #888;
|
||||
--twoslash-underline-color: currentcolor;
|
||||
--twoslash-popup-bg: var(--vp-c-neutral-inverse);
|
||||
--twoslash-popup-shadow: var(--vp-shadow-2);
|
||||
--twoslash-matched-color: inherit;
|
||||
--twoslash-unmatched-color: #888;
|
||||
--twoslash-cursor-color: #8888;
|
||||
--twoslash-error-color: var(--vp-c-danger-1);
|
||||
--twoslash-error-bg: var(--vp-c-danger-soft);
|
||||
--twoslash-tag-color: var(--vp-c-tip-1);
|
||||
--twoslash-tag-bg: var(--vp-c-tip-soft);
|
||||
--twoslash-tag-warn-color: var(--vp-c-warning-1);
|
||||
--twoslash-tag-warn-bg: var(--vp-c-warning-soft);
|
||||
--twoslash-tag-annotate-color: var(--vp-c-green-1);
|
||||
--twoslash-tag-annotate-bg: var(--vp-c-green-soft);
|
||||
}
|
||||
|
||||
div[class*="language-"].line-numbers-mode:has(> .twoslash) {
|
||||
.line-numbers {
|
||||
display: none;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding-left: 1.5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Respect people's wishes to not have animations */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.twoslash * {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== Hover Info ===== */
|
||||
.twoslash:hover .twoslash-hover {
|
||||
border-color: var(--twoslash-underline-color);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-hover {
|
||||
position: relative;
|
||||
border-bottom: 1px dotted transparent;
|
||||
transition: border-color 0.3s;
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
|
||||
.twoslash .twoslash-popup-info {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
display: inline-block;
|
||||
padding: 4px 6px;
|
||||
text-align: left;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
background: var(--twoslash-popup-bg);
|
||||
border: 1px solid var(--twoslash-border-color);
|
||||
border-radius: 4px;
|
||||
box-shadow: var(--twoslash-popup-shadow);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
transform: translateY(1.5em);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-query-presisted .twoslash-popup-info {
|
||||
left: 50%;
|
||||
z-index: 9;
|
||||
transform: translate(-1.3em, 1.8em);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-hover:hover .twoslash-popup-info,
|
||||
.twoslash .twoslash-query-presisted .twoslash-popup-info {
|
||||
pointer-events: auto;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.twoslash .twoslash-popup-info:hover {
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.twoslash .twoslash-popup-arrow {
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
left: 1em;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
pointer-events: none;
|
||||
background: var(--twoslash-popup-bg);
|
||||
border-top: 1px solid var(--twoslash-border-color);
|
||||
border-right: 1px solid var(--twoslash-border-color);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-popup-jsdoc {
|
||||
padding-top: 6px;
|
||||
padding-bottom: 2px;
|
||||
font-family: sans-serif;
|
||||
font-size: 0.8em;
|
||||
color: var(--twoslash-jsdoc-color);
|
||||
}
|
||||
|
||||
/* ===== Error Line ===== */
|
||||
.twoslash .twoslash-error-line {
|
||||
position: relative;
|
||||
padding: 6px;
|
||||
margin: 0.2em 0;
|
||||
color: var(--twoslash-error-color);
|
||||
background-color: var(--twoslash-error-bg);
|
||||
border-left: 3px solid var(--twoslash-error-color);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-error {
|
||||
padding-bottom: 2px;
|
||||
background:
|
||||
url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%206%203'%20enable-background%3D'new%200%200%206%203'%20height%3D'3'%20width%3D'6'%3E%3Cg%20fill%3D'%23c94824'%3E%3Cpolygon%20points%3D'5.5%2C0%202.5%2C3%201.1%2C3%204.1%2C0'%2F%3E%3Cpolygon%20points%3D'4%2C0%206%2C2%206%2C0.6%205.4%2C0'%2F%3E%3Cpolygon%20points%3D'0%2C2%201%2C3%202.4%2C3%200%2C0.6'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
|
||||
repeat-x bottom left;
|
||||
}
|
||||
|
||||
/* ===== Completeions ===== */
|
||||
.twoslash .twoslash-completions-list {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.twoslash .twoslash-completions-list ul {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 8;
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
width: 240px;
|
||||
padding: 4px;
|
||||
margin: 3px 0 0 -1px;
|
||||
font-size: 0.8rem;
|
||||
user-select: none;
|
||||
background: var(--twoslash-popup-bg);
|
||||
border: 1px solid var(--twoslash-border-color);
|
||||
box-shadow: var(--twoslash-popup-shadow);
|
||||
transform: translate(0, 1.2em);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-completions-list ul:hover {
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.twoslash .twoslash-completions-list ul::before {
|
||||
position: absolute;
|
||||
top: -1.6em;
|
||||
left: -1px;
|
||||
width: 2px;
|
||||
height: 1.4em;
|
||||
content: " ";
|
||||
background-color: var(--twoslash-cursor-color);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-completions-list ul li {
|
||||
display: flex;
|
||||
gap: 0.25em;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.twoslash .twoslash-completions-list ul li span.twoslash-completions-unmatched {
|
||||
color: var(--twoslash-unmatched-color);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-completions-list ul .deprecated {
|
||||
text-decoration: line-through;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.twoslash .twoslash-completions-list ul li span.twoslash-completions-matched {
|
||||
color: var(--twoslash-matched-color);
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
.twoslash .twoslash-completions-list .twoslash-completions-icon {
|
||||
flex: none;
|
||||
width: 1em;
|
||||
color: var(--twoslash-unmatched-color);
|
||||
}
|
||||
|
||||
/* Custom Tags */
|
||||
.twoslash .twoslash-tag-line {
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: 0.3em;
|
||||
align-items: center;
|
||||
padding: 6px;
|
||||
margin: 0.2em 0;
|
||||
color: var(--twoslash-tag-color);
|
||||
background-color: var(--twoslash-tag-bg);
|
||||
border-left: 3px solid var(--twoslash-tag-color);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-tag-line .twoslash-tag-icon {
|
||||
width: 1.1em;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.twoslash .twoslash-tag-line.twoslash-tag-error-line {
|
||||
color: var(--twoslash-error-color);
|
||||
background-color: var(--twoslash-error-bg);
|
||||
border-left: 3px solid var(--twoslash-error-color);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-tag-line.twoslash-tag-warn-line {
|
||||
color: var(--twoslash-tag-warn-color);
|
||||
background-color: var(--twoslash-tag-warn-bg);
|
||||
border-left: 3px solid var(--twoslash-tag-warn-color);
|
||||
}
|
||||
|
||||
.twoslash .twoslash-tag-line.twoslash-tag-annotate-line {
|
||||
color: var(--twoslash-tag-annotate-color);
|
||||
background-color: var(--twoslash-tag-annotate-bg);
|
||||
border-left: 3px solid var(--twoslash-tag-annotate-color);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user