Documentation
DASCore uses comments for implementation intent, NumPy-style docstrings for API documentation, and .qmd pages for guides and examples.
Build and test
After the development install, install Quarto and run:
python scripts/build_api_docs.py
quarto render dascore/docsUse quarto preview dascore/docs for live editing. Generated HTML is under dascore/docs/_site/.
Edit scripts/_templates/_quarto.yml for navigation; dascore/docs/_quarto.yml is generated and overwritten. The API sidebar intentionally lists top-level sections rather than every object; dascore/docs/api/_metadata.yml assigns unlisted API pages to it.
The docs build records timing, output size, and URL changes:
python scripts/_doc_report.py time build_api_docs -- python scripts/build_api_docs.py
python scripts/_doc_report.py index
python scripts/_doc_report.py time quarto_render -- quarto render dascore/docs
python scripts/_doc_report.py site
python scripts/_doc_report.py summaryRun these in order. scripts/_baselines/api_urls.tsv protects published API URLs; regenerate it with python scripts/_api_urls.py freeze only when intentional URL changes are explained in the PR.
A page that is also an agent skill holds only an include; its text, and its executable blocks, live in dascore/.agents/skills/<name>/SKILL.md, so edit that file.
Executable Python blocks in hand-written .qmd files, and in the skill files they include, are mirrored into pytest files; blocks with eval: false are not tested:
python scripts/generate_doc_code_tests.py
pytest tests/test_autogenerated_doccodemarimo tutorials
Runnable tutorials become marimo notebooks that run in the browser; CI builds them, and the .qmd files remain the source. Build them before rendering docs locally:
python -m build --wheel
python scripts/build_notebooks.pyThis needs quarto, marimo and uv on the path and the generated _quarto.yml from scripts/build_api_docs.py. It exports the notebooks, with the newest wheel in dist/ and the example data, to dascore/docs/marimo/. The bundled wheel pins notebooks to the documented checkout and avoids WebAssembly-incompatible dependencies of released versions. Rendering without these steps omits the Open in marimo links. To try a notebook locally, serve the export (python -m http.server -d dascore/docs/marimo) and open a page.
marimo runs cells as a dependency graph, so a tutorial page must define each top-level name, imports included, in only one {python} block. Choose a new name rather than reassigning one from an earlier block; names starting with _ are local to their block and may be reused. The converter would otherwise rename later definitions (patch_1) or drop repeated imports, and the notebook would drift from the page, so tests/test_build_notebooks.py checks this.
Set DASCORE_DOC_SITE_URL for the deployment that notebook links should target. Add tutorial data to MIRRORED_DATA in scripts/build_notebooks.py to avoid browser downloads and shared-IP rate limits.
Links, citations, and equations
Link API objects by placing their import path in backticks:
[Patch](`dascore.core.Patch`)From docstrings, link pages relative to dascore/docs/, for example [Documentation](dascore/docs/contributing/documentation.qmd). In .qmd pages, use ordinary relative paths.
Add publications to dascore/docs/references.bib and cite them with Pandoc syntax such as @lindsey2021fiber or [@lindsey2021fiber].
Use standard LaTeX: $E=mc^2$ inline or a labeled display for cross-references:
$$
y = mx + b
$$ {#eq-line}
See @eq-line.
See the Quarto documentation for layout and formatting options.
Comments and docstrings
Comments should explain non-obvious intent, not restate code. Prefer clearer names or smaller functions when comments merely narrate operations.
Use NumPy-style docstrings and accurate type hints. Public objects need complete docstrings; private objects may use a short summary. Describe behavior and constraints, not types already expressed by annotations.
Docstring examples use doctest. Quarto options such as
>>> #| code-fold: trueand headings such as>>> ### Detailare preserved in generated API pages.For IO contracts, document only the formatter’s responsibility.
FiberIO.scan()returns patch-local attrs and a fullCoordManager; the public scan pipeline adds source path, format, and version. Formats with stored per-sample coordinates return them exactly withsnap=False.