盒子
盒子
文章目录
  1. Nim编程入门
    1. 导入必要的库
    2. 构建 HTML

Nim 编程实现代码块语法高亮

Nim编程入门

这一节,我们介绍如何使用 Nim 语言实现 Html 代码块语法高亮。思路是,使用标准库 highlight 解析代码块语法,然后使用 karax, htmlgen 生成 Html。可以打开效果页预览。

导入必要的库

为了生成 Html 文件,我们需要 karax 构建 DSL,使用 htmlgen 生成 Html 字符串,使用 xmltree escape 字符。需要使用 nimble install karax 安装 karax

karax 可以用来构建服务器渲染(SSR),也可以构建单页应用(SPA)。简单地说,karax 既可以用于生成 Html,也可以用于生成 Javascript。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import karax / [karaxdsl, vdom]
import packages/docutils/highlite
from htmlgen import span
from xmltree import escape


## 代码块
const code = """
import hello

type
TreeObj* = object
left*: ref TreeObj
right*: ref TreeObj
value*: char
priority*: float
Tree* = ref TreeObj

## escape 函数会转义 `>=`
if a >= b:
echo a + b
"""

构建 HTML

karax 提供了 text 函数后接字符串,提供了 verbatim 函数后接 Html 字符串。

我们使用外联 CSS 文件来渲染关键字、注释、符号等语法信息。

其中 CSS 文件为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
span.Keyword {
color: blue;
font-size: 18px;
}

span.Operator {
color: purple;
font-size: 18px;
}

span.Comment {
color: green;
font-size: 18px;
}

Nim 代码如下,其中 buildLang 函数使用了标准库 highlight,用来解析语法信息,并生成 Html 字符串。

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
proc buildPre*(code: string): string =
let vnode = buildHtml(tdiv):
pre(class = "text"): text code
result = $vnode

proc buildVerbatimPre*(code: string, lang: string = "lang-Nim"): string =
let vnode = buildHtml(tdiv):
link(rel="stylesheet", `type`="text/css", href = "highlight.css")
pre(class = lang): verbatim code
result = $vnode

proc buildLang*(code: string): string =
var toknizr: GeneralTokenizer
initGeneralTokenizer(toknizr, code)
while true:
getNextToken(toknizr, langNim)
case toknizr.kind
of gtEof: break
of gtNone, gtWhitespace:
result.add substr(code, toknizr.start, toknizr.length +
toknizr.start - 1)
else:
result.add span(class=tokenClassToStr[toknizr.kind], escape(substr(code, toknizr.start, toknizr.length +
toknizr.start - 1)))


proc buildCode*(code: string, lang: string = "Nim"): string =
if getSourceLanguage(lang) != langNim:
return buildPre(code)
buildVerbatimPre(buildLang(code))

最后来测试语法高亮的效果,使用了 openDefaultBrowser 来打开浏览器,可以打开效果页预览。

1
2
3
4
5
6
import browsers
let file = "highlight.html"
let f = open(file, fmWrite)
f.write buildCode(code)
f.close()
openDefaultBrowser(file)