Documentation for the Open Force Field ecosystem
Documentation for individual packages live in each project's own repository. This repo produces a landing page for all OpenFF docs.
Check out the rendered docs at docs.openforcefield.org.
Clone the repo:
git clone https://github.com/openforcefield/openff-docs.git
cd openff-docs
Make a Conda environment with Mamba:
mamba env create --name openff-docs --file devtools/conda-envs/rtd_env.yml
Activate the environment and build the docs:
conda activate openff-docs
sphinx-build -b html -j auto source build/html
The examples page relies on a cache of pre-processed examples collected from other repositories, as well as a Sphinx extension. This pre-processing includes steps like injecting a setup cell for Google Colab, executing the notebooks that are presented in Sphinx, and preparing .TGZ archives of each notebook with its required files. The cache is stored in git branches in this repository so that it can be accessed from Google Colab. The Sphinx extension is coded in source/_ext/cookbook
, and shares some code with the pre-processing script source/_ext/proc_examples.py
.
When a Sphinx build starts, the cookbook Sphinx extension will look in the file system for the cache files. If it doesn't find them, it will get the cache from the branch specified in cookbook.globals_.DEFAULT_CACHE_BRANCH
. To generate the cache files locally, run the proc_examples.py
script from the devtools/conda-envs/examples_env.yml
environment. This environment includes dependencies for both the examples themselves and the pre-processing code:
mamba env create --file devtools/conda-envs/examples_env.yml --name openff-docs-examples
mamba activate openff-docs-examples
python source/_ext/proc_examples.py
This involves executing all the notebooks - it takes about half an hour on GitHub actions, but can execute notebooks in parallel so may be much faster where more cores are available.
To collect examples from a new project, add the project to the devtools/conda-envs/examples_env.yml
environment, add the GitHub repository identifier (eg, "openforcefield/openff-toolkit") to the GITHUB_REPOS
list in source/_ext/cookbook/globals_.py
, and regenerate the cache.
proc_examples.py
will look for a Git tag that matches the version number found in the top-level __version__
attribute. It will work with an exact match, or else plus or minus a leading "v" relative to the __version__
string. The module name is inferred from the repository name in GITHUB_REPOS
; for instance, for openforcefield/openff-toolkit
, the openff.toolkit.__version__
attribute is checked.
If looking for a tag fails, a particular tag, branch, or commit may be specified in GITHUB_REPOS
by appending a hash sign and the reference name:
GITHUB_REPOS = [
"openforcefield/openff-toolkit#0.14.0",
...
]
Note that while the example notebooks will be taken from this commit, they will be executed in the latest global examples environment from the docs repository, so its important to make sure the same version is installed there.
The cache for the main
branch, which is served at https://docs.openforcefield.org, is automatically regenerated every night at midnight UTC, and also when a new commit is merged into main
. To manually regenerate it, dispatch the cookbook_preproc.yaml
workflow from the main
branch with the PR#
input left blank. ReadTheDocs will automatically rebuild when the main
branch cache is successfully regenerated via this workflow.
Caches for PRs are stored in their own branches. To regenerate the cache for a PR, create a comment on the PR consisting only of the text:
/regenerate-cache
Note that you must have push permissions on this repository for this command to work. Note also that in a PR, the RTD build must be manually restarted after the cache is finished generating. The github-actions bot will comment on the PR to tell you when regeneration starts and finishes.
Generally, any Jupyter notebook (extension .ipynb
) in a subfolder of the examples
directory in any repository in GITHUB_REPOS
should be automatically included without modification, but there are some things you can do to improve the quality of your example:
- Include exactly one top-level heading as a title. The first top-level heading in each notebook is used as that notebook's title; it should be clear from that title what the notebook does even outside the context of the source repository. Avoid using multiple top-level headings, as it disturbs the natural hierarchy of the documentation.
- Add a category. A Jupyter notebook is a JSON file with a top-level object (
dict
in Python terms). That object has a"metadata"
property which specifies arbitrary metadata for the notebook. Adding an entry like"category": "force_field_dev"
to the metadata object will place the notebook in the matching category on the examples page. Seesource/examples.md
for the available categories. - Add a thumbnail. A file named
thumbnail.png
in the same folder as the notebook will be used as the thumbnail for that notebook in the examples page. - Avoid
nglview.show_file(...)
; usenglview.show_structure_file(...)
instead. The former loads the file with JavaScript and does not work in embedded contexts like the examples page; the latter loads the file with Python and then passes its contents to JavaScript and so does work.
Note that changes to examples must generally be in a release before they are rendered in the examples page; but see Adding a new repo for advice on overriding this.
ReadTheDocs should be configured to provide redirects that allow subprojects to be found at URLs like docs.openforcefield.org/toolkit. Redirects can be defined in the Redirects tab of the Admin page at readthedocs.org. For each project, two "exact" redirects should be defined:
- From
/projectname/$rest
to the URL of the project's docs. This handles arbitrary links within the docs. - From
/projectname
to the URL of the project's docs. This handles the bare project name without a trailing forward slash.
For projects hosted outside of ReadTheDocs, the "to" URL should be the URL of the hosted documentation:
Redirect type:
Exact redirect
From URL:/standards/$rest
To URL:https://openforcefield.github.io/standards/
Redirect type:
Exact redirect
From URL:/standards
To URL:https://openforcefield.github.io/standards/
For projects hosted within ReadTheDocs, the project should be added as a subproject of openff-docs
and the "to" URL should be /projects/projectname
Child:
openff-interchange
Alias:interchange
Redirect type:
Exact redirect
From URL:/interchange/$rest
To URL:/projects/interchange/
Redirect type:
Exact redirect
From URL:/interchange
To URL:/projects/interchange/
:
You must have maintainer access to a project on RTD to add it as a subproject. If a project cannot be added as a subproject, the "to" URL can be set to the URL of the hosted documentation as with projects hosted externally.