lizardbyte-dockle 2026.919.233535__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.
Files changed (29) hide show
  1. lizardbyte_dockle-2026.919.233535/.gitignore +33 -0
  2. lizardbyte_dockle-2026.919.233535/LICENSE +21 -0
  3. lizardbyte_dockle-2026.919.233535/PKG-INFO +254 -0
  4. lizardbyte_dockle-2026.919.233535/README.md +226 -0
  5. lizardbyte_dockle-2026.919.233535/pyproject.toml +129 -0
  6. lizardbyte_dockle-2026.919.233535/src/dockle/__init__.py +12 -0
  7. lizardbyte_dockle-2026.919.233535/src/dockle/__main__.py +5 -0
  8. lizardbyte_dockle-2026.919.233535/src/dockle/builders.py +956 -0
  9. lizardbyte_dockle-2026.919.233535/src/dockle/cli.py +154 -0
  10. lizardbyte_dockle-2026.919.233535/src/dockle/cmake/Dockle.cmake +98 -0
  11. lizardbyte_dockle-2026.919.233535/src/dockle/config.py +871 -0
  12. lizardbyte_dockle-2026.919.233535/src/dockle/jsdoc_template/publish.js +155 -0
  13. lizardbyte_dockle-2026.919.233535/src/dockle/jsdoc_template/tmpl/layout.tmpl +94 -0
  14. lizardbyte_dockle-2026.919.233535/src/dockle/markdown.py +123 -0
  15. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/__init__.py +1 -0
  16. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/__init__.py +1 -0
  17. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/__init__.py +1 -0
  18. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/layout.html +149 -0
  19. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/main.html +124 -0
  20. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/mkdocs_theme.yml +14 -0
  21. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/HIGHLIGHT_LICENSE.txt +29 -0
  22. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/LUCIDE_LICENSE.txt +43 -0
  23. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/dockle.css +2490 -0
  24. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/dockle.js +1449 -0
  25. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/highlight.min.js +5111 -0
  26. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/lucide.min.js +13 -0
  27. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/theme.toml +18 -0
  28. lizardbyte_dockle-2026.919.233535/src/dockle/sphinx_theme.py +22 -0
  29. lizardbyte_dockle-2026.919.233535/src/dockle/theme.py +1320 -0
@@ -0,0 +1,33 @@
1
+ # JetBrains IDEs
2
+ .idea/
3
+
4
+ # Dockle
5
+ .dockle/
6
+ _site/
7
+
8
+ # Node.js
9
+ .npm-cache/
10
+ .npm-tmp/
11
+ node_modules/
12
+
13
+ # Generated from pinned Node.js dependencies
14
+ src/dockle/sphinx/themes/dockle/static/HIGHLIGHT_LICENSE.txt
15
+ src/dockle/sphinx/themes/dockle/static/LUCIDE_LICENSE.txt
16
+ src/dockle/sphinx/themes/dockle/static/highlight.min.js
17
+ src/dockle/sphinx/themes/dockle/static/lucide.min.js
18
+
19
+ # Python
20
+ __pycache__/
21
+ *.py[cod]
22
+ *.egg-info/
23
+ .venv/
24
+ build/
25
+ dist/
26
+
27
+ # Test and tooling caches
28
+ .coverage
29
+ coverage/
30
+ junit-python.xml
31
+ junit.xml
32
+ .pytest_cache/
33
+ .ruff_cache/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LizardByte LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,254 @@
1
+ Metadata-Version: 2.5
2
+ Name: lizardbyte-dockle
3
+ Version: 2026.919.233535
4
+ Summary: Build documentation with multiple frameworks and one consistent theme.
5
+ Project-URL: Documentation, https://dockle.readthedocs.io/
6
+ Project-URL: Issues, https://github.com/LizardByte/dockle/issues
7
+ Project-URL: Repository, https://github.com/LizardByte/dockle
8
+ Author: LizardByte
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: documentation,doxygen,jsdoc,mkdocs,rustdoc,sphinx
12
+ Classifier: Environment :: Console
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Topic :: Documentation
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: markdown>=3.8
18
+ Provides-Extra: all
19
+ Requires-Dist: mkdocs>=1.6; extra == 'all'
20
+ Requires-Dist: myst-parser>=4.0; extra == 'all'
21
+ Requires-Dist: sphinx>=8.1; extra == 'all'
22
+ Provides-Extra: mkdocs
23
+ Requires-Dist: mkdocs>=1.6; extra == 'mkdocs'
24
+ Provides-Extra: sphinx
25
+ Requires-Dist: myst-parser>=4.0; extra == 'sphinx'
26
+ Requires-Dist: sphinx>=8.1; extra == 'sphinx'
27
+ Description-Content-Type: text/markdown
28
+
29
+ <div align="center">
30
+ <img
31
+ src="/branding/dockle-logo.svg"
32
+ alt="Dockle logo"
33
+ width="192"
34
+ />
35
+ <h1 align="center">Dockle</h1>
36
+ <h4 align="center">Build documentation with multiple frameworks and one consistent theme.</h4>
37
+ </div>
38
+
39
+ <div align="center">
40
+ <a href="https://github.com/LizardByte/dockle"><img src="https://img.shields.io/github/stars/lizardbyte/dockle.svg?logo=github&style=for-the-badge" alt="GitHub stars"></a>
41
+ <a href="https://codecov.io/gh/LizardByte/dockle"><img src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fapp.lizardbyte.dev%2Fdashboard%2Fshields%2Fcodecov%2Fdockle.json&style=for-the-badge&logo=codecov" alt="Codecov"></a>
42
+ <a href="https://sonarcloud.io/project/overview?id=LizardByte_dockle"><img src="https://img.shields.io/sonar/quality_gate/LizardByte_dockle?server=https%3A%2F%2Fsonarcloud.io&style=for-the-badge&logo=sonarqubecloud&label=sonarcloud" alt="SonarCloud"></a>
43
+ </div>
44
+
45
+ Dockle is a configuration and presentation layer for documentation generators. A project describes itself once in
46
+ `dockle.toml`; Dockle translates that model into temporary Sphinx, Doxygen, MkDocs, JSDoc, or rustdoc configuration,
47
+ runs the underlying tool, and applies its own shared, Furo-inspired visual layer to the generated HTML. A full build
48
+ publishes a configured home target directly, adding a landing page only when a project needs one.
49
+
50
+ Any framework can own the root, with cards to other published targets injected
51
+ when needed. Project assets and metadata are configured once and then applied
52
+ to every generated documentation set. Redirect-only compatibility aliases under
53
+ the home target's name preserve existing target-prefixed deep links without
54
+ restoring a separate landing page.
55
+
56
+ The Sphinx integration is a first-party `dockle` theme. Furo is a design reference, not a runtime dependency or base
57
+ theme.
58
+
59
+ ## Why Dockle?
60
+
61
+ - Keep framework-specific configuration out of consumer repositories.
62
+ - Build one or several documentation targets from one command.
63
+ - Give prose and API references the same colors, typography, spacing, code blocks, tables, and responsive behavior.
64
+ - Keep the generators replaceable: Dockle orchestrates them rather than attempting to parse every source format itself.
65
+
66
+ ## Quick start
67
+
68
+ Dockle requires Python 3.11 or newer. Install the adapters needed by the project:
69
+
70
+ ```shell
71
+ python -m pip install "lizardbyte-dockle[sphinx,mkdocs]"
72
+ ```
73
+
74
+ The PyPI distribution uses the organization-qualified name `lizardbyte-dockle`; the project, Python package, and
75
+ command remain `dockle`. Doxygen, JSDoc, and the Rust toolchain remain native tool dependencies. Their executable paths
76
+ can be overridden in `dockle.toml` when they are not available on `PATH`.
77
+
78
+ JavaScript-only projects can use the native Dockle JSDoc template without Python, Doxygen, or Graphviz:
79
+
80
+ ```shell
81
+ npm install --save-dev @lizardbyte/dockle
82
+ npx dockle-jsdoc src --destination docs
83
+ ```
84
+
85
+ That npm package includes JSDoc and the first-party template. The Python package uses the same template when JSDoc is
86
+ one target in a larger multi-framework site.
87
+
88
+ Create a single configuration file:
89
+
90
+ ```toml
91
+ [project]
92
+ name = "Example"
93
+ version = "1.0.0"
94
+ description = "Example project documentation"
95
+ repository = "https://github.com/example/example"
96
+ logo = "branding/logo.png"
97
+
98
+ [theme]
99
+ primary = "#2962ff"
100
+ content = "#2e3440"
101
+ light_background = "#ffffff"
102
+ dark_background = "#131416"
103
+
104
+ [build]
105
+ output = "_site"
106
+ work = ".dockle"
107
+ strict = true
108
+
109
+ [[targets]]
110
+ name = "docs"
111
+ title = "Project documentation"
112
+ framework = "sphinx"
113
+ source = "docs"
114
+ home = true
115
+
116
+ [[targets]]
117
+ name = "cpp-api"
118
+ framework = "doxygen"
119
+ source = "."
120
+
121
+ [targets.doxygen]
122
+ inputs = ["README.md", "docs", "src"]
123
+ main_page = "README.md"
124
+ predefined = ["EXAMPLE_PUBLIC_API=1"]
125
+
126
+ [[targets]]
127
+ name = "rust-api"
128
+ framework = "rustdoc"
129
+ source = "."
130
+
131
+ [[targets]]
132
+ name = "web-api"
133
+ framework = "jsdoc"
134
+ source = "src"
135
+
136
+ [targets.jsdoc]
137
+ readme = "README.md"
138
+ ```
139
+
140
+ Then inspect or run the build:
141
+
142
+ ```shell
143
+ dockle build --dry-run
144
+ dockle check
145
+ dockle build
146
+ dockle build manual cpp-api
147
+ ```
148
+
149
+ The configuration path can be changed with `dockle --config path/to/dockle.toml build`. A complete build cleans the
150
+ whole output tree so removed targets cannot leave stale pages behind; a named-target build only replaces that target.
151
+ Strict mode is opt-in for consumers; set `strict = true` when warnings should fail the build. Doxygen's individual
152
+ documentation warning switches remain enabled by default. A Sphinx target can set `extra_config` to a Python fragment
153
+ that Dockle executes after its generated `conf.py`, and a Doxygen target can set `generate_xml = true` and
154
+ `publish = false` when an extension such as Breathe needs XML without a separate public API site. On Read the Docs,
155
+ Dockle derives the displayed version from `READTHEDOCS_VERSION` and preserves the configured width of all-zero versions
156
+ for numeric pull-request builds.
157
+
158
+ ## Review all five adapters
159
+
160
+ This repository is also an executable comparison suite. Every adapter has an
161
+ overview, component reference, GitHub-style alerts, code, tables, and an API or
162
+ reference page. Each language fixture differs only where the underlying
163
+ generator requires it:
164
+
165
+ ```shell
166
+ python -m pip install -e ".[all]"
167
+ npm ci --ignore-scripts
168
+ npm run build
169
+ dockle check
170
+ dockle build
171
+ ```
172
+
173
+ Doxygen and Cargo must be installed separately. The JSDoc adapter finds a project-local executable in
174
+ `node_modules/.bin`, so a global Node.js package is not required. Open `_site/index.html` to move between the generated
175
+ Sphinx, Doxygen, MkDocs, JSDoc, and rustdoc sites.
176
+
177
+ ## Read the Docs
178
+
179
+ The root `.readthedocs.yaml` delegates to `readthedocs_build.sh` because Dockle, rather than Read the Docs, owns generator
180
+ selection. Consumers call the same script from a `third-party/dockle` checkout. A fully pinned conda environment supplies
181
+ Doxygen, Graphviz, and Python while Read the Docs supplies Node.js and Rust. The script creates that environment, installs
182
+ the hosted prerequisites, runs Dockle through `conda run`, and copies the complete portal to
183
+ `$READTHEDOCS_OUTPUT/html/`. Optional project hooks named `readthedocs_pre_build.sh` and
184
+ `readthedocs_post_build.sh` run immediately before and after Dockle.
185
+
186
+ No Sphinx or MkDocs configuration is duplicated for the hosting service. Once this repository is imported into Read
187
+ the Docs, each branch and pull request build will exercise the root Sphinx documentation and all five adapters used
188
+ locally.
189
+
190
+ ## Distribution
191
+
192
+ The Python package is the canonical multi-framework orchestrator. PyPI provides the normal install path, while
193
+ standalone per-platform executables make that command available to C++, JavaScript, and Rust projects without requiring
194
+ a managed Python environment. The `@lizardbyte/dockle` npm package is intentionally narrower: it provides JSDoc, the
195
+ native Dockle JSDoc template, and the `dockle-jsdoc` command without installing Python or unrelated documentation
196
+ toolchains. A crates.io package still only makes sense if it provides comparable installation value or a real Rust API
197
+ rather than a second implementation.
198
+
199
+ For CMake projects, [`cmake/Dockle.cmake`](cmake/Dockle.cmake) already exposes `dockle_add_docs()`. It finds an installed
200
+ or standalone Dockle command and falls back to `Python3 -m dockle`.
201
+
202
+ ## Adapter status
203
+
204
+ | Framework | Configuration generated by Dockle | Shared theme path | Initial adapter |
205
+ | --- | --- | --- | --- |
206
+ | Sphinx | `conf.py` | Dockle's packaged Sphinx theme | Implemented |
207
+ | Doxygen | `Doxyfile` | `HTML_EXTRA_STYLESHEET` | Implemented |
208
+ | MkDocs | `mkdocs.yml` | Dockle's packaged MkDocs theme | Implemented |
209
+ | JSDoc | `jsdoc.json` | Dockle's packaged native JSDoc template | Implemented |
210
+ | rustdoc | Cargo command and environment | Generated HTML normalization | Implemented |
211
+
212
+ Every adapter now receives Dockle's generated client-side search index and the
213
+ same search interface, including result ranking and empty/error behavior. The
214
+ color-scheme control sits beside search and uses a state-aware Lucide icon.
215
+ Sphinx, MkDocs, and JSDoc use first-party templates. Doxygen and rustdoc keep
216
+ their semantic output while Dockle normalizes their structure and visual
217
+ primitives. Doxygen additionally receives a persistent tree, an automatically
218
+ completed page outline, and generated previous/next navigation.
219
+
220
+ Authored code blocks are re-highlighted with Dockle's pinned Highlight.js
221
+ runtime after each framework renders them, so native Pygments, Prettify,
222
+ Doxygen, and rustdoc token markup cannot produce different results. Dockle
223
+ normalizes common language aliases before highlighting; use `shell` for
224
+ commands and scripts, and reserve `console` for transcripts that include a
225
+ prompt or command output. Line-numbered native source listings retain their
226
+ generator-provided navigation.
227
+
228
+ Markdown GitHub alerts are enabled through MyST for Sphinx, a
229
+ Dockle Markdown extension for MkDocs and the root portal, Doxygen's native
230
+ parser, and a shared post-render enhancement for JSDoc and rustdoc. Dockle
231
+ extends the same syntax with attention, danger, error, hint, see-also, and todo
232
+ alerts. Its generated Doxyfile also supplies matching Doxygen aliases for
233
+ admonition types that Doxygen does not provide itself. Portable tab sets use
234
+ semantic `details` markup and are upgraded by Dockle's self-contained client
235
+ script with keyboard navigation. An optional `data-dockle-tab-group` name links
236
+ matching selections across tab sets and pages. Doxygen receives equivalent
237
+ `@tab`, `@tabs`, and `@tabs_grouped` aliases without depending on
238
+ `doxygen-awesome-css` or `doxyconfig`.
239
+
240
+ ## Development
241
+
242
+ The centralized common-lint workflow handles repository linting on pull
243
+ requests. Install the locked Python dependencies and run the test suite:
244
+
245
+ ```shell
246
+ uv sync --locked --all-extras
247
+ $env:PYTHONPATH = "src" # PowerShell
248
+ python -m unittest discover -s tests -v
249
+ python -m compileall -q src tests
250
+ ```
251
+
252
+ The root documentation is built from [docs/index.rst](docs/index.rst) with the
253
+ same first-party Sphinx theme used by the example. The Sphinx fixture includes
254
+ both MyST Markdown and reStructuredText component references.
@@ -0,0 +1,226 @@
1
+ <div align="center">
2
+ <img
3
+ src="/branding/dockle-logo.svg"
4
+ alt="Dockle logo"
5
+ width="192"
6
+ />
7
+ <h1 align="center">Dockle</h1>
8
+ <h4 align="center">Build documentation with multiple frameworks and one consistent theme.</h4>
9
+ </div>
10
+
11
+ <div align="center">
12
+ <a href="https://github.com/LizardByte/dockle"><img src="https://img.shields.io/github/stars/lizardbyte/dockle.svg?logo=github&style=for-the-badge" alt="GitHub stars"></a>
13
+ <a href="https://codecov.io/gh/LizardByte/dockle"><img src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fapp.lizardbyte.dev%2Fdashboard%2Fshields%2Fcodecov%2Fdockle.json&style=for-the-badge&logo=codecov" alt="Codecov"></a>
14
+ <a href="https://sonarcloud.io/project/overview?id=LizardByte_dockle"><img src="https://img.shields.io/sonar/quality_gate/LizardByte_dockle?server=https%3A%2F%2Fsonarcloud.io&style=for-the-badge&logo=sonarqubecloud&label=sonarcloud" alt="SonarCloud"></a>
15
+ </div>
16
+
17
+ Dockle is a configuration and presentation layer for documentation generators. A project describes itself once in
18
+ `dockle.toml`; Dockle translates that model into temporary Sphinx, Doxygen, MkDocs, JSDoc, or rustdoc configuration,
19
+ runs the underlying tool, and applies its own shared, Furo-inspired visual layer to the generated HTML. A full build
20
+ publishes a configured home target directly, adding a landing page only when a project needs one.
21
+
22
+ Any framework can own the root, with cards to other published targets injected
23
+ when needed. Project assets and metadata are configured once and then applied
24
+ to every generated documentation set. Redirect-only compatibility aliases under
25
+ the home target's name preserve existing target-prefixed deep links without
26
+ restoring a separate landing page.
27
+
28
+ The Sphinx integration is a first-party `dockle` theme. Furo is a design reference, not a runtime dependency or base
29
+ theme.
30
+
31
+ ## Why Dockle?
32
+
33
+ - Keep framework-specific configuration out of consumer repositories.
34
+ - Build one or several documentation targets from one command.
35
+ - Give prose and API references the same colors, typography, spacing, code blocks, tables, and responsive behavior.
36
+ - Keep the generators replaceable: Dockle orchestrates them rather than attempting to parse every source format itself.
37
+
38
+ ## Quick start
39
+
40
+ Dockle requires Python 3.11 or newer. Install the adapters needed by the project:
41
+
42
+ ```shell
43
+ python -m pip install "lizardbyte-dockle[sphinx,mkdocs]"
44
+ ```
45
+
46
+ The PyPI distribution uses the organization-qualified name `lizardbyte-dockle`; the project, Python package, and
47
+ command remain `dockle`. Doxygen, JSDoc, and the Rust toolchain remain native tool dependencies. Their executable paths
48
+ can be overridden in `dockle.toml` when they are not available on `PATH`.
49
+
50
+ JavaScript-only projects can use the native Dockle JSDoc template without Python, Doxygen, or Graphviz:
51
+
52
+ ```shell
53
+ npm install --save-dev @lizardbyte/dockle
54
+ npx dockle-jsdoc src --destination docs
55
+ ```
56
+
57
+ That npm package includes JSDoc and the first-party template. The Python package uses the same template when JSDoc is
58
+ one target in a larger multi-framework site.
59
+
60
+ Create a single configuration file:
61
+
62
+ ```toml
63
+ [project]
64
+ name = "Example"
65
+ version = "1.0.0"
66
+ description = "Example project documentation"
67
+ repository = "https://github.com/example/example"
68
+ logo = "branding/logo.png"
69
+
70
+ [theme]
71
+ primary = "#2962ff"
72
+ content = "#2e3440"
73
+ light_background = "#ffffff"
74
+ dark_background = "#131416"
75
+
76
+ [build]
77
+ output = "_site"
78
+ work = ".dockle"
79
+ strict = true
80
+
81
+ [[targets]]
82
+ name = "docs"
83
+ title = "Project documentation"
84
+ framework = "sphinx"
85
+ source = "docs"
86
+ home = true
87
+
88
+ [[targets]]
89
+ name = "cpp-api"
90
+ framework = "doxygen"
91
+ source = "."
92
+
93
+ [targets.doxygen]
94
+ inputs = ["README.md", "docs", "src"]
95
+ main_page = "README.md"
96
+ predefined = ["EXAMPLE_PUBLIC_API=1"]
97
+
98
+ [[targets]]
99
+ name = "rust-api"
100
+ framework = "rustdoc"
101
+ source = "."
102
+
103
+ [[targets]]
104
+ name = "web-api"
105
+ framework = "jsdoc"
106
+ source = "src"
107
+
108
+ [targets.jsdoc]
109
+ readme = "README.md"
110
+ ```
111
+
112
+ Then inspect or run the build:
113
+
114
+ ```shell
115
+ dockle build --dry-run
116
+ dockle check
117
+ dockle build
118
+ dockle build manual cpp-api
119
+ ```
120
+
121
+ The configuration path can be changed with `dockle --config path/to/dockle.toml build`. A complete build cleans the
122
+ whole output tree so removed targets cannot leave stale pages behind; a named-target build only replaces that target.
123
+ Strict mode is opt-in for consumers; set `strict = true` when warnings should fail the build. Doxygen's individual
124
+ documentation warning switches remain enabled by default. A Sphinx target can set `extra_config` to a Python fragment
125
+ that Dockle executes after its generated `conf.py`, and a Doxygen target can set `generate_xml = true` and
126
+ `publish = false` when an extension such as Breathe needs XML without a separate public API site. On Read the Docs,
127
+ Dockle derives the displayed version from `READTHEDOCS_VERSION` and preserves the configured width of all-zero versions
128
+ for numeric pull-request builds.
129
+
130
+ ## Review all five adapters
131
+
132
+ This repository is also an executable comparison suite. Every adapter has an
133
+ overview, component reference, GitHub-style alerts, code, tables, and an API or
134
+ reference page. Each language fixture differs only where the underlying
135
+ generator requires it:
136
+
137
+ ```shell
138
+ python -m pip install -e ".[all]"
139
+ npm ci --ignore-scripts
140
+ npm run build
141
+ dockle check
142
+ dockle build
143
+ ```
144
+
145
+ Doxygen and Cargo must be installed separately. The JSDoc adapter finds a project-local executable in
146
+ `node_modules/.bin`, so a global Node.js package is not required. Open `_site/index.html` to move between the generated
147
+ Sphinx, Doxygen, MkDocs, JSDoc, and rustdoc sites.
148
+
149
+ ## Read the Docs
150
+
151
+ The root `.readthedocs.yaml` delegates to `readthedocs_build.sh` because Dockle, rather than Read the Docs, owns generator
152
+ selection. Consumers call the same script from a `third-party/dockle` checkout. A fully pinned conda environment supplies
153
+ Doxygen, Graphviz, and Python while Read the Docs supplies Node.js and Rust. The script creates that environment, installs
154
+ the hosted prerequisites, runs Dockle through `conda run`, and copies the complete portal to
155
+ `$READTHEDOCS_OUTPUT/html/`. Optional project hooks named `readthedocs_pre_build.sh` and
156
+ `readthedocs_post_build.sh` run immediately before and after Dockle.
157
+
158
+ No Sphinx or MkDocs configuration is duplicated for the hosting service. Once this repository is imported into Read
159
+ the Docs, each branch and pull request build will exercise the root Sphinx documentation and all five adapters used
160
+ locally.
161
+
162
+ ## Distribution
163
+
164
+ The Python package is the canonical multi-framework orchestrator. PyPI provides the normal install path, while
165
+ standalone per-platform executables make that command available to C++, JavaScript, and Rust projects without requiring
166
+ a managed Python environment. The `@lizardbyte/dockle` npm package is intentionally narrower: it provides JSDoc, the
167
+ native Dockle JSDoc template, and the `dockle-jsdoc` command without installing Python or unrelated documentation
168
+ toolchains. A crates.io package still only makes sense if it provides comparable installation value or a real Rust API
169
+ rather than a second implementation.
170
+
171
+ For CMake projects, [`cmake/Dockle.cmake`](cmake/Dockle.cmake) already exposes `dockle_add_docs()`. It finds an installed
172
+ or standalone Dockle command and falls back to `Python3 -m dockle`.
173
+
174
+ ## Adapter status
175
+
176
+ | Framework | Configuration generated by Dockle | Shared theme path | Initial adapter |
177
+ | --- | --- | --- | --- |
178
+ | Sphinx | `conf.py` | Dockle's packaged Sphinx theme | Implemented |
179
+ | Doxygen | `Doxyfile` | `HTML_EXTRA_STYLESHEET` | Implemented |
180
+ | MkDocs | `mkdocs.yml` | Dockle's packaged MkDocs theme | Implemented |
181
+ | JSDoc | `jsdoc.json` | Dockle's packaged native JSDoc template | Implemented |
182
+ | rustdoc | Cargo command and environment | Generated HTML normalization | Implemented |
183
+
184
+ Every adapter now receives Dockle's generated client-side search index and the
185
+ same search interface, including result ranking and empty/error behavior. The
186
+ color-scheme control sits beside search and uses a state-aware Lucide icon.
187
+ Sphinx, MkDocs, and JSDoc use first-party templates. Doxygen and rustdoc keep
188
+ their semantic output while Dockle normalizes their structure and visual
189
+ primitives. Doxygen additionally receives a persistent tree, an automatically
190
+ completed page outline, and generated previous/next navigation.
191
+
192
+ Authored code blocks are re-highlighted with Dockle's pinned Highlight.js
193
+ runtime after each framework renders them, so native Pygments, Prettify,
194
+ Doxygen, and rustdoc token markup cannot produce different results. Dockle
195
+ normalizes common language aliases before highlighting; use `shell` for
196
+ commands and scripts, and reserve `console` for transcripts that include a
197
+ prompt or command output. Line-numbered native source listings retain their
198
+ generator-provided navigation.
199
+
200
+ Markdown GitHub alerts are enabled through MyST for Sphinx, a
201
+ Dockle Markdown extension for MkDocs and the root portal, Doxygen's native
202
+ parser, and a shared post-render enhancement for JSDoc and rustdoc. Dockle
203
+ extends the same syntax with attention, danger, error, hint, see-also, and todo
204
+ alerts. Its generated Doxyfile also supplies matching Doxygen aliases for
205
+ admonition types that Doxygen does not provide itself. Portable tab sets use
206
+ semantic `details` markup and are upgraded by Dockle's self-contained client
207
+ script with keyboard navigation. An optional `data-dockle-tab-group` name links
208
+ matching selections across tab sets and pages. Doxygen receives equivalent
209
+ `@tab`, `@tabs`, and `@tabs_grouped` aliases without depending on
210
+ `doxygen-awesome-css` or `doxyconfig`.
211
+
212
+ ## Development
213
+
214
+ The centralized common-lint workflow handles repository linting on pull
215
+ requests. Install the locked Python dependencies and run the test suite:
216
+
217
+ ```shell
218
+ uv sync --locked --all-extras
219
+ $env:PYTHONPATH = "src" # PowerShell
220
+ python -m unittest discover -s tests -v
221
+ python -m compileall -q src tests
222
+ ```
223
+
224
+ The root documentation is built from [docs/index.rst](docs/index.rst) with the
225
+ same first-party Sphinx theme used by the example. The Sphinx fixture includes
226
+ both MyST Markdown and reStructuredText component references.
@@ -0,0 +1,129 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "lizardbyte-dockle"
7
+ version = "2026.919.233535"
8
+ description = "Build documentation with multiple frameworks and one consistent theme."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.11"
12
+ keywords = ["documentation", "doxygen", "jsdoc", "mkdocs", "rustdoc", "sphinx"]
13
+ authors = [
14
+ { name = "LizardByte" },
15
+ ]
16
+ dependencies = [
17
+ "Markdown>=3.8",
18
+ ]
19
+ classifiers = [
20
+ "Environment :: Console",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "Topic :: Documentation",
24
+ ]
25
+
26
+ [project.urls]
27
+ Documentation = "https://dockle.readthedocs.io/"
28
+ Issues = "https://github.com/LizardByte/dockle/issues"
29
+ Repository = "https://github.com/LizardByte/dockle"
30
+
31
+ [project.optional-dependencies]
32
+ sphinx = [
33
+ "myst-parser>=4.0",
34
+ "sphinx>=8.1",
35
+ ]
36
+ mkdocs = [
37
+ "mkdocs>=1.6",
38
+ ]
39
+ all = [
40
+ "mkdocs>=1.6",
41
+ "myst-parser>=4.0",
42
+ "sphinx>=8.1",
43
+ ]
44
+
45
+ [dependency-groups]
46
+ test = [
47
+ "pytest==9.1.1",
48
+ "pytest-cov==7.1.0",
49
+ ]
50
+ package = [
51
+ "pyinstaller==6.22.3",
52
+ "twine==7.0.0",
53
+ ]
54
+ dev = [
55
+ { include-group = "package" },
56
+ { include-group = "test" },
57
+ ]
58
+
59
+ [project.scripts]
60
+ dockle = "dockle.cli:main"
61
+
62
+ [project.entry-points."sphinx.html_themes"]
63
+ dockle = "dockle.sphinx_theme"
64
+
65
+ [project.entry-points."mkdocs.themes"]
66
+ dockle = "dockle.sphinx.themes.dockle"
67
+
68
+ [tool.hatch.build]
69
+ artifacts = [
70
+ "/src/dockle/sphinx/themes/dockle/static/HIGHLIGHT_LICENSE.txt",
71
+ "/src/dockle/sphinx/themes/dockle/static/LUCIDE_LICENSE.txt",
72
+ "/src/dockle/sphinx/themes/dockle/static/highlight.min.js",
73
+ "/src/dockle/sphinx/themes/dockle/static/lucide.min.js",
74
+ ]
75
+
76
+ [tool.hatch.build.targets.wheel]
77
+ packages = ["src/dockle"]
78
+
79
+ [tool.hatch.build.targets.sdist]
80
+ include = [
81
+ "/LICENSE",
82
+ "/README.md",
83
+ "/pyproject.toml",
84
+ "/src",
85
+ ]
86
+
87
+ [tool.pytest.ini_options]
88
+ testpaths = ["tests"]
89
+ pythonpath = ["src"]
90
+ python_files = ["test_*.py"]
91
+ python_classes = ["Test*"]
92
+ python_functions = ["test_*"]
93
+ addopts = [
94
+ "-rxXs",
95
+ "--tb=native",
96
+ "--verbose",
97
+ "--color=yes",
98
+ "-p", "no:cacheprovider",
99
+ "--cov=src/dockle",
100
+ "--cov-report=term-missing",
101
+ "--cov-report=xml:coverage/python-coverage.xml",
102
+ "--junitxml=junit-python.xml",
103
+ "-o", "junit_family=legacy",
104
+ ]
105
+
106
+ [tool.coverage.run]
107
+ source = ["src/dockle"]
108
+ omit = [
109
+ "*/tests/*",
110
+ "*/__pycache__/*",
111
+ ]
112
+
113
+ [tool.coverage.report]
114
+ exclude_lines = [
115
+ "pragma: no cover",
116
+ "def __repr__",
117
+ "raise AssertionError",
118
+ "raise NotImplementedError",
119
+ "if __name__ == .__main__.:",
120
+ "if TYPE_CHECKING:",
121
+ "@abstractmethod",
122
+ ]
123
+
124
+ [tool.ruff]
125
+ line-length = 120
126
+ target-version = "py311"
127
+
128
+ [tool.ruff.lint]
129
+ select = ["E", "F", "I", "UP"]
@@ -0,0 +1,12 @@
1
+ """Dockle builds documentation with a shared configuration and visual language."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from importlib.metadata import PackageNotFoundError, version
6
+
7
+ __all__ = ["__version__"]
8
+
9
+ try:
10
+ __version__ = version("lizardbyte-dockle")
11
+ except PackageNotFoundError: # pragma: no cover - source tree without package metadata
12
+ __version__ = "0.0.0"
@@ -0,0 +1,5 @@
1
+ """Run Dockle with ``python -m dockle``."""
2
+
3
+ from dockle.cli import main
4
+
5
+ raise SystemExit(main())