Skip to content

Commit

Permalink
feat: introduce highlight.shikiEngine option (#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu authored Sep 16, 2024
1 parent a288cfa commit 150e2d4
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 44 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
},
"dependencies": {
"@nuxt/kit": "^3.13.1",
"@shikijs/transformers": "^1.17.0",
"@shikijs/transformers": "^1.17.7",
"@types/hast": "^3.0.4",
"@types/mdast": "^4.0.4",
"@vue/compiler-core": "^3.5.4",
Expand Down Expand Up @@ -100,7 +100,7 @@
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.0",
"scule": "^1.3.0",
"shiki": "^1.17.0",
"shiki": "^1.17.7",
"ufo": "^1.5.4",
"unified": "^11.0.5",
"unist-builder": "^4.0.0",
Expand Down
7 changes: 6 additions & 1 deletion playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ export default defineNuxtConfig({
'@nuxt/ui',
'../src/module'
],

mdc: {
highlight: {
theme: {
default: 'vitesse-light',
dark: 'material-theme-palenight'
},
shikiEngine: 'javascript',
preload: [
'sql'
]
Expand All @@ -23,7 +25,10 @@ export default defineNuxtConfig({
}
}
},

devtools: {
enabled: true
}
},

compatibilityDate: '2024-09-16'
})
74 changes: 39 additions & 35 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ function resolveOptions(options: ModuleOptions) {
default: 'github-light',
dark: 'github-dark'
}
options.highlight.shikiEngine ||= 'oniguruma'
options.highlight.langs ||= DefaultHighlightLangs

if (options.highlight.preload) {
Expand Down
9 changes: 6 additions & 3 deletions src/runtime/highlighter/shiki.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { CodeToHastOptions } from 'shiki/core'
import type { HighlighterCore, LanguageInput, ShikiTransformer, ThemeInput } from 'shiki'
import type { HighlighterCore, LanguageInput, ShikiTransformer, ThemeInput, RegexEngine } from 'shiki'
import type { Element } from 'hast'
import type { MdcConfig, Highlighter } from '@nuxtjs/mdc'

Expand All @@ -16,6 +16,8 @@ export interface CreateShikiHighlighterOptions {
options?: { wrapperStyle?: string }
/* A function to custom mdc configs */
getMdcConfigs?: () => Promise<MdcConfig[]>
/* Shiki regex engine */
engine?: RegexEngine | Promise<RegexEngine>
}

export function createShikiHighlighter({
Expand All @@ -24,7 +26,8 @@ export function createShikiHighlighter({
bundledLangs = {},
bundledThemes = {},
getMdcConfigs,
options: shikiOptions
options: shikiOptions,
engine
}: CreateShikiHighlighterOptions = {}): Highlighter {
let shiki: ReturnType<typeof _getShiki> | undefined
let configs: Promise<MdcConfig[]> | undefined
Expand All @@ -36,7 +39,7 @@ export function createShikiHighlighter({
const shiki: HighlighterCore = await createHighlighterCore({
langs,
themes,
loadWasm: () => import('shiki/wasm')
engine
})

for await (const config of await getConfigs()) {
Expand Down
13 changes: 11 additions & 2 deletions src/templates/mdc-highlighter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,16 @@ export async function mdcHighlighter({
...options?.themes || []
]))

const {
shikiEngine = 'oniguruma'
} = options

return [
'import { getMdcConfigs } from \'#mdc-configs\'',
shikiEngine === 'javascript'
? 'import { createJavaScriptRegexEngine } from \'shiki/engine/javascript\''
: 'import { createWasmOnigEngine } from \'shiki/engine/oniguruma\'',
code,

'const bundledLangs = {',
...Array.from(langsMap.entries())
.map(([name, lang]) => typeof lang === 'string'
Expand All @@ -86,7 +92,10 @@ export async function mdcHighlighter({
theme: options.theme,
wrapperStyle: options.wrapperStyle
}),
'const highlighter = createShikiHighlighter({ bundledLangs, bundledThemes, options, getMdcConfigs })',
shikiEngine === 'javascript'
? 'const engine = createJavaScriptRegexEngine({ forgiving: true })'
: `const engine = createWasmOnigEngine(() => import('shiki/wasm'))`,
'const highlighter = createShikiHighlighter({ bundledLangs, bundledThemes, options, getMdcConfigs, engine })',
'export default highlighter'
].join('\n')
}
Expand Down
10 changes: 10 additions & 0 deletions src/types/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ export interface ModuleOptions {
*/
themes?: (BundledTheme | ThemeRegistrationAny)[]

/**
* Engine to be used for Shiki
*
* Note that the `javascript` engine still in experimental, use with caution.
*
* @see https://shiki.style/guide/regex-engines
* @default 'oniguruma'
*/
shikiEngine?: 'oniguruma' | 'javascript'

/**
* Preloaded languages that will be available for highlighting code blocks.
*
Expand Down
4 changes: 3 additions & 1 deletion test/utils/parser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { vi } from 'vitest'
import { createWasmOnigEngine } from 'shiki/engine/oniguruma'
import { parseMarkdown as _parseMarkDown } from '../../src/runtime/parser'
import type { MDCParseOptions } from '../../src/types'
import { rehypeHighlight } from '../../src/runtime/highlighter/rehype-nuxt'
Expand Down Expand Up @@ -33,7 +34,8 @@ export const parseMarkdown = (md: string, options: MDCParseOptions = {}) => {
import('shiki/themes/github-dark.mjs')
],
options: {},
getMdcConfigs: async () => []
getMdcConfigs: async () => [],
engine: createWasmOnigEngine(import('shiki/wasm'))
})

options.highlight.highlighter = highlighter
Expand Down

0 comments on commit 150e2d4

Please sign in to comment.