How to write documentation
In this document you will learn how to write good, informative, pretty and actionable documentation.
It’s not hard!
Tip
New to documentation? Start with the Quick Start for Documentation Contributors below, then dive into the details.
Quick Start for Documentation Contributors
Want to contribute but not sure where to start? Here are the most common documentation tasks:
Fix a typo or improve existing text: Just edit the
.rstfile and submit a PRAdd a new tutorial: Create a new
.rstfile indocs/source/tutorials/Improve code documentation: Edit the docstrings in the Python files
Test your changes locally: See Building Documentation Locally below
Building Documentation Locally
To write documentation or test your changes, you’ll want to build the documentation locally on your computer and open the generated HTML files in your browser.
Install documentation dependencies:
pip install -r docs/requirements-docs.txt
Build the documentation:
cd docs/
make html
View the documentation:
Open the generated docs/_build/html/index.html file in your browser:
# On most systems:
open docs/_build/html/index.html
# Or use a simple HTTP server:
cd docs/_build/html
python -m http.server 8000
# Then visit http://localhost:8000
Note
The repository is currently setup to automatically build the documentation on every push to specific branches, including the main branch. Ask the maintainers if you want your branch to be automatically built too.
Overview
There are two major types of documentation:
docstrings: your code’s docstrings will be automatically parsed by the documentation sofware (Sphinx, more in About Sphinx).
Manual documentation such as this document. This can be for instance a detailed installation procedure, a tutorial, a FAQ, a contributor’s guide etc. you name it!
Both are written in ReStructured Text (.rst) format.
In this tutorial, we’ll go over the basics of .rst and Sphinx, and then we’ll look at some of the cool features that are available. To learn about docstrings specifically (what the conventions are, how to write good docstrings etc.), check out the next section.
Some of the great features of using Sphinx is to be able to automatically generate documentation from your code’s docstrings, and to be able to link to other parts of the documentation.
For instance: trajectorybalance_loss() or to an external function torch.cuda.synchronize().
Learn by example
The next section will introduce many of the cool features of .rst + Sphinx + plugins.
Click on “Code for the example” to look at the .rst code that generated what you are reading.
Include code to illustrate how to use the package / module / class / method / function etc.
Remember, this works in docstrings and in stand-alone .rst files.
import gflownet
# Create a new instance of the class
my_class = gflownet.MyClass()
# Call a method of the class
my_class.do_something()
# Get an attribute of the class
my_class.attribute
Note
This is a note. You can use it to add notes to your documentation.
Warning
This is a warning. You can use it to add warnings to your documentation.
Cool features:
Reference code docs of:
A class:
gflownet.envs.grid.Grid(long format)Another class
GFlowNetAgent(short format, by prepending~)A method
trajectorybalance_loss()Or even an external function
torch.cuda.synchronize()
An actual tutorial on .rst:
ReStructured Text for those who know Markdown
Important
Check out this documentation for more on the specific so-called admonitions like the “note”, “warning”, “important”, etc. coloured boxes in this document: Furo theme documentation
Attention
ReStructured Text is a bit more complicated than Markdown, but it’s worth it.
One common mistake is to forget that spaces and new lines matter in .rst.
For example, the following will not work:
.. note::
This is a note.
But this will
.. note::
This is a note.
Same goes for whitespaces: .. code-block:: ✅ ..code-block:: ❌.
Todo
Improving the documentation: Recommendations for Sphinx plugins.
Want to learn more?
You can also have images!
And icons and badges primary, primary-line
Or emphasize a link:
This is all documented in sphinx-design.
Include code to illustrate how to use the package / module / class / method / function etc.
Remember, this works in docstrings *and* in stand-alone ``.rst`` files.
.. code-block:: python
import gflownet
# Create a new instance of the class
my_class = gflownet.MyClass()
# Call a method of the class
my_class.do_something()
# Get an attribute of the class
my_class.attribute
.. note::
This is a note. You can use it to add notes to your documentation.
.. warning::
This is a warning. You can use it to add warnings to your documentation.
Cool features:
Reference code docs of:
- A class: :class:`gflownet.envs.grid.Grid` (long format)
- Another class :class:`~gflownet.gflownet.GFlowNetAgent` (short format, by prepending ``~``)
- A method :meth:`~gflownet.gflownet.GFlowNetAgent.trajectorybalance_loss`
- Or even an external function :func:`torch.cuda.synchronize()`
.. note
External content should be listed in ``docs/conf.py:intersphinx_mapping``.
More info in the `Read The Docs documentation <https://docs.readthedocs.io/en/stable/guides/intersphinx.html>`_.
An actual tutorial on ``.rst``:
`ReStructured Text for those who know Markdown <https://docs.open-mpi.org/en/v5.0.x/developers/rst-for-markdown-expats.html#hyperlinks-to-urls>`_
.. important::
Check out this documentation for more on the specific so-called *admonitions* like
the "note", "warning", "important", etc. coloured boxes in this document:
`Furo theme documentation <https://pradyunsg.me/furo/reference/admonitions/#supported-types>`_
.. attention::
ReStructured Text is a bit more complicated than Markdown, but it's worth it.
**One common mistake** is to forget that spaces and new lines matter in ``.rst``.
For example, the following will not work:
.. code-block::
.. note::
This is a note.
But this will
.. code-block::
.. note::
This is a note.
Same goes for whitespaces: ``.. code-block::`` ✅ ``..code-block::`` ❌.
.. todo::
Improving the documentation: `Recommendations for Sphinx plugins <https://pradyunsg.me/furo/recommendations/>`_.
.. dropdown:: :octicon:`megaphone` Want to learn more?
You can also have images!
.. image:: https://source.unsplash.com/200x200/daily?cute+animals
:alt: A cute animal
And icons :octicon:`project` and badges :bdg-primary:`primary`, :bdg-primary-line:`primary-line`
Or emphasize a link:
.. article-info::
:avatar: https://raw.githubusercontent.com/tristandeleu/jax-dag-gflownet/master/_assets/dag_gflownet.png
:avatar-link: https://www.youtube.com/watch?v=dQw4w9WgXcQ
:avatar-outline: muted
:author: Some Author
:date: Jul 24, 2021
:read-time: 5 min read
:class-container: sd-p-2 sd-outline-muted sd-rounded-1
This is all documented in `sphinx-design <https://sphinx-design.readthedocs.io/en/furo-theme>`_.
Note
The above tabulation with “Full-fledged .rst example” and Code for the example was generated using the following code:
.. tab-set::
.. tab-item:: Full-fledged ``.rst`` example
.. include:: example.rst
.. tab-item:: Code for the example
.. literalinclude:: example.rst
:language: rst
FAQ
How do I create new manual documentation files.
Create a new
.rstfile in thedocs/folderList it in
docs/index.rstfile under the.. toctree::directive- Or create a subfolder in
docs/with anindex.rstfile. This is useful for grouping documentation files together.
docs/{your_subfolder}/index.rstshould contain a.. toctree::directive listing the files in the subfolder.It should also be listed in the
docs/index.rstunder the.. toctree::directive to appear on the left handside of the documentation.
- Or create a subfolder in
You can look at the docs/contributors/ folder for an example.
How do I document a sub-package like gflownet.proxy.crystals?
Just add a docstring at the top of the __init__.py file of the sub-package:
"""
This is the docstring of the sub-package.
It can contain any kind of ``.rst`` syntax.
And refer to its members: :meth:`~gflownet.proxy.crystals.crystal.Stage`
.. note::
This is a note admonition.
"""
You can similarly document a module by adding a docstring at the top of the file
How do I document a module variable?
Add a docstring below the variable to document like
MY_VARIABLE = 42
"""
This is the docstring of the variable.
Again, It can contain any kind of ``.rst`` syntax.
"""
How do I document a class?
Currently, autoapi is setup to consider the documention of a class to be the same as the documentation for the __init__ method of the class.
This can be modified by changing the autoapi_python_class_content = "init" configuration variable in docs/conf.py. See AutoAPI for more details.
( advanced) How do I modify the main API Reference page?
The main page (that lists sub-modules and packages etc.) is generated by autoapi, using a template file docs/_templates/autoapi/index.rst.
Modify this file to change the main API Reference page.
Important
You will notice {% ... %} blocks. These are Jinja2 blocks, a templating language. You can modify them, but be careful not to break the template.
( advanced) How do I modify the structure of the class / method / package / module etc. pages?
The structure of the pages is defined by the autoapi template files in docs/_templates/autoapi/.
Modify these files to change the structure of the pages.
Important
You will notice {% ... %} blocks. These are Jinja2 blocks, a templating language. You can modify them, but be careful not to break the template.
Where is the documentation for those advanced features? (tabs, dropdowns etc.)
Sphinx-Design contains many components you can re-use
We use the Furo theme, you’ll find the list of available admonitions there
What plugins are used to make the documentation?
Todo enables the
.. todo::admonitionIntersphinx mapping enables linking to external documentation like in the
torch.cuda.synchronize()example aboveAutoAPI enables the automatic generation of documentation from docstrings & package structure
Sphinx Math Dollar enables the
$...$math syntaxSphinx autodoc type ints enables more fine-grained control on how types are displayed in the docs
MyST enables the parsing of enhanced Markdown syntax in the
.rstdocumentation.Hover X Ref Enables tooltips to display contents on the hover of links
Napoleon enables the parsing of Google-style docstrings
About Sphinx
Sphinx is a documentation generator. It works by parsing .rst files and generating HTML files from them.
It is configured by the docs/conf.py file.
To simplify the generation of documentation, we use the AutoAPI plugin, which automatically generates documentation from the package’s structure and the docstrings of the code.
AutoAPI reads the code, and generates .rst files in the docs/_autoapi folder. These files are then parsed by Sphinx to generate the documentation but to keep the documentation clean, we don’t want to commit these files to the repository so autoapi is configured to delete those .rst files after generating the documentation.
By default, the generated documentation will be put in the API Reference section of the overall documentation.