******
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:
.. prompt:: bash
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:
.. prompt:: bash
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:
.. prompt:: bash
cd docs/
rm index.html
Then, in the ``docs/`` directory:
.. prompt:: bash
sphinx-quickstart
Answer the following:
* ``Separate source and build directories (y/n) [n]:`` : answer ``y``
* ``Project name:`` : answer "C++ Array"
* ``Author names(s):`` : answer "PHY 504"
* ``Project release []:`` : just hit enter
* ``Project 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:
.. prompt:: bash
make html
Then you can view the default page via:
.. prompt:: bash
google-chrome build/html/index.html
Customizing our page
====================
There are two important files in ``source/``
* ``conf.py`` : this controls the configuration of Sphinx
* ``index.rst`` : this is the ReST file that will become ``index.rst``.
Configuration
-------------
Let's start by changing the configuration a bit:
* in the ``extensions`` section, change it to read:
.. code:: python
extensions = ["breathe"]
* change ``html_theme`` to be:
.. code:: python
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:
.. code:: ReST
***********
Using Array
***********
``Array.H`` provides a simple 2-d contiguous array. We can use it as:
.. code:: c++
#include
#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 (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:
.. code:: ReST
.. toctree::
:maxdepth: 2
:caption: Contents:
using
Let's add what we've do so far to our git:
.. prompt:: bash
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:
.. code:: yaml
- 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
.. code:: yaml
- 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 there
* It instructs the "Deploy" process to copy ``out`` to ``gh-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.
1. Move ``Doxyfile`` into ``docs/`` and change the following:
* change ``OUTPUT_DIRECTORY`` to ``doxy_files``
* change ``INPUT`` to ``../``
* Turn off HTML and turn on XML---Breathe works off of the XML output.
2. Update our ``conf.py`` to include Breathe and also run Doxygen for us. Here's
the updated ``conf.py``:
.. code:: python
# 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"
3. Create a ``doxygen_files.rst`` in ``source/`` with the following:
.. code:: ReST
Doxygen Files
=============
.. doxygenindex::
:project: cxx_array
4. Update ``index.rst`` by adding the following:
.. code:: ReST
.. 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.