diff --git a/__tests__/e2e/markdown-extensions/markdown-extensions.test.ts b/__tests__/e2e/markdown-extensions/markdown-extensions.test.ts
index aa1f6ff2a195..42a8989140ab 100644
--- a/__tests__/e2e/markdown-extensions/markdown-extensions.test.ts
+++ b/__tests__/e2e/markdown-extensions/markdown-extensions.test.ts
@@ -163,19 +163,19 @@ describe('Line Numbers', () => {
describe('Import Code Snippets', () => {
test('basic', async () => {
const lines = page.locator('#basic-code-snippet + div code > span')
- expect(await lines.count()).toBe(22)
+ expect(await lines.count()).toBe(11)
})
test('specify region', async () => {
const lines = page.locator('#specify-region + div code > span')
- expect(await lines.count()).toBe(6)
+ expect(await lines.count()).toBe(3)
})
test('with other features', async () => {
const div = page.locator('#with-other-features + div')
expect(await getClassList(div)).toContain('line-numbers-mode')
const lines = div.locator('code > span')
- expect(await lines.count()).toBe(6)
+ expect(await lines.count()).toBe(3)
expect(await getClassList(lines.nth(0))).toContain('highlighted')
})
})
@@ -216,10 +216,10 @@ describe('Code Groups', () => {
// blocks
const blocks = div.locator('.blocks > div')
- expect(await blocks.nth(0).locator('code > span').count()).toBe(22)
+ expect(await blocks.nth(0).locator('code > span').count()).toBe(11)
expect(await getClassList(blocks.nth(1))).toContain('line-numbers-mode')
expect(await getClassList(blocks.nth(1))).toContain('language-ts')
- expect(await blocks.nth(1).locator('code > span').count()).toBe(6)
+ expect(await blocks.nth(1).locator('code > span').count()).toBe(3)
expect(
await getClassList(blocks.nth(1).locator('code > span').nth(0))
).toContain('highlighted')
diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts
index 4818af45e282..500c583ec27b 100644
--- a/docs/.vitepress/config.ts
+++ b/docs/.vitepress/config.ts
@@ -13,7 +13,15 @@ export default defineConfig({
cleanUrls: true,
markdown: {
- math: true
+ math: true,
+ codeTransformers: [
+ // We use `[!!code` in demo to prevent transformation, here we revert it back.
+ {
+ postprocess(code) {
+ return code.replace(/\[\!\!code/g, '[!code')
+ }
+ }
+ ]
},
sitemap: {
diff --git a/docs/guide/markdown.md b/docs/guide/markdown.md
index 3756235d1709..8806bd649b56 100644
--- a/docs/guide/markdown.md
+++ b/docs/guide/markdown.md
@@ -80,7 +80,7 @@ For more details, see [Frontmatter](../reference/frontmatter-config).
**Input**
-```
+```md
| Tables | Are | Cool |
| ------------- | :-----------: | ----: |
| col 3 is | right-aligned | $1600 |
@@ -265,7 +265,7 @@ Wraps in a
## Syntax Highlighting in Code Blocks
-VitePress uses [Shiki](https://shiki.matsu.io/) to highlight language syntax in Markdown code blocks, using coloured text. Shiki supports a wide variety of programming languages. All you need to do is append a valid language alias to the beginning backticks for the code block:
+VitePress uses [Shikiji](https://github.com/antfu/shikiji) (an improved version of [Shiki](https://shiki.matsu.io/)) to highlight language syntax in Markdown code blocks, using coloured text. Shiki supports a wide variety of programming languages. All you need to do is append a valid language alias to the beginning backticks for the code block:
**Input**
@@ -377,7 +377,7 @@ export default { // Highlighted
}
```
-Alternatively, it's possible to highlight directly in the line by using the `// [!code hl]` comment.
+Alternatively, it's possible to highlight directly in the line by using the `// [!code hightlight]` comment.
**Input**
@@ -386,7 +386,7 @@ Alternatively, it's possible to highlight directly in the line by using the `//
export default {
data () {
return {
- msg: 'Highlighted!' // [!code hl]
+ msg: 'Highlighted!' // [!!code highlight]
}
}
}
@@ -399,7 +399,7 @@ export default {
export default {
data() {
return {
- msg: 'Highlighted!' // [!code hl]
+ msg: 'Highlighted!' // [!code highlight]
}
}
}
@@ -413,14 +413,12 @@ Additionally, you can define a number of lines to focus using `// [!code focus:<
**Input**
-Note that only one space is required after `!code`, here are two to prevent processing.
-
````
```js
export default {
data () {
return {
- msg: 'Focused!' // [!code focus]
+ msg: 'Focused!' // [!!code focus]
}
}
}
@@ -445,15 +443,13 @@ Adding the `// [!code --]` or `// [!code ++]` comments on a line will create a d
**Input**
-Note that only one space is required after `!code`, here are two to prevent processing.
-
````
```js
export default {
data () {
return {
- msg: 'Removed' // [!code --]
- msg: 'Added' // [!code ++]
+ msg: 'Removed' // [!!code --]
+ msg: 'Added' // [!!code ++]
}
}
}
@@ -479,15 +475,13 @@ Adding the `// [!code warning]` or `// [!code error]` comments on a line will co
**Input**
-Note that only one space is required after `!code`, here are two to prevent processing.
-
````
```js
export default {
data () {
return {
- msg: 'Error', // [!code error]
- msg: 'Warning' // [!code warning]
+ msg: 'Error', // [!!code error]
+ msg: 'Warning' // [!!code warning]
}
}
}
diff --git a/docs/reference/site-config.md b/docs/reference/site-config.md
index c6838c503059..b5e124d2d981 100644
--- a/docs/reference/site-config.md
+++ b/docs/reference/site-config.md
@@ -454,7 +454,7 @@ When using the default theme, enabling this option will display each page's last
- Type: `MarkdownOption`
-Configure Markdown parser options. VitePress uses [Markdown-it](https://github.com/markdown-it/markdown-it) as the parser, and [Shiki](https://shiki.matsu.io/) to highlight language syntax. Inside this option, you may pass various Markdown related options to fit your needs.
+Configure Markdown parser options. VitePress uses [Markdown-it](https://github.com/markdown-it/markdown-it) as the parser, and [Shikiji](https://github.com/antfu/shikiji) (an improved version of [Shiki](https://shiki.matsu.io/)) to highlight language syntax. Inside this option, you may pass various Markdown related options to fit your needs.
```js
export default {
@@ -462,87 +462,7 @@ export default {
}
```
-Below are all the options that you can have in this object:
-
-```ts
-interface MarkdownOptions extends MarkdownIt.Options {
- // Custom theme for syntax highlighting.
- // You can use an existing theme.
- // See: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
- // Or add your own theme.
- // See: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
- theme?:
- | Shiki.IThemeRegistration
- | { light: Shiki.IThemeRegistration; dark: Shiki.IThemeRegistration }
-
- // Enable line numbers in code block.
- lineNumbers?: boolean
-
- // Add support for your own languages.
- // https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
- languages?: Shiki.ILanguageRegistration[]
-
- // markdown-it-anchor plugin options.
- // See: https://github.com/valeriangalliat/markdown-it-anchor#usage
- anchor?: anchorPlugin.AnchorOptions
-
- // markdown-it-attrs plugin options.
- // See: https://github.com/arve0/markdown-it-attrs
- attrs?: {
- leftDelimiter?: string
- rightDelimiter?: string
- allowedAttributes?: Array
- disable?: boolean
- }
-
- // specify default language for syntax highlighter
- defaultHighlightLang?: string
-
- // @mdit-vue/plugin-frontmatter plugin options.
- // See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-frontmatter#options
- frontmatter?: FrontmatterPluginOptions
-
- // @mdit-vue/plugin-headers plugin options.
- // See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-headers#options
- headers?: HeadersPluginOptions | boolean
-
- // @mdit-vue/plugin-sfc plugin options.
- // See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-sfc#options
- sfc?: SfcPluginOptions
-
- // @mdit-vue/plugin-toc plugin options.
- // See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
- toc?: TocPluginOptions
-
- // @mdit-vue/plugin-component plugin options.
- // See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-component#options
- component?: ComponentPluginOptions
-
- // Configure the Markdown-it instance.
- config?: (md: MarkdownIt) => void
-
- // Same as `config` but will be applied before all other plugins.
- preConfig?: (md: MarkdownIt) => void
-
- // Disable cache (experimental)
- cache?: boolean
-
- // Math support (experimental)
- // You need to install `markdown-it-mathjax3` and set `math` to `true` to enable it.
- // You can also pass options to `markdown-it-mathjax3` here.
- // See: https://github.com/tani/markdown-it-mathjax3#customization
- math?: boolean | any
-
- // Global custom container titles
- container?: {
- infoLabel?: string
- tipLabel?: string
- warningLabel?: string
- dangerLabel?: string
- detailsLabel?: string
- }
-}
-```
+Check the [type declaration and jsdocs](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts) for all the options available.
### vite
diff --git a/package.json b/package.json
index 61bfb5445b5b..c1d3f9c76fa2 100644
--- a/package.json
+++ b/package.json
@@ -101,7 +101,8 @@
"mark.js": "8.11.1",
"minisearch": "^6.2.0",
"mrmime": "^1.0.1",
- "shiki": "^0.14.5",
+ "shikiji": "^0.7.2",
+ "shikiji-transformers": "^0.7.2",
"vite": "^5.0.0",
"vue": "^3.3.8"
},
@@ -187,7 +188,6 @@
"rollup-plugin-dts": "^6.1.0",
"rollup-plugin-esbuild": "^6.1.0",
"semver": "^7.5.4",
- "shiki-processor": "^0.1.3",
"simple-git-hooks": "^2.9.0",
"sirv": "^2.0.3",
"sitemap": "^7.1.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f8016659f609..7593fd335990 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -44,9 +44,12 @@ importers:
mrmime:
specifier: ^1.0.1
version: 1.0.1
- shiki:
- specifier: ^0.14.5
- version: 0.14.5
+ shikiji:
+ specifier: ^0.7.2
+ version: 0.7.2
+ shikiji-transformers:
+ specifier: ^0.7.2
+ version: 0.7.2
vite:
specifier: ^5.0.0
version: 5.0.0(@types/node@20.9.1)
@@ -261,9 +264,6 @@ importers:
semver:
specifier: ^7.5.4
version: 7.5.4
- shiki-processor:
- specifier: ^0.1.3
- version: 0.1.3(shiki@0.14.5)
simple-git-hooks:
specifier: ^2.9.0
version: 2.9.0
@@ -1121,6 +1121,12 @@ packages:
'@types/node': 20.9.1
dev: true
+ /@types/hast@3.0.3:
+ resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==}
+ dependencies:
+ '@types/unist': 3.0.2
+ dev: false
+
/@types/http-errors@2.0.4:
resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
dev: true
@@ -1180,6 +1186,12 @@ packages:
'@types/linkify-it': 3.0.5
'@types/mdurl': 1.0.5
+ /@types/mdast@4.0.3:
+ resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==}
+ dependencies:
+ '@types/unist': 3.0.2
+ dev: false
+
/@types/mdurl@1.0.5:
resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==}
@@ -1268,10 +1280,18 @@ packages:
resolution: {integrity: sha512-m04Om5Gz6kbjUwAQ7XJJQ30OdEFsSmAVsvn4NYwcTRyMVpKKa1aPuESw1n2CxS5fYkOQv3nHgDKeNa8e76fUkw==}
dev: true
+ /@types/unist@3.0.2:
+ resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==}
+ dev: false
+
/@types/web-bluetooth@0.0.20:
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
dev: false
+ /@ungap/structured-clone@1.2.0:
+ resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
+ dev: false
+
/@vitejs/plugin-vue@4.5.0(vite@5.0.0)(vue@3.3.8):
resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -1590,9 +1610,6 @@ packages:
engines: {node: '>=12'}
dev: true
- /ansi-sequence-parser@1.1.1:
- resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==}
-
/ansi-styles@3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
engines: {node: '>=4'}
@@ -1761,6 +1778,10 @@ packages:
set-function-length: 1.1.1
dev: true
+ /ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+ dev: false
+
/chai@4.3.10:
resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==}
engines: {node: '>=4'}
@@ -1788,6 +1809,14 @@ packages:
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
dev: true
+ /character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+ dev: false
+
+ /character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+ dev: false
+
/check-error@1.0.3:
resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
dependencies:
@@ -1884,6 +1913,10 @@ packages:
delayed-stream: 1.0.0
dev: true
+ /comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+ dev: false
+
/commander@11.1.0:
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
engines: {node: '>=16'}
@@ -2177,6 +2210,17 @@ packages:
engines: {node: '>=0.4.0'}
dev: true
+ /dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+ dependencies:
+ dequal: 2.0.3
+ dev: false
+
/diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -2244,6 +2288,11 @@ packages:
engines: {node: '>=0.12'}
dev: true
+ /entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+ dev: false
+
/error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
dependencies:
@@ -2681,6 +2730,88 @@ packages:
function-bind: 1.1.2
dev: true
+ /hast-util-from-parse5@8.0.1:
+ resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==}
+ dependencies:
+ '@types/hast': 3.0.3
+ '@types/unist': 3.0.2
+ devlop: 1.1.0
+ hastscript: 8.0.0
+ property-information: 6.4.0
+ vfile: 6.0.1
+ vfile-location: 5.0.2
+ web-namespaces: 2.0.1
+ dev: false
+
+ /hast-util-parse-selector@4.0.0:
+ resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+ dependencies:
+ '@types/hast': 3.0.3
+ dev: false
+
+ /hast-util-raw@9.0.1:
+ resolution: {integrity: sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==}
+ dependencies:
+ '@types/hast': 3.0.3
+ '@types/unist': 3.0.2
+ '@ungap/structured-clone': 1.2.0
+ hast-util-from-parse5: 8.0.1
+ hast-util-to-parse5: 8.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.0.2
+ parse5: 7.1.2
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.1
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+ dev: false
+
+ /hast-util-to-html@9.0.0:
+ resolution: {integrity: sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==}
+ dependencies:
+ '@types/hast': 3.0.3
+ '@types/unist': 3.0.2
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-raw: 9.0.1
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.0.2
+ property-information: 6.4.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.3
+ zwitch: 2.0.4
+ dev: false
+
+ /hast-util-to-parse5@8.0.0:
+ resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==}
+ dependencies:
+ '@types/hast': 3.0.3
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ property-information: 6.4.0
+ space-separated-tokens: 2.0.2
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+ dev: false
+
+ /hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+ dependencies:
+ '@types/hast': 3.0.3
+ dev: false
+
+ /hastscript@8.0.0:
+ resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==}
+ dependencies:
+ '@types/hast': 3.0.3
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 6.4.0
+ space-separated-tokens: 2.0.2
+ dev: false
+
/he@1.2.0:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
@@ -2697,6 +2828,10 @@ packages:
lru-cache: 10.0.2
dev: true
+ /html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+ dev: false
+
/htmlparser2@5.0.1:
resolution: {integrity: sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==}
dependencies:
@@ -2979,6 +3114,7 @@ packages:
/jsonc-parser@3.2.0:
resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
+ dev: true
/jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
@@ -3215,6 +3351,19 @@ packages:
speech-rule-engine: 4.0.7
dev: true
+ /mdast-util-to-hast@13.0.2:
+ resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==}
+ dependencies:
+ '@types/hast': 3.0.3
+ '@types/mdast': 4.0.3
+ '@ungap/structured-clone': 1.2.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.0
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ dev: false
+
/mdurl@1.0.1:
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
dev: true
@@ -3246,6 +3395,33 @@ packages:
resolution: {integrity: sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==}
dev: true
+ /micromark-util-character@2.0.1:
+ resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==}
+ dependencies:
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ dev: false
+
+ /micromark-util-encode@2.0.0:
+ resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==}
+ dev: false
+
+ /micromark-util-sanitize-uri@2.0.0:
+ resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==}
+ dependencies:
+ micromark-util-character: 2.0.1
+ micromark-util-encode: 2.0.0
+ micromark-util-symbol: 2.0.0
+ dev: false
+
+ /micromark-util-symbol@2.0.0:
+ resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==}
+ dev: false
+
+ /micromark-util-types@2.0.0:
+ resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==}
+ dev: false
+
/micromatch@4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
@@ -3542,6 +3718,12 @@ packages:
resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==}
dev: true
+ /parse5@7.1.2:
+ resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
+ dependencies:
+ entities: 4.5.0
+ dev: false
+
/path-browserify@1.0.1:
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
dev: true
@@ -3704,6 +3886,10 @@ packages:
sisteransi: 1.0.5
dev: true
+ /property-information@6.4.0:
+ resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==}
+ dev: false
+
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: true
@@ -3977,21 +4163,17 @@ packages:
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
dev: true
- /shiki-processor@0.1.3(shiki@0.14.5):
- resolution: {integrity: sha512-oZqVFKweklwt+fj6yUPb+ffrCpYYoJ4RYxNt7w1+aoHetHq5ZaN6oX6+4HrypOi0s/O6A2neBpn+Xf6bM4KfsQ==}
- peerDependencies:
- shiki: 0.x
+ /shikiji-transformers@0.7.2:
+ resolution: {integrity: sha512-Nxg79GL++TvMjprCwhKzXWA4UFTP4fP3jZrkJAkUnSchqV20T2emyy/NgNhNjeX69JoUqTbB82rfVASj5Vec9Q==}
dependencies:
- shiki: 0.14.5
- dev: true
+ shikiji: 0.7.2
+ dev: false
- /shiki@0.14.5:
- resolution: {integrity: sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==}
+ /shikiji@0.7.2:
+ resolution: {integrity: sha512-gOaq7lqi3zSqGm+pMVxDD9NXA6myj5/7s7ZXgJcGdM5eHa49FrUPV46C5nl13rZnN3ZDjEmqF8ZPpNJjXeiBrQ==}
dependencies:
- ansi-sequence-parser: 1.1.1
- jsonc-parser: 3.2.0
- vscode-oniguruma: 1.7.0
- vscode-textmate: 8.0.0
+ hast-util-to-html: 9.0.0
+ dev: false
/side-channel@1.0.4:
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
@@ -4070,6 +4252,10 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+ dev: false
+
/spdx-correct@3.2.0:
resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
dependencies:
@@ -4188,6 +4374,13 @@ packages:
safe-buffer: 5.2.1
dev: true
+ /stringify-entities@4.0.3:
+ resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==}
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+ dev: false
+
/strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
@@ -4299,6 +4492,10 @@ packages:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
dev: true
+ /trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+ dev: false
+
/trouter@3.2.1:
resolution: {integrity: sha512-oY3CmIiEYOe1YMEzh++I67lrNOUldtCeuLL0vRPydvQLHZpSJ03B5dgDFlpFsiriMq6e//NDjjopjUzXOztHow==}
engines: {node: '>=6'}
@@ -4401,6 +4598,39 @@ packages:
/undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+ /unist-util-is@6.0.0:
+ resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
+ dependencies:
+ '@types/unist': 3.0.2
+ dev: false
+
+ /unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+ dependencies:
+ '@types/unist': 3.0.2
+ dev: false
+
+ /unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+ dependencies:
+ '@types/unist': 3.0.2
+ dev: false
+
+ /unist-util-visit-parents@6.0.1:
+ resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==}
+ dependencies:
+ '@types/unist': 3.0.2
+ unist-util-is: 6.0.0
+ dev: false
+
+ /unist-util-visit@5.0.0:
+ resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
+ dependencies:
+ '@types/unist': 3.0.2
+ unist-util-is: 6.0.0
+ unist-util-visit-parents: 6.0.1
+ dev: false
+
/universalify@2.0.1:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
@@ -4427,6 +4657,28 @@ packages:
engines: {node: '>= 0.8'}
dev: true
+ /vfile-location@5.0.2:
+ resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==}
+ dependencies:
+ '@types/unist': 3.0.2
+ vfile: 6.0.1
+ dev: false
+
+ /vfile-message@4.0.2:
+ resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
+ dependencies:
+ '@types/unist': 3.0.2
+ unist-util-stringify-position: 4.0.0
+ dev: false
+
+ /vfile@6.0.1:
+ resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==}
+ dependencies:
+ '@types/unist': 3.0.2
+ unist-util-stringify-position: 4.0.0
+ vfile-message: 4.0.2
+ dev: false
+
/vite-node@1.0.0-beta.5(@types/node@20.9.1)(supports-color@9.4.0):
resolution: {integrity: sha512-iXm+GTJbR9R6V/bCM1+LQqIohL/tncZVNGIcTtzpYThBD8yiTkDPvEjy1Mf7KFACtG3qY/0VDMrkuMtqG/JFhg==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -4540,12 +4792,6 @@ packages:
- terser
dev: true
- /vscode-oniguruma@1.7.0:
- resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==}
-
- /vscode-textmate@8.0.0:
- resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==}
-
/vue-demi@0.14.6(vue@3.3.8):
resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
engines: {node: '>=12'}
@@ -4610,6 +4856,10 @@ packages:
- debug
dev: true
+ /web-namespaces@2.0.1:
+ resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
+ dev: false
+
/web-resource-inliner@6.0.1:
resolution: {integrity: sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==}
engines: {node: '>=10.0.0'}
@@ -4728,3 +4978,7 @@ packages:
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
engines: {node: '>=12.20'}
dev: true
+
+ /zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+ dev: false
diff --git a/src/client/theme-default/styles/components/vp-code.css b/src/client/theme-default/styles/components/vp-code.css
index ee74e5b27d70..1ff9429b4ac1 100644
--- a/src/client/theme-default/styles/components/vp-code.css
+++ b/src/client/theme-default/styles/components/vp-code.css
@@ -1,7 +1,7 @@
-.dark .vp-code-light {
- display: none;
+.dark .vp-code span {
+ color: var(--shiki-dark, inherit);
}
-html:not(.dark) .vp-code-dark {
- display: none;
+html:not(.dark) .vp-code span {
+ color: var(--shiki-light, inherit);
}
diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts
index 3ec80b9cba5e..67c631a1c567 100644
--- a/src/node/markdown/markdown.ts
+++ b/src/node/markdown/markdown.ts
@@ -18,7 +18,6 @@ import MarkdownIt from 'markdown-it'
import anchorPlugin from 'markdown-it-anchor'
import attrsPlugin from 'markdown-it-attrs'
import emojiPlugin from 'markdown-it-emoji'
-import type { ILanguageRegistration, IThemeRegistration } from 'shiki'
import type { Logger } from 'vite'
import { containerPlugin, type ContainerOptions } from './plugins/containers'
import { highlight } from './plugins/highlight'
@@ -28,36 +27,139 @@ import { lineNumberPlugin } from './plugins/lineNumbers'
import { linkPlugin } from './plugins/link'
import { preWrapperPlugin } from './plugins/preWrapper'
import { snippetPlugin } from './plugins/snippet'
+import type {
+ ThemeRegistration,
+ BuiltinTheme,
+ LanguageInput,
+ ShikijiTransformer
+} from 'shikiji'
export type { Header } from '../shared'
export type ThemeOptions =
- | IThemeRegistration
- | { light: IThemeRegistration; dark: IThemeRegistration }
+ | ThemeRegistration
+ | BuiltinTheme
+ | {
+ light: ThemeRegistration | BuiltinTheme
+ dark: ThemeRegistration | BuiltinTheme
+ }
export interface MarkdownOptions extends MarkdownIt.Options {
- lineNumbers?: boolean
+ /* ==================== General Options ==================== */
+
+ /**
+ * Setup markdown-it instance before applying plugins
+ */
preConfig?: (md: MarkdownIt) => void
+ /**
+ * Setup markdown-it instance
+ */
config?: (md: MarkdownIt) => void
+ /**
+ * Disable cache (experimental)
+ */
+ cache?: boolean
+ externalLinks?: Record
+
+ /* ==================== Syntax Highlighting ==================== */
+
+ /**
+ * Custom theme for syntax highlighting.
+ *
+ * You can also pass an object with `light` and `dark` themes to support dual themes.
+ *
+ * @example { theme: 'github-dark' }
+ * @example { theme: { light: 'github-light', dark: 'github-dark' } }
+ *
+ * You can use an existing theme.
+ * @see https://github.com/antfu/shikiji/blob/main/docs/themes.md#all-themes
+ * Or add your own theme.
+ * @see https://github.com/antfu/shikiji/blob/main/docs/themes.md#load-custom-themes
+ */
+ theme?: ThemeOptions
+ /**
+ * Languages for syntax highlighting.
+ * @see https://github.com/antfu/shikiji/blob/main/docs/languages.md#all-themes
+ */
+ languages?: LanguageInput[]
+ /**
+ * Custom language aliases.
+ *
+ * @example { 'my-lang': 'js' }
+ * @see https://github.com/antfu/shikiji/tree/main#custom-language-aliases
+ */
+ languageAlias?: Record
+ /**
+ * Show line numbers in code blocks
+ * @default false
+ */
+ lineNumbers?: boolean
+ /**
+ * Fallback language when the specified language is not available.
+ */
+ defaultHighlightLang?: string
+ /**
+ * Transformers applied to code blocks
+ * @see https://github.com/antfu/shikiji#hast-transformers
+ */
+ codeTransformers?: ShikijiTransformer[]
+
+ /* ==================== Markdown It Plugins ==================== */
+
+ /**
+ * Options for `markdown-it-anchor`
+ * @see https://github.com/valeriangalliat/markdown-it-anchor
+ */
anchor?: anchorPlugin.AnchorOptions
+ /**
+ * Options for `markdown-it-attrs`
+ * @see https://github.com/arve0/markdown-it-attrs
+ */
attrs?: {
leftDelimiter?: string
rightDelimiter?: string
allowedAttributes?: Array
disable?: boolean
}
- defaultHighlightLang?: string
+ /**
+ * Options for `@mdit-vue/plugin-frontmatter`
+ * @see https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-frontmatter
+ */
frontmatter?: FrontmatterPluginOptions
+ /**
+ * Options for `@mdit-vue/plugin-headers`
+ * @see https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-headers
+ */
headers?: HeadersPluginOptions | boolean
+ /**
+ * Options for `@mdit-vue/plugin-sfc`
+ * @see https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-sfc
+ */
sfc?: SfcPluginOptions
- theme?: ThemeOptions
- languages?: ILanguageRegistration[]
+ /**
+ * Options for `@mdit-vue/plugin-toc`
+ * @see https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc
+ */
toc?: TocPluginOptions
- externalLinks?: Record
- cache?: boolean
+ /**
+ * Options for `@mdit-vue/plugin-component`
+ * @see https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-component
+ */
component?: ComponentPluginOptions
- math?: boolean | any
+ /**
+ * Options for `markdown-it-container`
+ * @see https://github.com/markdown-it/markdown-it-container
+ */
container?: ContainerOptions
+ /**
+ * Math support (experimental)
+ *
+ * You need to install `markdown-it-mathjax3` and set `math` to `true` to enable it.
+ * You can also pass options to `markdown-it-mathjax3` here.
+ * @default false
+ * @see https://vitepress.dev/guide/markdown#math-equations
+ */
+ math?: boolean | any
}
export type MarkdownRenderer = MarkdownIt
@@ -80,7 +182,9 @@ export const createMarkdownRenderer = async (
theme,
options.languages,
options.defaultHighlightLang,
- logger
+ logger,
+ options.codeTransformers,
+ options.languageAlias
)),
...options
})
diff --git a/src/node/markdown/plugins/highlight.ts b/src/node/markdown/plugins/highlight.ts
index 524632864a88..da9524ab604e 100644
--- a/src/node/markdown/plugins/highlight.ts
+++ b/src/node/markdown/plugins/highlight.ts
@@ -1,23 +1,23 @@
import { customAlphabet } from 'nanoid'
import c from 'picocolors'
+import type { LanguageInput, ShikijiTransformer } from 'shikiji'
import {
- BUNDLED_LANGUAGES,
- type HtmlRendererOptions,
- type ILanguageRegistration,
- type IThemeRegistration
-} from 'shiki'
-import {
- addClass,
- createDiffProcessor,
- createFocusProcessor,
- createHighlightProcessor,
- createRangeProcessor,
- defineProcessor,
+ bundledLanguages,
getHighlighter,
- type Processor
-} from 'shiki-processor'
+ addClassToHast,
+ isPlaintext as isPlainLang,
+ isSpecialLang
+} from 'shikiji'
import type { Logger } from 'vite'
import type { ThemeOptions } from '../markdown'
+import {
+ transformerCompactLineOptions,
+ transformerNotationDiff,
+ transformerNotationErrorLevel,
+ transformerNotationFocus,
+ transformerNotationHighlight,
+ type TransformerCompactLineOption
+} from 'shikiji-transformers'
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10)
@@ -29,7 +29,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10)
* 2. convert line numbers into line options:
* [{ line: number, classes: string[] }]
*/
-const attrsToLines = (attrs: string): HtmlRendererOptions['lineOptions'] => {
+const attrsToLines = (attrs: string): TransformerCompactLineOption[] => {
attrs = attrs.replace(/^(?:\[.*?\])?.*?([\d,-]+).*/, '$1').trim()
const result: number[] = []
if (!attrs) {
@@ -53,37 +53,38 @@ const attrsToLines = (attrs: string): HtmlRendererOptions['lineOptions'] => {
}))
}
-const errorLevelProcessor = defineProcessor({
- name: 'error-level',
- handler: createRangeProcessor({
- error: ['highlighted', 'error'],
- warning: ['highlighted', 'warning']
- })
-})
-
export async function highlight(
theme: ThemeOptions,
- languages: ILanguageRegistration[] = [],
+ languages?: LanguageInput[],
defaultLang: string = '',
- logger: Pick = console
+ logger: Pick = console,
+ userTransformers: ShikijiTransformer[] = [],
+ languageAlias: Record = {}
): Promise<(str: string, lang: string, attrs: string) => string> {
- const hasSingleTheme = typeof theme === 'string' || 'name' in theme
- const getThemeName = (themeValue: IThemeRegistration) =>
- typeof themeValue === 'string' ? themeValue : themeValue.name
-
- const processors: Processor[] = [
- createFocusProcessor(),
- createHighlightProcessor({ hasHighlightClass: 'highlighted' }),
- createDiffProcessor(),
- errorLevelProcessor
- ]
-
const highlighter = await getHighlighter({
- themes: hasSingleTheme ? [theme] : [theme.dark, theme.light],
- langs: [...BUNDLED_LANGUAGES, ...languages],
- processors
+ themes:
+ typeof theme === 'string' || 'name' in theme
+ ? [theme]
+ : [theme.light, theme.dark],
+ langs: languages?.length ? languages : Object.keys(bundledLanguages),
+ langAlias: languageAlias
})
+ const transformers: ShikijiTransformer[] = [
+ transformerNotationDiff(),
+ transformerNotationFocus({
+ classActiveLine: 'has-focus',
+ classActivePre: 'has-focused-lines'
+ }),
+ transformerNotationHighlight(),
+ transformerNotationErrorLevel(),
+ {
+ pre(node) {
+ addClassToHast(node, 'vp-code')
+ }
+ }
+ ]
+
const styleRE = /]*(style=".*?")/
const preRE = /^/
const vueRE = /-vue$/
@@ -102,7 +103,7 @@ export async function highlight(
if (lang) {
const langLoaded = highlighter.getLoadedLanguages().includes(lang as any)
- if (!langLoaded && !['ansi', 'plaintext', 'txt', 'text'].includes(lang)) {
+ if (!langLoaded && !isPlainLang(lang) && !isSpecialLang(lang)) {
logger.warn(
c.yellow(
`\nThe language '${lang}' is not loaded, falling back to '${
@@ -155,24 +156,21 @@ export async function highlight(
str = removeMustache(str).trimEnd()
- const codeToHtml = (theme: IThemeRegistration) => {
- const res =
- lang === 'ansi'
- ? highlighter.ansiToHtml(str, {
- lineOptions,
- theme: getThemeName(theme)
- })
- : highlighter.codeToHtml(str, {
- lang,
- lineOptions,
- theme: getThemeName(theme)
- })
- return fillEmptyHighlightedLine(cleanup(restoreMustache(res)))
- }
+ const highlighted = highlighter.codeToHtml(str, {
+ lang,
+ transformers: [
+ ...transformers,
+ transformerCompactLineOptions(lineOptions),
+ ...userTransformers
+ ],
+ ...(typeof theme === 'string' || 'name' in theme
+ ? { theme }
+ : {
+ themes: theme,
+ defaultColor: false
+ })
+ })
- if (hasSingleTheme) return codeToHtml(theme)
- const dark = addClass(codeToHtml(theme.dark), 'vp-code-dark', 'pre')
- const light = addClass(codeToHtml(theme.light), 'vp-code-light', 'pre')
- return dark + light
+ return fillEmptyHighlightedLine(cleanup(restoreMustache(highlighted)))
}
}
diff --git a/template/markdown-examples.md b/template/markdown-examples.md
index 8e55eb8add18..3ea9aa9f2aeb 100644
--- a/template/markdown-examples.md
+++ b/template/markdown-examples.md
@@ -4,11 +4,11 @@ This page demonstrates some of the built-in markdown extensions provided by Vite
## Syntax Highlighting
-VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting:
+VitePress provides Syntax Highlighting powered by [Shikiji](https://github.com/antfu/shikiji), with additional features like line-highlighting:
**Input**
-````
+````md
```js{4}
export default {
data () {