1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 |
x43
x43
x43
x43
x43
x43
x406
x406
x2493
x831
x1251
x1251
x831
x406
x406
x406
x407
x407
x407
x406
x407
x407
x407
x406
x407
x407
x406
x406
x43
x995
x995
x995
x995
x2054
x2054
x2054
x12930
x2586
x2054
x2581
x2581
x2581
x2054
x1420
x995
x43
x570
x570
x570
x570
x570
x570
x570
x570
x570
x570 |
|
import hljs from "highlight.js/lib/core"
import typescript from "highlight.js/lib/languages/typescript"
import { bgBlack, bgWhite, bgYellow, black, blue, cyan, gray, green, stripAnsiCode, underline, yellow } from "@std/fmt/colors"
import { unescape } from "@std/html/entities"
hljs.registerLanguage("typescript", typescript)
export function highlight(text: string, { underline: underlined = false, header = "", type = "" } = {} as { underline?: boolean; header?: string; type?: string }): string {
text = text
.replace(/`([^`]*?)`/g, (_, content) => {
let highlighted = process(unescape(hljs.highlight(content, { language: "typescript" }).value))
if (underlined) {
highlighted = underline(highlighted)
}
return highlighted
})
let background = bgWhite
if (type === "warn") {
text = yellow(stripAnsiCode(text))
background = bgYellow
}
if (type === "debug") {
text = gray(stripAnsiCode(text))
background = bgBlack
}
if (header) {
text = `${background(black(` ${header} `))} ${text}`
}
return text
}
function process(html: string) {
const stack = []
const regex = /(?<open><span[^>]*class="(?<classname>[^"]*)"[^>]*>)|(?<close><\/span>)/gs
let match = null as ReturnType<typeof regex.exec>
while ((match = regex.exec(html)) !== null) {
const [captured] = match
const { open, close, classname } = match.groups!
if (open) {
stack.push({ classname, a: match.index, b: match.index + captured.length })
}
if (close) {
const { a, b, classname } = stack.pop()!
return process(`${html.substring(0, a)}${color(html.substring(b, match.index), classname)}${html.substring(match.index + close.length)}`)
}
}
return html
}
function color(content: string, classname: string) {
return ({
"hljs-comment": gray,
"hljs-keyword": cyan,
"hljs-string": green,
"hljs-title function_": blue,
"hljs-title class_": blue,
"hljs-literal": yellow,
"hljs-number": yellow,
}[classname] ?? ((text: string) => text))(content)
}
|