Skip to content

Maintaining tutorials and the documentation site

View this page on GitHub

Tutorials are ordinary GitHub-readable Markdown. Keep the narrative, small reference exports, and SVG figures in docs/tutorials/; put executable reproduction scripts in scripts/. Readers should not need a solver build or a notebook server just to see a result.

Each tutorial has a generated link below its title. On GitHub it opens the corresponding documentation page; the site build replaces it with a link to that tutorial's Markdown file on GitHub. Both destinations come from zensical.toml and the source path, including tutorial index pages.

After adding or renaming a tutorial, git add its path and refresh the links:

python3 scripts/tutorial_links.py
python3 scripts/tutorial_links.py --check

The generator updates only the marked link block in tracked tutorials and leaves the narrative intact. CI rejects missing or stale links. The site build changes the link only in its temporary staging copy, keeping the checked-in Markdown ready for GitHub readers.

Numerical figures

Use a frontend's CSV/TSV/JSON exports as the data source. Include its provenance and convergence information, check unsuccessful exit codes and missing values, and explain energy, momentum and symmetry conventions in the tutorial. Do not imply spectral weights when a solver supplies only kinematic bounds.

Use bare bethe-* command names in calculation examples, with no assumed build directory. Keep source-relative Python commands in reproduction sections and identify their working directory. Downloaded CSV provenance retains the actual command used to generate it; those historical paths are not setup instructions.

Plotting environment

From the source checkout, activate a Python environment with the plotting dependencies. For example:

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -r docs/tutorials/requirements.txt

The environment can live elsewhere; .venv is just a conventional local choice. Solvers themselves do not need Python. To regenerate data, supply a command on PATH or an executable path with --solver; scripts that use multiple frontends accept their containing directory. These can be build-tree or installed programs.

Validate saved data

Validate the saved numerical examples:

python3 scripts/plot_xxz_tutorial.py --check
python3 scripts/plot_hubbard_tutorial.py --check
python3 scripts/plot_spin1_tutorial.py --check
python3 scripts/plot_lieb_liniger_tutorial.py --check
python3 scripts/plot_sutherland_tutorial.py --check
python3 scripts/plot_xxx_tutorial.py --check
python3 scripts/plot_xxx_precision_tutorial.py --check
python3 scripts/plot_haldane_shastry_tutorial.py --check
python3 scripts/plot_xyz_tutorial.py --check
python3 scripts/plot_q_boson_tutorial.py --check
python3 scripts/plot_biquadratic_tutorial.py --check
python3 scripts/plot_field_theory_tutorial.py --check
python3 scripts/plot_exclusion_tutorial.py --check
python3 scripts/plot_fermion_tutorial.py --check
python3 scripts/plot_multicomponent_tutorial.py --check
python3 scripts/plot_potts_qg_tutorial.py --check
python3 scripts/plot_gaudin_tutorial.py --check
python3 scripts/plot_kondo_ladder_tutorial.py --check
python3 -m unittest discover -s scripts -p 'test_tutorial*.py'

These checks require neither plotting packages nor a C++ build. To redraw or regenerate, follow the XXZ tutorial or the Hubbard tutorial. The ULS tutorial also describes regenerating the ULS and TB figures together. The Lieb–Liniger and Sutherland tutorials each have a standalone export-and-plot script. The XXX and Haldane–Shastry examples also show how to join named auxiliary tables. Their regeneration scripts share a temporary-file capture helper and validate all exports before saving them. The XYZ tutorial checks branch/parity copies; the q-boson tutorial joins roots and state tables and checks spectral moments against occupation-basis hopping. Both biquadratic sign tutorials share one export/plot script, checking physical-spin counts, sign conventions, Q-system completeness diagnostics and targeted finite-string branches. The Sine-Gordon and Lee–Yang tutorials share field-theory table validation, including independently converged levels, source diagnostics, vacuum subtraction and mass/circumference scaling. The TASEP and ASEP tutorials share relaxation/root validation, including analytic endpoints, stationary-only sectors, original Bethe equations and a small Markov-matrix check. The Gaudin–Yang and t–J examples share nested-table checks while keeping their equations, free-shell branches, units and momentum conventions distinct. The SU(n) fermion and Bose–Fermi mixture examples share multicomponent export validation, checking population-to-sea mappings, graded equations and independent Gaudin–Yang/Lieb–Liniger reductions. The Potts and non-Hermitian XXZ examples distinguish selected regular families from complete endpoint sectors. Their shared script checks charge/momentum selection, root joins and Jordan-block dimensions; --oracle adds independent small clock/spin matrices using NumPy. The Richardson and central-spin examples share Gaudin-variable validation but retain their distinct sectors and Hamiltonians. Their --oracle checks every saved example against independent occupation/spin matrices, including a central-polarization check of the energy derivative. The Kondo and ladder tutorials check subtracted-response units and fixed-sector field envelopes respectively. The ladder --oracle minimizes independent color matrices over all allowed populations; the separate reference_kondo.py uses mpmath for the continuum response. scripts/tutorial_common.py shares CSV/provenance validation and deterministic SVG writing; each model's script and tests own its schema and physics checks.

Light and dark figures

The site follows the visitor's system colour preference initially. The sun/moon button beside search selects an explicit light or dark theme and remembers it. Scientific figures can have separate versions for the two themes, using the theme-specific image support. Use the same descriptive alt text for both images:

![Spinon dispersion and continuum boundaries](figures/xxz-spinons.svg#gh-light-mode-only)
![Spinon dispersion and continuum boundaries](figures/xxz-spinons-dark.svg#gh-dark-mode-only)

These selectors work on the site and in GitHub Markdown. They follow the site's chosen theme, including a manual override of the operating-system preference. Printing uses the light version. An unpaired figure can stay as a normal image; the site supplies a white background for figures with transparent areas.

tutorial_common.save_svg(fig, path) writes the original light SVG and a -dark.svg companion. Both render the same data, axes and numerical scales. The shared style adapts text, ticks, spines, legends and the common categorical line colours. It preserves heatmap/scatter colour maps and normalization, including logarithmic scales, and never applies an image-inversion filter. The caller's original Matplotlib figure is not modified by the dark styling.

Regenerate both versions from saved exports with the usual plotting command, without a solver option, for example:

python3 scripts/plot_xxz_tutorial.py
python3 -m unittest discover -s scripts -p 'test_tutorial_plot_style.py'

Review both versions, especially filled regions, coloured annotations and heatmap overlays. Unknown categorical colours remain the author's choice. If a figure needs a different design, use save_svg(fig, path, dark=False) and create its dark companion explicitly in the same plotting script. Keep scientific colour scales consistent unless the caption explains a difference. The rendering tests require the plotting environment; the ordinary data checks and site build do not. Documentation CI installs it to run those checks too.

Build the site locally

From the source checkout, use a Python environment and an output directory of your choice. Here both .venv and .cache are ignored by Git:

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -r docs/requirements-site.txt
python3 -m unittest discover -s scripts -p 'test_build_docs.py'
python3 scripts/build_docs.py --work-dir .cache/docs-site
python3 scripts/check_docs_site.py .cache/docs-site/site
python3 -m http.server 8000 --directory .cache/docs-site/site

Open http://localhost:8000/. The build stages Git-tracked documentation only; git add new pages and assets before previewing them. Existing tracked files use their current working-tree content. Local untracked drafts cannot accidentally enter the site. Staging uses a fresh temporary directory per build.

zensical.toml controls the navigation. The build adapter keeps the repository's protected inline math and fenced math blocks intact in source, converting them only in staging to MathJax wrappers. Code examples remain code. MathJax 3.2.2 is loaded from a CDN, so equations need network access in a browser; figures and page content are served locally. Run scripts/check_markdown_math.py to check GitHub-safe source syntax (optionally --github for GitHub's renderer).

Publish

The Pages workflow validates the committed tutorial data and math adapter, then builds the site on pull requests. Pushes to main affecting documentation also deploy it; manual dispatch is available. Deployment uses the GitHub Pages environment and a Pages artifact, not a generated branch.

The site build deliberately does not compile solvers or regenerate figures. Numerical regeneration is an explicit, reviewable update to data and figures. This keeps prose-only publishing fast and independent of Uni20/MPLAPACK builds.