diff --git a/packages/markdown-it/src/core.ts b/packages/markdown-it/src/core.ts index 234a01ca..58f7b17e 100644 --- a/packages/markdown-it/src/core.ts +++ b/packages/markdown-it/src/core.ts @@ -1,5 +1,15 @@ import type MarkdownIt from 'markdown-it' -import type { BuiltinTheme, CodeOptionsMeta, CodeOptionsThemes, CodeToHastOptions, HighlighterGeneric, ShikiTransformer, TransformerOptions } from 'shiki' +import type { + BuiltinLanguage, + BuiltinTheme, + CodeOptionsMeta, + CodeOptionsThemes, + CodeToHastOptions, + HighlighterGeneric, + LanguageInput, + ShikiTransformer, + TransformerOptions, +} from 'shiki' export interface MarkdownItShikiExtraOptions { /** @@ -21,6 +31,18 @@ export interface MarkdownItShikiExtraOptions { * @default true */ trimEndingNewline?: boolean + + /** + * When lang of code block is empty string, it will work. + * + * @default 'text' + */ + defaultLanguage?: LanguageInput | BuiltinLanguage + + /** + * When lang of code block is not included in langs of options, it will be as a fallback lang. + */ + fallbackLanguage?: LanguageInput | BuiltinLanguage } export type MarkdownItShikiSetupOptions = @@ -37,9 +59,17 @@ export function setupMarkdownIt( const { parseMetaString, trimEndingNewline = true, + defaultLanguage = 'text', + fallbackLanguage, } = options - + const langs = highlighter.getLoadedLanguages() markdownit.options.highlight = (code, lang = 'text', attrs) => { + if (lang === '') { + lang = defaultLanguage as string + } + if (fallbackLanguage && !langs.includes(lang)) { + lang = fallbackLanguage as string + } const meta = parseMetaString?.(attrs, code, lang) || {} const codeOptions: CodeToHastOptions = { ...options, diff --git a/packages/markdown-it/test/fixtures/b.md b/packages/markdown-it/test/fixtures/b.md new file mode 100644 index 00000000..ceab8676 --- /dev/null +++ b/packages/markdown-it/test/fixtures/b.md @@ -0,0 +1,3 @@ +```j +console.log('it works!') +``` diff --git a/packages/markdown-it/test/fixtures/b.out.html b/packages/markdown-it/test/fixtures/b.out.html new file mode 100644 index 00000000..963989fc --- /dev/null +++ b/packages/markdown-it/test/fixtures/b.out.html @@ -0,0 +1 @@ +
console.log('it works!')
diff --git a/packages/markdown-it/test/fixtures/c.md b/packages/markdown-it/test/fixtures/c.md new file mode 100644 index 00000000..52f8e2fc --- /dev/null +++ b/packages/markdown-it/test/fixtures/c.md @@ -0,0 +1,3 @@ +``` +console.log('it works!') +``` diff --git a/packages/markdown-it/test/fixtures/c.out.html b/packages/markdown-it/test/fixtures/c.out.html new file mode 100644 index 00000000..963989fc --- /dev/null +++ b/packages/markdown-it/test/fixtures/c.out.html @@ -0,0 +1 @@ +
console.log('it works!')
diff --git a/packages/markdown-it/test/index.test.ts b/packages/markdown-it/test/index.test.ts index 08ab7672..1c0d7b38 100644 --- a/packages/markdown-it/test/index.test.ts +++ b/packages/markdown-it/test/index.test.ts @@ -4,7 +4,7 @@ import MarkdownIt from 'markdown-it' import { transformerMetaHighlight } from '@shikijs/transformers' import Shiki from '../src' -it('run', async () => { +it('run for base', async () => { const md = MarkdownIt() md.use(await Shiki({ themes: { @@ -20,3 +20,37 @@ it('run', async () => { expect(result).toMatchFileSnapshot('./fixtures/a.out.html') }) +it('run for fallback language', async () => { + const md = MarkdownIt() + md.use(await Shiki({ + themes: { + light: 'vitesse-light', + dark: 'vitesse-dark', + }, + fallbackLanguage: 'js', + transformers: [ + transformerMetaHighlight(), + ], + })) + + const result = md.render(await fs.readFile(new URL('./fixtures/b.md', import.meta.url), 'utf-8')) + + expect(result).toMatchFileSnapshot('./fixtures/b.out.html') +}) +it('run for default language', async () => { + const md = MarkdownIt() + md.use(await Shiki({ + themes: { + light: 'vitesse-light', + dark: 'vitesse-dark', + }, + defaultLanguage: 'js', + transformers: [ + transformerMetaHighlight(), + ], + })) + + const result = md.render(await fs.readFile(new URL('./fixtures/c.md', import.meta.url), 'utf-8')) + + expect(result).toMatchFileSnapshot('./fixtures/c.out.html') +})