
# 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`](https://github.com/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`](https://github.com/slevithan/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.
