Ga naar de inhoud

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:

PHP
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.

PHP
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.

JavaScript
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).

JavaScript
console.log('old line') // [!code --]
console.log('new line') // [!code ++]

NotationFocus

Shikiphp\Transformer\Notation\NotationFocus — // [!code focus] voegt de klasse focused toe.

JavaScript
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.

JavaScript
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).

JavaScript
// [!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.

PHP
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}.

PHP
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 één theme behouden de tokenspans hun inline style="color:…", net als in Shiki.
PHP
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_.