shikiphp
shikiphpはShikiの純粋なPHP移植版です。ShikiはVS Codeと同じTextMate文法とテーマでコードを色付けする構文ハイライターです。同じTextMate文法でコードをトークン化し、Shikiと同じVS Codeテーマで色付けすることで、Shiki 3.23.0と同じHTMLを生成します。すべてPHPで動作します。
Nodeランタイムは不要です。jsonとmbstring以外のPHP拡張機能も不要です。ネイティブOnigurumaバインディングも、JavaScriptプロセスの起動やホスト型APIの利用も必要ありません。
use Shikiphp\Shikiphp;
echo Shikiphp::codeToHtml(<<<'PHP'
<?php
function greet(string $name): string {
return "Hello, {$name}!";
}
PHP, [
'lang' => 'php',
'theme' => 'github-dark',
]);
shikiphpを選ぶ理由
PHPでサーバー側構文ハイライトを行うには、通常3つの妥協が必要です。Nodeを起動する、ホスト型のAPIを呼び出す、または言語を実際には理解しない正規表現ベースのハイライターで済ませることです。いずれもLaravel、WordPress、静的サイトのビルド工程にはうまく適合しません。
shikiphpはShikiの実際の処理パイプラインをPHPに移植することで、こうした妥協をなくします。
- TextMate文法トークナイザー(忠実な移植版は
vscode-textmate)。埋め込み言語、インジェクション、ネストしたリポジトリにも対応 - スコープセレクターの詳細度と親スコープの照合に対応したVS Codeテーマ解決
- Shiki互換のHTML:CSS変数によるライト/ダーク両テーマ、
codeToHast、トランスフォーマー(すべてのフック)、装飾、colorReplacements、structure: 'inline'、ANSI(lang: 'ansi')ハイライト - Shikiの全バンドル —
tm-grammars言語すべて(235と、それらに埋め込まれた補助文法18種)、およびtm-themesテーマすべて(65種)
Shiki 3.23.0との照合
出力は「十分近い」ものではなく、固定したShikiのリリースと照合されています。
| パッケージ | バージョン | 用途 |
|---|---|---|
shiki |
3.23.0 | JavaScript正規表現エンジンで実行する正解の基準 |
tm-grammars |
1.31.15 | 同梱文法 |
tm-themes |
1.12.2 | 同梱テーマ |
@shikijs/transformers |
4.2.0 | トランスフォーマーの同等性テスト |
Shiki自体を正解の基準としています。回帰テストハーネスには214のシナリオがあり、それぞれ既定オプションを使い、1つの言語とテーマで1つのサンプルを扱います。各シナリオをShikiとshikiphpでハイライトし、先頭と末尾の空白を取り除いた後の2つのHTML文字列が完全に一致することを確認します。シナリオ全体で、同梱されている253個の文法のうち167個、lang: 'ansi'、65個すべてのテーマをカバーします。オプション(structure、tabindex、colorReplacements、デュアルテーマ、defaultColorなど)、codeToTokensWithThemes、組み込みトランスフォーマーは個別の同等性テストで確認します。期待される出力は、同じバージョンのShikiから取得しています。
これに伴い、2つの制約があります。Shikiの既定エンジンはWebAssemblyにコンパイルされたOnigurumaですが、正解の基準には代わりにShikiのJavaScript正規表現エンジンを使っています。これはshikiphpが移植しているエンジンです。また、後発のShiki(4.x系)は検証されていません。
仕組み
shikiphpは、inline0/phasisの純粋PHPJavaScript正規表現エンジンを同梱し、oniguruma-to-esのPHP移植版を入力として使います。ShikiのJavaScript正規表現エンジンは、TextMate文法のOnigurumaパターンをJavaScriptRegExpに変換します。そのため、JS正規表現エンジンが自然な基盤となり、shikiphpはそのエンジンの出力とオフセット単位で一致できます。
code → grammar tokenizer → theme resolver → themed tokens → HTML
│
└─ OnigScanner → PatternConverter (oniguruma-to-es) → Shikiphp\Regex (JS RegExp engine)
パイプライン全体についてはアーキテクチャを参照してください。
必要条件
- PHP 8.2以降(CIではPHP 8.4でテストスイートを実行)
ext-jsonとext-mbstring(ほぼすべてのPHPビルドに同梱)
次に読むページ
- はじめに — インストールして最初のブロックを描画します。
- API — メソッドの全容。
- オプション —
codeToHtmlで使えるすべてのオプション。 - トランスフォーマー — フックのパイプラインと組み込み機能。
- CLI —
bin/shikiphp highlight、langs、themes。
ライセンス
MIT、著作権はinline0。TextMate文法とテーマは、各上流プロジェクトのライセンスに従います。