diff options
Diffstat (limited to 'packages/markdown')
-rw-r--r-- | packages/markdown/remark/src/index.ts | 1 | ||||
-rw-r--r-- | packages/markdown/remark/src/shiki.ts | 13 | ||||
-rw-r--r-- | packages/markdown/remark/src/types.ts | 2 | ||||
-rw-r--r-- | packages/markdown/remark/test/shiki.test.js | 28 |
4 files changed, 40 insertions, 4 deletions
diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts index 5849f5799..a9ae7ed59 100644 --- a/packages/markdown/remark/src/index.ts +++ b/packages/markdown/remark/src/index.ts @@ -37,6 +37,7 @@ export const markdownConfigDefaults: Required<AstroMarkdownOptions> = { themes: {}, wrap: false, transformers: [], + langAlias: {}, }, remarkPlugins: [], rehypePlugins: [], diff --git a/packages/markdown/remark/src/shiki.ts b/packages/markdown/remark/src/shiki.ts index 28f51c5e8..2f06ef9a9 100644 --- a/packages/markdown/remark/src/shiki.ts +++ b/packages/markdown/remark/src/shiki.ts @@ -45,24 +45,29 @@ export async function createShikiHighlighter({ defaultColor, wrap = false, transformers = [], + langAlias = {}, }: ShikiConfig = {}): Promise<ShikiHighlighter> { theme = theme === 'css-variables' ? cssVariablesTheme() : theme; const highlighter = await getHighlighter({ langs: ['plaintext', ...langs], + langAlias, themes: Object.values(themes).length ? Object.values(themes) : [theme], }); return { async highlight(code, lang = 'plaintext', options) { + const resolvedLang = langAlias[lang] ?? lang; const loadedLanguages = highlighter.getLoadedLanguages(); - if (!isSpecialLang(lang) && !loadedLanguages.includes(lang)) { + if (!isSpecialLang(lang) && !loadedLanguages.includes(resolvedLang)) { try { - await highlighter.loadLanguage(lang as BundledLanguage); + await highlighter.loadLanguage(resolvedLang as BundledLanguage); } catch (_err) { + const langStr = + lang === resolvedLang ? `"${lang}"` : `"${lang}" (aliased to "${resolvedLang}")`; console.warn( - `[Shiki] The language "${lang}" doesn't exist, falling back to "plaintext".`, + `[Shiki] The language ${langStr} doesn't exist, falling back to "plaintext".`, ); lang = 'plaintext'; } @@ -120,7 +125,7 @@ export async function createShikiHighlighter({ // Add "user-select: none;" for "+"/"-" diff symbols. // Transform `<span class="line"><span style="...">+ something</span></span> // into `<span class="line"><span style="..."><span style="user-select: none;">+</span> something</span></span>` - if (lang === 'diff') { + if (resolvedLang === 'diff') { const innerSpanNode = node.children[0]; const innerSpanTextNode = innerSpanNode?.type === 'element' && innerSpanNode.children?.[0]; diff --git a/packages/markdown/remark/src/types.ts b/packages/markdown/remark/src/types.ts index aa7b62c9a..d95676b55 100644 --- a/packages/markdown/remark/src/types.ts +++ b/packages/markdown/remark/src/types.ts @@ -3,6 +3,7 @@ import type * as mdast from 'mdast'; import type { Options as RemarkRehypeOptions } from 'remark-rehype'; import type { BuiltinTheme, + HighlighterCoreOptions, LanguageRegistration, ShikiTransformer, ThemeRegistration, @@ -37,6 +38,7 @@ export type ThemePresets = BuiltinTheme | 'css-variables'; export interface ShikiConfig { langs?: LanguageRegistration[]; + langAlias?: HighlighterCoreOptions['langAlias']; theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw; themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>; defaultColor?: 'light' | 'dark' | string | false; diff --git a/packages/markdown/remark/test/shiki.test.js b/packages/markdown/remark/test/shiki.test.js index c3cb81370..ca17ab1d8 100644 --- a/packages/markdown/remark/test/shiki.test.js +++ b/packages/markdown/remark/test/shiki.test.js @@ -101,4 +101,32 @@ describe('shiki syntax highlighting', () => { // Doesn't have `color` or `background-color` properties. assert.doesNotMatch(code, /color:/); }); + + it('the highlighter supports lang alias', async () => { + const highlighter = await createShikiHighlighter({ + langAlias: { + cjs: 'javascript', + }, + }); + + const html = await highlighter.highlight(`let test = "some string"`, 'cjs', { + attributes: { 'data-foo': 'bar', autofocus: true }, + }); + + assert.match(html, /data-language="cjs"/); + }); + + it('the markdown processsor support lang alias', async () => { + const processor = await createMarkdownProcessor({ + shikiConfig: { + langAlias: { + cjs: 'javascript', + }, + }, + }); + + const { code } = await processor.render('```cjs\nlet foo = "bar"\n```'); + + assert.match(code, /data-language="cjs"/); + }); }); |