
# Вивід ANSI

Задайте `lang` значення `'ansi'`, щоб підсвітити вивід термінала — текст з escape-послідовностями ANSI — замість токенізації за граматикою. shikiphp аналізує escape-коди й розфарбовує текст палітрою ANSI теми. Це порт токенізатора Shiki `lang: 'ansi'`, а чотири сценарії еталонного тестування перевіряють його HTML щодо Shiki 3.23.0.

```php
use Shikiphp\Shikiphp;

echo Shikiphp::codeToHtml("\e[31merror\e[0m: something broke", [
    'lang'  => 'ansi',
    'theme' => 'github-dark',
]);
```

Це природний спосіб відобразити перехоплений вивід CLI — засобів запуску тестів, журналів збірки, вивід `git` — зі збереженням початкових кольорів. Escape-послідовності видаляються з виводу; залишається лише текст, обгорнутий у кольорові spans.

Зверніть увагу на рядок PHP у подвійних лапках: `"\e"` — це escape-символ. Під час відображення виводу, перехопленого з процесу (наприклад, за допомогою `shell_exec` або `proc_open`), escape-символи вже містяться в рядку.

## Що він розпізнає

Токенізатор читає послідовності SGR (Select Graphic Rendition), `ESC [ … m`, з будь-якою кількістю кодів, розділених `;`:

| Коди | Ефект |
| --- | --- |
| `0` | скидає всі кольори й атрибути |
| `1`, `3`, `4`, `9` | жирний шрифт, курсив, підкреслення, закреслення |
| `2` | тьмяний: передній план відображається з половинною непрозорістю |
| `7` | інверсія: кольори переднього плану й тла міняються місцями |
| `21`, `23`, `24`, `27`, `29` | вимикають відповідний атрибут |
| `22` | звичайна інтенсивність: вимикає тьмяність і жирний шрифт |
| `30`–`37`, `90`–`97` | передній план: 8 стандартних і 8 яскравих кольорів |
| `40`–`47`, `100`–`107` | тло: 8 стандартних і 8 яскравих кольорів |
| `38;5;n`, `48;5;n` | колір переднього плану або тла з таблиці на 256 кольорів |
| `38;2;r;g;b`, `48;2;r;g;b` | 24-бітний повноколірний передній план або тло |
| `39`, `49` | стандартний колір переднього плану або тла |

Прихований (`8`) і надкреслений (`53`) атрибути розбираються, але не змінюють вивід; інші коди ігноруються. Стилі зберігаються між рядками, доки їх не скинуто, як у терміналі.

## Кольори

16 іменованих кольорів беруться з кольорів `terminal.ansi*` теми (`terminal.ansiRed`, `terminal.ansiBrightBlue` тощо). Якщо тема не визначає колір, використовується стандартна палітра VS Code (`#cd3131` для червоного, `#2472C8` для синього тощо). Текст без заданого кольору використовує колір переднього плану теми, а тло блока — колір тла теми, як і для підсвічування за граматикою. У таблиці на 256 кольорів записи 0–15 — це ті самі 16 іменованих кольорів; записи 16–255 (куб кольорів 6×6×6 і шкала відтінків сірого) та значення повного кольору не залежать від теми.

[`colorReplacements`](https://shikiphp.inline0.dev/uk/docs/options#colorreplacements) застосовуються і до кольорів ANSI.

## Подвійні теми

ANSI враховує карту `themes` так само, як підсвічування за граматикою, створюючи варіанти CSS для тем, відмінних від стандартної:

```php
use Shikiphp\Shikiphp;

$log = "\e[32mPASS\e[0m tests/Unit\n\e[31mFAIL\e[0m tests/Integration";

echo Shikiphp::codeToHtml($log, [
    'lang'   => 'ansi',
    'themes' => ['light' => 'github-light', 'dark' => 'github-dark'],
]);
```

Кожен іменований колір визначається за палітрою відповідної теми, тому червоний у світлій і темній темах може відрізнятися.

## Без стану граматики

Оскільки ANSI не використовує граматику TextMate, зберігати стан граматики не потрібно. `getLastGrammarState` викидає помилку для `lang: 'ansi'`, а `codeToTokensResult` повертає `null` `grammarState`.
