execlib/docs/reference/documentation/sphinx.md

4.9 KiB

Sphinx

The primary driver of this package's documentation is Sphinx's autodoc extension, using the Furo theme.

High-level details:

  • sphinx-apidoc generates package-based documentation to the _autoref/ directory, with navigation available under "Autoref" in the sidebar.
  • Markdown-based documentation files are manually written under the reference/ directory, showing up under "Contents" in the sidebar.

Detailed directory structure

All files are placed under docs/sphinx:

  • _-prefixed are Sphinx-managed directories
    • _build/html/ houses output HTML files
    • _autoref/ is the target for module-based RST files written by autodoc
  • reference/: houses all manually written documentation (totally separate from auto-generated package docs)
  • conf.py: single Sphinx configuration file
  • index.md: documentation index, setups up a persistent sidebar across all other pages

For manually written documentation under reference/, topics are nested as needed. Within a nested directory reference/<topic>, an index.md should created with content like:

# <Topic>

\`\`\`{toctree}
:hidden:

sub-topic-1.rst
sub-topic-2.rst
...
\`\`\`

This will add the nested directory to the sidebar navigation, using the name set under the top-level header. See [Markdown syntax][#markdown-syntax] for more details on the syntax.

Sphinx autodoc

Sphinx's autodoc extension allows automatic generation of documents according to (Python) subpackage structure and available docstrings. A few notes here:

  • In the conf.py file, autodoc is enabled by adding "sphinx.ext.autodoc" to the extensions list. "sphinx.ext.viewcode" can also be added to provide links to source code.

  • Documents are actually generated by calling the sphinx-apidoc CLI command. The current Makefile uses the following call:

    sphinx-apidoc --module-first -o docs/sphinx/_autoref/ localsys
    

    This writes the automatically generated docs for modules in the package at the local directory localsys/ to the docs/sphinx/_autoref directory. These are reStructuredText files by default.

    • --module-first places the module-level descriptions at the top of the module page. By default, this is placed at the bottom (oddly), and can be obscured by large lists of subpackages if this flag isn't provided.
    • See available sphinx-apidoc options here, as well as more advanced config here.

Markdown syntax

The myst_parser extension enables Markdown (or something close to it) to be used when writing documentation files. The Sphinx directives can be difficult to track, and they change slightly under the MyST Markdown syntax. The following are a few common blocks:

Page hierarchies: the following will generate link hierarchy according to the provided pages:

\`\`\`{toctree}
:maxdepth: <n>
:caption: <caption>
:hidden:

example-file-1
example-file-2
example-dir/index
...
\`\`\`
  • :maxdepth: limits the depth of nesting
  • :caption: title for the group of pages
  • :hidden: if provided, links will only show in the sidebar (hidden on the page)
  • Constituent files: listed files will be rendered as a link directly. If a listed file has a {toctree} directive, this tree will be rendered in place of the page's link as a dropdown. The dropdown will be named according to the file's top-level heading, and clicking directly on the dropdown header will show that page's content. Files found in the tree will be placed as links under the dropdown, recursively subject to same rules described here.

Include files: the following will include file content pages:

\`\`\`{include} README.md
\`\`\`

Reference directives

Notes on docstring syntax

  • Code literals need to be surrounded in two backticks, e.g., "variable". Sphinx will also complain if you make the reference plural by having an "s" after the backtick; it needs to go on the inside.
  • MyST parsing, even if enabled, doesn't apply to docstrings. You need to use RST generally, with a few directives being different under extensions like napoleon.
  • Code blocks and admonitions need a space between the heading and the rest of the content.

Nice syntax cheatsheet here

General docstring structure should be structured as follows:

def example_function(a, b):
    '''
    Minimal function description. (either first sentence or line; gets used in
    autosummaries)

    Additional exposition, unwrapped by admonitions.

    .. admonition:: Admonition description
        Indented content, code blocks, lists, etc

    Parameters:
        a: a's description
        b: b's description

    Returns:
        <return-type>: Description of return value
    '''
    ...