ANSI-Colored Terminal Output for Sphinx

erbsland-sphinx-ansi is a lightweight Sphinx extension that renders ANSI-colored and formatted terminal output directly in your documentation.

It is especially useful when documenting command-line tools, build logs, or interactive sessions where color improves readability and realism.

Features

  • Render ANSI-colored terminal output in Sphinx documentation.

  • Support for standard ANSI text styles and colors.

  • Optional escape-char parameter for readable source files.

  • Optional theme parameter for custom CSS styling.

  • Works with both HTML and non-HTML output formats.

  • Gracefully ignores unsupported terminal control sequences.

Quick Start

Installation

Install the package from PyPI:

pip install erbsland-sphinx-ansi

Configuration

Enable the extension in your conf.py:

extensions = [
    # ...
    "erbsland.sphinx.ansi",
]

No additional configuration is required.

Usage

To render ANSI-colored output, use the erbsland-ansi directive:

.. erbsland-ansi::
    :escape-char: ␛

    ␛[32m[sphinx-autobuild] ␛[36mStarting initial build␛[0m
    ␛[32m[sphinx-autobuild] ␛[34m> python -m sphinx build doc _build␛[0m
    ␛[32m[sphinx-autobuild] ␛[36mServing on http://127.0.0.1:9000␛[0m
    ␛[32m[sphinx-autobuild] ␛[36mWaiting to detect changes...␛[0m

The :escape-char: option defines which character in the source file represents the ANSI escape character. This makes the escape sequences visible and editable in your documentation sources.

If the option is omitted, the directive expects real ANSI escape sequences.

Rendered Example

The following block demonstrates the rendered output:

[sphinx-autobuild] Starting initial build
[sphinx-autobuild] > python -m sphinx build doc _build
[sphinx-autobuild] Serving on http://127.0.0.1:9000
[sphinx-autobuild] Waiting to detect changes...

When building HTML documentation, the ANSI color codes are converted into styled output that closely resembles the original terminal appearance.

Custom Theming

Use the parameter theme to customize the CSS class prefix used for styling:

.. erbsland-ansi::
    :escape-char::theme: my-theme

    ␛[32m[sphinx-autobuild] ␛[36mStarting initial build␛[0m
    ␛[32m[sphinx-autobuild] ␛[34m> python -m sphinx build doc _build␛[0m
    ␛[32m[sphinx-autobuild] ␛[36mServing on http://127.0.0.1:9000␛[0m
    ␛[32m[sphinx-autobuild] ␛[36mWaiting to detect changes...␛[0m

Create a CSS file static/my-theme.css with the following content:

.my-theme-block {
    background-color: #fdfbff;
    color: #23143a;
}

.my-theme-bold { font-weight: bold; }
.my-theme-dim { opacity: 0.5; }
.my-theme-italic { font-style: italic; }
.my-theme-underline { text-decoration: underline; }
.my-theme-blink { text-decoration: blink; }
.my-theme-reverse { }
.my-theme-hidden { opacity: 0; }
.my-theme-strike { text-decoration: line-through; }
.my-theme-black { color: #2f153f; }
.my-theme-red { color: #c0213a; }
.my-theme-green { color: #1b8a3a; }
.my-theme-yellow { color: #b26a00; }
.my-theme-blue { color: #1c5fd4; }
.my-theme-magenta { color: #9a1f9b; }
.my-theme-cyan { color: #007e9c; }
.my-theme-white { color: #3a234e; }
.my-theme-black.my-theme-bold, .my-theme-bright-black { color: #16001f; }
.my-theme-red.my-theme-bold, .my-theme-bright-red { color: #a80023; }
.my-theme-green.my-theme-bold, .my-theme-bright-green { color: #0b6b2a; }
.my-theme-yellow.my-theme-bold, .my-theme-bright-yellow { color: #8f4b00; }
.my-theme-blue.my-theme-bold, .my-theme-bright-blue { color: #0c49b8; }
.my-theme-magenta.my-theme-bold, .my-theme-bright-magenta { color: #7d0082; }
.my-theme-cyan.my-theme-bold, .my-theme-bright-cyan { color: #006682; }
.my-theme-white.my-theme-bold, .my-theme-bright-white { color: #210e33; }
.my-theme-background-black { background-color: #f0e7ff; }
.my-theme-background-red { background-color: #ffd9de; }
.my-theme-background-green { background-color: #d6f5dd; }
.my-theme-background-yellow { background-color: #ffe9bf; }
.my-theme-background-blue { background-color: #dbe7ff; }
.my-theme-background-magenta { background-color: #f5dcff; }
.my-theme-background-cyan { background-color: #d6f6ff; }
.my-theme-background-white { background-color: #efe3ff; }
.my-theme-background-bright-black { background-color: #16001f; }
.my-theme-background-bright-red { background-color: #a80023; }
.my-theme-background-bright-green { background-color: #0b6b2a; }
.my-theme-background-bright-yellow { background-color: #8f4b00; }
.my-theme-background-bright-blue { background-color: #0c49b8; }
.my-theme-background-bright-magenta { background-color: #7d0082; }
.my-theme-background-bright-cyan { background-color: #006682; }
.my-theme-background-bright-white { background-color: #210e33; }

Output with the custom theme:

[sphinx-autobuild] Starting initial build
[sphinx-autobuild] > python -m sphinx build doc _build
[sphinx-autobuild] Serving on http://127.0.0.1:9000
[sphinx-autobuild] Waiting to detect changes...

Limitations

erbsland-sphinx-ansi is an ANSI style renderer, not a terminal emulator.

The extension supports ANSI text formatting such as:

  • Colors (foreground and background)

  • Bold, faint, italic, underline, strike-through

  • Style reset sequences

Some terminal control sequences are ignored because they cannot be represented reliably in static documentation. Examples include:

  • Cursor movement

  • Cursor visibility changes

  • Screen clearing

  • Alternate screen buffers

  • Character-set switching

  • Interactive terminal updates

If your output contains terminal control sequences that modify the screen state, the rendered result may differ from what you see in a real terminal.

Preprocessing Terminal Output

Some tools generate output that relies on terminal emulation. Examples include progress bars, full-screen applications, interactive programs, and output that uses cursor movement or character-set switching.

For such output, preprocess the captured terminal session with erbsland-ansi-convert before including it in your documentation:

pip install erbsland-ansi-convert

erbsland-ansi-convert input.ansi -o output.ansi

erbsland-ansi-convert emulates a terminal and writes the final screen contents as plain ANSI-formatted text. The converted output can then be rendered correctly by erbsland-sphinx-ansi.

Rendering ANSI Output

Note

The following example contains a few terminal control sequences that are ignored during rendering. The extension renders the text and formatting information only; it does not emulate terminal behavior.

command-line-help [<options>]

Summary
This demo prints a fictive command-line help page that adapts to the terminal width. On wider terminals it uses  
Terminal::printParagraph() to keep descriptions aligned, wrapped, and easy to scan. Below 40 columns it          
intentionally falls back to plain line-oriented output so you can compare both styles.                           

Preview Paragraph
Preview This paragraph keeps a visible background so options like background mode, wrap markers, word breaks,    
ellipsis handling, and alignment become easier to inspect while you adjust the rendering settings.               

Options
--help/-h                               Render this formatted help output. The flag is mostly here so the demo   
                                        behaves like a familiar command-line tool.                               
--terminal-width/-t=<columns>           Disable automatic width detection and simulate a terminal width between
                                        20 and 200 cells for deterministic wrapping.
--description-column/-c=<column>        Override the description tab stop for the options list. Valid values are
                                        12 to 60.
--alignment/-a=<left|center|right>      Choose the horizontal alignment used for the wrapped preview paragraphs.
--line-indent/-l=<columns>              Indent the preview paragraphs by 0 to 10 columns before any wrapping
                                        takes place.
--first-line-indent/-f=<columns>        Override the first-line indent for preview paragraphs. Valid values are 0
                                        to 12.
--wrapped-line-indent/-w=<columns>      Override the indentation of wrapped lines. Values between 0 and 30 make
                                        the effect easy to inspect.
--background-mode/-b=<mode>             Set the background fill strategy: default, wrapped-left, wrapped-right,
                                        wrapped-both, full-right, or full-both.
--line-break-start-mark/-s=<text>       Insert a one- or two-character marker at the start of each wrapped
                                        continuation line.
--line-break-end-mark/-m=<text>         Append a one- or two-character marker at the right edge when a line
                                        wraps.
--paragraph-spacing/-p=<single|double>  Switch between compact paragraphs or double-spaced output with one empty
                                        row in between.
--word-separators/-i=<tokens>           Use comma-separated separator tokens such as space,tab,slash or
                                        one-character literals like ; and |.
--word-break-mark/-k=<char>             Set the single character inserted when a word is split because it does
                                        not fit on the current line.
--maximum-line-wraps/-r=<count>         Limit the number of automatic wraps per paragraph. Use 0 for unlimited or
                                        values up to 8 to trigger ellipsis behaviour.
--paragraph-ellipsis-mark/-x=<text>     Choose the marker that signals clipped paragraphs after the configured
                                        wrap limit has been reached.
--tab-stops/-u=<list>                   Provide comma-separated tab stops like 1,24,40 or use wrapped to align a
                                        stop with the wrapped-line indent.
--on-error/-o=<plain|empty>             Choose the fallback when the paragraph cannot be laid out: plain output
                                        or empty output.


Contents

Indices and Tables