Transformers
Met transformers kunt u de gemarkeerde uitvoer in elke fase aanpassen — van de ruwe bronstring, via het tokenraster tot de uiteindelijke HAST-boom en HTML. shikiphp neemt het transformer-model van Shiki hook voor hook over, zodat transformers hetzelfde werken als hun tegenhangers in JavaScript.
Geef ze door via de optie 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(),
],
]);
De pipeline
Elke transformer is een object dat Shikiphp\Transformer\Transformer implementeert.
De pipeline voert de hooks in volgorde uit tijdens het opbouwen van één blok:
| Hook | Handtekening | Wanneer |
|---|---|---|
preprocess |
(string $code, array &$options, $context): ?string |
vóór tokenisatie; kan de bron herschrijven en opties aanpassen |
tokens |
(array $tokens, $context): ?array |
na tokenisatie, op het 2D-raster ThemedToken |
root |
(Element $el, $context): ?Element |
op de HAST-root |
pre |
(Element $el, $context): ?Element |
op het element <pre> |
code |
(Element $el, $context): ?Element |
op het element <code> |
line |
(Element $el, int $line, $context): ?Element |
per regelelement (vanaf 1) |
span |
(Element $el, int $line, int $col, Element $lineEl, ThemedToken $token, $context): ?Element |
per tokenspan |
postprocess |
(string $html, array $options, $context): ?string |
op de uiteindelijke geserialiseerde string HTML |
Elke hook is optioneel. Als u een waarde retourneert, wordt de invoer vervangen; null retourneren laat die ongewijzigd.
enforce() bepaalt de volgorde tussen transformers: 'pre' wordt als eerste uitgevoerd, 'post' als laatste en null (de standaardinstelling) ertussen, in de volgorde waarin ze zijn geregistreerd.
Een transformer schrijven
Breid Shikiphp\Transformer\AbstractTransformer uit, zodat u alleen de hooks overschrijft die u nodig hebt; de rest doet niets. De transformercontext biedt addClassToHast() om klassen aan elementen toe te voegen.
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" …>
Ingebouwde transformers
Notatietransformers
Deze lezen speciale commentaren voor // [!code …] in de bron (de commentaarsyntaxis van de taal wordt automatisch herkend) en zetten die om in klassen, waarbij het commentaar zelf wordt verwijderd. Dit zijn directe ports van de notatieset @shikijs/transformers.
NotationHighlight
Shikiphp\Transformer\Notation\NotationHighlight — // [!code highlight] (of // [!code hl]) voegt de klasse highlighted toe aan de regel.
console.log('kept plain')
console.log('this line is highlighted') // [!code highlight]
NotationDiff
Shikiphp\Transformer\Notation\NotationDiff — // [!code ++] markeert een regel als toegevoegd (diff add) en // [!code --] als verwijderd (diff remove).
console.log('old line') // [!code --]
console.log('new line') // [!code ++]
NotationFocus
Shikiphp\Transformer\Notation\NotationFocus — // [!code focus] voegt de klasse focused toe.
console.log('focus on me') // [!code focus]
NotationErrorLevel
Shikiphp\Transformer\Notation\NotationErrorLevel — // [!code error], // [!code warning] en // [!code info] voegen de klasse highlighted toe, plus error / warning / info.
throwSomething() // [!code error]
maybeRisky() // [!code warning]
NotationWordHighlight
Shikiphp\Transformer\Notation\NotationWordHighlight — // [!code word:foo] wikkelt elke voorkomens van foo in een span met highlighted-word (optioneel // [!code word:foo:2] om dit tot de volgende N regels te beperken).
// [!code word:config]
const config = loadConfig()
Metadatatransformers
Deze lezen de metastring van het codeblok, die via de optie
meta wordt meegegeven (meta['__raw']), zoals Shiki de tekst
na een afgebakend codeblok met een taal leest.
MetaHighlight
Shikiphp\Transformer\MetaHighlight — markeert regels die in een metadatabereik zoals {1,3-5} zijn genoemd, met de klasse 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 — markeert woorden die in de metatekst zijn genoemd met de syntaxis /word/ en voegt highlighted-word toe.
Witruimte en structuur
RenderWhitespace
Shikiphp\Transformer\RenderWhitespace — wikkelt spaties en tabs in spans (standaard de klassen space en tab), zodat ze zichtbaar kunnen worden weergegeven. De constructor neemt (classSpace, classTab, position), waarbij position 'all' is (standaard), 'boundary', 'trailing' of 'leading'.
CompactLineOptions
Shikiphp\Transformer\CompactLineOptions — past klassen toe op specifieke regels aan de hand van een lijst met items van {line, classes}.
use Shikiphp\Transformer\CompactLineOptions;
$transformer = new CompactLineOptions([
['line' => 1, 'classes' => 'highlighted'],
['line' => 3, 'classes' => ['highlighted', 'error']],
]);
Regelnummers beginnen bij 1. Geef het object door via de optie transformers, net als elke andere transformer.
RemoveNotationEscape
Shikiphp\Transformer\RemoveNotationEscape — maakt de [\!code …]-vorm ongedaan die wordt gebruikt om een letterlijk notatiecommentaar te schrijven zonder een notatietransformer te activeren.
RemoveLineBreak
Shikiphp\Transformer\RemoveLineBreak — verwijdert de regeleindetekstknooppunten tussen regels (de transformerRemoveLineBreak van Shiki).
StyleToClass
Shikiphp\Transformer\StyleToClass — verplaatst inline stijlen naar gegenereerde klassen en verzamelt een stylesheet die u met getCSS() ophaalt. Klassennamen hashen de stijl met de cyrb53 van Shiki, zodat de uitvoer byte voor byte identiek is aan @shikijs/transformers 4.2.0, inclusief de scope:
- De stijl
<pre>wordt altijd een klasse. - Tokenspans worden alleen omgezet als ze een vooraf gebouwde stijl bevatten, zoals bij een kaart met
themes. Met éénthemebehouden de tokenspans hun inlinestyle="color:…", net als in 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
De constructor neemt (classPrefix, classSuffix, classReplacer); het standaardprefix is __shiki_.