feat: (试验性)代码高亮支持 twoslash
This commit is contained in:
parent
de8d9e0d61
commit
d0fdf79477
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
|
||||
|
||||
@ -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;
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
123
pnpm-lock.yaml
generated
123
pnpm-lock.yaml
generated
@ -4,6 +4,11 @@ settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
patchedDependencies:
|
||||
'@vuepress/markdown@2.0.0-rc.0':
|
||||
hash: zvwmijlesxcdy3i4trojywcm7y
|
||||
path: patches/@vuepress__markdown@2.0.0-rc.0.patch
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
@ -16,7 +21,7 @@ importers:
|
||||
version: 18.4.4
|
||||
'@pengzhanbo/eslint-config-vue':
|
||||
specifier: ^1.5.3
|
||||
version: 1.5.3(@vue/compiler-sfc@3.4.5)(eslint@8.56.0)(typescript@5.3.3)
|
||||
version: 1.5.3(@vue/compiler-sfc@3.4.7)(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@pengzhanbo/stylelint-config':
|
||||
specifier: ^1.5.3
|
||||
version: 1.5.3(stylelint@16.1.0)
|
||||
@ -79,7 +84,7 @@ importers:
|
||||
version: 2.0.0-rc.0(@types/node@20.9.1)(sass@1.69.7)(typescript@5.3.3)
|
||||
'@vuepress/bundler-webpack':
|
||||
specifier: 2.0.0-rc.0
|
||||
version: 2.0.0-rc.0(@vue/compiler-sfc@3.4.5)(typescript@5.3.3)
|
||||
version: 2.0.0-rc.0(@vue/compiler-sfc@3.4.7)(typescript@5.3.3)
|
||||
'@vuepress/cli':
|
||||
specifier: 2.0.0-rc.0
|
||||
version: 2.0.0-rc.0(typescript@5.3.3)
|
||||
@ -361,6 +366,9 @@ importers:
|
||||
shikiji-transformers:
|
||||
specifier: ^0.9.18
|
||||
version: 0.9.18
|
||||
shikiji-twoslash:
|
||||
specifier: ^0.9.18
|
||||
version: 0.9.18(typescript@5.3.3)
|
||||
|
||||
theme:
|
||||
dependencies:
|
||||
@ -3803,7 +3811,7 @@ packages:
|
||||
'@parcel/watcher-win32-x64': 2.3.0
|
||||
dev: false
|
||||
|
||||
/@pengzhanbo/eslint-config-vue@1.5.3(@vue/compiler-sfc@3.4.5)(eslint@8.56.0)(typescript@5.3.3):
|
||||
/@pengzhanbo/eslint-config-vue@1.5.3(@vue/compiler-sfc@3.4.7)(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-5QdiHebq5wQGLBC1nZKJGK4rjB1fMM3RcWWLNBn2NqbYMOKRllj9CVrnHvjhKoO9KTUNV89doRDBmnIIQoortA==}
|
||||
peerDependencies:
|
||||
'@unocss/eslint-plugin': '>=0.50.0'
|
||||
@ -3820,7 +3828,7 @@ packages:
|
||||
eslint: 8.56.0
|
||||
eslint-merge-processors: 0.1.0(eslint@8.56.0)
|
||||
eslint-plugin-vue: 9.19.2(eslint@8.56.0)
|
||||
eslint-processor-vue-blocks: 0.1.1(@vue/compiler-sfc@3.4.5)(eslint@8.56.0)
|
||||
eslint-processor-vue-blocks: 0.1.1(@vue/compiler-sfc@3.4.7)(eslint@8.56.0)
|
||||
vue-eslint-parser: 9.3.2(eslint@8.56.0)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/compiler-sfc'
|
||||
@ -4386,6 +4394,13 @@ packages:
|
||||
resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==}
|
||||
dev: false
|
||||
|
||||
/@types/lz-string@1.5.0:
|
||||
resolution: {integrity: sha512-s84fKOrzqqNCAPljhVyC5TjAo6BH4jKHw9NRNFNiRUY5QSgZCmVm5XILlWbisiKl+0OcS7eWihmKGS5akc2iQw==}
|
||||
deprecated: This is a stub types definition. lz-string provides its own type definitions, so you do not need this installed.
|
||||
dependencies:
|
||||
lz-string: 1.5.0
|
||||
dev: false
|
||||
|
||||
/@types/markdown-it-emoji@2.0.4:
|
||||
resolution: {integrity: sha512-H6ulk/ZmbDxOayPwI/leJzrmoW1YKX1Z+MVSCHXuYhvqckV4I/c+hPTf6UiqJyn2avWugfj30XroheEb6/Ekqg==}
|
||||
dependencies:
|
||||
@ -4699,6 +4714,28 @@ packages:
|
||||
eslint-visitor-keys: 3.4.3
|
||||
dev: true
|
||||
|
||||
/@typescript/twoslash@3.2.4(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-/TCIOuPQaKltzUUT1qJo6mplYwjbAxkaSFvkeZD3FeFt3Ovt+HJi8xisu8rcLyDRmM3VJ0+jAx+AAICwn4Zlhw==}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
dependencies:
|
||||
'@types/lz-string': 1.5.0
|
||||
'@typescript/vfs': 1.5.0
|
||||
debug: 4.3.4(supports-color@9.2.2)
|
||||
lz-string: 1.5.0
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@typescript/vfs@1.5.0:
|
||||
resolution: {integrity: sha512-AJS307bPgbsZZ9ggCT3wwpg3VbTKMFNHfaY/uF0ahSkYYrPF2dSSKDNIDIQAHm9qJqbLvCsSJH7yN4Vs/CsMMg==}
|
||||
dependencies:
|
||||
debug: 4.3.4(supports-color@9.2.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@ungap/structured-clone@1.2.0:
|
||||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||
dev: true
|
||||
@ -4756,15 +4793,6 @@ packages:
|
||||
vue: 3.4.7(typescript@5.3.3)
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-core@3.4.5:
|
||||
resolution: {integrity: sha512-Daka7P1z2AgKjzuueWXhwzIsKu0NkLB6vGbNVEV2iJ8GJTrzraZo/Sk4GWCMRtd/qVi3zwnk+Owbd/xSZbwHtQ==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.23.6
|
||||
'@vue/shared': 3.4.5
|
||||
entities: 4.5.0
|
||||
estree-walker: 2.0.2
|
||||
source-map-js: 1.0.2
|
||||
|
||||
/@vue/compiler-core@3.4.7:
|
||||
resolution: {integrity: sha512-hhCaE3pTMrlIJK7M/o3Xf7HV8+JoNTGOQ/coWS+V+pH6QFFyqtoXqQzpqsNp7UK17xYKua/MBiKj4e1vgZOBYw==}
|
||||
dependencies:
|
||||
@ -4773,33 +4801,12 @@ packages:
|
||||
entities: 4.5.0
|
||||
estree-walker: 2.0.2
|
||||
source-map-js: 1.0.2
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-dom@3.4.5:
|
||||
resolution: {integrity: sha512-J8YlxknJVd90SXFJ4HwGANSAXsx5I0lK30sO/zvYV7s5gXf7gZR7r/1BmZ2ju7RGH1lnc6bpBc6nL61yW+PsAQ==}
|
||||
dependencies:
|
||||
'@vue/compiler-core': 3.4.5
|
||||
'@vue/shared': 3.4.5
|
||||
|
||||
/@vue/compiler-dom@3.4.7:
|
||||
resolution: {integrity: sha512-qDKBAIurCTub4n/6jDYkXwgsFuriqqmmLrIq1N2QDfYJA/mwiwvxi09OGn28g+uDdERX9NaKDLji0oTjE3sScg==}
|
||||
dependencies:
|
||||
'@vue/compiler-core': 3.4.7
|
||||
'@vue/shared': 3.4.7
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-sfc@3.4.5:
|
||||
resolution: {integrity: sha512-jauvkDuSSUbP0ebhfNqljhShA90YEfX/0wZ+w40oZF43IjGyWYjqYaJbvMJwGOd+9+vODW6eSvnk28f0SGV7OQ==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.23.6
|
||||
'@vue/compiler-core': 3.4.5
|
||||
'@vue/compiler-dom': 3.4.5
|
||||
'@vue/compiler-ssr': 3.4.5
|
||||
'@vue/shared': 3.4.5
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.30.5
|
||||
postcss: 8.4.33
|
||||
source-map-js: 1.0.2
|
||||
|
||||
/@vue/compiler-sfc@3.4.7:
|
||||
resolution: {integrity: sha512-Gec6CLkReVswDYjQFq79O5rktri4R7TsD/VPCiUoJw40JhNNxaNJJa8mrQrWoJluW4ETy6QN0NUyC/JO77OCOw==}
|
||||
@ -4813,20 +4820,12 @@ packages:
|
||||
magic-string: 0.30.5
|
||||
postcss: 8.4.33
|
||||
source-map-js: 1.0.2
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-ssr@3.4.5:
|
||||
resolution: {integrity: sha512-DDdEcDzj2lWTMfUMMtEpLDhURai9LhM0zSZ219jCt7b2Vyl0/jy3keFgCPMitG0V1S1YG4Cmws3lWHWdxHQOpg==}
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.4.5
|
||||
'@vue/shared': 3.4.5
|
||||
|
||||
/@vue/compiler-ssr@3.4.7:
|
||||
resolution: {integrity: sha512-PvYeSOvnCkST5mGS0TLwEn5w+4GavtEn6adcq8AspbHaIr+mId5hp7cG3ASy3iy8b+LuXEG2/QaV/nj5BQ/Aww==}
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.4.7
|
||||
'@vue/shared': 3.4.7
|
||||
dev: false
|
||||
|
||||
/@vue/devtools-api@6.5.1:
|
||||
resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==}
|
||||
@ -4867,12 +4866,8 @@ packages:
|
||||
resolution: {integrity: sha512-/zYUwiHD8j7gKx2argXEMCUXVST6q/21DFU0sTfNX0URJroCe3b1UF6vLJ3lQDfLNIiiRl2ONp7Nh5UVWS6QnA==}
|
||||
dev: false
|
||||
|
||||
/@vue/shared@3.4.5:
|
||||
resolution: {integrity: sha512-6XptuzlMvN4l4cDnDw36pdGEV+9njYkQ1ZE0Q6iZLwrKefKaOJyiFmcP3/KBDHbt72cJZGtllAc1GaHe6XGAyg==}
|
||||
|
||||
/@vue/shared@3.4.7:
|
||||
resolution: {integrity: sha512-G+i4glX1dMJk88sbJEcQEGWRQnVm9eIY7CcQbO5dpdsD9SF8jka3Mr5OqZYGjczGN1+D6EUwdu6phcmcx9iuPA==}
|
||||
dev: false
|
||||
|
||||
/@vuepress/bundler-vite@2.0.0-rc.0(@types/node@20.9.1)(sass@1.69.7)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-rX8S8IYpqqlJfNPstS/joorpxXx/4WuE7+gDM31i2HUrxOKGZVzq8ZsRRRU2UdoTwHZSd3LpUS4sMtxE5xLK1A==}
|
||||
@ -4904,7 +4899,7 @@ packages:
|
||||
- typescript
|
||||
dev: false
|
||||
|
||||
/@vuepress/bundler-webpack@2.0.0-rc.0(@vue/compiler-sfc@3.4.5)(typescript@5.3.3):
|
||||
/@vuepress/bundler-webpack@2.0.0-rc.0(@vue/compiler-sfc@3.4.7)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-PUbjaQCTE+pwkmHkozT4CCjdEiAEO89XOXKTO/VwEsv6hWNeT97fi7TnScV/x8R/9WeA45QrW3eHipMwkKJ8uQ==}
|
||||
dependencies:
|
||||
'@types/express': 4.17.21
|
||||
@ -4926,7 +4921,7 @@ packages:
|
||||
postcss-loader: 7.3.3(postcss@8.4.31)(webpack@5.89.0)
|
||||
style-loader: 3.3.3(webpack@5.89.0)
|
||||
vue: 3.4.7(typescript@5.3.3)
|
||||
vue-loader: 17.3.1(@vue/compiler-sfc@3.4.5)(vue@3.4.7)(webpack@5.89.0)
|
||||
vue-loader: 17.3.1(@vue/compiler-sfc@3.4.7)(vue@3.4.7)(webpack@5.89.0)
|
||||
vue-router: 4.2.5(vue@3.4.7)
|
||||
webpack: 5.89.0
|
||||
webpack-chain: 6.5.1
|
||||
@ -4980,7 +4975,7 @@ packages:
|
||||
resolution: {integrity: sha512-uoOaZP1MdxZYJIAJcRcmYKKeCIVnxZeOuLMOOB9CPuAKSalT1RvJ1lztw6RX3q9SPnlqtSZPQXDncPAZivw4pA==}
|
||||
dependencies:
|
||||
'@vuepress/client': 2.0.0-rc.0(typescript@5.3.3)
|
||||
'@vuepress/markdown': 2.0.0-rc.0
|
||||
'@vuepress/markdown': 2.0.0-rc.0(patch_hash=zvwmijlesxcdy3i4trojywcm7y)
|
||||
'@vuepress/shared': 2.0.0-rc.0
|
||||
'@vuepress/utils': 2.0.0-rc.0
|
||||
vue: 3.4.7(typescript@5.3.3)
|
||||
@ -4990,7 +4985,7 @@ packages:
|
||||
- typescript
|
||||
dev: false
|
||||
|
||||
/@vuepress/markdown@2.0.0-rc.0:
|
||||
/@vuepress/markdown@2.0.0-rc.0(patch_hash=zvwmijlesxcdy3i4trojywcm7y):
|
||||
resolution: {integrity: sha512-USmqdKKMT6ZFHYRztTjKUlO8qgGfnEygMAAq4AzC/uYXiEfrbMBLAWJhteyGS56P3rGLj0OPAhksE681bX/wOg==}
|
||||
dependencies:
|
||||
'@mdit-vue/plugin-component': 1.0.0
|
||||
@ -5012,6 +5007,7 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
patched: true
|
||||
|
||||
/@vuepress/plugin-active-header-links@2.0.0-rc.0(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-UJdXLYNGL5Wjy5YGY8M2QgqT75bZ95EHebbqGi8twBdIJE9O+bM+dPJyYtAk2PIVqFORiw3Hj+PchsNSxdn9+g==}
|
||||
@ -5033,7 +5029,7 @@ packages:
|
||||
dependencies:
|
||||
'@types/markdown-it': 13.0.7
|
||||
'@vuepress/core': 2.0.0-rc.0(typescript@5.3.3)
|
||||
'@vuepress/markdown': 2.0.0-rc.0
|
||||
'@vuepress/markdown': 2.0.0-rc.0(patch_hash=zvwmijlesxcdy3i4trojywcm7y)
|
||||
'@vuepress/shared': 2.0.0-rc.0
|
||||
'@vuepress/utils': 2.0.0-rc.0
|
||||
markdown-it: 13.0.2
|
||||
@ -5074,7 +5070,7 @@ packages:
|
||||
dependencies:
|
||||
'@vuepress/client': 2.0.0-rc.0(typescript@5.3.3)
|
||||
'@vuepress/core': 2.0.0-rc.0(typescript@5.3.3)
|
||||
'@vuepress/markdown': 2.0.0-rc.0
|
||||
'@vuepress/markdown': 2.0.0-rc.0(patch_hash=zvwmijlesxcdy3i4trojywcm7y)
|
||||
'@vuepress/shared': 2.0.0-rc.0
|
||||
'@vuepress/utils': 2.0.0-rc.0
|
||||
vue: 3.4.7(typescript@5.3.3)
|
||||
@ -8610,13 +8606,13 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-processor-vue-blocks@0.1.1(@vue/compiler-sfc@3.4.5)(eslint@8.56.0):
|
||||
/eslint-processor-vue-blocks@0.1.1(@vue/compiler-sfc@3.4.7)(eslint@8.56.0):
|
||||
resolution: {integrity: sha512-9+dU5lU881log570oBwpelaJmOfOzSniben7IWEDRYQPPWwlvaV7NhOtsTuUWDqpYT+dtKKWPsgz4OkOi+aZnA==}
|
||||
peerDependencies:
|
||||
'@vue/compiler-sfc': ^3.3.0
|
||||
eslint: ^8.50.0
|
||||
dependencies:
|
||||
'@vue/compiler-sfc': 3.4.5
|
||||
'@vue/compiler-sfc': 3.4.7
|
||||
eslint: 8.56.0
|
||||
dev: true
|
||||
|
||||
@ -11611,6 +11607,11 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/lz-string@1.5.0:
|
||||
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/macos-release@3.1.0:
|
||||
resolution: {integrity: sha512-/M/R0gCDgM+Cv1IuBG1XGdfTFnMEG6PZeT+KGWHO/OG+imqmaD9CH5vHBTycEM3+Kc4uG2Il+tFAuUWLqQOeUA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
@ -14365,6 +14366,16 @@ packages:
|
||||
shikiji: 0.9.18
|
||||
dev: false
|
||||
|
||||
/shikiji-twoslash@0.9.18(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-+Np6QAdV244p6CVofefszrRWdcmbUNvTXaGV4V+wjKRyfp8jVTUtxjuVjtG7e3vyA8Nu989K99CCjhcTQOuEaw==}
|
||||
dependencies:
|
||||
'@typescript/twoslash': 3.2.4(typescript@5.3.3)
|
||||
shikiji-core: 0.9.18
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: false
|
||||
|
||||
/shikiji@0.9.18:
|
||||
resolution: {integrity: sha512-/tFMIdV7UQklzN13VjF0/XFzmii6C606Jc878hNezvB8ZR8FG8FW9j0I4J9EJre0owlnPntgLVPpHqy27Gs+DQ==}
|
||||
dependencies:
|
||||
@ -16031,7 +16042,7 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vue-loader@17.3.1(@vue/compiler-sfc@3.4.5)(vue@3.4.7)(webpack@5.89.0):
|
||||
/vue-loader@17.3.1(@vue/compiler-sfc@3.4.7)(vue@3.4.7)(webpack@5.89.0):
|
||||
resolution: {integrity: sha512-nmVu7KU8geOyzsStyyaxID/uBGDMS8BkPXb6Lu2SNkMawriIbb+hYrNtgftHMKxOSkjjjTF5OSSwPo3KP59egg==}
|
||||
peerDependencies:
|
||||
'@vue/compiler-sfc': '*'
|
||||
@ -16043,7 +16054,7 @@ packages:
|
||||
vue:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@vue/compiler-sfc': 3.4.5
|
||||
'@vue/compiler-sfc': 3.4.7
|
||||
chalk: 4.1.2
|
||||
hash-sum: 2.0.0
|
||||
vue: 3.4.7(typescript@5.3.3)
|
||||
|
||||
@ -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