Techwriter at work blog.

Living and writing documentation at Documatt, small team of programmers that do write documentation too.

reStructuredText overview

If you have time to read the only one reStructuredText and Sphinx article, it should be this one. Here you will essential overview of the syntax and tools used for building professional documentation.

What is Sphinx and reStructuredText?


reStructuredText is the syntax (the rules of writing) for a documentation. Tech writer code is somewhat similar to the programmer, but much simpler. Programmers write in Java, Python, etc., while tech writers write in plain text files containing reStructuredText.

reStructuredText is often shortened as RST or reST (don’t confuse with the REST which is kind of APIs). Files has often .rst extension.

Documentation languages as reStructuredText are also called markup languages [1], because they add the formatting and semantic meaning to the plain text. At the time of writing, you should not be concerned how the text will look like at production. The outputs like web page or PDF may look very different.

Have a look at the example of reStructuredText source and corresponding result.

Paragraphs may contain *emphasised*, **strong emphasised** words.
Links to external webs like are
auto-recognized. Sometimes you need ``monospaced text``. Useful are
also :sup:`superscript` or :sub:`subscript`.

Unordered lists usually use ``*`` as bullet symbol:

* A bullet list item
* Second item
* A sub item


Sphinx is the tool that takes reStructuredText files and build a documentation in formats like HTML or PDF. Sphinx is not the only tool that works with the reStructuredText, but is the most advanced and the most used in the industry.

Sphinx also adds few new useful constructs to the reStructuredText, e.g. for creating a table of contents, documenting programming language code. reStructuredText and Sphinx makes a perfect couple.

Sphinx is command-line tool with no graphical interface. Write .rst files in any (plain) text editor you like. Folder with .rst files and Sphinx configuration file is called Sphinx project.

To invoke Sphinx to build a project, do e.g. (on the Linux or macOS):

$ cd my_sphinx_project
$ ls
$ make html

and Sphinx will produce HTML version of the project.

Block and inline elements

reStructuredText contains two types of elements: block and inline-level.

Block-level elements appear in the text as the rectangular objects which do no break across lines. Examples of block elements: section title, paragraph, bullet list, and many more.

Inline elements are part of the document text flow and they do break across lines. Inlines are e.g. emphasis (italic), strong emphasis (bold), literal (code example in monospace font) and few more.


Whitespace and indentation


Whitespaces are invisible but very important characters not only in reStructuredText. The common whitespaces are under the Space and Tab keys.

Blank lines

Blank lines separates paragraphs and other block elements. As you will see bellow, blank line is important to delimit new list sublist within another list.

In normal text, multiple successive blank lines are considered as a single blank line. They are only preserved in the literal blocks.

Blank lines separates paragraphs and other elements.

In normal text, multiple successive blank lines are
considered as a single blank line.


   They are only

   preserved in the

   literal blocks.


Tricky part of reStructuredText is indentation. Indentation means putting whitespaces before the line text itself. I strongly recommend you to use e.g., four Spaces instead of Tab character.


Keeping proper indentation and blank line separators in reStructuredText is definitively the biggest trouble not only for beginners! Read the following part very carefully.

The indentation is part of the syntax of many reStructuredText elements:

  • block quotes

  • definition lists

  • bullet and enumerated lists

  • content of literal blocks

  • content of blocks like directive, footnote, comment, etc.

  • any nested content, e.g. a list withing another list item

Wrongly indented means wrongly recognized. For example, just indenting the second paragraph makes it the block quote element. First and third has original indentation and thus are normal paragraphs.

My favorite quote is

    Don't count the days, make the days count.

but I don't remember its author.

Extreme attention has to be paid for bullet or enumerated lists. List item content needs to keep proper indentation level.

* list item #1
* item #2 is on three lines
  in the source but they are
  all the same indented
* item #3
* item #4 contain sublist

  * sublist must be intended
    on the same level as
    parent item
  * also, item #4 and sublist must be
    separated by the blank line

* item #5 returns back to the
  original indentation

Previous example also shows that block elements must be separated by the at least one blank line. If you forgot to separate sublist new a blank line, it will be a continuation of item #1:

* item #1
  * sublist without separating blank line is continuation of previous element

* item #2

  * sublist has to be started with the blank line

* item #3

Another crazy situation easily occurs if you indent the sublist, but not at the same level as the parent item:

Wrong indented sublist:

#. list #1

 #. not a sublist of #1 but a block quote!

#. another list #2, not related to the previous one

Above fixed:

#. list #1

   #. sublist of #1 because it's indented as parent item

#. still list #1, the second item

Directives and roles

The last what I consider as reStructuredText and Sphinx essential knowledge is the understanding of directives and roles. They are syntactic constructions that can add new features to the reStructuredText.

Directives are block elements. Begin with the .., followed by a name, and ends with ::. Roles are inline elements. Role name is enclosed into :.

For example, the following uses :ref: role and code-block:: directive:


Directive anatomy

You need to grasp some terminology of reStructuredText directive anatomy - name, argument, options, and content:

  • every directive begins on the new line with ..

  • follows the directive name

  • after the name is ::

  • if directive accepts the argument, they are after ::

  • if directive accepts the option(s), they are within : and each on a new line

  • some of them takes the option value that follows the option name, e.g. ::emphasize-lines: 2

  • if directive accepts the content, it is after a blank line

Everything above illustrated:


For example, the directive image:: accepts a path to the file as the required argument, recognize few optional options like :width: and :class:, and doesn’t except any content:

.. image:: img/overview/sample-image.svg
   :class: no-scaled-link
   :width: 50%

Role anatomy

Similarly, a role syntax has few terminology that is useful to know - role name and text:

  • the role name is between :

  • anything within ` is the role text

The above illustrated:


For example, the above used role :ref: is used to make a reference (link) to another place in the docs. This role text is code-block <code-block-directive>. The text interpretation is up to the role. :ref: role creates a link code-block that will point to place labeled code-block-directive.

For details see :ref:`code-block <code-block-directive>`.


Why are directives and roles so important? They are an extension mechanism to bring the new feature without introducing a new syntax.

Many times used :ref: role is actually added to the reStructuredText by Sphinx.

Another example - pure reStructuredText contains bullet lists that you saw above. But the Sphinx adds hlist:: directive that creates horizontally distributed list:

.. hlist::
   :columns: 3

   * A list of
   * short items
   * that should be
   * displayed
   * horizontally

Many third-party extensions to the Sphinx adds new roles and directives. You can develop your own directives and roles. This extensibility is definitively reStructuredText’s selling point - you are never limited in what the documentation will contain or appear. For example, you can develop an extension that lookup values or print tables from CSV files.



comments powered by Disqus