| name | docs-style-guide |
| description | Writing conventions for Markdown documentation (.md files) and Python docstrings. Covers file structure, language style, formatting rules, and Google-style docstring conventions (Args:, Returns:, Raises:, Attributes:, Examples:). Use when creating or editing docs/, README files, or writing/reviewing Python docstrings.
|
Documentation Style Guide
When to use me
Use this skill when:
- Creating or editing
.md files in docs/
- Writing README files
- Updating documentation structure
- Adding code examples to docs
- Writing or reviewing Python docstrings
- Checking whether a docstring uses the correct style (Google vs NumPy)
Principles
- Brief over complete. A reader who needs every detail will read the source. A reader who needs to get started needs the essentials fast.
- Show, don't just tell. Every concept should be illustrated with at least one concrete example.
- One idea per section. If a section tries to explain two things, split it.
- One TL;DR per file, as an abstract. Placed directly below the H1 title, before any prose. It covers the whole file — name each major section briefly so a reader can decide where to focus.
File structure
Every documentation file follows this template:
# Title
> **TL;DR** — Two to four sentences summarising the whole file. State what each major section covers so a reader can decide where to focus. Think paper abstract, not chapter summary.
---
## Section
Body text ...
- The TL;DR is a
> blockquote immediately below the H1 — never a paragraph.
- It covers the whole file, not individual sections. Name each major section in 1–2 words.
- The
--- horizontal rule separates the TL;DR from the first section.
- Sections use
##; subsections use ###. Never go deeper than ####.
Language
| Prefer | Avoid |
|---|
"Run uv sync" | "You should run uv sync" |
| "The solver minimises the residual." | "The solver will minimize the residual." |
"Pass seg=None to fit all voxels." | "It is possible to pass seg=None in order to fit all voxels." |
"Returns self for chaining." | "This method returns self, which allows chaining." |
- American English spelling (
minimize, color, behavior).
- Avoid filler words: simply, just, obviously, note that, please.
- Capitalise proper names: Python, NumPy, NIfTI, NNLS, TOML.
Formatting
Inline code
Use backticks for file names, paths, function/class/parameter names, CLI flags, TOML keys, and literal values.
Code blocks
Always specify the language tag:
- Shell commands →
bash
- Python →
python
- Config files →
toml
Tables
Use tables for: argument references, parameter lists, model comparisons. Keep them scannable.
Callouts
Use sparingly — one per page at most:
> [!NOTE]
> Extra context that does not fit the main flow.
> [!WARNING]
> Something that will cause a hard-to-debug problem if ignored.
Do not use [!TIP] or [!IMPORTANT].
Examples
- Runnable snippets — include all imports and show expected output in a comment.
- Fragments — mark continuation with
# ...; never present partial code as complete.
- TOML snippets — always include the section header (
[Fitting.model]), not bare keys.
File naming and location
| Content type | Location | File name pattern |
|---|
| User guides (how-to) | docs/guide/ | kebab-case.md |
| Conceptual reference | docs/concepts/ | kebab-case.md |
| Developer / contributor docs | docs/dev/ | PascalCase.md |
| Shared assets | docs/assets/ | kebab-case |
Cross-references
- Link to other doc files with relative paths:
[Configuration](guide/configuration.md).
- Link to source only when a specific line is essential.
What to document — and what not to
Document:
- How to install, configure, and run the tool.
- The meaning of every user-facing config key and CLI flag.
- Expected input/output shapes and units for model parameters.
- Non-obvious design decisions — record the why, not just the what.
Do not document:
- Internal implementation details fully captured by docstrings.
- Things obvious from reading the code.
- Planned features that do not exist yet.
Python docstrings
Style
Use Google style for all docstrings. Never use NumPy style.
| Google (correct) | NumPy (wrong) |
|---|
Args: | Parameters / ---------- |
Returns: | Returns / ------- |
Raises: | Raises / ------ |
Attributes: | Attributes / ---------- |
Examples: | Examples / -------- |
Structure
def fit(self, xdata: np.ndarray, ydata: np.ndarray) -> "MySolver":
"""Fit model parameters to observed data.
Args:
xdata: Independent variable (e.g., b-values), shape (n_measurements,)
ydata: Observed signal, shape (n_measurements,) or (n_pixels, n_measurements)
Returns:
MySolver: self, with fitted parameters in self.params_
Raises:
ValueError: If xdata and ydata shapes are incompatible
Examples:
>>> solver.fit(bvalues, signal)
>>> print(solver.params_)
"""
Rules
- One-line summary on the opening line, separated from sections by a blank line.
- Every public method and class must have a docstring.
- Private methods (
_name) only need a docstring if the logic is non-obvious.
- Class-level description goes on the class body, not on
__init__. Give __init__ a concise one-line summary instead.
Attributes: section belongs on the class body docstring, documenting instance attributes set in __init__.
- Shape annotations use plain text:
shape (n_pixels, n_bins).
- Use triple double-quotes (
""") — never single quotes.