Zum Inhalt springen

shikiphp

shikiphp ist ein reiner PHP-Port von Shiki, dem Syntax-Highlighter, der Code mit denselben TextMate-Grammatiken und Themes wie VS Code einfärbt. Der Code wird mit denselben TextMate-Grammatiken tokenisiert und mit denselben VS Code-Themes gestaltet, die auch Shiki verwendet. So entsteht dieselbe HTML wie in Shiki 3.23.0 — vollständig in PHP.

Keine Node-Laufzeitumgebung. Keine PHP-Erweiterungen außer json und mbstring. Keine native Oniguruma-Bindung. Kein Aufruf eines JavaScript-Prozesses und kein gehostetes API.

PHP
use Shikiphp\Shikiphp;

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

Warum shikiphp

Serverseitiges Syntax-Highlighting in PHP erfordert üblicherweise einen von drei Kompromissen: Node aufrufen, eine gehostete API verwenden oder sich mit einem Regex-basierten Highlighter begnügen, der die Sprache nicht wirklich versteht. Nichts davon passt gut in einen Laravel-, WordPress- oder Static-Site-Build-Schritt.

shikiphp beseitigt diese Kompromisse, indem es Shikis echte Pipeline nach PHP portiert:

  • einen Tokenizer für TextMate-Grammatiken (ein originalgetreuer Port von vscode-textmate), einschließlich eingebetteter Sprachen, Injections und verschachtelter Repositories
  • Auflösung von VS Code-Themes mit Spezifität der Scope-Selektoren und Abgleich übergeordneter Scopes
  • Shiki-kompatible HTML: duale helle und dunkle Themes mit CSS-Variablen, codeToHast, Transformern (allen Hooks), Dekorationen, colorReplacements, structure: 'inline' und ANSI-Highlighting (lang: 'ansi')
  • das vollständige Shiki-Paket — alle tm-grammars-Sprachen (235 sowie 18 eingebettete Hilfsgrammatiken) und alle tm-themes Themes (65)

Mit Shiki 3.23.0 abgeglichen

Die Ausgabe ist nicht nur „nah genug“: Sie wird mit einer festgelegten Shiki-Version verglichen.

Paket Version Verwendungszweck
shiki 3.23.0 Referenz, ausgeführt mit seiner JavaScript-Regex-Engine
tm-grammars 1.31.15 mitgelieferte Grammatiken
tm-themes 1.12.2 mitgelieferte Themes
@shikijs/transformers 4.2.0 Paritätstests der Transformer

Shiki selbst dient als Referenz. Die Regressionstests umfassen 214 Szenarien, jeweils ein Beispiel in einer Sprache und einem Theme mit den Standardoptionen. Shiki und shikiphp heben jedes Szenario hervor. Nach dem Entfernen führender und nachgestellter Leerzeichen müssen die beiden HTML-Zeichenfolgen identisch sein. Zusammen decken die Szenarien 167 der 253 mitgelieferten Grammatiken, lang: 'ansi' und alle 65 Themes ab. Die Optionen (structure, tabindex, colorReplacements, Dual-Themes, defaultColor und weitere), codeToTokensWithThemes sowie die integrierten Transformer werden mit separaten Paritätstests geprüft. Die erwarteten Ausgaben dafür wurden mit denselben Shiki-Versionen erfasst.

Daraus ergeben sich zwei Einschränkungen. Shikis Standard-Engine ist Oniguruma, kompiliert zu WebAssembly. Als Referenz dient stattdessen Shikis JavaScript-Regex-Engine, die shikiphp portiert. Spätere Shiki-Versionen (die 4.x-Reihe) wurden nicht geprüft.

So funktioniert es

shikiphp basiert auf einer vendorten, reinen PHP-JavaScript-Regex-Engine aus inline0/phasis, die von einem PHP-Port von oniguruma-to-es gespeist wird. Shikis JavaScript-Regex-Engine wandelt Oniguruma-Muster aus TextMate-Grammatiken in JavaScript-RegExp um. Daher eignet sich eine JS-Regex-Engine als Grundlage: So kann shikiphp die Ausgabe dieser Engine offsetgenau nachbilden.

Code
code → grammar tokenizer → theme resolver → themed tokens → HTML
              │
              └─ OnigScanner → PatternConverter (oniguruma-to-es) → Shikiphp\Regex (JS RegExp engine)

Die vollständige Pipeline findest du unter Architektur.

Voraussetzungen

  • PHP 8.2 oder höher (CI führt die Testsuite mit PHP 8.4 aus)
  • ext-json und ext-mbstring (beide sind in praktisch jedem PHP-Build enthalten)

Was kommt als Nächstes

  • Erste Schritte — installiere das Paket und rendere deinen ersten Codeblock.
  • API — alle verfügbaren Methoden.
  • Optionen — alle Optionen, die codeToHtml akzeptiert.
  • Transformer — die Hook-Pipeline und integrierte Transformer.
  • CLI — bin/shikiphp highlight, langs und themes.

Lizenz

MIT, Copyright Inline0. Für mitgelieferte TextMate-Grammatiken und Themes gelten weiterhin ihre jeweiligen Upstream-Lizenzen.