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

  • Optional escape-char parameter that allows you to replace the ANSI escape character (\x1b) with a visible placeholder character inside reStructuredText sources.

  • Optional theme parameter that allows you to customize the CSS class prefix used for styling.

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

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

Demo

The following demo includes additional control sequences that are ignored during rendering.

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