Omniverse reStructured Text Guide

Omniverse uses reStructred Text for its technical documentation. If you’re new to reStructuredText, think of reStructuredText as a human readable documentation markup that is expressive enough to allow for tooling capable of highly customized transformation/rendering to other formats (such as HTML).

Before diving into reStructuredText, be sure to review Omniverse’s Documentation Guide. Instructions for building documentation can be found in our Quick Start Guide.

reStructured Text Pros

RST Files Are Human Readable/Reviewable

While not quite as readable as Markdown, RST is a great deal more readable than LaTeX or HTML.

A Single Syntax

If you’re a Markdown user, gone are the days of different “flavors” of markup.

Features Tailored To Programmers

Easy syntax highlighting. Ability to include/inline source code in your docs. Ability to reference Doxygen API docs. Substitution. Comments.

LaTeX Math Syntax

Pretty math typesetting like the expensive textbooks back in school.

In addition, to the pros above, the Omniverse documentation system uses Sphinx to convert the reStructuredText to a publishable format like HTML. Sphinx not allow not only for easy customization via configuration settings, it also allows users to run arbitrary code during the documentation parsing and rendering process. As a bonus, Sphinx is able to ingest other documentation formats, such as Markdown, Mermaid, or draw.io; allowing you the freedom to author docs in the format of your choice.

reStructured Text Cons

It’s Not Markdown

There’s a reason Markdown has been so successful, it’s really easy to author, read, and render. If you’re a Markdown fan, you’ll find reStructuredText’s syntax to much like “coding”. However, even though reStructuredText’s syntax is more complex, that complexity gives you a great deal more control in formatting and referencing other documents (such as source code).

It’s Not Ubiquitous

A slew of tools are able to render raw Markdown, HTML, and sometimes LaTeX. reStructuredText does not enjoy that level of adoption. For example, while reStructuredText docs generally look good on github.com, gitlab.com’s rendering of reStructuredText is lacking.

It’s Not Doxygen

Doxygen is often used in C++ circles to document APIs. It does a great job of providing documentation/cross-linking for the minutiae of an API. reStructuredText attempts to do this, but isn’t as good. Where reStructuredText shines is creating high-level documentation. The fact that you can reference Doxygen documentation in reStructuredText is a plus.

reStructured Text Cheat Sheet

reStructuredText has a rich syntax tailored towards programmers/technical authors. If you find yourself fighting reStructuredText, a quick search may lead to a specialized command to solve your problem. Said differently, someone else has likely tried, and documented, what you’re trying to do.

reStructuredText basics can be found at Sphinx’s reStructuredText Primer.

You can find a list of directives at Sphinx’s Directives.

Following are a set of reStructuredText recipes you may find useful when writing Omniverse documentation.

Text

Italic

reStructuredText:
*Italic*
Output:

Italic

Bold

reStructuredText:
**Bold**
Output:

Bold

Inline Code

reStructuredText:
``main()``
Output:

main()

Filenames

reStructuredText:
*foo.txt*
Output:

foo.txt

In the Omniverse SDK docs, filenames are always italicized.

Directory Names

reStructuredText:
*source/examples/*
Output:

source/examples/

In the Omniverse SDK docs, directory names are always italicized and end in a /.

Images

Embedded Images

reStructuredText:
.. image:: omni-marbles.jpg
    :width: 200
    :alt: Alternative Text

Output:

Alternative Text

Lists

Unordered List (Bullet List)

reStructuredText:
* Idea 1
* Idea 2
  spanning multiple lines.

  * Nested idea.  The blank line above is needed to start a nested list.
    This idea spans multiple lines.

    We can even have multiple paragraphs in the list item.
Output:
  • Idea 1

  • Idea 2 spanning multiple lines.

    • Nested idea. The blank line above is needed to start a nested list. This idea spans multiple lines.

      We can even have multiple paragraphs in the list item.

A newline is required when starting a sub-list. A newline is acceptable between items within the same level of a list.

Ordered List (Numbered List)

Nested lists are possible, but be aware that they must be separated from the parent list items by blank lines.

reStructuredText:
#. Idea 1

   #. Idea 1.A

      #. Idea 1.A.1

#. Idea 2
   spanning multiple line.

   An addition paragraph in the list item.
Output:
  1. Idea 1

    1. Idea 1.A

      1. Idea 1.A.1

  2. Idea 2 spanning multiple line.

    An addition paragraph in the list item.

A newline is required when starting a sub-list. A newline is acceptable between items within the same level of a list.

Definition List

reStructuredText:
Cat
    A creature.

Fish
    An aquatic creature.

    They tend to be wet.
Output:
Cat

A creature.

Fish

An aquatic creature.

They tend to be wet.

API Documentation

Linking to API Documentation

Linking to API documentation has a fairly verbose syntax:

Link to a function: carb::startupFramework().

If your function is overloaded, you’ll have to fully specify its arguments.

You can customize the text displayed in the link: How to Startup Carbonite.

You must specify the “type” of the entity referenced. Here are some examples:

  • Struct: carb::Framework.

  • Member: carb::PlugingLoadingDesc::loadedFileWildcards.

  • Member: carb::PlugingLoadingDesc::loadedFileWildcards.

  • Function/Member-function: carb::PlugingLoadingDesc::getDefault().

  • Macro: OMNI_CORE_INIT. Note, the c instead of cpp for macros.

  • Enum carb::tasking::Priority

  • Enum value: carb::tasking::Priority::eMain

  • Type: carb::tasking::TaskContext

More types can be found at Sphinx Domains.

Templates must include all template arguments and include customized text in the link: carb::Framework::acquireInterface. Note that the template’s < was escaped with \.

Above, the input reStructredText was:

Linking to API documentation has a fairly verbose syntax:

Link to a function: :cpp:func:`carb::startupFramework`.

If your function is overloaded, you'll have to fully specify its arguments.

You can customize the text displayed in the link: :cpp:func:`How to Startup Carbonite <carb::startupFramework>`.

You must specify the "type" of the entity referenced.  Here are some examples:

* Struct: :cpp:struct:`carb::Framework`.

* Member: :cpp:struct:`carb::PlugingLoadingDesc::loadedFileWildcards`.

* Member: :cpp:member:`carb::PlugingLoadingDesc::loadedFileWildcards`.

* Function/Member-function: :cpp:func:`carb::PlugingLoadingDesc::getDefault()`.

* Macro: :c:macro:`OMNI_CORE_INIT`.  Note, the ``c`` instead of ``cpp`` for macros.

* Enum :cpp:enum:`carb::tasking::Priority`

* Enum value: :cpp:enumerator:`carb::tasking::Priority::eMain`

* Type: :cpp:type:`carb::tasking::TaskContext`

More types can be found at `Sphinx Domains <https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html>`_.

Templates must include all template arguments and include customized text in the link:
:cpp:func:`carb::Framework::acquireInterface <template\<typename T\> T* carb::Framework::acquireInterface(const char*)>`.
Note that the ``template``'s ``<`` was escaped with ``\``.

In order to cut down on typing, adding a substitution at the top of your file is recommended:

.. |carb::Framework::acquireInterface| replace:: :cpp:func:`carb::Framework::acquireInterface <template\<typename T\> T* carb::Framework::acquireInterface(const char*)>`

You can then reference the substitution throughout your doc as follows.

reStructuredText:
You should call |carb::framework::acquireInterface|.
Output:

You should call carb::Framework::acquireInterface.

Source Code

Source Code

reStructuredText:
.. code:: c++

    class recursive_shared_mutex : private carb::thread::shared_mutex
    {
    public:
    #if !CARB_DEBUG
        constexpr
    #endif
        recursive_shared_mutex() = default;
        ~recursive_shared_mutex() = default;

        // Exclusive locking
        void lock();
        bool try_lock();
        void unlock();
Output:
class recursive_shared_mutex : private carb::thread::shared_mutex
{
public:
#if !CARB_DEBUG
    constexpr
#endif
    recursive_shared_mutex() = default;
    ~recursive_shared_mutex() = default;

    // Exclusive locking
    void lock();
    bool try_lock();
    void unlock();

Languages other than C++ are supported, such as python, toml, and json.

Including Source Code

One of RST’s most powerful features is the ability to include, inline, other documents. Omniverse SDKs use this feature to provide code samples in documentation that are unit tested.

reStructuredText:
.. literalinclude:: ../source/HelloWorld.cpp
    :language: c++
    :dedent:
    :start-after: example-begin badCode
    :end-before: example-end badCode
Output:
void badCode()
{
    int* zeroPage = nullptr;
    *zeroPage = 42;
}

Substitution

Substitution of RST Commands

For example, to create an easy substitution of the shrug emoji:

reStructuredText:
.. |shrug| unicode:: U+1F937

I don't know what I'm doing. |shrug|
Output:

I don’t know what I’m doing. 🤷

Tables

List Table

Full docs can be found at List Tables.

reStructuredText:
.. list-table:: Optional Title (It Produces a Link)
    :header-rows: 1

    * - Heading row 1, column 1
      - Heading row 1, column 2
      - Heading row 1, column 3
    * - ``header-rows`` is needed to style the first row as a header.
      -
      - Row 1, column 3
    * - ``:widths:`` (which is optional) can be used to specify a ratio of column widths.
      - Row 2, column 2

      - Row 2, column 3.  This cell is really long and shows that text can be wrapped, it can even have
        additional paragraphs and other markup.

        I'm a paragraph in the last cell.
Output:
Optional Title (It Produces a Link)

Heading row 1, column 1

Heading row 1, column 2

Heading row 1, column 3

header-rows is needed to style the first row as a header.

Row 1, column 3

:widths: (which is optional) can be used to specify a ratio of column widths.

Row 2, column 2

Row 2, column 3. This cell is really long and shows that text can be wrapped, it can even have additional paragraphs and other markup.

I’m a paragraph in the last cell.

Grid Table

Full docs can be found at Grid Tables.

reStructuredText:
+-------------------------------------------+-------------------------------------------------------------------------+-------------+
|             Camera Properties             |                                  Usage                                  |    Units    |
+===========================================+=========================================================================+=============+
| Clipping Range                            | Clips the view outside of both near and far range values.               | World Units |
+-------------------------------------------+-------------------------------------------------------------------------+-------------+
| Focal Length                              | Longer Lens Lengths Narrower FOV, Shorter Lens Lengths Wider FOV        | Millimeters |
+-------------------------------------------+-------------------------------------------------------------------------+-------------+
| Focus Distance                            | The distance at which perfect sharpness is achieved.                    | World Units |
+-------------------------------------------+-------------------------------------------------------------------------+-------------+
| fStop                                     | Controls Distance Blurring.  Lower Numbers decrease focus range, larger | N/A         |
|                                           | numbers increase it.                                                    |             |
+-------------------------------------------+-------------------------------------------------------------------------+-------------+

Output:

Camera Properties

Usage

Units

Clipping Range

Clips the view outside of both near and far range values.

World Units

Focal Length

Longer Lens Lengths Narrower FOV, Shorter Lens Lengths Wider FOV

Millimeters

Focus Distance

The distance at which perfect sharpness is achieved.

World Units

fStop

Controls Distance Blurring. Lower Numbers decrease focus range, larger numbers increase it.

N/A

Misc

Admonitions (Message Boxes)

reStructuredText:
.. note::
    This is a note.
Output:

Note

This is a note.

Other admonitions are supported: “attention”, “caution”, “danger”, “error”, “hint”, “important”, “note”, “tip”, “warning”.

Attention

This is a attention.

Caution

This is a caution.

Danger

This is a danger.

Error

This is a error.

Hint

This is a hint.

Important

This is a important.

Tip

This is a tip.

Warning

This is a warning.

LaTeX-like Math

reStructuredText:
:math:`\int_0^\infty \frac{x^3}{e^x-1}\,dx = \frac{\pi^4}{15}`
Output:

\(\int_0^\infty \frac{x^3}{e^x-1}\,dx = \frac{\pi^4}{15}\)

Mermaid Graphs

Mermaid enables the creation of diagrams using a simple markup language.

reStructuredText:
.. mermaid::

    graph LR
        log{ILog} --> std[StandardLogger]
        log --> l0[ILogMessageConsumer]
        log --> l1[ILogMessageConsumer]
        c0(audio.mp3.encode) -.-> log
        c1(audio.mp3.decode) -.-> log
        c2(audio.spatial) -.-> log
        c3(omni.core) -.-> log

        classDef bold font-weight:bold,stroke-width:4px;
        class log bold
Output:
graph LR log{ILog} --> std[StandardLogger] log --> l0[ILogMessageConsumer] log --> l1[ILogMessageConsumer] c0(audio.mp3.encode) -.-> log c1(audio.mp3.decode) -.-> log c2(audio.spatial) -.-> log c3(omni.core) -.-> log classDef bold font-weight:bold,stroke-width:4px; class log bold

YouTube

reStructuredText:
.. youtube:: NgcYLIvlp_k
Output:

Emoji

reStructuredText:
|:fire:| |:book:| |:fire:|
Output:

🔥 📖 🔥

Supported emoji’s can be found at Sphinx Emoji Codes.