Code-aware static site generator with directive-based content extraction
Project description
selfdocumenting
Code-aware documentation site generator. Builds full static sites from Markdown templates and source code. Your code is the documentation -- directives in Markdown pull live content from your codebase at build time.
Supports Python, Go, and TypeScript/JavaScript. One runtime dependency (strictcli). Pure Python.
Install
pip install selfdocumenting
or via npm (delegates to Python under the hood):
npm install -g selfdocumenting
Requires Python 3.11+.
The npm package is named selfdocumenting (npm blocks selfdoc due to name similarity). The CLI command remains selfdoc.
Quick start
# Initialize in an existing project (auto-detects language)
selfdoc init
# Auto-generate API and CLI reference pages
selfdoc gen
# Edit docs/ pages -- add directives referencing your code
# Build HTML output
selfdoc build
# Validate directives, coverage, and SEO lint
selfdoc check
# Serve locally with live reload
selfdoc serve
Your selfdoc.json needs versions and locales -- even for a single-version, single-locale project:
{
"language": "python",
"source": ["src/"],
"base_url": "https://my-project.example.com",
"versions": [{"version": "1.0.0", "indexed": true}],
"locales": [{"code": "en", "label": "English", "default": true}]
}
Features
- Directive syntax -- embed live API references, schemas, tests, and CLI help directly from source code (
:-:,:<:,:>:) - Auto-generated pages -- API reference and CLI docs from source code structure (
selfdoc gen) - Multi-version docs -- build from git tags, cached builds, version picker UI
- Localization -- parallel locale directories, hreflang tags, locale picker, per-locale sitemaps
- Monorepo support -- unified site builder combines multiple projects into one docs site
- Faceted search -- key=value filter syntax, 7 dimensions, chip UI, auto-injected version default
- Sandboxed data generation -- run scripts in bubblewrap isolation (
selfdoc gen-data) - Theming -- dark mode, accent colors, custom CSS overrides
- Search engines -- builtin, Fuse.js, or MiniSearch
- SEO -- 15+ lint rules, WCAG contrast validation, JSON-LD structured data, sitemaps
- Coverage tracking -- per-symbol documentation coverage with configurable thresholds
- Syntax highlighting -- build-time Pygments, code tabs, sortable tables
- Performance -- CSS/JS/HTML minification, critical CSS inlining, gzip and Brotli pre-compression
- Feeds and AI -- Atom feed,
robots.txtwith AI crawler controls,llms.txt/llms-full.txt - Landing page -- hero section, tagline, and feature cards
- Live reload -- SSE-based dev server
- Auto-commit -- generated files committed automatically (prefers safegit)
Directive syntax
Directives are inline blocks in your Markdown templates. They get replaced with content extracted from your source code at build time.
:-: directive-name path="arg"
Self-closing directives use :-:. Block directives that wrap a body use :<: to open, :>: to close, with :=: and ::: to delimit sections inside. Directives inside fenced code blocks are ignored.
Built-in directives
| Directive | Description |
|---|---|
callout-danger |
Styled danger callout block |
callout-important |
Styled important callout block |
callout-note |
Styled note callout block |
callout-tip |
Styled tip callout block |
callout-warning |
Styled warning callout block |
code-help |
Extract CLI help/usage text and flag definitions |
code-test |
Embed test source code (whole file or specific function) |
list-features |
Module summaries from docstring first lines |
list-glossary |
Definition list from Term: Definition lines |
list-modules |
List source modules with file paths and docstring summaries |
list-tree |
File/directory tree listing |
prose-desc |
Extract module/package docstring as prose text |
ref |
Extract module docstring, exported functions, and classes |
table-commands |
CLI command summary table from strictcli structure |
table-config |
Render a config file (JSON/TOML) as a key-value table |
table-config-schema |
Configuration field reference table from schema |
table-dep |
Dependencies table from pyproject.toml |
table-directives |
Table of all core built-in directives |
table-endpoint |
REST API endpoint table from OpenAPI spec |
table-schema |
Extract dataclass/struct fields as a markdown table |
var |
Interpolate project metadata value |
Example -- embed the API docs for a Python module:
## API Reference
:-: ref path="selfdoc.config"
Example -- show a JSON schema as a table:
:-: table-schema path="selfdoc.json"
Custom directives
Register custom directives in selfdoc.json under the directives key. Each entry maps a directive name to a Python script (relative to project root) that exports a resolve(attrs, config, body) function returning a Markdown string.
{
"directives": {
"changelog": "scripts/changelog_directive.py"
}
}
Script interface:
def resolve(attrs: dict, config: dict, body: list) -> str:
"""Return Markdown string to replace the directive block.
attrs -- directive attributes as str->str dict (e.g. {"path": "v1.0.0"})
config -- the full selfdoc.json config dict
body -- body lines from the directive block (empty list for one-liners)
"""
version = attrs.get("path")
...
Use in templates:
:-: changelog path="v1.0.0"
Custom directives take priority over built-in names.
Configuration
selfdoc.json at the project root:
{
"language": "python",
"source": ["selfdoc/"],
"docs": "docs/",
"output": "docs/_build/",
"base_url": "https://my-project.example.com",
"versions": [{"version": "1.0.0", "indexed": true}],
"locales": [{"code": "en", "label": "English", "default": true}],
"deploy": {
"provider": "cloudflare-pages",
"project": "my-docs"
},
"directives": {}
}
| Field | Required | Description |
|---|---|---|
source |
yes | List of source entries to extract documentation from. |
base_url |
yes | Base URL of the generated site, used for canonical links and SEO. |
version |
no | Project version. When present, used by deploy instead of reading from pyproject.toml/package.json. |
version_source |
no | Manifest file to read the project version from. |
docs |
no | Directory containing Markdown documentation templates. |
output |
no | Output directory for generated HTML files. |
theme |
no | Visual theme for the generated site. |
repo |
no | GitHub repository URL shown in the site header. |
lang |
no | BCP 47 language tag for the site content (e.g. 'en', 'pt-BR'). |
description |
no | Short description of the project, used in meta tags and SEO. |
branch |
no | Git branch used for source links in the generated site. |
search |
no | Search UI mode: icon button, full bar, or hidden. |
search_engine |
no | Client-side search engine implementation to use. |
code_icons |
no | Style of language icons shown on code blocks. |
line_numbers |
no | Show line numbers in code blocks. |
run_button |
no | Show a run button on code blocks for supported languages. |
page_nav |
no | Show previous/next navigation links between pages. |
page_progress |
no | Show a reading progress bar at the top of each page. |
glossary |
no | Auto-generate a glossary page from dfn terms. |
feed_max_entries |
no | Maximum number of entries in the Atom feed, sorted by most recent. |
lint_ignore |
no | List of lint rule IDs to suppress (e.g. 'SEO007', 'STALE001'). |
root_files |
no | List of underscore-prefixed template paths in docs/ for root file generation. |
redirects |
no | Page-level redirects expanded across all locale/version combos. |
deploy |
no | Deployment configuration for publishing the generated site. |
directives |
no | Custom directive mappings from directive name to source file path. |
author |
no | Author information for meta tags and structured data. |
feedback |
no | Feedback collection configuration (at least one of webhook or ga required). |
branding |
no | Landing page branding and call-to-action configuration. |
auto_detect |
no | Automatic content detection settings for step guides and API entries. |
gen |
no | Configuration for the gen command. |
gen_data |
no | Configuration for the gen-data command. |
versions |
no | List of documentation versions to build. |
locales |
no | List of locales for multi-language documentation. |
unified |
no | Configuration for unified multi-project documentation. |
selfdoc init auto-detects language and source paths from project files (pyproject.toml, go.mod, tsconfig.json, package.json).
Commands
| Command | Description |
|---|---|
init |
Initialize selfdoc in the current project |
build |
Build the documentation site |
serve |
Serve the documentation site locally |
deploy |
Deploy the documentation site |
check |
Check documentation coverage and consistency |
gen |
Auto-generate documentation pages from project structure |
gen-data |
Generate data files by running sandboxed scripts |
Deploy
Cloudflare Pages
Requires the Wrangler CLI installed and authenticated.
{
"deploy": {
"provider": "cloudflare-pages",
"project": "my-docs-project"
}
}
selfdoc build && selfdoc deploy
GitHub Pages
Pushes the output directory to the gh-pages branch via force-push.
{
"deploy": {
"provider": "github-pages"
}
}
Enable GitHub Pages in your repo settings (source: gh-pages branch).
Integration with rlsbl
When rlsbl detects a selfdoc.json in the project, it can trigger selfdoc build and selfdoc deploy as part of the release lifecycle via the .rlsbl/hooks/post-release.sh hook.
Documentation
Full documentation at selfdoc.smmh.dev.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file selfdoc-0.16.0.tar.gz.
File metadata
- Download URL: selfdoc-0.16.0.tar.gz
- Upload date:
- Size: 620.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b239db0161f96020e92f97b530112821542ec5ad1ba0e12a73d9f658ab29f00d
|
|
| MD5 |
339d0f42c622403ee5194a30de15b5ea
|
|
| BLAKE2b-256 |
32746e800e696c64f3eb343fde241432e70c1aa1d4888989dfe963741a6c20cb
|
Provenance
The following attestation bundles were made for selfdoc-0.16.0.tar.gz:
Publisher:
publish.yml on smm-h/selfdoc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
selfdoc-0.16.0.tar.gz -
Subject digest:
b239db0161f96020e92f97b530112821542ec5ad1ba0e12a73d9f658ab29f00d - Sigstore transparency entry: 1806447670
- Sigstore integration time:
-
Permalink:
smm-h/selfdoc@62d39e48d1cc3f0d05cd6d97d904645eb40041e4 -
Branch / Tag:
refs/tags/v0.16.0 - Owner: https://github.com/smm-h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@62d39e48d1cc3f0d05cd6d97d904645eb40041e4 -
Trigger Event:
release
-
Statement type:
File details
Details for the file selfdoc-0.16.0-py3-none-any.whl.
File metadata
- Download URL: selfdoc-0.16.0-py3-none-any.whl
- Upload date:
- Size: 242.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2dfc54caafa16dd614764d01b4fc603be57a880231fa7456e8def5877df637d
|
|
| MD5 |
f880af3df9753296ac2e1db68b331cfe
|
|
| BLAKE2b-256 |
edb6ce7c6b3941b9d8b170f74b0d1052f58a496c479a39de6be717642501de09
|
Provenance
The following attestation bundles were made for selfdoc-0.16.0-py3-none-any.whl:
Publisher:
publish.yml on smm-h/selfdoc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
selfdoc-0.16.0-py3-none-any.whl -
Subject digest:
d2dfc54caafa16dd614764d01b4fc603be57a880231fa7456e8def5877df637d - Sigstore transparency entry: 1806447679
- Sigstore integration time:
-
Permalink:
smm-h/selfdoc@62d39e48d1cc3f0d05cd6d97d904645eb40041e4 -
Branch / Tag:
refs/tags/v0.16.0 - Owner: https://github.com/smm-h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@62d39e48d1cc3f0d05cd6d97d904645eb40041e4 -
Trigger Event:
release
-
Statement type: