Arhitektūra
shikiphp pārvērš avota kodu stilizētā, iezīmētā HTML, izmantojot TextMate gramatikas
un VS Code tēmas, bez PHP paplašinājumiem, izņemot json/mbstring, bez Node izpildvides un vietējām Oniguruma saistībām. Šajā lapā apkopota darbplūsma; pilns normatīvais līgums atrodas repozitorija failā ARCHITECTURE.md.
Darbplūsma
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>
Viss darbojas UTF-16 koda vienību nobīžu telpā — tāpat kā JS regex dzinis un Shiki tokenizētājs. ASCII gadījumā tā sakrīt ar baitu nobīdēm.
Regex izpildvide
Pamatā ir Shikiphp\Regex — pilnvērtīgs tīri PHP ECMAScript regex dzinis, piegādāts no inline0/phasis (tīri PHP JavaScript dzinis). Tas parsē JS-RegExp avotu kopā ar karogiem un veic meklēšanu uz priekšu ar Oniguruma onig_search semantiku.
Oniguruma → JS pārveide
TextMate gramatikas ir rakstītas Oniguruma. Shikiphp\Oniguruma\PatternConverter ir PHP ports no oniguruma-to-es: tas pārvērš Oniguruma rakstu par JS ar RegExp saderīgu avotu un karodziņu virkni, ko pieņem regex dzinējs. Šī ir tā pati Oniguruma → RegExp plūsma, ko izmanto Shiki JavaScript regex dzinējs; tā ļauj shikiphp salīdzināt šī dzinēja izvadi ar precīzu nobīdi. Konvertētājs apstrādā reālās konstrukcijas, ko izmanto gramatikas: POSIX klases, īpašnieciskos kvantifikatorus un atomārās grupas, iekļautos karodziņus, nosauktās grupas un atpakaļatsauces, Unicode īpašības un vēl daudz ko citu.
Skenētājs un tā PCRE ātrā izpildes ceļa variants
Shikiphp\Oniguruma\OnigScanner darbojas tāpat kā vscode-oniguruma skenētājs: tas tiek izveidots reizi katram noteikumam no rakstu saraksta un atrod pirmo atbilstību no kreisās puses norādītajā sākuma pozīcijā vai aiz tās.
Koka traversēšanas atbilstības meklētājs ir pareizs, taču lēns, tāpēc skenētājam ir PCRE ātrā izpildes ceļa variants ar ekvivalences pārbaudi divos līmeņos. PcreTranslator pārveido konvertētāja JS avotu par vietējo PCRE rakstu tikai tad, ja var pierādīt rezultāta pareizību:
- Pilna atbilstība. Ja tulkojums darbojas identiski atbilstības meklētājam, ieskaitot katru uztveršanas grupu, raksts tiek izpildīts tieši ar PCRE. Nosauktās grupas, atpakaļatsauces,
\p{},\b,\G, atomāro grupu emulācija un uztveršanas grupas, kuru JavaScript semantika atšķiras no PCRE (kvantificētā grupā vai lookbehind), šajā līmenī tiek noraidītas. - Tikai pozīcija. Ja atšķirties var tikai uztveršanas grupas, otrs tulkojums atbalsta šīs konstrukcijas (
\bun\Bkā precīzus ASCII lookaround, atomārās grupas kā vietējās(?>…),\p{…}, ja PCRE spēj to kompilēt). PCRE tad tikai atrod nākamās atbilstības pozīciju, un atbilstības meklētājs atkārto meklēšanu šajā nobīdē, lai iegūtu īstās uztveršanas grupas. Atpakaļatsauces un\Garī šeit tiek noraidītas.
Visos pārējos gadījumos tiek izmantots tikai atbilstības meklētājs. No komplektā iekļautajām gramatikām Shiki 3.23.0 aptuveni 39% 14,234 atšķirīgo rakstu tiek pilnībā izpildīti ar PCRE, aptuveni 57% izmanto pozīcijas līmeni, bet aptuveni 4% paliek atbilstības meklētājā. Klasifikāciju pārbauda izstrādes rīks repozitorijā (bin/.oracle-tools/pcre-equivalence.php), kas salīdzina ātro izpildes ceļu ar atbilstības meklētāju — indeksu, beigu pozīciju un pirmajā līmenī arī katras uztveršanas grupas diapazonu — scenāriju ievadēs un sintētisku virkņu kopā; atšķirības nav pieļaujamas.
Gramatika un tēma
- Gramatika (
Shikiphp\Grammar) ir uzticamsvscode-textmateports:Registryatrisina gramatikas pēc tvēruma nosaukuma (tostarpincludeatsauces, iegultās valodas un injekcijas), betTokenizeruztur noteikumu un tvērumu stekus pa rindām. - Tēma (
Shikiphp\Theme) pārnesvscode-textmatetēmu atbilstības loģiku: priekšplāna krāsas un fonta stils tiek noteikti pēc tvēruma atlasītāja specifiskuma, ņemot vērā arī vecāktvērumus.
Atveidošana
Shikiphp\Render\HtmlRenderer izveido tieši tādu pašu pre.shiki > code > span.line > span HAST koku, kādu veido Shiki, un pēc tam to serializē. Vienas tēmas režīmā tiek ierakstītas vienkāršas krāsas; divu tēmu režīmā tiek ierakstīti --shiki-light / --shiki-dark CSS mainīgie.
Pārbaudīts pret Shiki
Pats Shiki ir etalons, piesaistīts shiki 3.23.0 ar tā JavaScript regex dzinēju. Mapē scenarios/ ir 214 pārbaudes piemēri, katrs ar vienu ievadi vienā valodā un vienā tēmā; kopā tie aptver 167 no 253 komplektā iekļautajām gramatikām, lang: 'ansi' un visas 65 tēmas. bin/test-regression izceļ katru piemēru ar abiem dzinējiem un pārbauda, vai HTML ir identiska pēc atstarpju apgriešanas sākumā un beigās. Opcijas un pārveidotāji tiek pārbaudīti ar atbilstības testiem, salīdzinot ar izvadi, kas iegūta no tām pašām Shiki un @shikijs/transformers 4.2.0 versijām. Obligātais noteikums ir tāds, ka izcelšanas izvade nedrīkst regresēt salīdzinājumā ar Shiki.