シンタックスハイライト

unifast で利用できる 4 つのシンタックスハイライトエンジン (tree-sitter、syntect、Shiki、highlight.js) から選択します。

unifast は 4 つのシンタックスハイライトエンジンをサポートしています。そのうち 2 つ (tree-sittersyntect) は Rust コンパイラ内部で動作し、残りの 2 つ (Shikihighlight.js) は JavaScript で動作します。

比較

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 は ts- で始まる CSS クラス名を生成します。これらのクラスに対応する 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 は sy- で始まる CSS クラス名を生成します。これらのクラスに対応する 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/highlightlowlight (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;
}

関連項目