Kalian akan belajar memakai package @shikijs/transformers untuk menambah fitur seperti diff dan highlight lewat notasi baris, serta membuat custom transformer untuk mengubah token dan metadata hasil highlight sesuai kebutuhan proyek.

Meta string memberi kalian kendali lewat sintaks Markdown, tetapi tidak semua kebutuhan bisa diungkapkan lewat meta. Saat kalian ingin memanipulasi token, menandai baris dengan notasi khusus, atau menambah metadata pada output, giliran transformers yang bekerja.
Episode 10 membahas transformers di ekosistem Shiki: konsep dasar transformer, katalog transformer siap pakai dari @shikijs/transformers, cara memakainya lewat opsi transformers pada rehype-pretty-code, dan cara membuat custom transformer sendiri. Transformers adalah kunci untuk melepas batas fitur bawaan.
Shiki memproses kode dalam beberapa tahap: tokenisasi, transformasi, lalu render menjadi HAST. Transformer adalah fungsi yang menyisipkan logika di antara tahap tersebut. Melalui hooks seperti preprocess, code, line, dan span, kalian bisa mengubah kode, token, dan elemen sebelum HTML akhir dibentuk.
Setiap transformer adalah objek yang membawa properti name dan kumpulan hooks. Hooks menerima data tahap tertentu dan boleh mengembalikan nilai baru untuk diteruskan ke tahap berikutnya.
Transformers terpisah ke package tersendiri sejak Shiki v4. Pasang bersama shiki:
npm i shiki @shikijs/transformersPerintah npm i shiki @shikijs/transformers menambah kedua dependency ke proyek. Package @shikijs/transformers berisi koleksi transformer siap pakai yang ditulis dan diuji oleh tim Shiki.
Kelompok transformer ini membaca komentar khusus di dalam kode sebagai instruksi visual. Contoh yang paling sering dipakai:
transformerNotationDiff mengenali komentar // [!code ++] dan // [!code --] untuk menandai baris tambah dan hapus.transformerNotationHighlight mengenali // [!code highlight] untuk menyorot baris.transformerNotationFocus mengenali // [!code focus] untuk memfokuskan baris.transformerNotationWordHighlight menandai kata setelah // [!code word:...].Notasi ini populer karena penulis cukup menulis komentar di baris kode aslinya, tanpa meta string tambahan. Cocok untuk konten yang ditulis dengan gaya VitePress.
Selain notasi, ada transformer untuk kebutuhan teknis:
transformerRenderWhitespace menampilkan spasi dan tab secara visual.transformerCompactLineOptions merapikan opsi baris pada output.transformerMetaHighlight menerjemahkan meta string menjadi highlight baris.transformerRemoveLineBreak menghilangkan baris kosong yang tidak diinginkan.Gunakan transformer yang benar-benar dibutuhkan saja, karena setiap transformer menambah pekerjaan saat render.
rehype-pretty-code meneruskan opsi transformers ke Shiki. Susun daftar transformer pada konfigurasi plugin:
import {
transformerNotationDiff,
transformerNotationHighlight,
} from "@shikijs/transformers";
const options = {
theme: "github-dark-default",
transformers: [
transformerNotationDiff(),
transformerNotationHighlight(),
],
};Setelah konfigurasi ini, kalian bisa menulis komentar // [!code ++] di dalam code block dan baris tersebut otomatis ditandai sebagai tambahan. Urutan dalam array menentukan urutan eksekusi hooks.
Berikut blok TypeScript yang memakai notasi diff lewat transformer:
const lama = 1;
const baru = 2;
console.log(lama);
console.log(baru);Perhatikan bahwa kalian tidak perlu menulis meta string diff pada baris pembuka. Transformer notasi membaca komentar di dalam isi kode secara mandiri. Inilah kelebihan memakai transformers: fitur dipindahkan dari meta string ke dalam isi kode.
Kalian bisa membuat transformer sendiri berupa objek ShikiTransformer dengan hooks. Contoh berikut menambahkan atribut data-theme-source pada elemen blok kode:
import type { ShikiTransformer } from "shiki";
export const themeSourceTransformer: ShikiTransformer = {
name: "theme-source-transformer",
preprocess(code, options) {
options.theme = options.theme ?? "github-dark-default";
return code;
},
code(hast) {
hast.properties["data-theme-source"] = "shiki";
},
};Hook preprocess mengubah input sebelum tokenisasi, sedangkan hook code menerima node HAST <pre> dan boleh memodifikasi propertinya. Kombinasi keduanya mencakup sebagian besar kebutuhan kustomisasi.
Pilih hook sesuai tahap yang ingin diubah:
preprocess untuk memodifikasi string kode sebelum tokenisasi.tokens untuk mengubah kumpulan token yang sudah dianotasi.line untuk memodifikasi elemen HAST satu baris.span untuk memodifikasi elemen HAST satu token.code untuk memodifikasi elemen HAST blok kode secara utuh.Setiap hook menerima data tahap tersebut dan dapat mengembalikan data baru. Kalian juga bisa memakai shiki versi dev untuk mengetes custom transformer sebelum dipakai produksi.
Inti yang harus dibawa pulang:
@shikijs/transformers menyediakan transformer siap pakai.// [!code ++] memperkaya kode tanpa meta string.transformers di rehype-pretty-code menerima array transformer.name dan hooks.preprocess, line, span, dan code mengontrol setiap lapisan output.Di episode 11 kalian akan belajar integrasi dengan framework konten: memasang pipeline yang sama di Next.js dengan MDX atau Velite, serta pola integrasi di Astro, SvelteKit, dan VitePress yang masing-masing hanya berbeda di titik konfigurasi.