Pāriet uz saturu

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

Kods
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 (\b un \B kā 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 \G arī š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 uzticams vscode-textmate ports: Registry atrisina gramatikas pēc tvēruma nosaukuma (tostarp include atsauces, iegultās valodas un injekcijas), bet Tokenizer uztur noteikumu un tvērumu stekus pa rindām.
  • Tēma (Shikiphp\Theme) pārnes vscode-textmate tē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.