Sphinx¶
Sphinx is a documentation tool that is commonly used for writing code documentation (especially for python projects). It uses restructured text as the format for writing the documentation and compiles it into HTML, LaTeX/PDF, … It can also highlight code syntax.
Tip
These course notes are all written using Sphinx
Despite its python origins, sphinx can be used with Doxygen via Breathe to allow for nice looking sphinx documentation to provide the C++ documentation Doxygen generates.
Setting It Up¶
We can install Sphinx locally via:
pip3 install sphinx sphinx_rtd_theme breathe --user
Tip
On the MathLab machines, python 2 is the default, which is why we are
using pip3
here, to ensure that we get python 3.
Tip
For some reason, the MathLab machines don’t include
~/.local/bin
in your Unix path, so we need to manually add it via:
export PATH=~/.local/bin:$PATH
Now we want to change our code documentation from our handwritten
index.html
to a site generated by Sphinx. We’ll take over the
docs/
directory:
cd docs/
rm index.html
Then, in the docs/
directory:
sphinx-quickstart
Answer the following:
Separate source and build directories (y/n) [n]:
: answery
Project name:
: answer “C++ Array”Author names(s):
: answer “PHY 504”Project release []:
: just hit enterProject language [en]:
: just hit enter
You should now have the following files:
build/
make.bat
Makefile
source/
you can delete make.bat
.
To test things out, do:
make html
Then you can view the default page via:
google-chrome build/html/index.html
Customizing our page¶
There are two important files in source/
conf.py
: this controls the configuration of Sphinxindex.rst
: this is the ReST file that will becomeindex.rst
.
Configuration¶
Let’s start by changing the configuration a bit:
in the
extensions
section, change it to read:extensions = ["breathe"]
change
html_theme
to be:html_theme = "sphinx_rtd_theme"
Index¶
Let’s have the index.rst
page link to a page showing how the library works.
Create a file using.rst
with the following content:
***********
Using Array
***********
``Array.H`` provides a simple 2-d contiguous array. We can use it as:
.. code:: c++
#include <iostream>
#include "array.H"
int main() {
// create a 10x10 array
Array x(10, 10);
for (std::size_t row=0; row < x.nrows(); ++row) {
for (std::size_t col=0; col < x.ncols(); ++col) {
x(row, col) = static_cast<double> (10*row + 100*col + 13);
}
}
std::cout << x << std::endl;
std::cout << "x.min() = " << x.min() << std::endl;
// create a 4x3 array but fill it by looping over a flattened
// view
Array y(4, 3);
double c{0};
for (auto &e : y.flat()) {
e = c;
c += 1;
}
std::cout << y << std::endl;
Then add to index.rst
just after the contents using
, so it reads like:
.. toctree::
:maxdepth: 2
:caption: Contents:
using
Let’s add what we’ve do so far to our git:
git add Makefile source/conf.py source/index.rst source/using.rst
git commit
We now need to change our GitHub action to build this new site and
copy it over to the gh-pages
branch.
In the .github/workflows/gh-pages.yml
file, change the sections:
- name: Build Doxygen
run: |
mkdir docs
doxygen Doxyfile
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
keep_files: true
to
- name: Build Sphinx
run: |
cd docs
make html
cd ..
mkdir -p out
mv docs/build/html/* out/
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./out
keep_files: true
This does 3 things:
It switches to building the sphinx pages via
make html
It creates a top-level directory called
out/
and puts all of the web site thereIt instructs the “Deploy” process to copy
out
togh-pages
now
Tip
Commit and push these changes and in a minute or two, the project webpage should be regenerated to reflect the Sphinx layout.
Using Doxygen with Sphinx¶
Now we’ll try to combine Doxygen and Sphinx.
Tip
The Sphinx breathe extension allows us to incorporate Doxygen documentation into Sphinx sites.
Move
Doxyfile
intodocs/
and change the following:change
OUTPUT_DIRECTORY
todoxy_files
change
INPUT
to../
Turn off HTML and turn on XML – Breathe works off of the XML output.
Update our
conf.py
to include Breathe and also run Doxygen for us. Here’s the updatedconf.py
:# Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) import subprocess # run doyxgen subprocess.call("cd ..; doxygen", shell=True) # -- Project information ----------------------------------------------------- project = 'C++ Array' copyright = '2022, PHY 504' author = 'PHY 504' # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ["sphinx.ext.autodoc", "breathe"] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = [] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'sphinx_rtd_theme' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] breathe_projects = { "cxx_array": "../doxy_files/xml/" } breathe_default_project = "cxx_array"
Create a
doxygen_files.rst
insource/
with the following:Doxygen Files ============= .. doxygenindex:: :project: cxx_array
Update
index.rst
by adding the following:.. toctree:: :maxdepth: 1 :caption: API doxygen_files
We don’t need to do any changes to our GitHub workflow. We should be able to just add these new files / changes, commit, and push, and the website will be updated.