コンテンツへスキップ

ShikiPHP

純粋な PHP 構文ハイライター。Shiki の移植版です。Node を使わずに VS Code のテーマと TextMate 文法でコードブロックを装飾でき、214 のオラクルシナリオで Shiki 3.23.0 と一致する出力を生成します。

ターミナル
composer require shikiphp/shikiphp

最新リリース v0.1.0 MIT PHP 8.2+, ext-json, ext-mbstring

実践例

PHP テンプレートやビルドスクリプトのコードをハイライトし、返される HTML を出力します。

コードブロックごとに1回呼び出すだけ

Shikiphp::codeToHtml にコード、言語ID、テーマIDを渡します。色をインラインで記述した完全な pre ブロックが返されるので、追加のスタイルシートなしで表示できます。

themes の代わりにテーマのマップを渡すと、同じブロックにライトとダークの色が CSS 変数を通じて保持されます。theme

PHP
use Shikiphp\Shikiphp;

echo Shikiphp::codeToHtml(<<<'PHP'
<?php
function greet(string $name): string {
    return "Hello, {$name}!";
}
PHP, [
    'lang'  => 'php',
    'theme' => 'github-dark',
]);

本格的な TextMate 文法

vscode-textmate を忠実に移植。埋め込み言語、インジェクション、ネストしたリポジトリに対応し、Shiki や VS Code がトークン化するものと同じ文法を使用します。

VS Code のテーマ

vscode-textmate から移植したスコープセレクターの優先度と親スコープの照合に対応。単一テーマ、または CSS 変数によるライト・ダーク両テーマに対応します。

Shiki と同一の出力

167 個の同梱文法のうち 253 個、ANSI、および65種類すべてのテーマを対象とする214のオラクルシナリオで、Shiki 3.23.0 の HTML と一致します。先頭と末尾の空白を除き、出力は完全に一致します。JavaScript

純粋な PHP 正規表現エンジン

inline0/phasis の JavaScript RegExp エンジンを同梱し、oniguruma-to-es の移植版を通じて動作します。Shiki の JavaScript 正規表現エンジンも、同じ Oniguruma から RegExp への経路を使います。

トランスフォーマー

Shikiの全フック(preprocess, tokens, root, pre, code, line, span, postprocess)に加え、組み込みのnotation、meta、whitespace変換機能を備えています。

すべての機能を同梱

tm-grammars のすべての言語(235個と補助文法18個)と tm-themes のテーマ(65種類)を同梱しています。ANSI ターミナル出力、装飾、colorReplacements も含まれます。

CLI

ファイルを HTML でハイライトしたり、コマンドラインから bin/shikiphp を使って同梱言語やテーマを一覧表示したりできます。

Node 不要

PHP 8.2以降で動作し、ext-json と ext-mbstring のみを必要とします。Node ランタイムも、ネイティブの Oniguruma バインディングも、シェルコマンドの実行も不要です。

ShikiPHPを選ぶ理由

PHP が動く場所で動作

ハイライト処理は PHP プロセス内で行われ、Node のシェル実行やホストされた API の呼び出しは不要です。Laravel、WordPress、静的サイトのビルド手順に適しています。

キャッシュに適した出力

同じコードに同じオプションを指定すれば、常に同じ HTML が生成されます。ビルド時にハイライトするか、ソースが変わるまでコードとオプションをキーに HTML をキャッシュできます。

ライト・ダーク共通のブロック

テーママップを使うと、同じマークアップに2つ目のテーマを CSS 変数として記述でき、数行の CSS で切り替えられます。defaultColor オプションで、インラインに記述するテーマを選べます。

信頼できない入力への対策

正規表現エンジンは失敗をメモ化し、ReDoS を防ぐため、極端なパターンでも停止せず処理が遅くなるだけです。tokenizeMaxLineLength オプションを使うと、長すぎる行は1つのプレーントークンとして出力されます。

との比較

PHP サイトでコードをハイライトする他の方法と、ShikiPHPとの違いを紹介します。

他のツールとShikiPHPの比較
Shiki 得意なことJavaScript のリファレンス実装です。最新の JavaScript ランタイムで Node.js API なしに動作し、文法やテーマを必要に応じて読み込み、TypeScript Twoslash 統合機能を備えています。 ShikiPHPとの違いShikiPHP はそのパイプラインを PHP に移植し、PHP サーバーでページを表示します。オラクルハーネスは出力を Shiki 3.23.0 と比較しますが、Shiki のメインブランチは v4 に進んでいます。HTML
Phiki 得意なことTextMate 文法と VS Code テーマを使う PHP ハイライターです。Laravel の Str::markdown と連携する league/commonmark 拡張、ターミナル出力、コマンドライン実行ファイルを同梱しています。 ShikiPHPとの違いPhiki は、トークナイザーを vscode-textmate に着想を得たものと説明していますが、1対1の移植ではありません。ShikiPHP は vscode-textmate と oniguruma-to-es を移植し、214のオラクルシナリオでその HTML を Shiki の出力と照合しています。
highlight.php 得意なことPHP サーバーサイドの highlight.js 移植版です。元の言語定義とスタイル定義を使って185言語に対応し、言語を自動検出できます。 ShikiPHPとの違いShikiPHP は TextMate 文法でトークン化し、VS Code テーマで色付けします。Shiki と同じファイルを使い、呼び出しごとに言語を指定します。
Torchlight 得意なことVS Code 互換のハイライトサービスです。ハイライト、フォーカス、差分用のコメント注釈を備えた HTTP API で、Laravel、CommonMark、Statamic などのスタック向けに公式クライアントを提供します。 ShikiPHPとの違いShikiPHP はホストされた API なしで、PHP プロセス内で動作します。組み込みの記法トランスフォーマーは、ハイライト行、フォーカス行、差分行に同様のコメントを使います。

質問と回答

ShikiPHPのドキュメントから、簡潔に回答します。

まず入門ガイドから始め、ページに必要に応じてトランスフォーマー、カスタム文法、ANSI 出力を追加してください。