Published on Jul 04, 2025 in sphinx

How to add numbered images to tutorials in Sphinx#

Learn how to add numbered images to Sphinx tutorials with SVGs, Markdown, and reStructuredText. Often in step-by-step HOWTO guides, we want to refer to a certain point on a screenshot. For example, “Delete a book (4)”, where (4) refers to the (4) in the screenshot. Explore together more aesthetically pleasing alternatives to plain text “(4)”.

The result#

While working on Documatt help, we wrote numerous step-by-step guides. We wanted to achieve nice red circled numbers corresponding to the red circled numbers in a screenshot figures.

How to create number images#

There are multiple ways to prepare number images. It’s a lot of manual work, but you can create it in the graphic editor and save it alongside other images used throughout your documentation.

The better approach is to generate images as SVG. Because they are vector, number images will be fully resizable and selectable as standard text.

The most basic SVG for a white number in a red circle is:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" style="width: 1em; display: inline;">
    <circle cx="16" cy="16" r="16" fill="#fff"></circle>
    <text x="16" y="22" fill="#fff" text-anchor="middle" style="font-weight: bold;">
      1
   </text>
</svg>

Customize colors, sizing, or font according to your brand conventions.

Create an image generator function#

In your conf.py, add a function that will return an SVG string representing a passed number.

def svg_number(number: str):
    """Return an SVG representation of a number."""
    return f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" style="width: 1em; display: inline;"><circle cx="16" cy="16" r="16" fill="#1976d2"></circle><text x="16" y="22" fill="#fff" text-anchor="middle" style="font-weight: bold;">{number}</text></svg>'

If you complete this step, continue according to whether you prefer Markdown or reStructuredText syntax.

Substitutions in Markdown#

To use Markdown in Sphinx, add MyST parser to your documentation project first.

  1. Enable MyST substitutions extension.

  2. Add a few numbers as substitute items. For example, the first 10 numbers. Because the substitution item key cannot be a number like 1, 2, etc., let’s use word alternatives like one, two, etc.

    myst_substitutions = {
        "one": svg_number("1"),
        "two": svg_number("2"),
        "three": svg_number("3"),
        "four": svg_number("4"),
        "five": svg_number("5"),
        "six": svg_number("6"),
        "seven": svg_number("7"),
        "eight": svg_number("8"),
        "nine": svg_number("9"),
        "ten": svg_number("10"),
    }
    
  3. Now use substitution anywhere in regular text with {{ <substitution_key> }} syntax. E.g.,

    The left side of the screen features a persistent _activity bar_.
    It allows you to **navigate between key sections of the application**
    described later:
    
    - Book shelf {{ one }}
    - Templates {{ two }}
    - Editor {{ three }}
    - My profile {{ four }}
    

Substitutions in reStructuredText#

If you prefer writing Sphinx documentation in native reStructuredText markup language, no additional extensions are necessary since reStructuredText has built-in substitution.

  1. Add to the conf.py:

    rst_epilog = f"""
    .. |one| replace:: {svg_number("1")}
    .. |two| replace:: {svg_number("2")}
    .. |three| replace:: {svg_number("3")}
    .. |four| replace:: {svg_number("4")}
    .. |five| replace:: {svg_number("5")}
    .. |six| replace:: {svg_number("6")}
    .. |seven| replace:: {svg_number("7")}
    .. |eight| replace:: {svg_number("8")}
    .. |nine| replace:: {svg_number("9")}
    .. |ten| replace:: {svg_number("10")}
    """
    
  2. Use anywhere in regular text with |substitution-name| syntax.

    The left side of the screen features a persistent *activity bar*.
    It allows you to **navigate between key sections of the application**
    described later:
    
    - Book shelf |one|
    - Templates |two|
    - Editor |three|
    - My profile |four|
    

Alternative with emojis#

As an alternative, you can use some of the Unicode emoji characters for numbers.

The disadvantage of emojis is that you can’t control the look. If it looks nice on your browser, it’s not guaranteed to look the same on different platforms (Windows, Mac, iPhone, Android, various browsers).

For example, the number emoji for “4” on macOS has the following appearance: