Documentation Wiki¶
This page regroups information about the creation of this documentation.
Important
Please read this carefully if you want to participate in the documentation process.
Getting started¶
We all think we know what software documentation should look like… well guess what, most of us are wrong!
So read this and finally understand what software documentation is!
For a list of awesome Sphinx extension look here: https://github.com/yoloseem/awesome-sphinxdoc
Sphinx¶
Many tools allow generation and publication of technical documentation, but I chose to use sphinx as it is the only one (to my knowledge) oriented towards Python and offering solutions to automatically generate documentation from the docstrings.
Setup¶
To install the Sphinx package:
Usage¶
Initial documentation setup¶
In a terminal, at the root of the package (e.g. timagetk/
), initialize your sphinx documentation with:
sphinx-quickstart
This will create a docs
folder at the root of the package.
Build documentation¶
To generate the documentation HTML files, got to the documentation root folder, e.g. timegetk/docs/
and call make html
:
cd timagetk/docs
make html
You should now have a build
directory under timegetk/docs/
where you will find a index.html
file.
MyST parser¶
As reStructuredText can be super tedious, we use the MyST parser to write the documentation in Markdown instead.
Setup¶
To install the MyST parser package:
In the docs/source/conf.py
configuration file, add myst_parser
to the extensions
list:
extensions = [
...
'myst_parser', # Markdown parser
...
]
The chosen configuration is also specified in the docs/source/conf.py
after activating the extension:
# Optional MyST syntax:
myst_enable_extensions = [
"amsmath",
"dollarmath",
"colon_fence",
"deflist"
]
# Activate auto-generated header anchors (for Hearders H1-3)
myst_heading_anchors = 3
Look here for a description of optional MyST syntaxes.
To be able to use a file named index.md
instead of the default index.rst
, you have to set these variables in the conf.py:
source_suffix = '.md'
master_doc = 'index'
Usage¶
You may now write files in Markdown to generate your documentation. Do not forget to read the official MyST syntax guide here.
MyST notebooks¶
We use jupyter notebooks for tutorials and how-to.
Setup¶
To install the MyST{NB} package:
In the docs/source/conf.py
configuration file, add myst_nb
to the extensions
list:
extensions = [
...
# 'myst_parser', # MyST markdown parser, activated by 'myst_nb'
'myst_nb', # MyST jupyter notebooks parser
...
]
Warning
If you are using MyST-NB in your documentation, do not activate myst_parser
in the extensions
list.
It will be automatically activated by myst_nb
.
Usage¶
Configuration¶
In the docs/source/conf.py
configuration file, we force the execution of notebooks with:
jupyter_execute_notebooks = "force"
Cleanup prior to documentation generation¶
Edit the Makefile
to force documentation notebooks to have their output cells cleaned up prior to generating the documentation with sphinx.
Add these lines to top of the the html
section of the Makefile
:
@echo "Cleaning documentation notebooks cell outputs..."
find source -type f \( -name "*.ipynb" -not -wholename "*/.ipynb_checkpoints/*" \) -print -exec jupyter nbconvert --ClearOutputPreprocessor.enabled=True --inplace {} \;
This will search for all .ipynb
files in the source
documentation folder, excluding those in hidden .ipynb_checkpoints
folders and clean them up.
Report notebook execution statistics¶
Create a notebooks_summary.md
MarkDown file with the following content:
# Notebooks execution statistics
```{nb-exec-table}
```
This will generate a table summarizing the execution of the notebooks by MyST-NB. We do not reference it in the table of content has it is meant to be used by developers to check the correct execution of the notebooks.
Automatic API generation¶
To automatically generate the reference API we use the sphinx module autodoc
.
As we write our docstring in Numpy format (reference style guide here) we also use the napoleon
extension.
Setup¶
In the docs/source/conf.py
configuration file, add sphinx.ext.autodoc
& sphinx.ext.napoleon
to the extensions
list:
extensions = [
...
'sphinx.ext.autodoc', # Include documentation from docstrings
'sphinx.ext.napoleon', # Support for NumPy and Google style docstrings
...
]
The chosen configuration for the napoleon
extension is also specified in the docs/source/conf.py
after activating the extension:
napoleon_google_docstring = False
napoleon_numpy_docstring = True
napoleon_include_init_with_doc = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = False
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_keyword = True
napoleon_use_param = True
napoleon_use_rtype = False
Usage¶
The official documentation of MyST has a specific section in their “how-to” detailing this, look here
Now you can use the autodoc module to generate the reference API documentation using the .. automodule::
directive.
For example, to generate the reference API of the blockmatching
algorithm:
Note
The :noindex:
option here is to avoid duplicate object description of timagetk.algorithms.blockmatching.blockmatching
as it is already called in the API documentation.
Automatic CLI documentation¶
To automatically add the documentation of CLI scripts built with the argparse
Python module we use the sphinx-argparse
extension.
Setup¶
Install the sphinx-argparse
extension:
In the docs/source/conf.py
configuration file, add sphinxarg.ext
to the extensions
list:
extensions = [
...
'sphinxarg.ext' # To include tables describing command-line arguments for executable scripts
...
]
Usage¶
To automatically document a script built with argparse
:
Note
The :noindex:
option here is to avoid duplicate object description of timagetk.algorithms.blockmatching.blockmatching
as it is already called in the API documentation.
Simple inheritance diagram¶
In Sphinx, you can use the .. inheritance-diagram::
directive to generate simple inheritance diagrams.
Setup¶
In the docs/source/conf.py
configuration file, add sphinx.ext.inheritance_diagram
to the extensions
list:
extensions = [
...
'sphinx.ext.inheritance_diagram', # Add inheritance diagram directive
...
]
Usage¶
To generate the inheritance diagram of the SpatialImage
Class:
Don’t forget to add this inside the {eval-rst}
block with MyST!
UML diagrams¶
We use pyreverse
, a part of Pylint, to generate a full UML class diagram of our data structures.
Setup¶
Install pylint
package:
Warning
This also require installing Graphviz
system-wide as the python package only contains the bindings!
sudo apt install graphviz
Usage¶
Added these lines to the top of the html
section of the Makefile
to automatically re-generates the PNGs when using make html
:
@echo "Generating components UML diagram for classes & modules..."
pyreverse ../src/timagetk/components/ -o png -d source/_static/image/
This export a files packages.png
& classes.png
to timagetk/docs/source/_static/image/
.
Tabbed content¶
We use the sphinx-panels
extension to produce tabbed content.
Link to sphinx-panels documentation.
Setup¶
Install the sphinx-panels
extension:
In the docs/source/conf.py
configuration file, add sphinx_panels
to the extensions
list:
extensions = [
...
'sphinx_panels', # Enable panels, cards & tabs usage
...
]
Usage¶
The tabbed content in the Setup section where you can choose between conda & pip is made using:
````{tabbed} conda
```shell
conda install -c conda-forge sphinx-panels
```
````
````{tabbed} pip
```shell
python -m pip install sphinx-panels
```
````
Warning
Adding this extension changed the website layout by fixing a max width on the notebook cells. This was fixed by adding panels_add_bootstrap_css = False
to the docs/source/conf.py
configuration file.
Layout and styling¶
We modified the builtin theme Alabaster to improve it and chose to set:
Modified docs/source/conf.py
configuration file:
html_theme = 'alabaster'
html_theme_options = {
'body_min_width': '700px',
'body_max_width': '1400px',
'font_size': '17px',
'code_font_size': '16px',
'font_family': 'Lato,proxima-nova,Helvetica Neue,Arial,sans-serif',
'page_width': '65%',
'logo': 'image/logo_timagetk.png',
'fixed_sidebar': True,
'show_powered_by': True,
'show_relbar_bottom': True,
'pre_bg': '#272822'
}
pygments_style = 'monokai'
html_static_path = ['_static/']
html_css_files = ['css/custom.css']
panels_add_bootstrap_css = False
Added custom CSS style-sheet _static/css/custom.css
:
dl {
margin: 0 0 1.5em 0;
padding: 0;
}
pre {
padding: 7px 10px;
}
div.container.cell {
font-size: 16px;
}