Architektúra
A shikiphp a forráskódot témával kiemelt HTML formátumba alakítja a TextMate nyelvtanok és VS Code témák használatával; a json/mbstring eszközökön kívül nincs szükség PHP bővítményekre, Node.js-futtatókörnyezetre vagy natív Oniguruma-kötésre. Ez az oldal összefoglalja a folyamatot; a teljes, normatív szerződés a tárházbeli ARCHITECTURE.md fájlban található.
A folyamat
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>
Minden művelet UTF-16 kódegység-eltolásokkal dolgozik — ugyanabban a tartományban, mint a JS regexmotor és a Shiki tokenizálója. ASCII esetén ez megegyezik a bájteltolásokkal.
A regex futtatókörnyezete
Az alján található a Shikiphp\Regex, egy teljes, tisztán PHP ECMAScript regexmotor, a inline0/phasis forrásából átvéve (tisztán PHP JavaScript motor). Egy JS-RegExp forrást és flagjeit elemzi, majd előre irányuló kereséseket futtat Oniguruma onig_search szemantikával.
Oniguruma → JS átalakítás
A TextMate grammatikák Oniguruma nyelven íródnak. A Shikiphp\Oniguruma\PatternConverter a PHP oniguruma-to-es portja: egy Oniguruma mintát a JS-RegExp-kompatibilis forrássá és a regexmotor által elfogadott flag-karakterlánccá alakít. Ugyanezt az Oniguruma → RegExp útvonalat használja a Shiki JavaScript regexmotorja is, így a shikiphp eltolásonként képes egyeztetni a motor kimenetével. Az átalakító kezeli a grammatikákban használt valós konstrukciókat: POSIX-osztályokat, mohó kvantorokat és atomcsoportokat, inline flageket, elnevezett csoportokat és visszahivatkozásokat, Unicode tulajdonságokat és másokat.
A szkenner és a PCRE gyorsútvonala
A Shikiphp\Oniguruma\OnigScanner a vscode-oniguruma szkennerét utánozza: szabályonként egyszer épül fel minták listájából, és a kezdőpozíciónál vagy utána található legbaloldalibb egyezést keresi.
A fa bejárásán alapuló illesztő helyes, de lassú, ezért a szkennernek van egy egyezés-ellenőrzéshez kötött PCRE gyorsútvonala, két szinttel. Egy PcreTranslator a konverter JS forrását csak akkor írja át natív PCRE-mintává, ha bizonyítani tudja az eredményt:
- Teljes egyezés. Ha az átalakítás az összes rögzítést is beleértve pontosan úgy viselkedik, mint az illesztő, a minta közvetlenül PCRE-n fut. A névvel ellátott csoportokat, visszahivatkozásokat,
\p{},\b,\Gelemeket, az atomi emulációt, valamint azokat a rögzítéseket, amelyek JavaScript szemantikája eltér a PCRE-étől (kvantált csoporton vagy visszatekintő állításon belül), ez a szint elutasítja. - Csak pozíció. Ha csak a rögzítések térhetnek el, egy második átalakítás engedélyezi ezeket a szerkezeteket (a
\bés\Belemeket pontos ASCII lookaroundként, az atomi csoportokat natív(?>…)formában,\p{…}esetén, ha a PCRE le tudja fordítani). A PCRE ekkor csak a következő egyezés helyét keresi meg; az illesztő ezen az eltoláson újra lefut, hogy előállítsa a tényleges rögzítéseket. A visszahivatkozások és a\Gebben a szintben is tiltottak.
Minden más csak az illesztőt használja. A Shiki 3.23.0 helyen található csomagolt nyelvtanoknál a 14,234 különböző minták körülbelül 39%-a teljes egészében PCRE-n fut, körülbelül 57% a pozíciószintet használja, 4% pedig az illesztőn marad. A besorolást egy tárházbeli fejlesztői eszköz (bin/.oracle-tools/pcre-equivalence.php) ellenőrzi: összeveti a gyorsútvonalat az illesztővel a forgatókönyvek bemenetein és egy sor szintetikus karakterláncon — az indexet, a véget és az első szintnél minden rögzítési tartományt is —, és nem enged meg eltérést.
Nyelvtan és téma
- Nyelvtan (
Shikiphp\Grammar): avscode-textmatehű portja. EgyRegistryhatókörnév alapján oldja fel a nyelvtanokat (beleértve aincludehivatkozásokat, a beágyazott nyelveket és a beszúrásokat), egyTokenizerpedig sorról sorra karbantartja a szabály- és hatókörvermet. - Téma (
Shikiphp\Theme): avscode-textmatetémakezelésének portja. Az előtér és a betűstílus a hatókörválasztó specifikussága és a szülőhatókörök illesztése alapján oldódik fel.
Megjelenítés
A Shikiphp\Render\HtmlRenderer létrehozza a Shiki által készített pontos pre.shiki > code > span.line > span HAST-fát, majd szerializálja. Egytémás módban egyszerű színeket ír ki; kéttémás módban --shiki-light / --shiki-dark CSS változókat ír ki.
Ellenőrzés a Shiki alapján
Maga az Shiki a mérvadó forrás, az shiki 3.23.0 verziójához rögzítve, a saját JavaScript reguláriskifejezés-motorjával. Az scenarios/ könyvtár 214 tesztpéldát tartalmaz; mindegyik egy bemenet egy nyelven és egy témával. Együtt az 253 csomagban található nyelvtanok 167-át, az lang: 'ansi'-t és mind a 65 témát fedik le. Az bin/test-regression mindkét motorral kiemeli ezeket, majd ellenőrzi, hogy az HTML a kezdő és záró szóközök eltávolítása után azonos-e. Az opciók és az átalakítók paritástesztjei ugyanabból az Shiki-ből és az @shikijs/transformers 4.2.0-ből rögzített kimenettel való egyezést ellenőrzik. Az alapvető szabály: a kiemelés kimenete nem romolhat az Shiki-hoz képest.