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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 |
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x12
x14
x14
x14
x14
x13
x14
x14
x14
x4
x14
x12
x1021
x1021
x995
x995
x995
x995
x995
x995
x995
x995
x1021
x12
x32
x32
x32
x32
x38
x38
x38
x38
x38
x19
x19
x19
x38
x13
x32
x12
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19
x19 |
|
import hljs from "highlight.js/lib/core"
import typescript from "highlight.js/lib/languages/typescript"
import css from "highlight.js/lib/languages/css"
import markdown from "highlight.js/lib/languages/markdown"
import xml from "highlight.js/lib/languages/xml"
import diff from "highlight.js/lib/languages/diff"
import yaml from "highlight.js/lib/languages/yaml"
import json from "highlight.js/lib/languages/json"
import { blue, bold, cyan, gray, green, italic, magenta, red, underline, yellow } from "@std/fmt/colors"
import { unescape } from "@std/html/entities"
hljs.registerLanguage("typescript", typescript)
hljs.registerLanguage("css", css)
hljs.registerLanguage("markdown", markdown)
hljs.registerLanguage("xml", xml)
hljs.registerLanguage("diff", diff)
hljs.registerLanguage("yaml", yaml)
hljs.registerLanguage("json", json)
export type HighlightOptions = {
underline?: boolean
raw?: boolean
language?: string
}
export function highlight(text: string, { underline: underlined = false, raw = false, language = "typescript" }: HighlightOptions = {}): string {
const colorize = (content: string) => {
let highlighted = process(unescape(hljs.highlight(content, { language }).value))
if (underlined)
highlighted = underline(highlighted)
return highlighted
}
if (raw)
return colorize(text)
return text.replace(/`([^`]*?)`/g, (_, content) => colorize(content))
}
export function inspect(value: unknown): string {
if (typeof value === "function")
return "fn"
return Deno.inspect(value, { colors: true, compact: true, depth: Infinity })
.replace(/\n\s+/g, " ")
.replace(/AbortSignal \{[^}]+?\}/g, "AbortSignal")
.replace(/\[Function: ([A-Z]\w*)\]/g, "$1")
.replace(/\[Function: (\w*)\]/g, "Function")
.replace(/\[Function \(anonymous\)]/g, "Function")
.replace(/\{ \[class (\w+)\] [^}]+?\}/g, "$1")
.replace(/\[Object: null prototype\] \{ url: [^,]+?, main: [^}]+?, filename: [^,]+?, dirname: [^,]+?\}/g, "import.meta")
}
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-quote": gray,
"hljs-meta": gray,
"hljs-code": gray,
"hljs-keyword": cyan,
"hljs-attr": cyan,
"hljs-attribute": cyan,
"hljs-type": cyan,
"hljs-built_in": cyan,
"hljs-string": green,
"hljs-regexp": green,
"hljs-addition": green,
"hljs-deletion": red,
"hljs-literal": yellow,
"hljs-number": yellow,
"hljs-bullet": yellow,
"hljs-symbol": yellow,
"hljs-title function_": blue,
"hljs-title class_": blue,
"hljs-section": blue,
"hljs-name": blue,
"hljs-selector-tag": blue,
"hljs-selector-class": magenta,
"hljs-selector-id": magenta,
"hljs-selector-pseudo": magenta,
"hljs-template-variable": magenta,
"hljs-variable": magenta,
"hljs-strong": bold,
"hljs-emphasis": italic,
}[classname] ?? ((text: string) => text))(content)
}
|