Mimari
shikiphp, kaynak kodu, TextMate dilbilgileri ve VS Code temaları kullanarak temalı ve vurgulanmış HTML biçimine dönüştürür. json/mbstring dışındaki PHP uzantıları, Node çalışma zamanı ve yerel Oniguruma bağlaması gerekmez. Bu sayfa işlem hattını özetler; tüm bağlayıcı sözleşme depodaki ARCHITECTURE.md içinde yer alır.
İşlem hattı
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>
Her şey UTF-16 kod birimi ofset alanında çalışır; bu, JS regex motorunun ve Shiki belirteç ayırıcısının kullandığı alanla aynıdır. ASCII için bu, bayt ofsetlerine eşittir.
Regex çalışma zamanı
En altta, eksiksiz ve saf-PHP ECMAScript regex motoru olan Shikiphp\Regex bulunur; inline0/phasis kaynağından satıcıdan alınmıştır (saf-PHP JavaScript motoru). Bir JS RegExp kaynağını ve bayrakları ayrıştırır, ardından Oniguruma onig_search anlamlarıyla ileri yönde aramalar yapar.
Oniguruma → JS dönüşümü
TextMate dilbilgileri Oniguruma ile yazılır. Shikiphp\Oniguruma\PatternConverter, oniguruma-to-es için bir PHP uyarlamasıdır: bir Oniguruma desenini, regex motorunun kabul ettiği JS uyumlu RegExp kaynak koduna ve bayrak dizgesine dönüştürür. Bu, aynı regex motorunun izlediği Oniguruma → RegExp yoludur; Shiki'ın JavaScript motoru da bu yolu izler. Böylece shikiphp, motorun çıktısıyla her ofsette eşleşebilir. Dönüştürücü, dilbilgilerinde kullanılan gerçek dünya yapılarını destekler: POSIX sınıfları, sahiplenici niceleyiciler ve atomik gruplar, satır içi bayraklar, adlandırılmış gruplar ve geri başvurular, Unicode özellikleri ve daha fazlası.
Tarayıcı ve PCRE hızlı yolu
Shikiphp\Oniguruma\OnigScanner, vscode-oniguruma tarayıcısını yansıtır: her kural için desen listesinden bir kez oluşturulur ve başlangıç konumunda veya sonrasında en soldaki eşleşmeyi bulur.
Ağaçta dolaşan eşleştirici doğrudur ancak yavaştır; bu nedenle tarayıcıda, eşdeğerliği koşul olarak kullanan iki katmanlı bir PCRE hızlı yolu bulunur. PcreTranslator, dönüştürücünün JS kaynağını yalnızca sonucu kanıtlayabildiği durumlarda yerel bir PCRE desenine dönüştürür:
- Tam eşleşme. Her yakalama dâhil olmak üzere dönüşüm, eşleştiriciyle aynı şekilde davrandığında desen doğrudan PCRE üzerinde çalışır. Adlandırılmış gruplar, geriye başvurular,
\p{},\b,\G, atomik öykünme ve JavaScript anlamları PCRE'den farklı olan yakalamalar (nicelenmiş bir grubun içinde veya geriye dönük bakışta) bu katmana alınmaz. - Yalnızca konum. Yalnızca yakalamaların farklı olabileceği durumlarda ikinci bir dönüşüm, bu yapıları kabul eder (
\bve\Btam ASCII bakışları olarak, atomik gruplar yerel(?>…)olarak; PCRE derleyebilirse\p{…}). PCRE yalnızca sonraki eşleşmenin konumunu bulur; gerçek yakalamaları üretmek için eşleştirici o ofsette yeniden çalışır. Geriye başvurular ve\Gburada da kabul edilmez.
Diğer her şey yalnızca eşleştiriciyle çalışır. Shiki 3.23.0 sürümündeki paketlenmiş dilbilgiler için 14,234 farklı desenin yaklaşık %39'u tamamen PCRE üzerinde, yaklaşık %57'si konum katmanında çalışır ve yaklaşık %4'ü eşleştiricide kalır. Sınıflandırma, depodaki bir geliştirme aracı (bin/.oracle-tools/pcre-equivalence.php) tarafından denetlenir. Bu araç hızlı yolu eşleştiriciyle karşılaştırır: senaryo girdileri ve sentetik dizeler kümesi üzerinde dizin, bitiş ve ilk katmanda her yakalama aralığını denetler; hiçbir farklılığa izin verilmez.
Dilbilgisi ve tema
- Dilbilgisi (
Shikiphp\Grammar),vscode-textmateiçin aslına sadık bir uyarlamadır:Registry, dilbilgilerini kapsam adına göre çözümler (includebaşvuruları, gömülü diller ve enjeksiyonlar dâhil);Tokenizerise kural ve kapsam yığınlarını satır satır tutar. - Tema (
Shikiphp\Theme),vscode-textmatetema eşleştirmesini uyarlar: ön plan ve yazı tipi stili, üst kapsam eşleştirmesiyle kapsam seçicisinin özgüllüğüne göre çözümlenir.
İşleme
Shikiphp\Render\HtmlRenderer, Shiki'ın oluşturduğu pre.shiki > code > span.line > span HAST ağacını birebir oluşturur, ardından serileştirir. Tek tema kipinde düz renkler; çift tema kipinde ise --shiki-light / --shiki-dark CSS değişkenleri yazılır.
Shiki ile doğrulandı
Shiki, shiki 3.23.0 sürümüne ve onun JavaScript regex motoruna sabitlenmiş doğruluk kaynağıdır. scenarios/ dizini, her biri bir dil ve temada tek bir girdi olan 214 test fikstürü içerir; bunlar birlikte paketlenmiş dilbilgilerinin 253 167 kadarını, lang: 'ansi''i ve 65 temanın tümünü kapsar. bin/test-regression, her birini iki motorla vurgular ve baştaki ve sondaki boşluklar kırpıldıktan sonra HTML değerinin aynı olduğunu doğrular. Seçenekler ve dönüştürücüler, aynı Shiki ve @shikijs/transformers 4.2.0 üzerinden yakalanan çıktıyla eşitlik testleri kullanılarak denetlenir. Vazgeçilmez kural, vurgulama çıktısının Shiki karşısında gerilememesidir.