Siirry sisältöön

Arkkitehtuuri

shikiphp muuntaa lähdekoodin teeman mukaiseksi korostetuksi HTML-sisällöksi käyttäen TextMate-kielioppeja ja VS Code-teemoja. Se ei tarvitse PHP-laajennuksia json/mbstring-tuen lisäksi, Node-ajoympäristöä eikä natiivisidontaa kohteeseen Oniguruma. Tämä sivu tiivistää käsittelyputken; koko normatiivinen sopimus on arkiston tiedostossa ARCHITECTURE.md.

Käsittelyputki

Koodi
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>

Kaikki toimii UTF-16-koodiyksiköiden siirtymäavaruudessa — samassa kuin JS-regex-moottori ja Shiki-jäsennin. ASCII-merkistössä tämä vastaa tavusiirtymiä.

Regex-ajoympäristö

Alimpana on Shikiphp\Regex, täydellinen puhdas-PHP ECMAScript-regex-moottori, joka on toimittajan mukana inline0/phasis (puhdas-PHP JavaScript-moottori). Se jäsentää JS-RegExp-lähdekoodin ja liput sekä suorittaa eteenpäin suuntautuvia hakuja semantiikalla Oniguruma onig_search.

Muunnos Oniguruma → JS

TextMate-kieliopit kirjoitetaan Oniguruma-kielellä. Shikiphp\Oniguruma\PatternConverter on PHP-porttaus oniguruma-to-es-kirjastosta: se muuntaa Oniguruma-mallin JS-RegExp-yhteensopivaksi lähdekoodiksi ja lippumerkkijonoksi, jonka regex-moottori hyväksyy. Tämä on sama Oniguruma → RegExp-polku, jota Shiki:n JavaScript-regex-moottori käyttää. Siksi shikiphp voi täsmätä moottorin tulokseen tavu tavulta. Muunnin käsittelee kieliopeissa käytetyt todelliset rakenteet: POSIX-luokat, ahneet kvantifioijat ja atomiset ryhmät, rivinsisäiset liput, nimetyt ryhmät ja takautuvat viittaukset, Unicode-ominaisuudet ja paljon muuta.

Jäsennin ja sen PCRE-pikapolku

Shikiphp\Oniguruma\OnigScanner vastaa vscode-oniguruman jäsennintä: se luodaan kerran kutakin sääntöä varten malliluettelosta, ja se etsii vasemmanpuoleisimman osuman aloituskohdasta tai sen jälkeen.

Puurakennetta läpikäyvä täsmääjä on oikea mutta hidas, joten jäsentimessä on vastaavuuden varmistava PCRE-pikapolku, jossa on kaksi tasoa. PcreTranslator muuntaa muuntimen JS-lähdekoodin natiiviksi PCRE-malliksi vain, kun tuloksen oikeellisuus voidaan todistaa:

  • Täysi osuma. Kun käännös toimii samalla tavalla kuin täsmääjä, kaikki kaappaukset mukaan lukien, malli suoritetaan suoraan PCRE:llä. Nimetyt ryhmät, takaviittaukset, \p{}, \b, \G, atomisten ryhmien emulointi sekä kaappaukset, joiden JavaScript-semantiikka eroaa PCRE:stä (kvantifioidun ryhmän sisällä tai takautuvassa haussa), eivät kelpaa tälle tasolle.
  • Vain sijainti. Kun vain kaappaukset voivat erota, toinen käännös sallii nämä rakenteet (\b ja \B täsmällisinä ASCII-hakuina, atomiset ryhmät natiivina (?>…)-rakenteena, \p{…} jos PCRE kääntää sen). PCRE etsii tällöin vain seuraavan osuman sijainnin, ja täsmääjä suoritetaan uudelleen kyseisestä kohdasta oikeiden kaappausten tuottamiseksi. Takaviittaukset ja \G eivät kelpaa tällekään tasolle.

Kaikki muu suoritetaan vain täsmääjällä. Mukana toimitettavista kieliopeista kohdassa Shiki 3.23.0 noin 39 % 14,234 erillisestä mallista suoritetaan kokonaan PCRE:llä, noin 57 % käyttää sijaintitasoa ja noin 4 % jää täsmääjän varaan. Luokittelun tarkistaa kehitystyökalu repositoriossa (bin/.oracle-tools/pcre-equivalence.php), joka vertaa pikapolkua täsmääjään — indeksin, lopun ja ensimmäisellä tasolla kaikkien kaappausten jänteet — skenaarioiden syötteillä ja synteettisten merkkijonojen joukolla. Eroja ei sallita.

Kielioppi ja teema

  • Kielioppi (Shikiphp\Grammar) on uskollinen porttaus lähteestä vscode-textmate: Registry selvittää kieliopit laajuusnimen perusteella (mukaan lukien include-viittaukset, upotetut kielet ja injektiot), ja Tokenizer ylläpitää sääntö- ja laajuuspinoja rivi riviltä.
  • Teema (Shikiphp\Theme) porttaa lähteen vscode-textmate teemojen täsmäytyksen: etualan väri ja fonttityyli määräytyvät laajuusvalitsimen tarkkuuden ja ylälaajuuden täsmäytyksen perusteella.

Renderöinti

Shikiphp\Render\HtmlRenderer rakentaa täsmälleen saman HAST-puun, jonka pre.shiki > code > span.line > spanShiki rakentaa, ja sarjallistaa sen sitten. Yhden teeman tila kirjoittaa tavalliset värit; kahden teeman tila kirjoittaa --shiki-light / --shiki-dark CSS-muuttujat.

Varmennettu lähteeseen Shiki nähden

Shiki on itse vertailukohta, joka on lukittu versioon shiki 3.23.0 sen JavaScript-regex-moottorilla. scenarios/-hakemisto sisältää 214 testitapausta, joista kukin on yksi syöte yhdellä kielellä ja yhdellä teemalla; yhdessä ne kattavat 167 253 mukana toimitetusta kieliopista, lang: 'ansi' ja kaikki 65 teemaa. bin/test-regression korostaa kunkin molemmilla moottoreilla ja varmistaa, että HTML on identtinen, kun alun ja lopun välilyönnit on poistettu. Asetukset ja muuntimet tarkistetaan saman Shiki- ja @shikijs/transformers-version 4.2.0-tuloksista kerättyjen tulosten kanssa parity-testeillä. Ehdoton sääntö on, ettei korostustulos saa heikentyä suhteessa versioon Shiki.