Preskočiť na obsah

Transformátory

Transformátory umožňujú upravovať zvýraznený výstup v každej fáze — od surového zdrojového reťazca cez mriežku tokenov až po výsledný strom HAST a HTML. shikiphp preberá model transformátorov Shiki háčik za háčikom, takže transformátory sa správajú rovnako ako ich náprotivky v JavaScript.

Odovzdajte ich cez možnosť 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(),
    ],
]);

Proces spracovania

Každý transformátor je objekt implementujúci Shikiphp\Transformer\Transformer. Reťazec v danom poradí spustí háčiky pri zostavovaní jedného bloku:

Háčik Signatúra Kedy
preprocess (string $code, array &$options, $context): ?string pred tokenizáciou; môže prepísať zdroj a zmeniť možnosti
tokens (array $tokens, $context): ?array po tokenizácii, v 2D mriežke ThemedToken
root (Element $el, $context): ?Element na koreni HAST
pre (Element $el, $context): ?Element na prvku <pre>
code (Element $el, $context): ?Element na prvku <code>
line (Element $el, int $line, $context): ?Element pre každý prvok riadka (číslovanie od 1)
span (Element $el, int $line, int $col, Element $lineEl, ThemedToken $token, $context): ?Element pre každý rozsah tokenu
postprocess (string $html, array $options, $context): ?string nad výsledným serializovaným reťazcom HTML

Každý háčik je voliteľný. Vrátená hodnota nahradí vstup; vrátenie null ho ponechá nezmenený.

enforce() určuje poradie transformátorov: 'pre' sa spustí ako prvý, 'post' ako posledný a null (predvolené nastavenie) sa spustí medzi nimi v poradí registrácie.

Písanie transformátora

Rozšírte Shikiphp\Transformer\AbstractTransformer, aby ste museli prepísať iba tie háčiky, ktoré potrebujete; ostatné nerobia nič. Kontext transformátora poskytuje addClassToHast() na pridávanie tried prvkom.

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" …>

Vstavané transformátory

Transformátory zápisu

Čítajú špeciálne komentáre // [!code …] v zdrojovom kóde (syntax komentárov daného jazyka sa zisťuje automaticky) a prevádzajú ich na triedy, pričom samotný komentár odstraňujú. Ide o priame porty zo sady zápisu @shikijs/transformers.

NotationHighlight

Shikiphp\Transformer\Notation\NotationHighlight — // [!code highlight] (alebo // [!code hl]) pridá na riadok triedu highlighted.

JavaScript
console.log('kept plain')
console.log('this line is highlighted') // [!code highlight]

NotationDiff

Shikiphp\Transformer\Notation\NotationDiff — // [!code ++] označí riadok ako pridaný (diff add), // [!code --] ako odstránený (diff remove).

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

NotationFocus

Shikiphp\Transformer\Notation\NotationFocus — // [!code focus] pridá triedu focused.

JavaScript
console.log('focus on me') // [!code focus]

NotationErrorLevel

Shikiphp\Transformer\Notation\NotationErrorLevel — // [!code error], // [!code warning] a // [!code info] pridajú triedu highlighted aj error / warning / info.

JavaScript
throwSomething() // [!code error]
maybeRisky()     // [!code warning]

NotationWordHighlight

Shikiphp\Transformer\Notation\NotationWordHighlight — // [!code word:foo] (voliteľne // [!code word:foo:2] na obmedzenie na nasledujúcich N riadkov) obalí každý výskyt foo prvkom span s triedou highlighted-word.

JavaScript
// [!code word:config]
const config = loadConfig()

Transformátory metadát

Čítajú reťazec metadát bloku kódu dodaný cez možnosť meta (meta['__raw']), podobne ako Shiki číta text za jazykom ohraničeného bloku kódu.

MetaHighlight

Shikiphp\Transformer\MetaHighlight — zvýrazní riadky uvedené v rozsahu metadát, napríklad {1,3-5}, a pridá triedu 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 — zvýrazní slová uvedené v reťazci metadát pomocou syntaxe /word/ a pridá highlighted-word.

Medzery a štruktúra

RenderWhitespace

Shikiphp\Transformer\RenderWhitespace — obalí medzery a tabulátory prvkami span (predvolené triedy space a tab), aby sa dali viditeľne vykresliť. Konstruktor prijíma (classSpace, classTab, position), pričom position je 'all' (predvolené), 'boundary', 'trailing' alebo 'leading'.

CompactLineOptions

Shikiphp\Transformer\CompactLineOptions — použije triedy na konkrétne riadky zo zoznamu položiek {line, classes}.

PHP
use Shikiphp\Transformer\CompactLineOptions;

$transformer = new CompactLineOptions([
    ['line' => 1, 'classes' => 'highlighted'],
    ['line' => 3, 'classes' => ['highlighted', 'error']],
]);

Čísla riadkov začínajú od 1. Odovzdajte objekt v možnosti transformers, rovnako ako ktorýkoľvek iný transformátor.

RemoveNotationEscape

Shikiphp\Transformer\RemoveNotationEscape — zruší escapovanie zápisu [\!code …], ktorý slúži na zápis doslovného komentára so zápisom bez spustenia transformátora zápisu.

RemoveLineBreak

Shikiphp\Transformer\RemoveLineBreak — odstráni textové uzly zalomenia riadka medzi riadkami (Shiki: transformerRemoveLineBreak).

StyleToClass

Shikiphp\Transformer\StyleToClass — presunie vložené štýly do vygenerovaných tried a zhromaždí štýlopis, ktorý načítate pomocou getCSS(). Názvy tried sú hashom štýlu pomocou Shiki cyrb53, takže výstup je bajt po bajte zhodný s @shikijs/transformers 4.2.0 vrátane jeho rozsahu pôsobnosti:

  • Štýl <pre> sa vždy zmení na triedu.
  • Rozsahy tokenov sa konvertujú iba vtedy, keď obsahujú vopred vytvorený štýl, čo platí pre mapu themes. Pri jedinom theme si rozsahy tokenov zachovajú vložený style="color:…", rovnako ako v 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

Konstruktor prijíma (classPrefix, classSuffix, classReplacer); predpona je predvolene __shiki_.