Writing Documentation#
The documentation for Pyrokinetics is written in reStructuredText (RST) using the Sphinx documentation generator. One of the really useful things about RST is that it is extensible by design. Sphinx adds more roles and directives that are useful for writing technical documentation. This page will summarise the more important ones for Pyrokinetics.
Getting And Running Sphinx#
Pyrokinetics uses a couple of Sphinx plugins, as well as the Sphinx Book Theme. You can easily install all of these with one command:
$ pip install --editable .[docs]
Here we’re using --editable
to make sure our local changes are reflected in
the installed package. You might prefer to use a virtual environment for this.
Running Sphinx is as simple as:
$ cd docs
$ make html
This is exactly equivalent to running the following from the top-level directory:
Important
There are currently seven expected warnings when building the docs, all of the form:
WARNING: Cannot resolve forward reference in type annotations of “pyrokinetics.units.PyroUnitRegistry.Unit”: name ‘Unit’ is not defined
and one more also related to pint.facets.plain.unit
. These are
all due to the version of pint
we’re using. If you get more
warnings than this, you should fix them!
$ sphinx-build -b html docs/ docs/_build/html
You can then view the built documentation by opening
docs/_build/html/index.html
in your browser.
reStructuredText Gotchas#
The reStructuredText Primer covers the basics of using the RST markup. Here we’ll cover some of the common “gotchas” and more specific syntax.
Backticks#
The most common gotcha is the use of backtick. In Markdown, single backticks
are used for inline monospace
. To achieve the same in RST, we have to use
double backticks ``monospace``
: monospace
.
Instead, single backticks in RST are used for roles:
:ref:`sec-writing-docs`
links to the top of this section, for instance:
Writing Documentation. The default role if you don’t include the initial
:role:
part is the any role. This makes it easy to link to a section
(`sec-getting-started`
: Getting Started), a module (`constants`
:
constants
), a class (`Pyro`
: Pyro
), and so on.
Linking to Sections#
When writing documentation pages, you may want to link to other sections
including those in other files. The main thing here is that you will need to
manually put in a label above the section name. See the Sphinx docs on
Cross-referencing arbitrary locations. Note that the developers recommend
explicitly using the :ref:
role so that typos and mistakes can be more
easily caught.
By convention, we prefix these labels with sec-
to make clear we’re linking
to a section.
Linking to the right Python object#
A lot of the time, you can link to a particular Python object like a class or
module by just putting its name in backticks. For example, `Pyro`
is
(usually!) sufficient to make a link to Pyro
. But sometimes you might need to
specify the kind of object in the role: for example: :class:`Pyro`
. You
can see the whole list of Python roles in the Sphinx docs.
Sometimes you need to be more specific and give the full “dotted” name:
:meth:`pyrokinetics.species.Species.grad_rho`
:
pyrokinetics.species.Species.grad_rho()
. Although you’ll notice this has
the side effect of making the link the full dotted name too. You can start the
name with a tilde ~
to just use the last bit of the name:
:meth:`~pyrokinetics.species.Species.grad_rho`
:
grad_rho()
.
Sometimes you can get away with just using the final component of the full
dotted name: :class:`.Equilibrium`
; Equilibrium
. You can see this
just uses the last bit of the name as the link.
Getting these links right can sometimes be a bit of trial and error, which is annoying! It’s worth checking the generated docs and that all the links work as you expect.
LaTeX and maths#
To use LaTeX and equations in RST files and Python docstrings, use either the
math role for inline maths (:math:`\pi`
: \(\pi\)), or the math
directive for using the whole line:
.. math::
(a + b)^2 = a^2 + 2ab + b^2
Code blocks#
The default syntax highlighting for literal/code blocks is Python. You can
specify a different language, for example console
or text
:
.. code:: console
$ echo "hello world"
$ echo "hello world"
Docstrings#
We make use of Python’s built-in docstring facility for documenting code in-source. However, in Pyrokinetics we use the numpydoc style for docstrings. This is probably familiar to you from Numpy’s docstrings.
At a minimum, it’s useful to have a one line short summary, followed by the
Parameters
(or equivalently, Arguments
) section:
def some_function(x: int, y: float) -> List[float]:
"""Calculate something really impressive
Parameters
----------
x : type
Description of parameter `x`.
y
Description of parameter `y` (with type not specified).
"""
...
Note that if you use type hints in the function signature, then you can usually skip the type in the docstring, unless you add more information like expected units.
Caution
The Returns
section syntax is a little different to
the Parameters section! The name of the parameter is optional and the type
is required. If you use a type hint for the return value, you can skip this
section altogether.
Getting Fancier#
The Kitchen Sink example in the Sphinx Book Theme docs shows off lots of the features of this theme. You might find it useful to have a look through to see how different features can be used, including admonitions (like the note above), images, tables, and citations.