main
ts 78 lines 2.15 KB
Raw
1 import type { BundledLanguage, BundledTheme, HighlighterGeneric } from "shiki"
2 import { createHighlighter } from "shiki"
3 import { createOnigurumaEngine } from "shiki/engine/oniguruma"
4
5 const THEME_LIGHT = "slack-ochin"
6 const THEME_DARK = "aurora-x"
7
8 let highlighterInstance: HighlighterGeneric<BundledLanguage, BundledTheme> | null = null
9 let highlighterPromise: Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> | null = null
10
11 export async function getHighlighter() {
12 if (highlighterInstance) {
13 return highlighterInstance
14 }
15 if (highlighterPromise) {
16 return highlighterPromise
17 }
18
19 highlighterPromise = createHighlighter({
20 themes: [import("shiki/themes/slack-ochin.mjs"), import("shiki/themes/aurora-x.mjs")],
21 langs: [
22 import("shiki/langs/javascript.mjs"),
23 import("shiki/langs/typescript.mjs"),
24 import("shiki/langs/powershell.mjs"),
25 import("shiki/langs/shellscript.mjs"),
26 import("shiki/langs/json.mjs"),
27 import("shiki/langs/xml.mjs"),
28 import("shiki/langs/yaml.mjs"),
29 import("shiki/langs/html.mjs"),
30 import("shiki/langs/scss.mjs"),
31 import("shiki/langs/css.mjs"),
32 import("shiki/langs/csharp.mjs"),
33 import("shiki/langs/http.mjs"),
34 import("shiki/langs/sql.mjs"),
35 import("shiki/langs/lua.mjs"),
36 import("shiki/langs/vb.mjs"),
37 import("shiki/langs/php.mjs"),
38 import("shiki/langs/markdown.mjs")
39 ],
40 engine: createOnigurumaEngine(() => import("shiki/wasm"))
41 }).then(instance => {
42 highlighterInstance = instance
43 return instance
44 })
45
46 return highlighterPromise
47 }
48
49 export const codeThemes = {
50 light: THEME_LIGHT,
51 dark: THEME_DARK
52 }
53
54 const LEADING_WHITESPACE_REGEX = /^\s+/
55 const TAB_CHAR_REGEX = /\t/g
56
57 export function resetIndent(el: HTMLElement) {
58 if (el) {
59 let lines: string[] = el.innerHTML?.split("\n")
60
61 if (lines?.length) {
62 if (lines[0] === "") {
63 lines.shift()
64 }
65
66 const matches = LEADING_WHITESPACE_REGEX.exec(lines[0] ?? "") ?? null
67 const indentation = matches !== null ? (matches[0] ?? "") : ""
68 if (indentation) {
69 lines = lines.map(line => {
70 line = line.replace(indentation, "")
71 return line.replace(TAB_CHAR_REGEX, " ")
72 })
73
74 el.innerHTML = lines.join("\n").trim()
75 }
76 }
77 }
78 }