Transformer
Transformer memungkinkan Anda mengubah bentuk keluaran yang disorot pada setiap tahap — dari string sumber mentah, melalui kisi token, hingga pohon HAST final dan HTML. shikiphp mengadaptasi model transformer Shiki hook demi hook, sehingga transformer berperilaku sama dengan padanannya di JavaScript.
Teruskan melalui opsi transformers:
use Shikiphp\Shikiphp;
use Shikiphp\Transformer\Notation\NotationHighlight;
use Shikiphp\Transformer\Notation\NotationDiff;
$code = <<<'JS'
console.log('this line is highlighted') // [!code highlight]
console.log('old line') // [!code --]
console.log('new line') // [!code ++]
JS;
echo Shikiphp::codeToHtml($code, [
'lang' => 'js',
'theme' => 'vitesse-dark',
'transformers' => [
new NotationHighlight(),
new NotationDiff(),
],
]);
Pipeline
Setiap transformer adalah objek yang mengimplementasikan Shikiphp\Transformer\Transformer.
Pipeline menjalankan hook secara berurutan saat membangun satu blok:
| Hook | Tanda tangan | Kapan |
|---|---|---|
preprocess |
(string $code, array &$options, $context): ?string |
sebelum tokenisasi; dapat mengubah sumber dan memodifikasi opsi |
tokens |
(array $tokens, $context): ?array |
setelah tokenisasi, pada kisi 2D ThemedToken |
root |
(Element $el, $context): ?Element |
pada akar HAST |
pre |
(Element $el, $context): ?Element |
pada elemen <pre> |
code |
(Element $el, $context): ?Element |
pada elemen <code> |
line |
(Element $el, int $line, $context): ?Element |
untuk setiap elemen baris (indeks mulai dari 1) |
span |
(Element $el, int $line, int $col, Element $lineEl, ThemedToken $token, $context): ?Element |
untuk setiap rentang token |
postprocess |
(string $html, array $options, $context): ?string |
pada string HTML serialisasi final |
Setiap hook bersifat opsional. Mengembalikan nilai akan mengganti input; mengembalikan null akan membiarkannya tetap sama.
enforce() mengatur urutan antar-transformer: 'pre' dijalankan pertama, 'post' dijalankan terakhir, dan null (default) dijalankan di antaranya sesuai urutan pendaftaran.
Menulis transformer
Perluas Shikiphp\Transformer\AbstractTransformer agar Anda hanya perlu mengganti hook yang diperlukan; sisanya tetap tanpa operasi. Konteks transformer menyediakan addClassToHast() untuk menambahkan kelas ke elemen.
use Shikiphp\Hast\Element;
use Shikiphp\Shikiphp;
use Shikiphp\Transformer\AbstractTransformer;
use Shikiphp\Transformer\TransformerContext;
final class AddLanguageClass extends AbstractTransformer
{
public function pre(Element $element, TransformerContext $context): ?Element
{
if ($context->lang !== null) {
$context->addClassToHast($element, 'language-' . $context->lang);
}
return $element;
}
}
echo Shikiphp::codeToHtml('const answer = 42', [
'lang' => 'js',
'theme' => 'nord',
'transformers' => [new AddLanguageClass()],
]);
// <pre class="shiki nord language-js" …>
Transformer bawaan
Transformer notasi
Transformer ini membaca komentar // [!code …] khusus dalam sumber (sintaks komentar bahasa dideteksi secara otomatis) dan mengubahnya menjadi kelas, lalu menghapus komentarnya. Transformer ini merupakan adaptasi langsung dari kumpulan notasi @shikijs/transformers.
NotationHighlight
Shikiphp\Transformer\Notation\NotationHighlight — // [!code highlight] (atau // [!code hl]) menambahkan kelas highlighted ke barisnya.
console.log('kept plain')
console.log('this line is highlighted') // [!code highlight]
NotationDiff
Shikiphp\Transformer\Notation\NotationDiff — // [!code ++] menandai baris sebagai ditambahkan (diff add), // [!code --] sebagai dihapus (diff remove).
console.log('old line') // [!code --]
console.log('new line') // [!code ++]
NotationFocus
Shikiphp\Transformer\Notation\NotationFocus — // [!code focus] menambahkan kelas focused.
console.log('focus on me') // [!code focus]
NotationErrorLevel
Shikiphp\Transformer\Notation\NotationErrorLevel — // [!code error], // [!code warning], dan // [!code info] menambahkan kelas highlighted beserta error / warning / info.
throwSomething() // [!code error]
maybeRisky() // [!code warning]
NotationWordHighlight
Shikiphp\Transformer\Notation\NotationWordHighlight — // [!code word:foo] (opsional // [!code word:foo:2] untuk membatasi hingga N baris berikutnya) membungkus setiap kemunculan foo dalam rentang yang memuat highlighted-word.
// [!code word:config]
const config = loadConfig()
Transformer meta
Transformer ini membaca string meta code fence yang diberikan melalui opsi meta (meta['__raw']), seperti Shiki membaca teks setelah bahasa pada blok kode berpagar.
MetaHighlight
Shikiphp\Transformer\MetaHighlight — menyorot baris yang disebutkan dalam rentang meta seperti {1,3-5}, dengan menambahkan kelas highlighted.
use Shikiphp\Shikiphp;
use Shikiphp\Transformer\MetaHighlight;
$code = "const a = 1\nconst b = 2\nconst c = 3\nconst d = 4\nconst e = 5";
echo Shikiphp::codeToHtml($code, [
'lang' => 'js',
'theme' => 'nord',
'meta' => ['__raw' => '{1,3-5}'],
'transformers' => [new MetaHighlight()],
]);
MetaWordHighlight
Shikiphp\Transformer\MetaWordHighlight — menyorot kata yang disebutkan dalam string meta dengan sintaks /word/, dengan menambahkan highlighted-word.
Spasi dan struktur
RenderWhitespace
Shikiphp\Transformer\RenderWhitespace — membungkus karakter spasi dan tab dalam rentang (kelas space dan tab secara default) agar dapat ditampilkan secara visual.
Konstruktor menerima (classSpace, classTab, position), dengan position berupa 'all' (default), 'boundary', 'trailing', atau 'leading'.
CompactLineOptions
Shikiphp\Transformer\CompactLineOptions — menerapkan kelas pada baris tertentu dari daftar entri {line, classes}.
use Shikiphp\Transformer\CompactLineOptions;
$transformer = new CompactLineOptions([
['line' => 1, 'classes' => 'highlighted'],
['line' => 3, 'classes' => ['highlighted', 'error']],
]);
Nomor baris dimulai dari 1. Teruskan objek melalui opsi transformers seperti transformer lainnya.
RemoveNotationEscape
Shikiphp\Transformer\RemoveNotationEscape — menghapus escape pada bentuk [\!code …] yang digunakan untuk menulis komentar notasi literal tanpa memicu transformer notasi.
RemoveLineBreak
Shikiphp\Transformer\RemoveLineBreak — menghapus node teks pemisah baris di antara baris (Shiki milik transformerRemoveLineBreak).
StyleToClass
Shikiphp\Transformer\StyleToClass — memindahkan gaya inline ke dalam kelas yang dihasilkan dan mengumpulkan stylesheet yang dapat Anda ambil dengan getCSS(). Nama kelas menggunakan hash gaya dengan Shiki milik cyrb53, sehingga keluaran identik byte demi byte dengan @shikijs/transformers 4.2.0, termasuk cakupannya:
- Gaya
<pre>selalu menjadi kelas. - Rentang token hanya dikonversi jika memuat gaya yang telah dibuat sebelumnya, seperti pada peta
themes. Dengan satutheme, rentang token tetap menggunakan gaya inlinestyle="color:…", seperti pada Shiki.
use Shikiphp\Shikiphp;
use Shikiphp\Transformer\StyleToClass;
$code = 'const answer = 42';
$styleToClass = new StyleToClass();
$html = Shikiphp::codeToHtml($code, [
'lang' => 'js',
'themes' => ['light' => 'github-light', 'dark' => 'github-dark'],
'transformers' => [$styleToClass],
]);
$css = $styleToClass->getCSS(); // collected stylesheet for the classes above
Konstruktor menerima (classPrefix, classSuffix, classReplacer); prefiks defaultnya adalah __shiki_.