Skip to content

ANSI Output

Set lang to 'ansi' to highlight terminal output — text containing ANSI escape sequences — instead of tokenizing with a grammar. shikiphp parses the escape codes and colors the text from the theme's ANSI palette. It is a port of Shiki's lang: 'ansi' tokenizer, and four oracle scenarios check its HTML against Shiki 3.23.0.

PHP
use Shikiphp\Shikiphp;

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

This is the natural way to render captured CLI output — test runners, build logs, git output — with its original colors preserved. The escape sequences are removed from the output; only the text remains, wrapped in colored spans.

Note the double-quoted PHP string: "\e" is the escape character. When you render output captured from a process (for example with shell_exec or proc_open), the escape characters are already in the string.

What it understands

The tokenizer reads SGR (Select Graphic Rendition) sequences, ESC [ … m, with any number of ;-separated codes:

Codes Effect
0 reset all colors and attributes
1, 3, 4, 9 bold, italic, underline, strikethrough
2 dim: the foreground is drawn at half opacity
7 reverse: foreground and background swap
21, 23, 24, 27, 29 turn the matching attribute off
22 normal intensity: turns off dim and bold
30–37, 90–97 foreground: the 8 standard and 8 bright colors
40–47, 100–107 background: the 8 standard and 8 bright colors
38;5;n, 48;5;n foreground or background from the 256-color table
38;2;r;g;b, 48;2;r;g;b 24-bit true-color foreground or background
39, 49 default foreground or background

Hidden (8) and overline (53) are parsed but do not change the output, and other codes are ignored. Styles carry across line breaks until they are reset, as in a terminal.

Colors

The 16 named colors come from the theme's terminal.ansi* colors (terminal.ansiRed, terminal.ansiBrightBlue, and so on). Where a theme does not define one, the VS Code default palette is used (#cd3131 for red, #2472C8 for blue, and so on). Text with no color set takes the theme's foreground, and the block background is the theme's background, as for grammar-based highlighting. In the 256-color table, entries 0–15 are those same 16 named colors; entries 16–255 (the 6×6×6 color cube and the grayscale ramp) and true-color values do not depend on the theme.

colorReplacements apply to ANSI colors too.

Dual themes

ANSI honors the themes map just like grammar-based highlighting, emitting CSS-variable variants for the non-default themes:

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

Each named color resolves against each theme's own palette, so a red in the light theme and a red in the dark theme can differ.

No grammar state

Because ANSI does not use a TextMate grammar, there is no grammar state to carry. getLastGrammarState throws for lang: 'ansi', and codeToTokensResult returns a null grammarState.