Documentation — build, workflow, and style guide

This file explains how the docs are built, their dependencies, the expected workflow, and our style choices (including how we embed reStructuredText in Doxygen comments).


TL;DR (quick start)

# 1) Install Python deps
pip install -r requirements.txt

# 2) Make sure doxygen is installed (e.g., apt-get install doxygen)

# 3) Build and preview
./scripts/build_docs.sh --serve --open

What you get:

  • Doxygen XML is written under build-docs/docs/_build/doxygen/xml/

  • Sphinx HTML is written to build-docs/docs/html/

  • Exhale generates an API index under docs/api/ (this folder is regenerated each build)

Note: build_docs.sh now always performs a clean build by removing build-docs/ and docs/api/ before rebuilding.


Dependencies

  • Sphinx + Furo theme for the HTML site.

  • Breathe to bridge Doxygen XML into Sphinx.

  • Exhale to generate a consistent, tidy C++ API tree under docs/api/.

  • MyST-Parser to allow Markdown files in the docs.

  • Doxygen to parse C/C++/Fortran sources and emit XML for Breathe.

Install Python dependencies with:

pip install -r requirements.txt

The versions are pinned broadly in requirements.txt and are compatible with Sphinx 7+.


Source layout and build outputs

docs/                  # Sphinx project root (this folder)
├─ conf.py             # Sphinx configuration (Furo theme; Breathe/Exhale integration)
├─ index.rst           # Landing page
├─ memory.rst          # (example content)
├─ api/                # 🔁 generated by Exhale each build (deleted & recreated)
└─ README.md           # ← this file

build-docs/            # out-of-tree build area
└─ docs/
   ├─ html/            # final site (open index.html here)
   ├─ doctrees/        # Sphinx cached state
   └─ _build/doxygen/  # Doxygen outputs (XML under ./xml/)

How the pipeline fits together

  1. Doxygen scans src/ (C/C++/Fortran) and writes XML.

    • Config template: Doxyfile.in (no CMake configure step is required by the script).

    • We pass normalized paths so the build stays relocatable.

  2. Breathe reads that XML and exposes it as Sphinx directives/roles.

  3. Exhale walks the symbol graph and writes a clean API index beneath docs/api/.

  4. Sphinx renders everything to HTML using the Furo theme.

Key configuration highlights (see docs/conf.py):

  • Theme: furo (can override via SPHINX_THEME env var).

  • Strictness: set SPHINX_STRICT=1 to make Sphinx warnings fail the build.

  • TODOs: set SPHINX_TODOS=1 to include .. todo:: blocks in the HTML.

  • Graphviz: diagrams render as SVG when using .. graphviz::.

  • Auto-section labels: unique refs by document (:ref: works across files).


Building the docs

Using the helper script (preferred)

# For a clean build: removes build-docs/ and docs/api/
./scripts/build_docs.sh --clean

# Serve locally (http://localhost:8000) and try to open a browser tab
./scripts/build_docs.sh --serve --open

# Force rebuild regardless of timestamps
./scripts/build_docs.sh --force

Under the hood the script:

  • regenerates Doxyfile into build-docs/docs/Doxyfile

  • runs Doxygen (unless --no-doxygen)

  • exports DOXYGEN_XML_DIR so Breathe/Exhale see the right XML path

  • runs sphinx-build with a parallel job count

  • cleans build-docs/ and docs/api/ before building (project policy)

Using CMake (optional)

There is also a simple CMake target for docs:

cmake -S docs -B docs/build
cmake --build docs/build --target docs

This uses the find_package(Sphinx REQUIRED) path and builds HTML, but the script above remains the canonical developer workflow.


Authoring style & conventions

1) Titles and structure

  • Use reST (.rst) for most pages; Markdown via MyST is supported when convenient.

  • Use sentence-style capitalization for headings.

  • Keep section levels consistent (=, -, ^, ~ underlines).

2) Code blocks and languages

  • Prefer explicit languages (.. code-block:: cpp, python, yaml, etc.).

  • For short inline literals, use double backticks: like_this.

  • Long command lines go in bash blocks; keep lines wrapped ≤ 100 chars.

3) Admonitions and notes

  • .. note::, .. warning::, .. tip:: are encouraged for key points.

  • Keep admonition bodies short; link out for details.

4) Cross-references

  • Use :ref: for doc pages/sections.

  • For API, prefer Breathe/Exhale roles, e.g. ``:cpp:func:`ns::foo``` when convenient.

  • Autosection labels are enabled across documents; headings can be referenced safely.

5) Embedding reST inside Doxygen comments (our standard)

We enable Doxygen’s embedded reST via aliases (@rst/@endrst) with leading-asterisk support. This lets you write pretty Sphinx blocks directly inside /** */ comments without fighting indentation.

Example (exact style we use):

 * @rst 
*.. code-block:: cpp
*
*    exchange_ghosts(rho, mesh, cart_comm); // X±, Y±, Z± slabs
* @endrst

Tips:

  • Keep one blank * line between the directive and code body.

  • The alias handles the leading * characters automatically.

  • Use reST roles inside too (links, math, etc.).

6) Diagrams

  • Use .. graphviz:: for simple graphs; prefer small, focused diagrams.

  • Default output is SVG for crisp scaling in the Furo theme.


CI and publishing

A docs.yml workflow builds the site and can deploy to gh-pages. Locally you can preview with --serve; in CI use --force for deterministic, clean builds. Toggle strictness with SPHINX_STRICT=1 to treat warnings as errors.


Troubleshooting

  • doxygen not found → install it (Linux: apt-get install doxygen, macOS: brew install doxygen).

  • Empty API pages → ensure headers/sources live under src/ and symbols aren’t excluded.

  • Link targets not found → build once with SPHINX_STRICT=1 to catch broken refs.

  • Unicode in code samples → ensure your editor saves files as UTF‑8.