Μετασχηματιστές
Οι μετασχηματιστές σάς επιτρέπουν να αναδιαμορφώνετε το επισημασμένο αποτέλεσμα σε κάθε στάδιο — από την αρχική συμβολοσειρά πηγαίου κώδικα, μέσω του πλέγματος διακριτικών, έως το τελικό δέντρο HAST και το HTML. Το shikiphp υλοποιεί το μοντέλο μετασχηματιστών του Shiki hook προς hook, ώστε οι μετασχηματιστές να συμπεριφέρονται όπως και τα αντίστοιχα JavaScript.
Περάστε τους μέσω της επιλογής 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(),
],
]);
Η ροή επεξεργασίας
Κάθε μετασχηματιστής είναι ένα αντικείμενο που υλοποιεί το Shikiphp\Transformer\Transformer.
Η ακολουθία εκτελεί τα hooks με τη σειρά κατά τη δημιουργία ενός μπλοκ:
| Hook | Υπογραφή | Πότε |
|---|---|---|
preprocess |
(string $code, array &$options, $context): ?string |
πριν από την τοκενικοποίηση· μπορεί να ξαναγράψει την πηγή και να τροποποιήσει τις επιλογές |
tokens |
(array $tokens, $context): ?array |
μετά την τοκενικοποίηση, στο δισδιάστατο πλέγμα ThemedToken |
root |
(Element $el, $context): ?Element |
στη ρίζα HAST |
pre |
(Element $el, $context): ?Element |
στο στοιχείο <pre> |
code |
(Element $el, $context): ?Element |
στο στοιχείο <code> |
line |
(Element $el, int $line, $context): ?Element |
ανά στοιχείο γραμμής (με αρίθμηση από το 1) |
span |
(Element $el, int $line, int $col, Element $lineEl, ThemedToken $token, $context): ?Element |
ανά εύρος διακριτικού |
postprocess |
(string $html, array $options, $context): ?string |
στην τελική σειριοποιημένη συμβολοσειρά HTML |
Όλα τα hooks είναι προαιρετικά. Η επιστροφή μιας τιμής αντικαθιστά την είσοδο· η επιστροφή του null τη διατηρεί αμετάβλητη.
Το enforce() ελέγχει τη σειρά μεταξύ των μετασχηματιστών: το 'pre' εκτελείται πρώτο, το 'post' τελευταίο, ενώ το null (προεπιλογή) εκτελείται ενδιάμεσα, με τη σειρά καταχώρισης.
Σύνταξη μετασχηματιστή
Επεκτείνετε το Shikiphp\Transformer\AbstractTransformer για να παρακάμπτετε μόνο τα hooks που χρειάζεστε· τα υπόλοιπα δεν κάνουν τίποτα. Το περιβάλλον μετασχηματιστή παρέχει το addClassToHast() για την προσθήκη κλάσεων σε στοιχεία.
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" …>
Ενσωματωμένοι μετασχηματιστές
Μετασχηματιστές σημειογραφίας
Αυτοί διαβάζουν ειδικά σχόλια // [!code …] στην πηγή (η σύνταξη σχολίων της γλώσσας εντοπίζεται αυτόματα) και τα μετατρέπουν σε κλάσεις, αφαιρώντας το ίδιο το σχόλιο. Είναι άμεσες μεταφορές του συνόλου σημειογραφίας @shikijs/transformers.
NotationHighlight
Shikiphp\Transformer\Notation\NotationHighlight — Το // [!code highlight] (ή το // [!code hl]) προσθέτει την κλάση highlighted στη γραμμή του.
console.log('kept plain')
console.log('this line is highlighted') // [!code highlight]
NotationDiff
Shikiphp\Transformer\Notation\NotationDiff — Το // [!code ++] επισημαίνει μια γραμμή ως προσθήκη (diff add), ενώ το // [!code --] την επισημαίνει ως αφαίρεση (diff remove).
console.log('old line') // [!code --]
console.log('new line') // [!code ++]
NotationFocus
Shikiphp\Transformer\Notation\NotationFocus — Το // [!code focus] προσθέτει την κλάση focused.
console.log('focus on me') // [!code focus]
NotationErrorLevel
Shikiphp\Transformer\Notation\NotationErrorLevel — Τα // [!code error], // [!code warning] και // [!code info] προσθέτουν την κλάση highlighted, καθώς και τα error / warning / info.
throwSomething() // [!code error]
maybeRisky() // [!code warning]
NotationWordHighlight
Shikiphp\Transformer\Notation\NotationWordHighlight — Το // [!code word:foo] (προαιρετικά το // [!code word:foo:2] για περιορισμό στις επόμενες N γραμμές) περικλείει κάθε εμφάνιση του foo σε span που φέρει το highlighted-word.
// [!code word:config]
const config = loadConfig()
Μετασχηματιστές μεταδεδομένων
Αυτοί διαβάζουν τη συμβολοσειρά μεταδεδομένων της περίφραξης κώδικα, η οποία παρέχεται μέσω της επιλογής meta (meta['__raw']), όπως το Shiki διαβάζει το κείμενο μετά τη γλώσσα ενός περιφραγμένου μπλοκ κώδικα.
MetaHighlight
Shikiphp\Transformer\MetaHighlight — Επισημαίνει τις γραμμές που κατονομάζονται σε ένα εύρος μεταδεδομένων, όπως το {1,3-5}, προσθέτοντας την κλάση 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 — Επισημαίνει λέξεις που κατονομάζονται στη συμβολοσειρά μεταδεδομένων με τη σύνταξη /word/, προσθέτοντας το highlighted-word.
Κενά διαστήματα και δομή
RenderWhitespace
Shikiphp\Transformer\RenderWhitespace — Περικλείει χαρακτήρες διαστήματος και tab σε span (κλάσεις space και tab από προεπιλογή), ώστε να μπορούν να αποδοθούν ορατά.
Ο κατασκευαστής δέχεται το (classSpace, classTab, position), όπου το position είναι 'all' (προεπιλογή), 'boundary', 'trailing' ή 'leading'.
CompactLineOptions
Shikiphp\Transformer\CompactLineOptions — Εφαρμόζει κλάσεις σε συγκεκριμένες γραμμές από μια λίστα καταχωρίσεων {line, classes}.
use Shikiphp\Transformer\CompactLineOptions;
$transformer = new CompactLineOptions([
['line' => 1, 'classes' => 'highlighted'],
['line' => 3, 'classes' => ['highlighted', 'error']],
]);
Οι αριθμοί γραμμών ξεκινούν από το 1. Περάστε το αντικείμενο στην επιλογή transformers όπως οποιονδήποτε άλλο μετασχηματιστή.
RemoveNotationEscape
Shikiphp\Transformer\RemoveNotationEscape — Αφαιρεί τα escape από τη μορφή [\!code …], η οποία χρησιμοποιείται για την εγγραφή ενός κυριολεκτικού σχολίου σημειογραφίας χωρίς να ενεργοποιηθεί μετασχηματιστής σημειογραφίας.
RemoveLineBreak
Shikiphp\Transformer\RemoveLineBreak — Αφαιρεί τους κόμβους κειμένου αλλαγής γραμμής ανάμεσα στις γραμμές (το transformerRemoveLineBreak του Shiki).
StyleToClass
Shikiphp\Transformer\StyleToClass — Μεταφέρει τα ενσωματωμένα στυλ σε δημιουργημένες κλάσεις και συλλέγει ένα φύλλο στυλ που ανακτάτε με το getCSS(). Τα ονόματα κλάσεων κατακερματίζουν το στυλ με το cyrb53 του Shiki, ώστε η έξοδος να είναι πανομοιότυπη byte προς byte με το 4.2.0 @shikijs/transformers, μαζί με το scope του:
- Το στυλ
<pre>γίνεται πάντα κλάση. - Τα span διακριτικών μετατρέπονται μόνο όταν φέρουν προκατασκευασμένο στυλ, όπως συμβαίνει με έναν χάρτη
themes. Με ένα μόνοtheme, τα span διακριτικών διατηρούν το ενσωματωμένοstyle="color:…"τους, όπως και στο 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
Ο κατασκευαστής δέχεται το (classPrefix, classSuffix, classReplacer)· το προεπιλεγμένο πρόθεμα είναι __shiki_.