Přejít k obsahu

shikiphp

shikiphp je čistý port PHP projektu Shiki, zvýrazňovače syntaxe, který obarvuje kód pomocí stejných gramatik a motivů TextMate jako VS Code. Tokenizuje kód pomocí stejných gramatik TextMate a vykresluje jej se stejnými motivy VS Code, jaké používá Shiki, takže vytváří stejný HTML jako Shiki 3.23.0 — zcela v PHP.

Žádné prostředí Node. Žádná rozšíření PHP kromě json a mbstring. Žádná nativní vazba Oniguruma. Žádné spouštění externího procesu JavaScript ani hostované API.

PHP
use Shikiphp\Shikiphp;

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

Proč shikiphp

Zvýrazňování syntaxe na serveru v PHP obvykle znamená jeden ze tří kompromisů: spouštění Node, volání hostovaného API nebo použití zvýrazňovače založeného na regulárních výrazech, který jazyku ve skutečnosti nerozumí. Nic z toho se nehodí do sestavení Laravel, WordPress ani statického webu.

shikiphp tento kompromis odstraňuje portováním skutečného procesu Shiki do PHP:

  • tokenizér gramatik TextMate (věrný port vscode-textmate), včetně vložených jazyků, injekcí a vnořených repozitářů
  • VS Code rozlišení motivů se specificitou selektorů rozsahu a porovnáváním nadřazených rozsahů
  • Shiki-kompatibilní HTML: světlé a tmavé motivy pomocí proměnných CSS, codeToHast, transformátorů (všech háčků), dekorací, colorReplacements, structure: 'inline' a zvýrazňování ANSI (lang: 'ansi')
  • úplný balíček Shiki — všechny jazyky tm-grammars (235 a 18 pomocných gramatik, které vkládají) a všechna témata tm-themes (65)

Ověřeno proti Shiki 3.23.0

Výstup je ověřen proti připnutému vydání Shiki; pouhá přibližná shoda nestačí.

Balíček Verze Použití
shiki 3.23.0 referenční implementace se spuštěným regulárním jádrem JavaScript
tm-grammars 1.31.15 gramatiky obsažené v balíčku
tm-themes 1.12.2 motivy obsažené v balíčku
@shikijs/transformers 4.2.0 testy shody transformerů

Samotné Shiki slouží jako referenční implementace. Regresní sada obsahuje 214 scénářů; každý představuje ukázku v jednom jazyce a s jedním motivem při výchozím nastavení. Každý scénář zvýrazní Shiki i shikiphp a oba řetězce HTML musí být po oříznutí počátečních a koncových mezer totožné. Scénáře společně pokrývají 167 z 253 gramatik obsažených v balíčku, lang: 'ansi' a všech 65 motivů. Možnosti (structure, tabindex, colorReplacements, dvojice motivů, defaultColor a další), codeToTokensWithThemes i vestavěné transformery se ověřují v samostatných testech shody, jejichž očekávané výstupy byly zachyceny ze stejných verzí Shiki.

Z toho plynou dvě omezení. Výchozí jádro Shiki je Oniguruma zkompilované do WebAssembly, zatímco referenční implementace používá regulární jádro JavaScript z Shiki, které portuje shikiphp. Pozdější vydání Shiki (řada 4.x) navíc nebyla ověřena.

Jak to funguje

shikiphp je postaveno na převzatém čistém regulárním jádru JavaScript PHP z inline0/phasis, které využívá port PHP projektu oniguruma-to-es. Regulární jádro JavaScript projektu Shiki převádí vzory Oniguruma v gramatikách TextMate na JavaScript RegExp, takže přirozeným základem je regulární jádro JS — umožňuje totiž shikiphp porovnávat jeho výstup znak po znaku.

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

Úplný postup zpracování najdete v části Architektura.

Požadavky

  • PHP 8.2 nebo novější (CI spouští testovací sadu na PHP 8.4)
  • ext-json a ext-mbstring (obojí je součástí téměř každé sestavy PHP)

Kam dál

  • Začínáme — nainstalujte balíček a vykreslete svůj první blok.
  • API — úplný přehled metod.
  • Možnosti — všechny možnosti, které přijímá codeToHtml.
  • Transformery — řetězec hooků a vestavěné transformery.
  • CLI — bin/shikiphp highlight, langs a themes.

Licence

MIT, autorská práva inline0. Gramatiky a motivy TextMate obsažené v balíčku si zachovávají původní licence.