Preskoči na vsebino

Arhitektura

shikiphp pretvori izvorno kodo v označene HTML, obarvane s temami, z uporabo slovnic TextMate in tem VS Code, brez razširitev PHP razen json/mbstring, izvajalnega okolja Node in izvorne vezave Oniguruma. Ta stran povzema cevovod; celoten normativni dogovor je v repozitoriju v ARCHITECTURE.md.

Cevovod

Koda
source code
  └─ Highlighter::codeToTokens()
       ├─ Grammar\Registry        loads the grammar (+ its includes / embedded langs)
       ├─ Grammar\Tokenizer       line by line, driving an OnigScanner per rule state
       │     └─ Oniguruma\OnigScanner.findNextMatch()
       │           └─ Oniguruma\PatternConverter   Oniguruma pattern → JS regex
       │                 └─ Shikiphp\Regex (Parser + Matcher)   JS RegExp runtime
       ├─ Theme\Theme.match(scopeStack) → StyleAttributes   per token
       └─ Render\ThemedToken[]   (text + style) per line
  └─ Render\HtmlRenderer  → <pre class="shiki">…</pre>

Vse deluje v prostoru odmikov kodnih enot UTF-16 — enakem kot v pogonu regularnih izrazov JS in tokenizatorju Shiki. Pri ASCII to ustreza odmikov bajtov.

Izvajalno okolje za regularne izraze

Na najnižji ravni je Shikiphp\Regex, popoln čisti pogon ECMAScript za regularne izraze PHP, priložen iz inline0/phasis (čisti pogon PHP JavaScript). Razčleni vir JS-RegExp z zastavicami in izvede iskanje naprej s semantiko Oniguruma onig_search.

Pretvorba Oniguruma → JS

Slovnice TextMate so zapisane v Oniguruma. Shikiphp\Oniguruma\PatternConverter je prenos PHP za oniguruma-to-es: vzorec Oniguruma pretvori v vir in niz zastavic, združljivih z JS-RegExp, ki ju sprejme pogon za regularne izraze. Po isti poti Oniguruma → RegExp, ki jo uporablja pogon regularnih izrazov ShikiJavaScript, lahko shikiphp ujema izhod tega pogona na vsakem odmiku. Pretvornik podpira konstrukte, ki jih slovnice uporabljajo v praksi: razrede POSIX, posesivne kvantifikatorje in atomske skupine, vgrajene zastavice, poimenovane skupine in povratne reference, lastnosti Unicode ter še več.

Optični bralnik in hitra pot PCRE

Shikiphp\Oniguruma\OnigScanner posnema optični bralnik vscode-oniguruma: za vsako pravilo se enkrat zgradi iz seznama vzorcev in poišče najbolj levi ujemajoči se niz na začetnem položaju ali za njim.

Ujemanje s sprehodom po drevesu je pravilno, vendar počasno, zato ima optični bralnik hitro pot PCRE z dvema stopnjama, ki jo omogoča preverjanje enakovrednosti. PcreTranslator pretvori vir JS, ki ga ustvari pretvornik, v izvorni vzorec PCRE samo, kadar lahko dokaže rezultat:

  • Polno ujemanje. Če se prevod vede enako kot ujemalnik, vključno z vsemi zajetimi nizi, se vzorec neposredno obdela s PCRE. Poimenovane skupine, povratne reference, \p{}, \b, \G, posnemanje atomskih skupin in zajemi, katerih semantika JavaScript se razlikuje od PCRE (znotraj ponavljajoče se skupine ali negativnega pogleda nazaj), so iz te stopnje izključeni.
  • Samo položaj. Če se lahko razlikujejo samo zajemi, jih omogoča drugi prevod (\b in \B kot natančni pogledi ASCII, atomske skupine kot izvorni (?>…), \p{…}, če ga PCRE prevede). PCRE nato poišče samo položaj naslednjega ujemanja, ujemalnik pa znova zažene ujemanje na tem odmiku, da ustvari prave zajeme. Povratne reference in \G so tudi tu izključeni.

Vse drugo obdeluje samo ujemalnik. Pri vgrajenih slovnicah Shiki 3.23.0 se približno 39 % od 14,234 različnih vzorcev v celoti izvede s PCRE, približno 57 % jih uporablja stopnjo položaja, približno 4 % pa jih obdela ujemalnik. Razvrstitev preverja razvojno orodje v repozitoriju (bin/.oracle-tools/pcre-equivalence.php), ki primerja hitro pot z ujemalnikom — indeks, konec in pri prvi stopnji vsak zajeti razpon — na vhodih iz scenarijev in naboru sintetičnih nizov; odstopanja niso dovoljena.

Slovnica in tema

  • Slovnica (Shikiphp\Grammar) je zvest prenos vscode-textmate: Registry razrešuje slovnice po imenu obsega (vključno s sklici include, vdelanimi jeziki in injekcijami), Tokenizer pa vzdržuje sklad pravil in obsegov po vrsticah.
  • Tema (Shikiphp\Theme) prenaša ujemanje tem iz vscode-textmate: barva ospredja in slog pisave se razrešita glede na specifičnost izbirnika obsega in ujemanje nadrejenih obsegov.

Izris

Shikiphp\Render\HtmlRenderer izdela popolnoma enako drevo pre.shiki > code > span.line > span HAST Shiki, kot ga ustvarijo gradnje, nato pa ga serializira. Način z eno temo zapisuje navadne barve; način z dvema temama zapisuje spremenljivke --shiki-light / --shiki-dark CSS.

Preverjeno glede na Shiki

Sam Shiki je referenčni vir, pripet na shiki 3.23.0 z njegovim pogonom regularnih izrazov JavaScript. Imenik scenarios/ vsebuje 214 testnih primerov, vsak z enim vhodom, jezikom in temo; skupaj pokrivajo 167 od 253 vgrajenih slovnic, lang: 'ansi' in vseh 65 tem. bin/test-regression vsakega označi z obema pogonoma in preveri, ali je HTML enak po odstranitvi začetnih in končnih presledkov. Možnosti in pretvorniki se preverjajo s testi enakovrednosti glede na izhod, zajet iz istih različic Shiki in @shikijs/transformers 4.2.0. Obvezujoče pravilo je, da se izhod označevanja ne sme poslabšati glede na Shiki.