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 |
x58
x58
x58
x58
x58
x58
x951
x951
x4383
x1461
x1966
x1966
x1461
x951
x951
x951
x952
x952
x952
x951
x952
x952
x952
x951
x952
x952
x951
x951
x58
x1251
x1251
x1251
x1251
x2623
x2623
x2623
x16560
x3312
x2623
x3306
x3306
x3306
x2623
x1761
x1251
x58
x741
x741
x741
x741
x741
x741
x741
x741
x741
x741 |
|
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)
}
|