语法高亮

在 unifast 中,你可以从 tree-sitter、syntect、Shiki 和 highlight.js 这四种语法高亮引擎中自由选择。

unifast 支持四种语法高亮引擎。其中两种运行在 Rust 编译器内部(tree-sittersyntect),另外两种运行在 JavaScript 中(Shikihighlight.js)。

对比

tree-sittersyntectShikihighlight.js
运行时Rust(内置)Rust(内置)JavaScriptJavaScript
解析方式基于 AST(tree-sitter 语法)基于正则(TextMate 语法)基于正则(VS Code 语法)基于正则(highlight.js 语法)
速度最快较慢较慢
语言支持29 种语言 + syntect 回退100+(TextMate)VS Code 语法190+
CSS 输出基于类名(ts-*基于类名(sy-*内联样式或基于类名基于类名(hljs
所在包@unifast/node@unifast/node@unifast/shiki@unifast/highlight
适用场景需要精确高亮、覆盖范围广配置简单、启动快需要精细的主题控制利用 highlight.js 主题生态

使用 tree-sitter

tree-sitter 采用基于 AST 的解析方式实现精确的语法高亮。它运行在 Rust 编译器内部,原生支持 29 种语言;对于不支持的语言,会自动回退到 syntect。

tree-sitter 已包含在 @unifast/node 中 —— 无需单独安装。

import { compile, treeSitter } from "@unifast/node";

const result = compile(
  '```typescript\nconst x: number = 42;\n```',
  { plugins: [treeSitter()] }
);

tree-sitter 生成的 CSS 类名均以 ts- 为前缀。你需要在样式表中为这些类提供对应的 CSS 规则。

支持的语言

TypeScript、TSX、JavaScript、HTML、CSS、Python、Rust、JSON、YAML、Go、Ruby、TOML、Swift、PHP、Java、Lua、Scala、Zig、Elixir、OCaml、R、Make、Nix、Regex、Erlang、Bash、C、C++、CMake

同时也支持语言别名(例如 tspyrsshymlrb)。

使用 syntect

syntect 使用 TextMate 语法,完全运行在 Rust 编译器内部 —— 不会引入额外的 JavaScript 开销。

syntect 已包含在 @unifast/node 中 —— 无需单独安装。

import { compile, syntect } from "@unifast/node";

const result = compile(
  '```typescript\nconst x: number = 42;\n```',
  { plugins: [syntect()] }
);

syntect 生成的 CSS 类名均以 sy- 为前缀。你需要在样式表中为这些类提供对应的 CSS 规则。

使用 Shiki

Shiki 使用 VS Code 的 TextMate 语法引擎,可实现精确的高亮并支持主题。

import { compile } from "@unifast/node";
import { createShikiPlugin } from "@unifast/shiki";

const shiki = await createShikiPlugin({
  theme: "github-dark",
  langs: ["typescript", "rust", "bash"],
});

const result = compile(
  '```typescript\nconst x: number = 42;\n```',
  { plugins: [shiki] }
);

使用 highlight.js

@unifast/highlight 基于 lowlight(highlight.js 的封装),以 JavaScript HAST 转换的形式运行。它支持 190 多种语言,并可搭配任意 highlight.js 主题使用。

import { compile } from "@unifast/node";
import { highlight } from "@unifast/highlight";

const result = compile(
  '```typescript\nconst x: number = 42;\n```',
  { plugins: [highlight()] }
);

highlight.js 生成的类名带有 hljs 前缀。可以使用任意 highlight.js 主题 CSS 进行样式设置。

行号

所有引擎都支持行号。只需在编译选项中启用即可:

import { compile, treeSitter } from "@unifast/node";

const result = compile(source, {
  plugins: [treeSitter()],
  lineNumbers: true,
});

每一行都会被包裹在一个带 data-line 属性的 <span> 中,便于通过 CSS 进行样式定制:

[data-line]::before {
  content: attr(data-line);
  display: inline-block;
  width: 2rem;
  text-align: right;
  margin-right: 1rem;
  color: #6b7280;
}

参见