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.
- lizardbyte_dockle-2026.919.233535/.gitignore +33 -0
- lizardbyte_dockle-2026.919.233535/LICENSE +21 -0
- lizardbyte_dockle-2026.919.233535/PKG-INFO +254 -0
- lizardbyte_dockle-2026.919.233535/README.md +226 -0
- lizardbyte_dockle-2026.919.233535/pyproject.toml +129 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/__init__.py +12 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/__main__.py +5 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/builders.py +956 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/cli.py +154 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/cmake/Dockle.cmake +98 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/config.py +871 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/jsdoc_template/publish.js +155 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/jsdoc_template/tmpl/layout.tmpl +94 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/markdown.py +123 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/__init__.py +1 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/__init__.py +1 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/__init__.py +1 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/layout.html +149 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/main.html +124 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/mkdocs_theme.yml +14 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/HIGHLIGHT_LICENSE.txt +29 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/LUCIDE_LICENSE.txt +43 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/dockle.css +2490 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/dockle.js +1449 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/highlight.min.js +5111 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/static/lucide.min.js +13 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx/themes/dockle/theme.toml +18 -0
- lizardbyte_dockle-2026.919.233535/src/dockle/sphinx_theme.py +22 -0
- 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"
|