Spaces:
Running
Running
| import { createHighlighterCore } from 'shiki/core'; | |
| import { createJavaScriptRegexEngine } from 'shiki/engine/javascript'; | |
| export type CodeTheme = 'light' | 'dark'; | |
| const LANGUAGE_LOADERS = { | |
| bash: () => import('@shikijs/langs/bash'), | |
| c: () => import('@shikijs/langs/c'), | |
| cpp: () => import('@shikijs/langs/cpp'), | |
| csharp: () => import('@shikijs/langs/csharp'), | |
| css: () => import('@shikijs/langs/css'), | |
| dart: () => import('@shikijs/langs/dart'), | |
| diff: () => import('@shikijs/langs/diff'), | |
| dockerfile: () => import('@shikijs/langs/dockerfile'), | |
| go: () => import('@shikijs/langs/go'), | |
| graphql: () => import('@shikijs/langs/graphql'), | |
| html: () => import('@shikijs/langs/html'), | |
| java: () => import('@shikijs/langs/java'), | |
| javascript: () => import('@shikijs/langs/javascript'), | |
| json: () => import('@shikijs/langs/json'), | |
| jsonc: () => import('@shikijs/langs/jsonc'), | |
| jsx: () => import('@shikijs/langs/jsx'), | |
| kotlin: () => import('@shikijs/langs/kotlin'), | |
| less: () => import('@shikijs/langs/less'), | |
| lua: () => import('@shikijs/langs/lua'), | |
| markdown: () => import('@shikijs/langs/markdown'), | |
| mdx: () => import('@shikijs/langs/mdx'), | |
| nginx: () => import('@shikijs/langs/nginx'), | |
| perl: () => import('@shikijs/langs/perl'), | |
| php: () => import('@shikijs/langs/php'), | |
| powershell: () => import('@shikijs/langs/powershell'), | |
| python: () => import('@shikijs/langs/python'), | |
| r: () => import('@shikijs/langs/r'), | |
| regex: () => import('@shikijs/langs/regex'), | |
| ruby: () => import('@shikijs/langs/ruby'), | |
| rust: () => import('@shikijs/langs/rust'), | |
| scala: () => import('@shikijs/langs/scala'), | |
| scss: () => import('@shikijs/langs/scss'), | |
| shellscript: () => import('@shikijs/langs/shellscript'), | |
| sql: () => import('@shikijs/langs/sql'), | |
| swift: () => import('@shikijs/langs/swift'), | |
| toml: () => import('@shikijs/langs/toml'), | |
| tsx: () => import('@shikijs/langs/tsx'), | |
| typescript: () => import('@shikijs/langs/typescript'), | |
| xml: () => import('@shikijs/langs/xml'), | |
| yaml: () => import('@shikijs/langs/yaml'), | |
| } as const; | |
| type SupportedCodeLanguage = keyof typeof LANGUAGE_LOADERS; | |
| export type HighlightLanguage = SupportedCodeLanguage | 'text'; | |
| const LANGUAGE_ALIASES: Readonly<Record<string, SupportedCodeLanguage>> = { | |
| 'c#': 'csharp', | |
| 'c++': 'cpp', | |
| bat: 'shellscript', | |
| cmd: 'shellscript', | |
| cs: 'csharp', | |
| docker: 'dockerfile', | |
| gql: 'graphql', | |
| htm: 'html', | |
| js: 'javascript', | |
| md: 'markdown', | |
| ps1: 'powershell', | |
| py: 'python', | |
| rb: 'ruby', | |
| rs: 'rust', | |
| sh: 'bash', | |
| shell: 'shellscript', | |
| ts: 'typescript', | |
| yml: 'yaml', | |
| }; | |
| const THEME_NAMES: Record<CodeTheme, 'github-light' | 'github-dark'> = { | |
| light: 'github-light', | |
| dark: 'github-dark', | |
| }; | |
| const highlighterPromise = createHighlighterCore({ | |
| themes: [ | |
| import('@shikijs/themes/github-light'), | |
| import('@shikijs/themes/github-dark'), | |
| ], | |
| langs: [], | |
| engine: createJavaScriptRegexEngine(), | |
| }); | |
| const languagePromises = new Map<SupportedCodeLanguage, Promise<void>>(); | |
| export function normalizeCodeLanguage(value: string): HighlightLanguage { | |
| const candidate = value.trim().toLowerCase(); | |
| if (!candidate || ['text', 'txt', 'plain', 'plaintext'].includes(candidate)) return 'text'; | |
| const aliased = LANGUAGE_ALIASES[candidate] ?? candidate; | |
| return Object.hasOwn(LANGUAGE_LOADERS, aliased) | |
| ? aliased as SupportedCodeLanguage | |
| : 'text'; | |
| } | |
| export function codeThemeName(theme: CodeTheme): 'github-light' | 'github-dark' { | |
| return THEME_NAMES[theme]; | |
| } | |
| export async function getCodeHighlighter(language: HighlightLanguage) { | |
| const highlighter = await highlighterPromise; | |
| if (language === 'text' || highlighter.getLoadedLanguages().includes(language)) return highlighter; | |
| let loading = languagePromises.get(language); | |
| if (!loading) { | |
| loading = highlighter.loadLanguage(LANGUAGE_LOADERS[language]()).then(() => undefined); | |
| languagePromises.set(language, loading); | |
| } | |
| await loading; | |
| return highlighter; | |
| } | |