Hoppa till innehåll

shikiphp

shikiphp är en portning i ren PHP av Shiki, syntaxfärgläggaren som färglägger kod med samma TextMate-grammatiker och teman som VS Code. Den tokeniserar kod med samma TextMate-grammatiker och färglägger den med samma VS Code-teman som Shiki använder, vilket ger samma HTML som Shiki 3.23.0 — helt i PHP.

Ingen Node-körmiljö. Inga PHP-tillägg utöver json och mbstring. Ingen inbyggd Oniguruma-bindning. Inga anrop till en extern JavaScript-process och ingen värdtjänst för API.

PHP
use Shikiphp\Shikiphp;

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

Varför shikiphp

Syntaxmarkering på serversidan i PHP innebär vanligtvis en av tre kompromisser: att anropa Node, använda en värdtjänst för API eller nöja sig med en regexbaserad markerare som inte faktiskt förstår språket. Inget av detta passar särskilt bra i ett Laravel-, WordPress- eller statiskt webbplatsbygge.

shikiphp löser problemet genom att porta Shikis verkliga flöde till PHP:

  • En TextMate-tokeniserare för grammatiker (en trogen portering av vscode-textmate), inklusive inbäddade språk, injektioner och nästlade arkiv
  • VS Code-temalösning med specificitet för scope-väljare och matchning av överordnade scope
  • Shiki-kompatibel HTML: ljusa och mörka teman via CSS-variabler, codeToHast, transformatorer (alla hookar), dekorationer, colorReplacements, structure: 'inline' och ANSI-markering (lang: 'ansi')
  • Det fullständiga Shiki-paketet — alla tm-grammars språk (235 plus 18 hjälpargrammatiker som de bäddar in) och alla tm-themes teman (65)

Matchat mot Shiki 3.23.0

Resultatet är inte ”tillräckligt nära”: det kontrolleras mot en låst version av Shiki.

Paket Version Användningsområde
shiki 3.23.0 facit, kört med sin JavaScript-regexmotor
tm-grammars 1.31.15 de paketerade grammatikerna
tm-themes 1.12.2 de paketerade temana
@shikijs/transformers 4.2.0 paritetstester för transformatorer

Shiki är själv facit. Regressionstestriggen innehåller 214 scenarier, där varje scenario är ett exempel i ett språk och ett tema med standardalternativ. Varje scenario markeras av både Shiki och shikiphp, och de två HTML-strängarna måste vara identiska efter att inledande och avslutande blanksteg tagits bort. Tillsammans täcker scenarierna 167 av de 253 paketerade grammatikerna, lang: 'ansi' och alla 65 teman. Alternativen (structure, tabindex, colorReplacements, två teman, defaultColor och resten), codeToTokensWithThemes och de inbyggda transformatorerna täcks av separata paritetstester. Förväntade resultat i dessa fångades från samma Shiki-versioner.

Det följer två begränsningar av detta. Standardmotorn i Shiki är Oniguruma kompilerad till WebAssembly, medan facit använder regexmotorn JavaScript i Shiki, alltså motorn som shikiphp porterar. Senare utgåvor av Shiki (4.x-serien) har inte kontrollerats.

Så fungerar det

shikiphp bygger på en medföljande ren PHP JavaScript-regexmotor från inline0/phasis, baserad på en PHP-port av oniguruma-to-es. Shikis JavaScript-regexmotor omvandlar Oniguruma-mönstren i TextMate-grammatiker till JavaScript RegExp, så en JS-regexmotor är den naturliga grunden — den låter shikiphp matcha motorns utdata offset för offset.

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

Se Arkitektur för hela flödet.

Krav

  • PHP 8.2 eller senare (CI kör testsviten på PHP 8.4)
  • ext-json och ext-mbstring (båda ingår i nästan varje PHP-bygge)

Vad härnäst

  • Kom igång — installera och rendera ditt första block.
  • API — alla tillgängliga metoder.
  • Alternativ — alla alternativ som codeToHtml stöder.
  • Transformers — hook-flödet och de inbyggda varianterna.
  • CLI — bin/shikiphp highlight, langs och themes.

Licens

MIT, upphovsrätt inline0. Medföljande TextMate-grammatiker och teman behåller sina ursprungliga licenser.