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