跳转到正文

ShikiPHP

以纯 PHP 编写的语法高亮器,移植自 Shiki。使用 VS Code 主题和 TextMate 语法为代码块添加样式,无需 Node;在 214 个基准对照场景中,输出与 Shiki 3.23.0 一致。

终端
composer require shikiphp/shikiphp

最新版本 v0.1.0 MIT PHP 8.2+, ext-json, ext-mbstring

实践应用

从 PHP 模板或构建脚本中高亮代码片段,并打印其返回的 HTML。

每个代码块调用一次

Shikiphp::codeToHtml 接收代码、语言 ID 和主题 ID。它会返回完整的 pre 块,并将颜色以内联方式写入,因此无需额外样式表即可渲染。

传入 themes 映射,而不是 theme,同一个代码块就会通过 CSS 变量同时携带浅色和深色。

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 完全一致

214 个 oracle 场景涵盖 253 种内置语法中的 167 种、ANSI 和全部 65 种主题;除了开头和结尾的空白外,结果都与 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),以及内置的注释、元数据和空白字符转换器。

完整套件

所有 tm-grammars 语言(235,加上 18 种辅助语法)和 tm-themes 主题(65 种)均已包含。还包括 ANSI 终端输出、装饰和 colorReplacements。

CLI

使用 bin/shikiphp,直接从命令行高亮文件以输出到 HTML,或列出已捆绑的语言和主题。

无需 Node

可在 PHP 8.2+ 上运行,只需 ext-json 和 ext-mbstring。无需 Node 运行时、无需原生 Oniguruma 绑定,也无需调用外部命令。

为什么选择 ShikiPHP

在 PHP 所运行的环境中运行

代码高亮在 PHP 进程内完成,无需调用外部命令运行 Node,也无需调用托管的 API。适用于 Laravel、WordPress 或静态网站构建步骤。

可缓存的输出

相同代码使用相同选项时,总会生成相同的 HTML。可在构建时进行高亮,或以代码和选项为键缓存 HTML,直到源代码变更。

一个代码块兼顾明暗主题

主题映射会将第二个主题写为同一段标记中的 CSS 变量,只需几行 CSS 即可切换。defaultColor 选项决定以内联方式写入哪个主题。

为不可信输入设定限制

正则表达式引擎会记忆失败结果并防范 ReDoS,因此遇到病态模式时会变慢,而不会卡死。tokenizeMaxLineLength 选项会将超长行作为单个纯文本令牌输出。

对比

面向 PHP 网站的其他代码高亮方式,以及 ShikiPHP 的不同之处。

ShikiPHP 与其他工具的对比
Shiki 擅长领域位于 JavaScript 中的参考实现。它可在任何现代 JavaScript 运行时中运行,无需 Node.js API;按需加载语法和主题,并提供 TypeScript Twoslash 集成。 与 ShikiPHP 的区别ShikiPHP 将该流水线移植到 PHP,用于在 PHP 服务器上渲染的页面。它的 oracle 测试框架会将 HTML 与 Shiki 3.23.0 进行比较,而 Shiki 的主分支已经转向 v4。
Phiki 擅长领域一种 PHP 高亮器,同样使用 TextMate 语法和 VS Code 主题。它提供一个 league/commonmark 扩展,可与 Laravel 的 Str::markdown 配合使用,还支持终端输出和命令行二进制程序。 与 ShikiPHP 的区别Phiki 称其分词器的设计受 vscode-textmate 启发,但并非一对一翻译。ShikiPHP 移植了 vscode-textmate 和 oniguruma-to-es,并在 214 个 oracle 场景中将其 HTML 与 Shiki 的输出进行测试比较。
highlight.php 擅长领域一种服务端 PHP 移植版,源自 highlight.js,支持 185 种语言,采用原版的语言和样式定义,并能自动检测语言。 与 ShikiPHP 的区别ShikiPHP 使用 TextMate 语法进行分词,并使用 VS Code 主题着色;它使用与 Shiki 相同的文件,而且每次调用都会指定语言。
Torchlight 擅长领域兼容 VS Code 的代码高亮服务。它是一个 HTTP API,支持用于高亮、聚焦和差异标注的注释,并为 Laravel、CommonMark、Statamic 和其他技术栈提供官方客户端。 与 ShikiPHP 的区别ShikiPHP 在你的 PHP 进程中运行,无需托管 API。其内置的标注转换器会读取用于高亮、聚焦和差异行的注释。

问答

来自 ShikiPHP 文档的简明解答。

从入门指南开始,然后根据页面需要添加转换器、自定义语法或 ANSI 输出。