
# Dönüştürücüler

Dönüştürücüler, vurgulanmış çıktıyı her aşamada yeniden şekillendirmenizi sağlar: ham kaynak dizgesinden belirteç ızgarasına, son HAST ağacına ve HTML'e kadar. shikiphp, Shiki dönüştürücü modelini tüm kancalarıyla taşır; bu nedenle dönüştürücüler JavaScript karşılıklarıyla aynı şekilde davranır.

Bunları [`transformers`](https://shikiphp.inline0.dev/tr/docs/options#transformers) seçeneğiyle iletin:

```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(),
    ],
]);
```

## İşlem hattı

Her dönüştürücü, `Shikiphp\Transformer\Transformer` uygulayan bir nesnedir.
İşlem hattı, tek bir bloğun oluşturulması sırasında kancaları sırayla çalıştırır:

| Kanca | İmza | Ne zaman |
| --- | --- | --- |
| `preprocess` | `(string $code, array &$options, $context): ?string` | belirteçleştirmeden önce; kaynağı yeniden yazabilir ve seçenekleri değiştirebilir |
| `tokens` | `(array $tokens, $context): ?array` | belirteçleştirmeden sonra, 2D `ThemedToken` ızgarasında |
| `root` | `(Element $el, $context): ?Element` | HAST kökünde |
| `pre` | `(Element $el, $context): ?Element` | `<pre>` öğesinde |
| `code` | `(Element $el, $context): ?Element` | `<code>` öğesinde |
| `line` | `(Element $el, int $line, $context): ?Element` | her satır öğesi için (1 tabanlı) |
| `span` | `(Element $el, int $line, int $col, Element $lineEl, ThemedToken $token, $context): ?Element` | her belirteç aralığı için |
| `postprocess` | `(string $html, array $options, $context): ?string` | son serileştirilmiş HTML dizgesinde |

Her kanca isteğe bağlıdır. Bir değer döndürmek girdiyi değiştirir; `null` döndürmekse girdiyi olduğu gibi bırakır.

`enforce()` dönüştürücüler arasındaki sıralamayı belirler: önce `'pre'`, en son `'post'` çalışır; `null` (varsayılan) ise kayıt sırasına göre arada çalışır.

## Dönüştürücü yazma

`Shikiphp\Transformer\AbstractTransformer` sınıfını genişleterek yalnızca ihtiyacınız olan kancaları geçersiz kılın; diğerleri işlem yapmaz. Dönüştürücü bağlamı, öğelere sınıf eklemek için `addClassToHast()` arayüzünü sunar.

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

## Yerleşik dönüştürücüler

### Notasyon dönüştürücüleri

Bunlar kaynak içindeki özel `// [!code …]` yorumlarını okur (yorum söz dizimi otomatik olarak algılanır) ve bunları sınıflara dönüştürür; yorumun kendisini kaldırır. `@shikijs/transformers` notasyon kümesinin doğrudan uyarlamalarıdır.

#### `NotationHighlight`

`Shikiphp\Transformer\Notation\NotationHighlight` — `// [!code highlight]` (veya `// [!code hl]`), satırına `highlighted` sınıfını ekler.

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

#### `NotationDiff`

`Shikiphp\Transformer\Notation\NotationDiff` — `// [!code ++]` bir satırı eklenmiş (`diff add`), `// [!code --]` ise silinmiş (`diff remove`) olarak işaretler.

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

#### `NotationFocus`

`Shikiphp\Transformer\Notation\NotationFocus` — `// [!code focus]`, `focused` sınıfını ekler.

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

#### `NotationErrorLevel`

`Shikiphp\Transformer\Notation\NotationErrorLevel` — `// [!code error]`, `// [!code warning]` ve `// [!code info]`, `highlighted` sınıfını ve ayrıca `error` / `warning` / `info` sınıflarını ekler.

```js
throwSomething() // [!code error]
maybeRisky()     // [!code warning]
```

#### `NotationWordHighlight`

`Shikiphp\Transformer\Notation\NotationWordHighlight` — `// [!code word:foo]`
(isteğe bağlı olarak sonraki N satırla sınırlamak için `// [!code word:foo:2]`) `foo` öğesinin her
örneğini `highlighted-word` taşıyan bir span içine alır.

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

### Meta dönüştürücüleri

Bunlar [`meta`](https://shikiphp.inline0.dev/tr/docs/options#meta) seçeneği üzerinden sağlanan kod çiti **meta dizgesini** (`meta['__raw']`) okur; Shiki, çitlenmiş bir kod bloğundaki dil adından sonraki metni nasıl okuyorsa bu da öyle çalışır.

#### `MetaHighlight`

`Shikiphp\Transformer\MetaHighlight` — meta aralığında `{1,3-5}` gibi belirtilen satırları vurgular ve `highlighted` sınıfını ekler.

```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` — meta dizgesinde `/word/` söz dizimiyle belirtilen sözcükleri vurgular ve `highlighted-word` ekler.

### Boşluk ve yapı

#### `RenderWhitespace`

`Shikiphp\Transformer\RenderWhitespace` — boşluk ve sekme karakterlerini aralıklara alır (varsayılan olarak `space` ve `tab` sınıfları); böylece görünür biçimde görüntülenebilirler. Oluşturucu, `(classSpace, classTab, position)` değerini alır; burada `position`, `'all'` (varsayılan), `'boundary'`, `'trailing'` veya `'leading'` olur.

#### `CompactLineOptions`

`Shikiphp\Transformer\CompactLineOptions` — bir `{line, classes}` girdileri listesinden belirli satırlara sınıf uygular.

```php
use Shikiphp\Transformer\CompactLineOptions;

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

Satır numaraları 1 tabanlıdır. Nesneyi diğer dönüştürücüler gibi `transformers` seçeneğiyle iletin.

#### `RemoveNotationEscape`

`Shikiphp\Transformer\RemoveNotationEscape` — bir notasyon dönüştürücüsünü tetiklemeden gerçek bir notasyon yorumu yazmak için kullanılan `[\!code …]` biçiminin kaçış karakterlerini kaldırır.

#### `RemoveLineBreak`

`Shikiphp\Transformer\RemoveLineBreak` — satırlar arasındaki satır sonu metin düğümlerini kaldırır (Shiki öğesinin `transformerRemoveLineBreak` özelliği).

### `StyleToClass`

`Shikiphp\Transformer\StyleToClass` — satır içi stilleri oluşturulan sınıflara taşır ve `getCSS()` ile alabileceğiniz bir stil sayfası derler. Sınıf adları, stili Shiki öğesinin `cyrb53` değeriyle özetler; böylece kapsamı da dahil olmak üzere çıktı, `@shikijs/transformers` 4.2.0 ile bayt bayt aynı olur:

- `<pre>` stili her zaman bir sınıfa dönüşür.
- Belirteç aralıkları yalnızca önceden oluşturulmuş bir stil taşıdıklarında dönüştürülür; bu durum `themes` eşlemesiyle geçerlidir. Tek bir `theme` kullanıldığında belirteç aralıkları, Shiki içindeki gibi satır içi `style="color:…"` stilini korur.

```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
```

Oluşturucu, `(classPrefix, classSuffix, classReplacer)` değerini alır; varsayılan önek `__shiki_` olur.
