selfdoc 0.4.2__tar.gz → 0.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- selfdoc-0.4.4/.rlsbl/changes/.validated +1 -0
- selfdoc-0.4.4/.rlsbl/changes/0.4.3.jsonl +14 -0
- selfdoc-0.4.4/.rlsbl/changes/0.4.3.md +6 -0
- selfdoc-0.4.4/.rlsbl/changes/0.4.4.jsonl +2 -0
- selfdoc-0.4.4/.rlsbl/changes/0.4.4.md +5 -0
- selfdoc-0.4.4/.selfdoc/hashes/hashes.json +138 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/CHANGELOG.md +13 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/PKG-INFO +1 -1
- selfdoc-0.4.4/docs/architecture.md +240 -0
- selfdoc-0.4.4/docs/cli-build.md +19 -0
- selfdoc-0.4.4/docs/cli-check.md +21 -0
- selfdoc-0.4.4/docs/cli-deploy.md +12 -0
- selfdoc-0.4.4/docs/cli-gen-data.md +18 -0
- selfdoc-0.4.4/docs/cli-gen.md +18 -0
- selfdoc-0.4.4/docs/cli-index.md +25 -0
- selfdoc-0.4.4/docs/cli-init.md +18 -0
- selfdoc-0.4.4/docs/cli-serve.md +18 -0
- selfdoc-0.4.4/docs/configuration.md +92 -0
- selfdoc-0.4.4/docs/deployment.md +200 -0
- selfdoc-0.4.4/docs/directives.md +70 -0
- selfdoc-0.4.4/docs/gen-index.md +30 -0
- selfdoc-0.4.4/docs/getting-started.md +268 -0
- selfdoc-0.4.4/docs/index.md +50 -0
- selfdoc-0.4.4/docs/selfdoc-__main__.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-build.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-check.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-cli.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-config.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-deploy.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-directives.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-extractors-go.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-extractors-python.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-extractors-typescript.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-extractors.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-gen.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-gendata.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-html.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-resolver.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-strictcli_support.md +12 -0
- selfdoc-0.4.4/docs/selfdoc-tokenizer.md +12 -0
- selfdoc-0.4.4/docs/selfdoc.md +12 -0
- selfdoc-0.4.4/docs/theming.md +240 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/package.json +1 -1
- {selfdoc-0.4.2 → selfdoc-0.4.4}/pyproject.toml +1 -1
- selfdoc-0.4.4/scripts/catalog-directive.py +56 -0
- selfdoc-0.4.4/scripts/config-schema-directive.py +302 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/build.py +3 -1
- selfdoc-0.4.4/selfdoc/catalog.py +202 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/gen.py +20 -5
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/strictcli_support.py +35 -7
- selfdoc-0.4.4/selfdoc.json +54 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_catalog.py +62 -2
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_gen.py +36 -1
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_strictcli_support.py +23 -0
- selfdoc-0.4.4/todo/code-help-package-path-and-strictcli.md +36 -0
- selfdoc-0.4.4/todo/recursive-coverage-matching.md +29 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/uv.lock +14 -1
- selfdoc-0.4.2/.rlsbl/changes/.validated +0 -1
- selfdoc-0.4.2/.selfdoc/hashes/hashes.json +0 -6
- selfdoc-0.4.2/docs/index.md +0 -37
- selfdoc-0.4.2/selfdoc/catalog.py +0 -136
- selfdoc-0.4.2/selfdoc.json +0 -11
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.claude/settings.json +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.github/workflows/ci.yml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.github/workflows/publish.yml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.gitignore +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.claude/settings.json +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.github/workflows/ci.yml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.github/workflows/publish.yml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.gitignore +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.rlsbl/changes/unreleased.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.rlsbl/hooks/post-release.sh +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.rlsbl/hooks/pre-checks.sh +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.rlsbl/lint/go.toml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.rlsbl/lint/npm.toml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/.rlsbl/lint/python.toml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/bases/CLAUDE.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.1.0.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.1.0.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.2.0.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.2.0.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.3.0.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.3.0.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.3.1.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.3.1.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.4.0.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.4.0.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.4.1.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.4.1.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.4.2.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/0.4.2.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/changes/unreleased.jsonl +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/config.json +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/hashes.json +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/hooks/post-release.sh +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/hooks/pre-checks.sh +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/hooks/pre-release.sh +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/lint/go.toml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/lint/npm.toml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/lint/python.toml +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/.rlsbl/version +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/CLAUDE.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/LICENSE +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/README.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/bin/cli.js +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/demo/index.html +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/package-lock.json +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/__init__.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/__main__.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/check.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/cli.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/config.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/content.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/deploy.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/directives.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/extractors/__init__.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/extractors/base.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/extractors/go.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/extractors/protocol.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/extractors/python.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/extractors/typescript.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/gendata.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/git.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/html.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/resolver.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/staleness.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/themes/__init__.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/themes/clean.css +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/themes/clean.json +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/themes/minimal.css +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/themes/minimal.json +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/selfdoc/tokenizer.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_build.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_check.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_cli.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_config.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_content.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_contrast.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_custom_directives.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_demo_panel.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_directives.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_extractors_protocol.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_gendata.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_git.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_go_extractor.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_h1.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_python_extractor.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_search.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_staleness.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_token_migration.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_tokenizer.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/tests/test_ts_extractor.py +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/auto-commit-hashes.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/auto-generated-glossary.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/auto-generation-gaps.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/changelog-page.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/coverage-go-typescript.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/cross-page-term-linking.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/lint-ignores-code-blocks.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/reading-progress.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/seo-geo-audit.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/seo-linting-gaps.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/sticky-table-column.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/.done/styling-and-release.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/atom-feed-filtering.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/brotli-dependency.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/css-redesign.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/gen-cli-descriptions.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/generate-claude-readme.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/glossary-config-opt-in.md +0 -0
- {selfdoc-0.4.2 → selfdoc-0.4.4}/todo/sticky-column-striped-rows.md +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
31959b7369fcb2c583c7b44ec29ebc7cb273b3e6
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{"commits":["a3a79e095f830e86e3af6e0c91f332c2d0e3329b"],"user_facing":true,"description":"Directive catalog now includes descriptions, attribute specs, and usage examples for all core directives","type":"feature"}
|
|
2
|
+
{"commits":["4824bea604f4201072dc404ee7f82b13a1ef1967"],"user_facing":true,"description":"Generated API and CLI reference pages now appear in organized sidebar groups","type":"feature"}
|
|
3
|
+
{"commits":["7ef991c8f04d43572d00c26063511cafd5b26204"],"user_facing":false}
|
|
4
|
+
{"commits":["4576e3a555693e2c8276917f5dbfc5dbb8038244"],"user_facing":false}
|
|
5
|
+
{"commits":["43d35c2d58d0ae793d96b6e22907cff32678adfc"],"user_facing":false}
|
|
6
|
+
{"commits":["dff95f7d6016c794066a4b6cf62547b156472fec"],"user_facing":false}
|
|
7
|
+
{"commits":["cc28dff179806cb90cac6ec5893176175820e3ac"],"user_facing":false}
|
|
8
|
+
{"commits":["8a52b31439bafe5e7fdce77785ae1a1ce8de6099"],"user_facing":false}
|
|
9
|
+
{"commits":["28f4ee127fa09d1fc5b84ee03567043d23e24601"],"user_facing":false}
|
|
10
|
+
{"commits":["f0e4cc383154cd05097c066f6eba2e606cd1518d"],"user_facing":false}
|
|
11
|
+
{"commits":["20b46367718298885f83226e1ba37a0c10300979"],"user_facing":false}
|
|
12
|
+
{"commits":["586d6738a1293ab5395c7027a2e32758c76a4f99"],"user_facing":false}
|
|
13
|
+
{"commits":["6b02f79db1953a533dd37718abfd0afd86c85e47"],"user_facing":false}
|
|
14
|
+
{"commits":["b3577a113db28097e22b375a4ff04238ae7d79df"],"user_facing":false}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
{"commits":["a9e50ca98e8e0063ddb897b3ef005a0ad0d8ddfb"],"user_facing":true,"description":"Build now cleans the output directory before writing, preventing stale files from previous builds","type":"fix"}
|
|
2
|
+
{"commits":["dc24e7bbf0f67e256c4e56c3bfbd5a6623771c3e"],"user_facing":false}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"architecture.md": {
|
|
3
|
+
"content": "fc65c48b75f2d0f3f7aad3a402174473c1b64bec70db83bcd1b5b395b7be3629",
|
|
4
|
+
"description": "464747f099e75e988a325270cbdbb36c693ea208de0b2d943ff24b5f5252392c"
|
|
5
|
+
},
|
|
6
|
+
"cli-build.md": {
|
|
7
|
+
"content": "4f441939ec1d3d8343c42044480f4801e8e206e9f773412450b8856fe6ff7479",
|
|
8
|
+
"description": "11a0aaee6da7ee4c35003138aab30c0da61a8dd3bf5e044018aa70f6bfbf0ec1"
|
|
9
|
+
},
|
|
10
|
+
"cli-check.md": {
|
|
11
|
+
"content": "947cf39b048aaee0ac9690c1adc4ce51d9e97312e20c9ee555e68cc26924e823",
|
|
12
|
+
"description": "83e8642d203e66ffba0b975b220466ca1b8b7c46c931b3a8a1bdbd0a07b1d3a3"
|
|
13
|
+
},
|
|
14
|
+
"cli-deploy.md": {
|
|
15
|
+
"content": "c0767fe6deef9f08905033d612278aab70344a1ed2deaf95288b57fc0f08f361",
|
|
16
|
+
"description": "ad27bfa7ab8fc96330481bc3ed07ab64e31d6ec4ab467b224258c26b4a699ff7"
|
|
17
|
+
},
|
|
18
|
+
"cli-gen-data.md": {
|
|
19
|
+
"content": "3abfac56ea661721aa278eba03e4ce9951b30f1f92bc51112005a1f81b159637",
|
|
20
|
+
"description": "a68ffec614fa35a26edcfa34140521954e51c08774d98227ed53c394eafc7f55"
|
|
21
|
+
},
|
|
22
|
+
"cli-gen.md": {
|
|
23
|
+
"content": "293e1f4ed0cc55c0ea22a6e344794af46209ad96d20ec10fca0b2f9b11aad779",
|
|
24
|
+
"description": "f1d3d11f4f35831ff951eb13fbed3d4f20cdb7532b6313c1fa6261d3fcf792ef"
|
|
25
|
+
},
|
|
26
|
+
"cli-index.md": {
|
|
27
|
+
"content": "de219d0efb796b7b4f3ab24244cc41b4405ea19559c5f2d280636358e0e6be3e",
|
|
28
|
+
"description": "c6543973c3b8332ad546e3bdecc2541b5a88399c97d5216150b7f104dd055f2f"
|
|
29
|
+
},
|
|
30
|
+
"cli-init.md": {
|
|
31
|
+
"content": "5e8f0f46ebcf5e1e9651a81aa411a02184fe0b4b996fc07bcd537f4e66aff050",
|
|
32
|
+
"description": "6d1e068f0f9e76336b37a28f39ba59e7553d671158007299679ed23c4edd869b"
|
|
33
|
+
},
|
|
34
|
+
"cli-serve.md": {
|
|
35
|
+
"content": "ea2aadd9609b20c23f3382af79ee0b3e0c89542732939884ee446cf01ca25d69",
|
|
36
|
+
"description": "88323d7eb608336718f90d35a2f827a48b52aa27543aaa1dde3d2b130657d9de"
|
|
37
|
+
},
|
|
38
|
+
"configuration.md": {
|
|
39
|
+
"content": "4858f37dc862255798ce6f27a87e609e8cffa13a7a0dd605260eab9d5bc43f31",
|
|
40
|
+
"description": "d30e4e9e4c1b60a8bc5b61174320ec4ea58b7d7f378bd60584d9ec2d0299e0cd"
|
|
41
|
+
},
|
|
42
|
+
"deployment.md": {
|
|
43
|
+
"content": "496d3905a141686a3e00caa8b133f3e3340e46598789202590a35c81d1059427",
|
|
44
|
+
"description": "f9f30e6caa4ef2763b8df268eea782c65657392ebee25c2f806caaa8a1e9c269"
|
|
45
|
+
},
|
|
46
|
+
"directives.md": {
|
|
47
|
+
"content": "a4f4410da54796aa0054f1947929f55d7e42a4c73bb55053bda4d7ffcd7384eb",
|
|
48
|
+
"description": "85994821a561754f8f44d5f9726876a05998ae9ba9dff245d958f7fbbddd7dc2"
|
|
49
|
+
},
|
|
50
|
+
"gen-index.md": {
|
|
51
|
+
"content": "b9a34b4f67c1d3c80a949b39ec62bb6ffcc946f1b9c7efd1a3374b59518edd8e",
|
|
52
|
+
"description": "bc0df72d8e79b08f319aad256d06b946ee719ef2bfc5beab3544f708f1725922"
|
|
53
|
+
},
|
|
54
|
+
"getting-started.md": {
|
|
55
|
+
"content": "1a220d72194fde13e4adbcf07ac15affabf61b67b130c45d9538a96cec398127",
|
|
56
|
+
"description": "071f168a9369107d2eab946a88d6cee06f098c7fb97f1cdf7285356e961a2b75"
|
|
57
|
+
},
|
|
58
|
+
"index.md": {
|
|
59
|
+
"content": "0215ae1728fae958fced933434f5d4d782965d8c384b326e94b15ccdc9a3806f",
|
|
60
|
+
"description": "fc5340d9da34d6f4b4d6aab857b5e533907bd2222539b52cf388475ff11c81d1"
|
|
61
|
+
},
|
|
62
|
+
"selfdoc-__main__.md": {
|
|
63
|
+
"content": "19efba25c48ca26ab78e1964836c7506e02f2ac715c4228aa48974b6af98f5c2",
|
|
64
|
+
"description": "351bacca1ca67f29e4598fd2a9e25b176c7b7a441016ac56835b9d8ce99689e0"
|
|
65
|
+
},
|
|
66
|
+
"selfdoc-build.md": {
|
|
67
|
+
"content": "21a93bac9ec86685860f63d50cf78bc87951236530fdf0794709c4d52872352c",
|
|
68
|
+
"description": "be6f20e435f122041e45ac095b9e0baba6daaed128896562056712660094d0f5"
|
|
69
|
+
},
|
|
70
|
+
"selfdoc-check.md": {
|
|
71
|
+
"content": "cd63364de4f6e66b0900caba4367c78dbed9810c33582045433cf0bee71d3ab1",
|
|
72
|
+
"description": "a8203524aa4a4dd2203eed62ad2fa11c802265649e05559b4f06c2ade06cb530"
|
|
73
|
+
},
|
|
74
|
+
"selfdoc-cli.md": {
|
|
75
|
+
"content": "580f2ec3b7a0badb7e03a3a71a4699d43aa3ff8698f7408560f11ecc11d0f857",
|
|
76
|
+
"description": "1ed3e1bca9ce5f9dd1cda9b7438f1814723fdc809ba1e565199ef3e6ce34f847"
|
|
77
|
+
},
|
|
78
|
+
"selfdoc-config.md": {
|
|
79
|
+
"content": "9df82b5c322f48946bdac68f0bbfd2e8d8c4e2fe43112f31c7a1c871362ef7a7",
|
|
80
|
+
"description": "d3a27e63a4064e9ed04a28f998f1eec89b9af346f9bca09580175324f02afa9c"
|
|
81
|
+
},
|
|
82
|
+
"selfdoc-deploy.md": {
|
|
83
|
+
"content": "d753004c1be5186890f34d42342bd4d4d9a0d35d45dc48eb74bb9eadf1036fe3",
|
|
84
|
+
"description": "aeedfc3bd7ba0d35c5fe3a92ac01ac06b2384daac5d7d448f2bc35953437e8af"
|
|
85
|
+
},
|
|
86
|
+
"selfdoc-directives.md": {
|
|
87
|
+
"content": "284db842f12b44acc1a7e8b0d043571a0c587b59e474a13858291beb389484c3",
|
|
88
|
+
"description": "49d75691be8336bd4b491b6be99439cd0e19c8cbe0deb76146c5dd038d94149c"
|
|
89
|
+
},
|
|
90
|
+
"selfdoc-extractors-go.md": {
|
|
91
|
+
"content": "837dc9c718e1645f4a73f19e4c1d0d0a5c86f64ccd905a0263e7c0227300fdcd",
|
|
92
|
+
"description": "5165de519d0ec8ad6f401a64d0cc7b34fce376f6c40021f7a02215d87683d814"
|
|
93
|
+
},
|
|
94
|
+
"selfdoc-extractors-python.md": {
|
|
95
|
+
"content": "5036efd3be125c1b6ff24ee9d2872611dad0812c3daee6be7f96d82e90e75307",
|
|
96
|
+
"description": "59015b730d7770ead6707d7442e18a896ff8833268db7d8f2f4872d1614a2ac8"
|
|
97
|
+
},
|
|
98
|
+
"selfdoc-extractors-typescript.md": {
|
|
99
|
+
"content": "26e8c76b2bb4ab115b891eb6690012804c2d9cb41d29b4ced08cb55b66b214d5",
|
|
100
|
+
"description": "f452e7c33e92de442795ae1e50ead8d17c0be8541a63e1d78db54b002fb513e2"
|
|
101
|
+
},
|
|
102
|
+
"selfdoc-extractors.md": {
|
|
103
|
+
"content": "585b695cab232ab64f87ef0b28c8547612e34192dbca6079a0eed522871d8cd1",
|
|
104
|
+
"description": "f9fafcab95df9229d672f91ffe5d6ca766958dcfe3c1638302d824621f962ff2"
|
|
105
|
+
},
|
|
106
|
+
"selfdoc-gen.md": {
|
|
107
|
+
"content": "b21477fe438d6743531de0c2a74524eb0d9e28969a10d728ecb921244939e5cf",
|
|
108
|
+
"description": "03f8cccc2ca955e46a9a08bb9cb50e5f9ffaf3c46bf2c01d24106e1f8a9eb45f"
|
|
109
|
+
},
|
|
110
|
+
"selfdoc-gendata.md": {
|
|
111
|
+
"content": "54e9a0a6aee2b422ced3b860c872362c65d940dae28ba3d0b79c3117bc234b62",
|
|
112
|
+
"description": "516999e8f3c505e0f46146652e521a0667d6a4fcc3132afcc12ba273fc1cf111"
|
|
113
|
+
},
|
|
114
|
+
"selfdoc-html.md": {
|
|
115
|
+
"content": "b56b50df5396c1e8f2633ba3def2011e4b34500c712caca6dc5e4153df18a843",
|
|
116
|
+
"description": "7cabc6a2a59f70a50a02132568e6cfd45ca58aad267764fda8120add86f8de89"
|
|
117
|
+
},
|
|
118
|
+
"selfdoc-resolver.md": {
|
|
119
|
+
"content": "4158312182ee977769882e9a4552ac2613f31bfa0dadb71be8bed0848861063d",
|
|
120
|
+
"description": "458c35bc81993667cf6f82d148af5f2993c72a273191c014011eb5f47b1c77b6"
|
|
121
|
+
},
|
|
122
|
+
"selfdoc-strictcli_support.md": {
|
|
123
|
+
"content": "cd50a69cdc65b253ce6826b050114f65c6b62ecc8f6b09b07c4a5e212d1d1b74",
|
|
124
|
+
"description": "0c1d40804347c9e9783377363c6268adb29a83f82fb4a8cd07c362082b845837"
|
|
125
|
+
},
|
|
126
|
+
"selfdoc-tokenizer.md": {
|
|
127
|
+
"content": "c1ba210f48e96dd2747309a8de17f49a101fc15f87ced867dd423ebe29dc43d4",
|
|
128
|
+
"description": "d2a949819b783e024b634f56c0cd49533fcaa40a67dfb67c39b5b99314899029"
|
|
129
|
+
},
|
|
130
|
+
"selfdoc.md": {
|
|
131
|
+
"content": "740137aa79607266cf4710eda34a20f09e042eb59aa74d888e1ce1c21e49b8d4",
|
|
132
|
+
"description": "4b2eeed0350ea775619b4bdffaf63dbb7b4e1f7c618c81630cb1ea79a7e535b0"
|
|
133
|
+
},
|
|
134
|
+
"theming.md": {
|
|
135
|
+
"content": "bb327170ca977b166a27223ee5ab21c8049fafc85f34519aeef10d1aac7e1506",
|
|
136
|
+
"description": "47828070bf38ec6e6e1ec94a0bd10af2f813ffe77625fbe6a5cac232beae9d2e"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## 0.4.4
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
|
|
9
|
+
- Build now cleans the output directory before writing, preventing stale files from previous builds
|
|
10
|
+
|
|
11
|
+
## 0.4.3
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
- Directive catalog now includes descriptions, attribute specs, and usage examples for all core directives
|
|
16
|
+
- Generated API and CLI reference pages now appear in organized sidebar groups
|
|
17
|
+
|
|
5
18
|
## 0.4.2
|
|
6
19
|
|
|
7
20
|
### Features
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Architecture
|
|
3
|
+
description: "Internal architecture of selfdoc: the Markdown tokenizer, rendering pipeline, language extractors, directive resolver, and build system."
|
|
4
|
+
order: 60
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Architecture
|
|
8
|
+
|
|
9
|
+
This page documents the internal design of selfdoc for contributors and anyone interested in extending or debugging the system.
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The selfdoc build pipeline transforms Markdown templates containing directive markers into a fully-featured static HTML site through a sequence of well-separated stages. Each stage receives the output of the previous one and produces a deterministic result, making the overall system straightforward to test, debug, and extend:
|
|
14
|
+
|
|
15
|
+
1. **Scan** -- walk `docs/` for `.md` files, parse frontmatter
|
|
16
|
+
2. **Resolve directives** -- replace directive markers with generated Markdown content (from source code or content transforms)
|
|
17
|
+
3. **Tokenize** -- split the resolved Markdown into typed block tokens
|
|
18
|
+
4. **Render** -- dispatch each token to a block-level HTML renderer
|
|
19
|
+
5. **Post-process** -- apply heuristic transforms (code tabs, step guides, API entries, definitions, LCP promotion)
|
|
20
|
+
6. **Generate HTML** -- wrap rendered content in a full page shell with navigation, metadata, and styles
|
|
21
|
+
7. **Auxiliary output** -- generate sitemap, Atom feed, search index, OG images, `llms.txt`, and compressed companions
|
|
22
|
+
|
|
23
|
+
Each stage is a pure function of its input, making the system easy to test and reason about. There is no shared mutable state between stages.
|
|
24
|
+
|
|
25
|
+
## Tokenizer
|
|
26
|
+
|
|
27
|
+
**Module:** `selfdoc/tokenizer.py` -- the tokenizer is a standalone, zero-dependency module that splits Markdown source into a flat list of typed block tokens. It has no imports from selfdoc and is designed for reuse outside the project. The tokenizer guarantees that every source line belongs to exactly one token, with no gaps or overlaps between adjacent tokens.
|
|
28
|
+
|
|
29
|
+
### Token types
|
|
30
|
+
|
|
31
|
+
The tokenizer produces 11 token types, each represented as a `@dataclass` with `start` and `end` line numbers (1-based). These types cover the full range of Markdown block-level constructs that selfdoc supports, from headings and code blocks to tables, lists, and directives:
|
|
32
|
+
|
|
33
|
+
| Token | Represents |
|
|
34
|
+
|-------|-----------|
|
|
35
|
+
| `Heading` | ATX heading (`#` through `######`) with level and text |
|
|
36
|
+
| `CodeBlock` | Fenced code block with language, content lines, and annotations |
|
|
37
|
+
| `Table` | Pipe-delimited table rows |
|
|
38
|
+
| `UnorderedList` | Items starting with `-` or `*` |
|
|
39
|
+
| `OrderedList` | Items starting with `1.`, `2.`, etc. |
|
|
40
|
+
| `Blockquote` | `>` prefixed lines, with optional admonition type |
|
|
41
|
+
| `DefinitionList` | Term/definition pairs (DL/DT/DD) |
|
|
42
|
+
| `ThematicBreak` | `---`, `***`, or `___` |
|
|
43
|
+
| `BlankLine` | Empty separator lines |
|
|
44
|
+
| `Directive` | The legacy `:::name arg` / `:::` syntax (tokenizer-level) |
|
|
45
|
+
| `Paragraph` | Everything else -- contiguous non-blank lines |
|
|
46
|
+
|
|
47
|
+
All tokens are combined into a `Block` union type. The tokenizer guarantees full coverage: every source line belongs to exactly one token, with no gaps or overlaps.
|
|
48
|
+
|
|
49
|
+
### Design rationale
|
|
50
|
+
|
|
51
|
+
The tokenizer exists as a separate module rather than being embedded as inline parsing logic within the HTML renderer. This separation serves two important purposes and keeps the architecture clean by ensuring that parsing concerns are decoupled from rendering concerns:
|
|
52
|
+
|
|
53
|
+
- **Dual consumers:** both the rendering pipeline and the lint system operate on tokens. The lint system needs line numbers for diagnostics, and the renderer needs structured data for dispatch.
|
|
54
|
+
- **Testability:** tokenization can be tested in isolation without invoking HTML generation or directive resolution.
|
|
55
|
+
|
|
56
|
+
## Rendering Pipeline
|
|
57
|
+
|
|
58
|
+
**Module:** `selfdoc/html.py`, function `md_to_html` -- the rendering pipeline converts resolved Markdown to HTML through a three-phase process that cleanly separates tokenization, block-level rendering, and heuristic post-processing into distinct stages. Each phase has a single responsibility, which makes the pipeline easy to test and debug independently.
|
|
59
|
+
|
|
60
|
+
### Phase 1: Tokenize and render blocks
|
|
61
|
+
|
|
62
|
+
`md_to_html` calls the tokenizer, then iterates over the resulting tokens, dispatching each to `_render_block`. This function pattern-matches on token type and delegates to specialized renderers (`_render_heading`, `_render_code_block`, `_render_table`, `_render_definition_list`, etc.). The first H1 heading is consumed for use as the page title and not rendered inline.
|
|
63
|
+
|
|
64
|
+
### Phase 2: Post-processors
|
|
65
|
+
|
|
66
|
+
After block rendering produces a joined HTML string, a series of regex-based post-processors transform the output to detect cross-block patterns and apply semantic enhancements that cannot be determined from individual tokens alone:
|
|
67
|
+
|
|
68
|
+
- **Code tabs** (`_group_code_tabs`): consecutive code blocks with different languages are wrapped in a tabbed interface
|
|
69
|
+
- **Step guides** (`_apply_step_guides`): ordered lists following headings containing "step", "guide", or "tutorial" receive a `class="steps"` for special styling
|
|
70
|
+
- **API entries** (`_wrap_api_entries`): sequences of h3/h4 + code block + description paragraph are wrapped in `<div class="api-entry">` cards
|
|
71
|
+
- **Definitions** (`_apply_definitions`): definitional patterns after headings get `<dfn>` wrapping for semantic markup and glossary cross-linking
|
|
72
|
+
- **LCP promotion**: the first image in the page is promoted from `loading="lazy"` to `fetchpriority="high" loading="eager"` for faster Largest Contentful Paint
|
|
73
|
+
|
|
74
|
+
### Phase 3: Page assembly
|
|
75
|
+
|
|
76
|
+
The `generate_html` function wraps the per-page HTML in a full document shell that includes sidebar navigation, breadcrumbs, canonical URLs, OpenGraph tags, structured data (JSON-LD), theme CSS, and JavaScript for interactive features like code tabs and full-text search.
|
|
77
|
+
|
|
78
|
+
### Why post-processors operate on HTML strings
|
|
79
|
+
|
|
80
|
+
Post-processors run after block rendering rather than on tokens because they detect cross-block patterns (e.g., "three consecutive code blocks" or "a heading followed by an ordered list"). The token stream is flat, making it natural to detect these patterns with regex on the rendered output. This keeps the renderer simple (one token in, one HTML fragment out) and moves heuristic logic to an explicit post-processing phase.
|
|
81
|
+
|
|
82
|
+
## Directive System
|
|
83
|
+
|
|
84
|
+
**Modules:** `selfdoc/directives.py` (parser), `selfdoc/resolver.py` (dispatch), `selfdoc/content.py` (content directives) -- directives are the core mechanism for pulling live information from source code into documentation. They bridge the gap between your codebase and your Markdown templates, ensuring that documentation content always reflects the current state of the implementation.
|
|
85
|
+
|
|
86
|
+
### Syntax
|
|
87
|
+
|
|
88
|
+
The directive parser recognizes a structured marker syntax that supports both self-closing one-liner directives and multi-line block directives with attributes and body content. Directives inside fenced code blocks are automatically ignored, and unclosed block directives at end-of-file produce a clear error:
|
|
89
|
+
|
|
90
|
+
| Marker | Purpose |
|
|
91
|
+
|--------|---------|
|
|
92
|
+
| `:-: name key="value"` | One-liner directive |
|
|
93
|
+
| `:<: name [attrs]` | Block open |
|
|
94
|
+
| `:@: key="value"` | Additional attribute line |
|
|
95
|
+
| `:=:` | Body separator |
|
|
96
|
+
| `::: content` | Body line |
|
|
97
|
+
| `:>:` | Block close |
|
|
98
|
+
|
|
99
|
+
Directives inside fenced code blocks are ignored. Unclosed block directives at EOF produce a `DirectiveError`.
|
|
100
|
+
|
|
101
|
+
### Resolver dispatch chain
|
|
102
|
+
|
|
103
|
+
When a directive is encountered during the build, the resolver created by `make_resolver` processes it through a three-level dispatch chain that tries each handler in order and stops at the first match:
|
|
104
|
+
|
|
105
|
+
1. **Content directives** -- `resolve_content` handles callouts (`callout-note`, `callout-warning`, etc.) and `list-glossary`. These transform body content into styled HTML without needing source code access. If the directive matches a content type, resolution stops here.
|
|
106
|
+
|
|
107
|
+
2. **Custom directives** -- if the project's `selfdoc.json` declares a `"directives"` map, the resolver loads the referenced Python script and calls its `resolve(attrs, config, body)` function. This allows project-specific extraction logic.
|
|
108
|
+
|
|
109
|
+
3. **Language extractor** -- the built-in extractor for the project's configured language handles the directive. This is the most common path for code-aware directives (`ref`, `table-schema`, `code-test`, `code-help`, `table-config`).
|
|
110
|
+
|
|
111
|
+
If none of these can handle the directive, the resolver emits an inline error marker (`> *[selfdoc: ...]*`) that is visible in the rendered output.
|
|
112
|
+
|
|
113
|
+
### Built-in directives
|
|
114
|
+
|
|
115
|
+
The directive catalog in `selfdoc/catalog.py` defines two categories of directives, cleanly separating what is currently functional and shipped from what is declared as a valid name but planned for future implementation. This approach allows documentation authors to reference future directives without triggering parse errors:
|
|
116
|
+
|
|
117
|
+
- **Core directives** (shipped and functional): `ref`, `table-schema`, `code-test`, `code-help`, `table-config`, callouts, and `list-glossary`
|
|
118
|
+
- **Future directives** (declared, parse-valid, not yet implemented): a large set organized by prefix -- `table-*`, `code-*`, `list-*`, `callout-*`, `prose-*`
|
|
119
|
+
|
|
120
|
+
Declaring future directives means the parser accepts them without error, allowing documentation authors to mark intent before extraction logic exists.
|
|
121
|
+
|
|
122
|
+
## Language Extractors
|
|
123
|
+
|
|
124
|
+
**Module:** `selfdoc/extractors/` -- each supported language has a dedicated extractor module that implements the `LanguageExtractor` protocol, providing language-specific logic for resolving directives, detecting source files, and enumerating public symbols for coverage analysis.
|
|
125
|
+
|
|
126
|
+
### The protocol
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
class LanguageExtractor(Protocol):
|
|
130
|
+
@property
|
|
131
|
+
def name(self) -> str: ...
|
|
132
|
+
def detect(self, dir_path: str) -> bool: ...
|
|
133
|
+
def resolve_path(self, path_arg, source_paths, base_dir) -> str | None: ...
|
|
134
|
+
def extract(self, directive_name, attrs, body, source_paths, base_dir) -> str: ...
|
|
135
|
+
def file_extensions(self) -> list[str]: ...
|
|
136
|
+
def public_symbols(self, file_path: str) -> list[str]: ...
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The protocol is `runtime_checkable`, allowing the registry to validate extractors at import time.
|
|
140
|
+
|
|
141
|
+
### Implementations
|
|
142
|
+
|
|
143
|
+
| Extractor | Language | Parsing strategy |
|
|
144
|
+
|-----------|----------|-----------------|
|
|
145
|
+
| `PythonExtractor` | Python | `ast` module -- full AST parsing for accurate symbol extraction |
|
|
146
|
+
| `GoExtractor` | Go | Regex-based -- matches exported identifiers, struct fields, function signatures |
|
|
147
|
+
| `TypeScriptExtractor` | TypeScript, JavaScript | Regex-based -- matches exports, interfaces, type aliases |
|
|
148
|
+
|
|
149
|
+
The Python extractor uses the `ast` module because Python's grammar makes regex-based extraction unreliable (decorators, multiline signatures, nested classes). Go and TypeScript have simpler export conventions (capitalized names in Go, explicit `export` keywords in TypeScript) that regex handles reliably.
|
|
150
|
+
|
|
151
|
+
### What each directive extracts
|
|
152
|
+
|
|
153
|
+
| Directive | Extraction target |
|
|
154
|
+
|-----------|------------------|
|
|
155
|
+
| `ref` | Module docstring, exported functions, classes with their signatures and docs |
|
|
156
|
+
| `table-schema` | Dataclass/struct/interface fields rendered as a Markdown table |
|
|
157
|
+
| `code-test` | Test function source code (whole file or specific function) |
|
|
158
|
+
| `code-help` | CLI argument parser definitions and help text |
|
|
159
|
+
| `table-config` | Configuration keys with types and descriptions |
|
|
160
|
+
|
|
161
|
+
### Language detection
|
|
162
|
+
|
|
163
|
+
The extractor registry also provides auto-detection through the `detect_language` function, which probes for marker files (`pyproject.toml` for Python, `go.mod` for Go, `package.json` or `tsconfig.json` for TypeScript) in a fixed priority order. This powers the `selfdoc init` command, allowing it to automatically configure the correct language without user input.
|
|
164
|
+
|
|
165
|
+
## Build Pipeline
|
|
166
|
+
|
|
167
|
+
**Module:** `selfdoc/build.py`, function `build` -- the build function orchestrates the full site generation from Markdown templates to a deployable static site, coordinating directive resolution, HTML rendering, auxiliary file generation, and asset copying.
|
|
168
|
+
|
|
169
|
+
### Main pipeline
|
|
170
|
+
|
|
171
|
+
1. Load config from `selfdoc.json`
|
|
172
|
+
2. Walk `docs/` for `.md` templates (skipping the output directory)
|
|
173
|
+
3. Parse frontmatter from each file (YAML between `---` fences)
|
|
174
|
+
4. Resolve directives using the project's configured language extractor
|
|
175
|
+
5. Pass resolved Markdown through `generate_html` (which tokenizes, renders, and post-processes)
|
|
176
|
+
6. Copy non-Markdown assets (images, CSS, scripts) to the output directory
|
|
177
|
+
|
|
178
|
+
### Auxiliary file generation
|
|
179
|
+
|
|
180
|
+
After the main HTML pipeline completes, the build generates several companion files that enhance discoverability, accessibility, and performance of the published site. These auxiliary outputs are all derived from the same page metadata and content used by the HTML renderer, ensuring consistency across formats:
|
|
181
|
+
|
|
182
|
+
- **Sitemap** (`sitemap.xml`): standard sitemap with page URLs and last-modified dates
|
|
183
|
+
- **Atom feed** (`feed.xml`): full Atom feed for RSS readers, respecting per-page `feed: false` frontmatter
|
|
184
|
+
- **Search index** (`search-index.json`): JSON index built from headings and content for client-side search
|
|
185
|
+
- **OG images**: OpenGraph card PNGs for social sharing (uses predraw if available, falls back to pure-Python PNG generation)
|
|
186
|
+
- **`llms.txt`**: a structured plain-text index of the site for LLM consumption, plus an `llms-full.txt` with all content
|
|
187
|
+
- **Compressed companions**: gzip (and brotli if available) pre-compressed versions of text-based output files for efficient serving
|
|
188
|
+
|
|
189
|
+
### Staleness tracking
|
|
190
|
+
|
|
191
|
+
The build computes content hashes for each page and persists them. The check command later uses these hashes to detect when page content has changed but its description has not been updated -- a common source of stale SEO metadata.
|
|
192
|
+
|
|
193
|
+
### Atomic writes and concurrency
|
|
194
|
+
|
|
195
|
+
File writes to shared state use atomic write patterns (write to a temporary file, then `os.replace`). This prevents partial reads if another process accesses the output directory during a build.
|
|
196
|
+
|
|
197
|
+
## Lint System
|
|
198
|
+
|
|
199
|
+
**Module:** `selfdoc/check.py` -- the `check` command validates documentation quality across three dimensions: directive correctness, documentation coverage, and SEO best practices. It operates on the tokenized representation of each page, giving it access to structured information without needing to re-parse raw Markdown.
|
|
200
|
+
|
|
201
|
+
### Directive validation
|
|
202
|
+
|
|
203
|
+
For every directive in every documentation template file, the checker performs a full resolution attempt using the project's configured language extractor to verify that the directive would succeed at build time. This catches broken module paths, missing symbols, and malformed attributes before they reach production:
|
|
204
|
+
|
|
205
|
+
1. Parses the directive (validating syntax and name against the catalog)
|
|
206
|
+
2. Attempts full resolution using the project's extractor
|
|
207
|
+
3. Reports OK or FAILED with the specific error
|
|
208
|
+
|
|
209
|
+
This catches broken paths, missing symbols, and malformed attributes before they reach production.
|
|
210
|
+
|
|
211
|
+
### Coverage analysis
|
|
212
|
+
|
|
213
|
+
Coverage measures how many public symbols in the source code are referenced by at least one directive. The analysis uses each extractor's `public_symbols` method to enumerate exported symbols, then cross-references against successfully resolved directives.
|
|
214
|
+
|
|
215
|
+
### SEO lint checks
|
|
216
|
+
|
|
217
|
+
The lint system operates on tokens rather than raw Markdown, which gives it access to structured information like heading levels, image alt text, and link targets without re-parsing. There are currently 14 checks covering metadata, content structure, and accessibility:
|
|
218
|
+
|
|
219
|
+
| Code | Check |
|
|
220
|
+
|------|-------|
|
|
221
|
+
| SEO001 | Multiple H1 headings |
|
|
222
|
+
| SEO002 | Heading level gaps (e.g., H2 followed by H4) |
|
|
223
|
+
| SEO003 | Empty image alt text |
|
|
224
|
+
| SEO004 | Title too long for search results |
|
|
225
|
+
| SEO006 | Missing meta description |
|
|
226
|
+
| SEO007-008 | Link and structural diagnostics |
|
|
227
|
+
| SEO009 | Description too short |
|
|
228
|
+
| SEO010 | Description too long |
|
|
229
|
+
| SEO011-012 | Content quality signals |
|
|
230
|
+
| SEO013 | No title source (no frontmatter title and no H1) |
|
|
231
|
+
| SEO014 | Meaningless alt text (e.g., "image", "screenshot") |
|
|
232
|
+
| SEO015 | Generic anchor text (e.g., "click here", "link") |
|
|
233
|
+
|
|
234
|
+
### Staleness detection
|
|
235
|
+
|
|
236
|
+
When a page's content hash differs from the last build but its description hash is unchanged, the checker flags it as potentially stale. This catches the common case where documentation content is updated but the frontmatter description (used in search results and social cards) still describes the old content.
|
|
237
|
+
|
|
238
|
+
### Why tokens, not raw Markdown
|
|
239
|
+
|
|
240
|
+
Operating on tokens rather than raw text means the lint system gets pre-parsed structure for free. It does not need to re-implement heading detection, code block boundaries, or list parsing. It can reliably distinguish "an image inside a code block" (should not trigger SEO003) from "an image in body text" (should trigger it).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: selfdoc build
|
|
3
|
+
description: "Reference for the selfdoc build command — usage, flags, arguments, and examples for the build subcommand of the selfdoc CLI."
|
|
4
|
+
generated: true
|
|
5
|
+
nav_group: "CLI Reference"
|
|
6
|
+
nav_order: 1
|
|
7
|
+
---
|
|
8
|
+
<!-- generated by selfdoc gen (strictcli), do not edit -->
|
|
9
|
+
|
|
10
|
+
# selfdoc build
|
|
11
|
+
|
|
12
|
+
Build the documentation site
|
|
13
|
+
|
|
14
|
+
## Flags
|
|
15
|
+
|
|
16
|
+
| Name | Short | Type | Default | Env | Description |
|
|
17
|
+
|------|-------|------|---------|-----|-------------|
|
|
18
|
+
| `--warn-only` | | bool | | | (deprecated, no-op) Warnings are now non-fatal by default |
|
|
19
|
+
| `--no-commit` | | bool | | | Skip auto-committing changed files |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: selfdoc check
|
|
3
|
+
description: "Reference for the selfdoc check command — usage, flags, arguments, and examples for the check subcommand of the selfdoc CLI."
|
|
4
|
+
generated: true
|
|
5
|
+
nav_group: "CLI Reference"
|
|
6
|
+
nav_order: 2
|
|
7
|
+
---
|
|
8
|
+
<!-- generated by selfdoc gen (strictcli), do not edit -->
|
|
9
|
+
|
|
10
|
+
# selfdoc check
|
|
11
|
+
|
|
12
|
+
Check documentation coverage and consistency
|
|
13
|
+
|
|
14
|
+
## Flags
|
|
15
|
+
|
|
16
|
+
| Name | Short | Type | Default | Env | Description |
|
|
17
|
+
|------|-------|------|---------|-----|-------------|
|
|
18
|
+
| `--ignore` | | str | | | Comma-separated SEO codes to suppress (e.g., SEO007,SEO008) |
|
|
19
|
+
| `--format` | | str | text | | Output format (default: text) |
|
|
20
|
+
| `--warn-only` | | bool | | | (deprecated, no-op) Warnings are now non-fatal by default |
|
|
21
|
+
| `--no-commit` | | bool | | | Skip auto-committing changed files |
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: selfdoc deploy
|
|
3
|
+
description: "Reference for the selfdoc deploy command — usage, flags, arguments, and examples for the deploy subcommand of the selfdoc CLI."
|
|
4
|
+
generated: true
|
|
5
|
+
nav_group: "CLI Reference"
|
|
6
|
+
nav_order: 3
|
|
7
|
+
---
|
|
8
|
+
<!-- generated by selfdoc gen (strictcli), do not edit -->
|
|
9
|
+
|
|
10
|
+
# selfdoc deploy
|
|
11
|
+
|
|
12
|
+
Deploy the documentation site
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: selfdoc gen-data
|
|
3
|
+
description: "Reference for the selfdoc gen-data command — usage, flags, arguments, and examples for the gen-data subcommand of the selfdoc CLI."
|
|
4
|
+
generated: true
|
|
5
|
+
nav_group: "CLI Reference"
|
|
6
|
+
nav_order: 5
|
|
7
|
+
---
|
|
8
|
+
<!-- generated by selfdoc gen (strictcli), do not edit -->
|
|
9
|
+
|
|
10
|
+
# selfdoc gen-data
|
|
11
|
+
|
|
12
|
+
Generate data files by running sandboxed scripts
|
|
13
|
+
|
|
14
|
+
## Flags
|
|
15
|
+
|
|
16
|
+
| Name | Short | Type | Default | Env | Description |
|
|
17
|
+
|------|-------|------|---------|-----|-------------|
|
|
18
|
+
| `--no-commit` | | bool | | | Skip auto-committing changed files |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: selfdoc gen
|
|
3
|
+
description: "Reference for the selfdoc gen command — usage, flags, arguments, and examples for the gen subcommand of the selfdoc CLI."
|
|
4
|
+
generated: true
|
|
5
|
+
nav_group: "CLI Reference"
|
|
6
|
+
nav_order: 4
|
|
7
|
+
---
|
|
8
|
+
<!-- generated by selfdoc gen (strictcli), do not edit -->
|
|
9
|
+
|
|
10
|
+
# selfdoc gen
|
|
11
|
+
|
|
12
|
+
Auto-generate documentation pages from project structure
|
|
13
|
+
|
|
14
|
+
## Flags
|
|
15
|
+
|
|
16
|
+
| Name | Short | Type | Default | Env | Description |
|
|
17
|
+
|------|-------|------|---------|-----|-------------|
|
|
18
|
+
| `--no-commit` | | bool | | | Skip auto-committing changed files |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: selfdoc CLI Reference
|
|
3
|
+
description: "Complete CLI reference for selfdoc — all available commands, subcommands, flags, arguments, and usage examples with detailed descriptions."
|
|
4
|
+
generated: true
|
|
5
|
+
nav_group: "CLI Reference"
|
|
6
|
+
nav_order: 0
|
|
7
|
+
order: 91
|
|
8
|
+
---
|
|
9
|
+
<!-- generated by selfdoc gen (strictcli), do not edit -->
|
|
10
|
+
|
|
11
|
+
# selfdoc CLI Reference
|
|
12
|
+
|
|
13
|
+
Code-aware static site generator with directive-based content extraction
|
|
14
|
+
|
|
15
|
+
Version: __version__
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
- [init](cli-init.html) -- Initialize selfdoc in the current project
|
|
20
|
+
- [build](cli-build.html) -- Build the documentation site
|
|
21
|
+
- [serve](cli-serve.html) -- Serve the documentation site locally
|
|
22
|
+
- [deploy](cli-deploy.html) -- Deploy the documentation site
|
|
23
|
+
- [check](cli-check.html) -- Check documentation coverage and consistency
|
|
24
|
+
- [gen](cli-gen.html) -- Auto-generate documentation pages from project structure
|
|
25
|
+
- [gen-data](cli-gen-data.html) -- Generate data files by running sandboxed scripts
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: selfdoc init
|
|
3
|
+
description: "Reference for the selfdoc init command — usage, flags, arguments, and examples for the init subcommand of the selfdoc CLI."
|
|
4
|
+
generated: true
|
|
5
|
+
nav_group: "CLI Reference"
|
|
6
|
+
nav_order: 6
|
|
7
|
+
---
|
|
8
|
+
<!-- generated by selfdoc gen (strictcli), do not edit -->
|
|
9
|
+
|
|
10
|
+
# selfdoc init
|
|
11
|
+
|
|
12
|
+
Initialize selfdoc in the current project
|
|
13
|
+
|
|
14
|
+
## Flags
|
|
15
|
+
|
|
16
|
+
| Name | Short | Type | Default | Env | Description |
|
|
17
|
+
|------|-------|------|---------|-----|-------------|
|
|
18
|
+
| `--no-commit` | | bool | | | Skip auto-committing changed files |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: selfdoc serve
|
|
3
|
+
description: "Reference for the selfdoc serve command — usage, flags, arguments, and examples for the serve subcommand of the selfdoc CLI."
|
|
4
|
+
generated: true
|
|
5
|
+
nav_group: "CLI Reference"
|
|
6
|
+
nav_order: 7
|
|
7
|
+
---
|
|
8
|
+
<!-- generated by selfdoc gen (strictcli), do not edit -->
|
|
9
|
+
|
|
10
|
+
# selfdoc serve
|
|
11
|
+
|
|
12
|
+
Serve the documentation site locally
|
|
13
|
+
|
|
14
|
+
## Flags
|
|
15
|
+
|
|
16
|
+
| Name | Short | Type | Default | Env | Description |
|
|
17
|
+
|------|-------|------|---------|-----|-------------|
|
|
18
|
+
| `--port` | `-p` | int | 8000 | | Port to serve on (default: 8000) |
|