CLI Commands
DocAnvil provides six subcommands: new, theme, doctor, serve, build, and export.
Global Flags
| Flag | Description |
|---|---|
--verbose |
Enable verbose output |
--quiet |
Suppress non-error output |
docanvil new
Scaffold a new documentation project.
docanvil new <name>
| Argument | Required | Description |
|---|---|---|
name |
Yes | Directory name for the new project |
Creates a project directory with:
docanvil.toml— project configurationnav.toml— navigation structuredocs/— content directory with starter pagestheme/custom.css— empty custom stylesheet
# Create a docs project docanvil new my-docs
# Create and immediately start serving docanvil new my-docs && cd my-docs && docanvil serve
docanvil theme
Interactively generate a custom color theme for your project.
docanvil theme [--overwrite] [--path <dir>]
| Option | Default | Description |
|---|---|---|
--overwrite |
false |
Replace existing theme customizations |
--path |
. |
Path to the project root |
The command walks through an interactive prompt:
- Color mode — choose Light only, Dark only, or Both (light + dark with toggle)
- Primary color — hex code for the primary accent color (prompted once per mode)
- Secondary color — hex code for the warning/secondary color (prompted once per mode)
It then derives all color-related CSS variables, writes them to theme/custom.css, and updates docanvil.toml with both custom_css and color_mode.
If existing theme customizations are detected (custom_css or [theme.variables] in config), the command exits with a helpful message unless --overwrite is passed.
# Generate a theme for the current project docanvil theme
# Generate a theme for a project in another directory docanvil theme --path ../my-docs
# Replace an existing theme docanvil theme --overwrite
Color Modes
| Mode | Behavior |
|---|---|
| Light only | Single light palette in :root. No toggle button. |
| Dark only | Single dark palette in :root with dark backgrounds/text. No toggle. |
| Both | Light as default :root, dark via [data-theme="dark"], OS prefers-color-scheme auto-detection, and a sun/moon toggle button in the header. User preference is saved to localStorage. |
When "Both" is selected, you are prompted for separate primary and secondary colors for each mode, allowing independent light and dark palettes.
Derived Variables (Light)
From the two input colors, the following CSS variables are generated for light mode:
| Variable | Derivation |
|---|---|
--color-primary |
Primary color as-is |
--color-primary-light |
Primary lightened 10% |
--color-link |
Same as primary |
--color-link-hover |
Primary darkened 10% |
--color-sidebar-hover |
Primary tinted to 95% lightness |
--color-sidebar-active-bg |
Primary tinted to 95% lightness |
--color-sidebar-active-text |
Primary darkened 10% |
--color-note-bg |
Primary tinted to 95% lightness |
--color-note-border |
Primary lightened 10% |
--color-mark-bg |
Primary at 12% opacity |
--nav-group-toggle-hover |
Primary at 6% opacity |
--color-focus-ring |
Primary at 40% opacity |
--color-warning-border |
Secondary color as-is |
--color-warning-bg |
Secondary tinted to 95% lightness |
Derived Variables (Dark)
Dark mode uses inverted derivation logic plus explicit background and text colors:
| Variable | Derivation |
|---|---|
--color-bg |
Dark background (#0f172a) |
--color-bg-secondary |
Slightly lighter dark (#1e293b) |
--color-text |
Light text (#f1f5f9) |
--color-text-muted |
Mid-light text (#94a3b8) |
--color-border |
Dark border (#334155) |
--color-code-bg |
Dark code background (#1e293b) |
--color-primary |
Primary color as-is |
--color-primary-light |
Primary lightened 10% |
--color-link |
Same as primary |
--color-link-hover |
Primary lightened 10% (lighter on dark bg) |
--color-sidebar-hover |
Primary tinted to 15% lightness |
--color-sidebar-active-bg |
Primary tinted to 15% lightness |
--color-sidebar-active-text |
Primary lightened 10% |
--color-note-bg |
Primary tinted to 15% lightness |
--color-note-border |
Primary lightened 10% |
--color-mark-bg |
Primary at 20% opacity |
--nav-group-toggle-hover |
Primary at 12% opacity |
--color-focus-ring |
Primary at 40% opacity |
--color-warning-border |
Secondary color as-is |
--color-warning-bg |
Secondary tinted to 15% lightness |
Note
After generating a theme, run docanvil serve to preview the result. You can edit the generated theme/custom.css file directly for further tweaks.
docanvil doctor
Diagnose project configuration and content issues before building.
docanvil doctor [--fix] [--strict] [--format <fmt>] [--path <dir>]
| Option | Default | Description |
|---|---|---|
--fix |
false |
Automatically apply safe fixes (create missing dirs, files) |
--strict |
false |
Exit with code 3 if any warnings or errors are found (for CI) |
--format |
human |
Output format: human, checkstyle, or junit |
--path |
. |
Path to the project root |
# Check the current project docanvil doctor
# Check and auto-fix safe issues docanvil doctor --fix
# Use in CI to fail on any issues docanvil doctor --strict
# Check a project in another directory docanvil doctor --path ../my-docs
If no docanvil.toml is found, doctor prints a friendly message suggesting docanvil new and exits cleanly.
Machine-readable output
The --format flag switches from the default coloured terminal output to structured XML, which is useful for integrating with CI annotation tools or test reporters. Machine-readable output is written to stdout; progress messages are suppressed entirely.
| Format | Description |
|---|---|
human |
Coloured, human-readable output to stderr (default) |
checkstyle |
Checkstyle XML — compatible with reviewdog, GitHub Actions problem matchers, and most Java/linting CI tooling |
junit |
JUnit XML — compatible with GitHub Actions test summary, GitLab CI, CircleCI, and most test result reporters |
# Output Checkstyle XML (e.g. pipe to reviewdog) docanvil doctor --format checkstyle
# Output JUnit XML (e.g. for GitHub Actions test summary) docanvil doctor --format junit
# Fail CI and emit Checkstyle XML docanvil doctor --format checkstyle --strict
# Save JUnit results to a file docanvil doctor --format junit > test-results/doctor.xml
Checkstyle XML groups diagnostics by file. Each <error> element carries:
severity—info,warning, orerrormessage— the diagnostic messageline— source line number (0when not applicable)source—docanvil.{category}.{check}(e.g.docanvil.readability.long-paragraph)
JUnit XML maps each check category to a <testsuite>. All eight categories are always emitted — categories with no issues produce a single passing <testcase name="all-checks-passed"/>. Warnings and errors appear as <failure> elements; info diagnostics appear as <skipped/>.
Note
--quiet suppresses the human-readable summary but does not suppress XML output — machine formats always write to stdout regardless of --quiet.
Check categories
The doctor runs six categories of checks, expanding to eight when versioning and/or i18n is enabled:
- Project structure — config file, content directory, index page
- Configuration — TOML parsing, file references (logo, favicon), nav.toml validation
- Theme — custom CSS file existence, layout template Tera syntax
- Content — broken wiki-links, unclosed directives, front-matter JSON errors, duplicate slugs
- Readability — content quality checks across all Markdown source files (see below)
- Versions (versioning only) — version configuration and directory health
- Translations (i18n only) — translation coverage across enabled locales
- Output — output directory writability
Readability checks
These run against raw Markdown source and catch content quality issues before they reach readers. Each diagnostic includes the file path and line number.
Heading structure
| Check | Severity | What it catches |
|---|---|---|
multiple-h1 |
⚠️ Warning | More than one H1 heading on the same page |
skipped-heading-level |
⚠️ Warning | Heading level jump of more than one (e.g. H1 → H3) |
consecutive-headings |
⚠️ Warning | Two headings with nothing but blank lines between them |
empty-heading |
✗ Error | A heading with no text (## ) |
heading-punctuation |
ℹ Info | Heading ends with . or ! — question marks are fine |
duplicate-heading-text |
⚠️ Warning | Two headings with the same text; produces anchor ID collisions |
emphasis-used-as-heading |
⚠️ Warning | A line that is entirely **bold** — use ## Heading instead |
no-document-title |
⚠️ Warning | Page has no H1 and no "title" in front matter |
heading-adjacent-separator |
⚠️ Warning | A heading is immediately adjacent to a horizontal rule — headings already create visual breaks, so the separator is redundant |
Links and images
| Check | Severity | What it catches |
|---|---|---|
missing-alt-text |
⚠️ Warning | Image with no alt text:  |
reversed-link-syntax |
✗ Error | (text)[url] instead of [text](url) — link won't render |
empty-link |
✗ Error | [text]() (no destination) or [](url) (no visible text) |
non-descriptive-link-text |
⚠️ Warning | Link text gives no navigational context: "here", "read more", "learn more", etc. |
bare-url |
⚠️ Warning | Raw URL in prose — wrap it as <url> or [text](url) |
Code blocks
| Check | Severity | What it catches |
|---|---|---|
missing-fenced-code-language |
ℹ Info | Code fence with no language tag — syntax highlighting won't apply |
Prose quality
| Check | Severity | What it catches |
|---|---|---|
long-paragraph |
ℹ Info | Paragraph exceeds the word count threshold (default: 150 words) |
repeated-word |
⚠️ Warning | Consecutive duplicate words: the the, is is |
todo-comment |
⚠️ Warning | TODO, FIXME, HACK, XXX, or PLACEHOLDER in prose |
placeholder-text |
⚠️ Warning | Lorem ipsum, TBD, or [Insert … here] in prose |
All checks skip content inside fenced code blocks. Most also strip inline code spans before scanning to avoid false positives.
Version checks
These run when version.enabled is non-empty in docanvil.toml.
| Check | Severity | What it catches |
|---|---|---|
current-not-in-enabled |
✗ Error | version.current specifies a version not in the enabled list |
version-dir-missing |
✗ Error | An enabled version has no matching subdirectory in the content directory — --fix creates it |
empty-version |
⚠️ Warning | A version directory exists but contains no .md files |
Auto-fix
The --fix flag applies safe, non-destructive fixes:
| Issue | Fix applied |
|---|---|
| Content directory missing | Creates the directory |
No index.md at content root |
Creates a minimal index page |
| Custom CSS file not found | Creates an empty CSS file at the configured path |
| Version directory missing | Creates the missing version subdirectory in the content directory |
Readability issues are never auto-fixed — they require human judgment.
Note
Run docanvil doctor again after --fix to verify all issues are resolved. Some fixes (like creating the content directory) may reveal additional issues on the next run.
docanvil serve
Start a development server with live reload.
docanvil serve [--host <address>] [--port <port>] [--path <dir>]
| Option | Default | Description |
|---|---|---|
--host |
127.0.0.1 |
Address to bind the server to |
--port |
3000 |
Port number |
--path |
. |
Path to the project root |
The server:
- Builds the site on startup
- Watches all project files for changes (Markdown, TOML, CSS, templates)
- Rebuilds affected pages on file change
- Notifies the browser via WebSocket at
/__docanvil_ws - The browser reloads automatically — no manual refresh needed
# Default: localhost:3000 docanvil serve
# Custom host and port docanvil serve --host 0.0.0.0 --port 8080
# Verbose output to see rebuild events docanvil serve --verbose
# Serve a project from another directory docanvil serve --path ../my-docs
docanvil build
Generate the static HTML site for deployment.
docanvil build [--out <path>] [--clean] [--path <dir>]
| Option | Default | Description |
|---|---|---|
--out |
dist |
Output directory for the generated site |
--clean |
false |
Remove the output directory before building |
--strict |
false |
Emit warnings as errors and exit with code 3 |
--path |
. |
Path to the project root |
The build pipeline processes each page through:
- Directive expansion (components)
- Popover conversion
- Markdown rendering (comrak with GFM)
- Wiki-link resolution
- Inline attribute injection
- Template wrapping (Tera layout)
Static assets (custom CSS, images) are copied to the output directory.
# Default build to dist/ docanvil build
# Clean build to a custom directory docanvil build --out public --clean
# Build a project from another directory docanvil build --path ../my-docs
Note
Broken wiki-links are reported as warnings during build. Check the output for any "broken link" messages to find references to pages that don't exist.
docanvil export
Export your documentation to other formats.
docanvil export pdf
Export docs as a single PDF using Chrome or Chromium.
docanvil export pdf --out <path> [--path <dir>] [--locale <code>]
| Option | Required | Default | Description |
|---|---|---|---|
--out |
Yes | — | Output path for the PDF file |
--path |
No | . |
Path to the project root |
--locale |
No | project default | Locale to export. Pass all to generate one PDF per enabled locale — e.g. guide.pdf → guide.en.pdf, guide.fr.pdf. |
Requires Chrome or Chromium. DocAnvil searches common install locations on macOS, Windows, and Linux before falling back to PATH.
# Export the current project docanvil export pdf --out guide.pdf
# Export a single locale docanvil export pdf --out guide-fr.pdf --locale fr
# Export all enabled locales (i18n projects) docanvil export pdf --out guide.pdf --locale all
# Export a project in another directory docanvil export pdf --out guide.pdf --path ../my-docs
PDF output is configured via the [pdf] section in docanvil.toml. See PDF Export for the full guide, including cover pages, paper sizes, RTL support, and custom CSS.
Exit Codes
All commands return structured exit codes so CI pipelines can distinguish between different failure types:
| Code | Meaning | Example causes |
|---|---|---|
0 |
Success | Build completed, doctor passed |
1 |
General failure | IO error, directory already exists, runtime setup failure |
2 |
Configuration error | Missing docanvil.toml, invalid TOML syntax |
3 |
Content validation error | Missing content directory, --strict warnings, doctor --strict failures |
4 |
Rendering error | Template syntax error, Markdown rendering failure |
5 |
Internal error | Panic (bug) — includes a message asking you to file an issue |
You can use these in CI scripts to handle different failures appropriately:
docanvil build --strict code=$? case $code in 0) echo "Build succeeded" ;; 2) echo "Fix your docanvil.toml" ;; 3) echo "Content issues found — check warnings above" ;; *) echo "Build failed with exit code $code" ;; esac
Note
Exit code 5 should never happen in normal use. If you see it, please report the issue — it means DocAnvil hit an unexpected panic.
Related Pages
- Installation — install and create your first project
- Configuration —
docanvil.tomlandnav.tomlreference - PDF Export — cover pages, paper sizes, RTL support, and per-locale export