
# Вывод 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-последовательности удаляются из вывода; остается только текст, обернутый в цветные элементы span.

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

## Что он распознает

Токенизатор считывает последовательности 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 и шкала оттенков серого), а также значения True Color не зависят от темы.

[ANSI`colorReplacements` применимо и к цветам.](https://shikiphp.inline0.dev/ru/docs/options#colorreplacements)

## Две темы

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