feat(markdown): add languageLabel config and improve languageAlias display

pull/4960/head
Elecmonkey 6 hours ago
parent bce0b53659
commit f21b48589d

@ -88,11 +88,24 @@ export interface MarkdownOptions extends Options {
languages?: (LanguageInput | BuiltinLanguage)[]
/**
* Custom language aliases.
* Maps custom language names to existing languages for syntax highlighting.
* Language identifiers with underscores will automatically display with spaces.
* Alias lookup is case-insensitive.
*
* @example { 'my_lang': 'python' }
*
* ```My_Lang uses Python highlighting, displays "My Lang"
*
* @example { 'my-lang': 'js' }
* @see https://shiki.style/guide/load-lang#custom-language-aliases
*/
languageAlias?: Record<string, string>
/**
* Custom language labels for display.
* Overrides the default language label shown in code blocks.
*
* @example { 'vue': 'Vue SFC' }
*/
languageLabel?: Record<string, string>
/**
* Show line numbers in code blocks
* @default false
@ -249,7 +262,10 @@ export async function createMarkdownRenderer(
// custom plugins
md.use(componentPlugin, { ...options.component })
.use(highlightLinePlugin)
.use(preWrapperPlugin, { codeCopyButtonTitle })
.use(preWrapperPlugin, {
codeCopyButtonTitle,
languageLabel: options.languageLabel
})
.use(snippetPlugin, srcDir)
.use(containerPlugin, options.container)
.use(imagePlugin, options.image)

@ -68,7 +68,10 @@ export async function highlight(
...(options.languages || []),
...Object.values(options.languageAlias || {})
],
langAlias: options.languageAlias
langAlias: options.languageAlias ?
Object.fromEntries(
Object.entries(options.languageAlias).map(([key, value]) => [key.toLowerCase(), value])
) : undefined
})
await options?.shikiSetup?.(highlighter)

@ -2,6 +2,7 @@ import type { MarkdownItAsync } from 'markdown-it-async'
export interface Options {
codeCopyButtonTitle: string
languageLabel?: Record<string, string>
}
export function preWrapperPlugin(md: MarkdownItAsync, options: Options) {
@ -17,11 +18,12 @@ export function preWrapperPlugin(md: MarkdownItAsync, options: Options) {
token.info = token.info.replace(/ active$/, '').replace(/ active /, ' ')
const lang = extractLang(token.info)
const langLabel = getLangLabel(lang, options.languageLabel)
return (
`<div class="language-${lang}${active}">` +
`<button title="${options.codeCopyButtonTitle}" class="copy"></button>` +
`<span class="lang">${lang}</span>` +
`<span class="lang">${langLabel}</span>` +
fence(...args) +
'</div>'
)
@ -46,3 +48,11 @@ function extractLang(info: string) {
.replace(/^vue-html$/, 'template')
.replace(/^ansi$/, '')
}
function getLangLabel(lang: string, languageLabel?: Record<string, string>): string {
if (languageLabel && languageLabel[lang]) {
return languageLabel[lang]
}
return lang.replace(/_/g, ' ')
}

Loading…
Cancel
Save