doxtr-pdf-theme-core 1.0.0__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.
- doxtr_pdf_theme_core-1.0.0/PKG-INFO +1196 -0
- doxtr_pdf_theme_core-1.0.0/README.md +1178 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/__init__.py +1077 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/assets/doxtr_icon.png +3 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/assets/doxtr_icon_small.png +3 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/ast_processors/__init__.py +32 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/ast_processors/codeblocks.py +34 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/ast_processors/containers.py +75 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/ast_processors/epigraphs.py +88 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/ast_processors/highlights.py +43 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/ast_processors/needs.py +113 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/ast_processors/sidebars.py +193 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/ast_processors/tables.py +33 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/colors.py +158 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/config.py +341 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/core_config.py +1132 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/core_fallbacks.py +211 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/files.py +65 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_escape.py +50 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/admonition/default.tex_t +36 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/admonition/note.tex_t +35 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/admonition/seealso.tex_t +43 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/code/default.tex_t +55 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/container/default.tex_t +11 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/container/folder.tex_t +51 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/container/participant.tex_t +76 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/container_title_style/classic.tex_t +2 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/container_title_style/floating.tex_t +8 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/container_title_style/ribbon.tex_t +9 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/figure/default.tex_t +38 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/highlights/default.tex_t +30 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/need/default.tex_t +15 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/sidebar/default.tex_t +54 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/sphinxlatexstyleheadings.sty +0 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/sphinxlatexstylepage.sty +0 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/table/arrow.tex_t +179 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/table/default.tex_t +288 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/latex_styles/title_page/default.tex_t +50 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/preamble.tex_t +721 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/shell_icons.py +64 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/templates.py +313 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core/utils.py +860 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core.egg-info/PKG-INFO +1196 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core.egg-info/SOURCES.txt +47 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core.egg-info/dependency_links.txt +1 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core.egg-info/requires.txt +6 -0
- doxtr_pdf_theme_core-1.0.0/doxtr_pdf_theme_core.egg-info/top_level.txt +1 -0
- doxtr_pdf_theme_core-1.0.0/pyproject.toml +62 -0
- doxtr_pdf_theme_core-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,1196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: doxtr-pdf-theme-core
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Core PDF layout engine and AST flatteners for Doxtr themes.
|
|
5
|
+
Author: Jens Frey
|
|
6
|
+
Project-URL: Homepage, https://github.com/doxtr/doxtr-pdf-theme-core
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Framework :: Sphinx :: Extension
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: sphinx>=5.0
|
|
14
|
+
Requires-Dist: Jinja2>=3.0
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
17
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
18
|
+
|
|
19
|
+
# Doxtr PDF Theme Core
|
|
20
|
+
|
|
21
|
+
The core PDF layout engine for the Doxtr document authoring system. It provides a professional LaTeX/PDF output pipeline utilizing KOMA classes and LuaLaTeX, designed to be inherited by child themes that customize the look and feel.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install doxtr-pdf-theme-core
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Note on LaTeX Engine:** This core relies on `fontspec` and KOMA classes, which require LuaLaTeX. The core will automatically set `latex_engine = 'lualatex'` if you haven't explicitly configured an engine.
|
|
30
|
+
|
|
31
|
+
## Quick Start — Using a Child Theme
|
|
32
|
+
|
|
33
|
+
The easiest way to use the core is through a child theme (e.g., `doxtr-pdf-theme-aubergine`):
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
# conf.py
|
|
37
|
+
extensions = [
|
|
38
|
+
'doxtr_pdf_theme_aubergine',
|
|
39
|
+
]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
To use the core directly without a child theme:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
# conf.py
|
|
46
|
+
extensions = [
|
|
47
|
+
'doxtr_pdf_theme_core',
|
|
48
|
+
]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Create a Child Theme — Walkthrough
|
|
54
|
+
|
|
55
|
+
This section explains how to build your own child theme on top of the core engine.
|
|
56
|
+
A reference implementation is available at [doxtr-pdf-theme-aubergine](https://github.com/doxtr/doxtr-pdf-theme-aubergine).
|
|
57
|
+
|
|
58
|
+
### Project Structure
|
|
59
|
+
|
|
60
|
+
The minimum viable theme is 3 files:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
my_company_theme/
|
|
64
|
+
├── pyproject.toml # Package metadata
|
|
65
|
+
├── README.md # Usage documentation
|
|
66
|
+
└── my_company_theme/
|
|
67
|
+
└── __init__.py # Theme logic (colors, fonts, defaults)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
For themes with custom LaTeX templates:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
my_company_theme/
|
|
74
|
+
├── pyproject.toml
|
|
75
|
+
├── README.md
|
|
76
|
+
└── my_company_theme/
|
|
77
|
+
├── __init__.py
|
|
78
|
+
└── latex_styles/ # Optional: override visual templates
|
|
79
|
+
├── admonition/
|
|
80
|
+
│ └── rounded.tex_t # Custom admonition rendering
|
|
81
|
+
├── container/
|
|
82
|
+
│ └── default.tex_t # Custom container body
|
|
83
|
+
├── container_title_style/
|
|
84
|
+
│ └── minimal.tex_t # Custom container title geometry
|
|
85
|
+
├── code/
|
|
86
|
+
│ └── default.tex_t # Custom code block rendering
|
|
87
|
+
├── figure/
|
|
88
|
+
│ └── default.tex_t # Custom figure captions
|
|
89
|
+
├── highlights/
|
|
90
|
+
│ └── default.tex_t # Custom highlights rendering
|
|
91
|
+
├── need/
|
|
92
|
+
│ └── default.tex_t # Custom sphinx-needs boxes
|
|
93
|
+
├── sidebar/
|
|
94
|
+
│ └── default.tex_t # Custom sidebar rendering
|
|
95
|
+
├── table/
|
|
96
|
+
│ └── default.tex_t # Custom table captions
|
|
97
|
+
└── title_page/
|
|
98
|
+
└── my_cover.tex_t # Custom title page layout
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### `pyproject.toml`
|
|
102
|
+
|
|
103
|
+
```toml
|
|
104
|
+
[build-system]
|
|
105
|
+
requires = ["setuptools>=61.0"]
|
|
106
|
+
build-backend = "setuptools.build_meta"
|
|
107
|
+
|
|
108
|
+
[project]
|
|
109
|
+
name = "my-company-theme"
|
|
110
|
+
version = "0.1.0"
|
|
111
|
+
description = "My company's PDF theme for Doxtr."
|
|
112
|
+
requires-python = ">=3.8"
|
|
113
|
+
dependencies = [
|
|
114
|
+
"doxtr-pdf-theme-core>=0.1.10",
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
[tool.setuptools.packages.find]
|
|
118
|
+
include = ["my_company_theme*"]
|
|
119
|
+
|
|
120
|
+
[tool.setuptools]
|
|
121
|
+
include-package-data = true
|
|
122
|
+
|
|
123
|
+
[tool.setuptools.package-data]
|
|
124
|
+
my_company_theme = [
|
|
125
|
+
"*.tex_t",
|
|
126
|
+
"latex_styles/**/*.tex_t",
|
|
127
|
+
"assets/*.png",
|
|
128
|
+
]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### The Simplest Theme (Palette + Fonts Only)
|
|
132
|
+
|
|
133
|
+
A 20-line theme that recolors the entire document:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
# my_company_theme/__init__.py
|
|
137
|
+
from doxtr_pdf_theme_core import setup as core_setup
|
|
138
|
+
|
|
139
|
+
__version__ = "0.1.0"
|
|
140
|
+
|
|
141
|
+
def setup(app):
|
|
142
|
+
# 1. Initialize the core engine first — this registers all config values
|
|
143
|
+
core_setup(app)
|
|
144
|
+
|
|
145
|
+
# 2. Set 6 semantic colors — the entire document derives from these
|
|
146
|
+
app.config.doxtr_semantic_palette = {
|
|
147
|
+
'primary': '#1B4F72', # Deep blue — headings, borders, table headers
|
|
148
|
+
'secondary': '#F39C12', # Gold — accents, highlights, decorative lines
|
|
149
|
+
'info': '#2E86C1', # Info blue — notes, specs
|
|
150
|
+
'success': '#28B463', # Green — tips, hints, decisions
|
|
151
|
+
'warning': '#E67E22', # Orange — warnings, caution
|
|
152
|
+
'danger': '#E74C3C', # Red — errors, danger
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# 3. Set fonts (must be installed on the build system)
|
|
156
|
+
app.config.doxtr_main_font = 'Noto Serif'
|
|
157
|
+
app.config.doxtr_sans_font = 'Noto Sans'
|
|
158
|
+
app.config.doxtr_mono_font = 'Noto Sans Mono'
|
|
159
|
+
|
|
160
|
+
# Return value is required by Sphinx
|
|
161
|
+
return {'version': __version__, 'parallel_read_safe': True}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This produces a fully styled PDF with blue headings, gold accent lines, blue table headers, automatic WCAG-compliant contrast on all text, and full inheritance down the heading hierarchy.
|
|
165
|
+
|
|
166
|
+
### Adding Element-Specific Overrides
|
|
167
|
+
|
|
168
|
+
For more control, set `doxtr_theme_defaults` — a dictionary that overrides specific elements. You only set the keys you want to change; everything else inherits from the core.
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
def setup(app):
|
|
172
|
+
core_setup(app)
|
|
173
|
+
|
|
174
|
+
app.config.doxtr_semantic_palette = { ... }
|
|
175
|
+
app.config.doxtr_main_font = 'Noto Serif'
|
|
176
|
+
app.config.doxtr_sans_font = 'Noto Sans'
|
|
177
|
+
app.config.doxtr_mono_font = 'Noto Sans Mono'
|
|
178
|
+
|
|
179
|
+
# 4. Set theme defaults — the "middle layer" between Core and User
|
|
180
|
+
app.config.doxtr_theme_defaults = {
|
|
181
|
+
# Dark blue title page
|
|
182
|
+
'title_page': {
|
|
183
|
+
'page_color': '#1B2631',
|
|
184
|
+
'title_font': 'Noto Sans',
|
|
185
|
+
'title_size': r'\fontsize{34pt}{40pt}\selectfont',
|
|
186
|
+
'title_color': '#FFFFFF',
|
|
187
|
+
'subtitle_color': '#F39C12',
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
# Alternating headings with decorative chapter line
|
|
191
|
+
'headings': {
|
|
192
|
+
'align': 'alternate',
|
|
193
|
+
'numbers_in_margin': True,
|
|
194
|
+
'chapter': {
|
|
195
|
+
'font': 'Noto Sans',
|
|
196
|
+
'color': '#1B4F72',
|
|
197
|
+
'number_line': True,
|
|
198
|
+
'line_color': '#F39C12',
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
# Custom admonition styling
|
|
203
|
+
'admonitions': {
|
|
204
|
+
'generic': {
|
|
205
|
+
'title_font': 'Noto Sans',
|
|
206
|
+
'title_background_color': '#1B4F72',
|
|
207
|
+
'title_icon_box_background_color': '#0E3352',
|
|
208
|
+
'content_background_color': '#EBF5FB',
|
|
209
|
+
},
|
|
210
|
+
'warning': {
|
|
211
|
+
'title_background_color': '#E67E22',
|
|
212
|
+
'content_background_color': '#FEF5E7',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
# Table styling
|
|
217
|
+
'tables': {
|
|
218
|
+
'generic': {
|
|
219
|
+
'header_background_color': '#1B4F72',
|
|
220
|
+
'header_font_color': '#FFFFFF',
|
|
221
|
+
'row_color_odd': '#EBF5FB',
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return {'version': __version__, 'parallel_read_safe': True}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Overriding Visual Templates (Advanced)
|
|
230
|
+
|
|
231
|
+
For advanced visual changes (e.g., redesigning how admonition boxes are drawn), provide custom `.tex_t` template files and register their path.
|
|
232
|
+
|
|
233
|
+
`doxtr_theme_style_paths` is a **list** of directories searched in order. Use it for broad overrides spanning multiple style types. The per-type single-path variables (`doxtr_<type>_style_path`) take precedence over `doxtr_theme_style_paths` for their specific type.
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
import os
|
|
237
|
+
from pathlib import Path
|
|
238
|
+
|
|
239
|
+
def setup(app):
|
|
240
|
+
core_setup(app)
|
|
241
|
+
|
|
242
|
+
# Tell the core where to find your .tex_t overrides
|
|
243
|
+
pkg_dir = Path(__file__).parent.resolve()
|
|
244
|
+
app.config.doxtr_theme_style_paths = [
|
|
245
|
+
str(pkg_dir / 'latex_styles'),
|
|
246
|
+
]
|
|
247
|
+
|
|
248
|
+
# Reference your custom style by name
|
|
249
|
+
app.config.doxtr_theme_defaults = {
|
|
250
|
+
'admonitions': {
|
|
251
|
+
'generic': {
|
|
252
|
+
'style': 'rounded', # loads admonition/rounded.tex_t
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
'containers': {
|
|
256
|
+
'default': {
|
|
257
|
+
'title_style': 'minimal', # loads container_title_style/minimal.tex_t
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return {'version': __version__, 'parallel_read_safe': True}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Template resolution order:**
|
|
266
|
+
1. Per-type custom path (`doxtr_<type>_style_path`)
|
|
267
|
+
2. User project's `latex_styles/<type>/` folder
|
|
268
|
+
3. Theme's `doxtr_theme_style_paths` list (searched in order)
|
|
269
|
+
4. Core's `latex_styles/<type>/`
|
|
270
|
+
5. Absolute fallback (hardcoded in `core_fallbacks.py`)
|
|
271
|
+
|
|
272
|
+
### Font Weight Mapping
|
|
273
|
+
|
|
274
|
+
If your chosen font has non-standard weight variants (e.g., "Light" as the regular weight), use the `_options` variables to prevent LaTeX "Font shape undefined" warnings:
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
app.config.doxtr_main_font = 'Roboto'
|
|
278
|
+
app.config.doxtr_main_font_options = (
|
|
279
|
+
'UprightFont={Roboto Light}, '
|
|
280
|
+
'BoldFont={Roboto Medium}, '
|
|
281
|
+
'ItalicFont={Roboto Light Italic}, '
|
|
282
|
+
'BoldItalicFont={Roboto Medium Italic}'
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
app.config.doxtr_sans_font = 'Source Sans Pro'
|
|
286
|
+
app.config.doxtr_sans_font_options = 'Scale=MatchLowercase'
|
|
287
|
+
|
|
288
|
+
app.config.doxtr_mono_font = 'JetBrains Mono'
|
|
289
|
+
app.config.doxtr_mono_font_options = 'Scale=MatchLowercase'
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Using the Semantic Color System
|
|
293
|
+
|
|
294
|
+
The `dd:` expression system lets you derive colors dynamically from the palette. All color fields in every config section accept `dd:` expressions.
|
|
295
|
+
|
|
296
|
+
```python
|
|
297
|
+
app.config.doxtr_theme_defaults = {
|
|
298
|
+
'headings': {
|
|
299
|
+
'chapter': {
|
|
300
|
+
'color': 'dd:primary', # Palette's primary color
|
|
301
|
+
'line_color': 'dd:secondary', # Palette's secondary
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
'admonitions': {
|
|
305
|
+
'generic': {
|
|
306
|
+
'title_background_color': 'dd:primary',
|
|
307
|
+
'content_background_color': 'dd:primary:lighten:85', # 85% lighter
|
|
308
|
+
'content_font_color': 'dd:primary:darken:30', # 30% darker
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
'tables': {
|
|
312
|
+
'generic': {
|
|
313
|
+
'header_background_color': 'dd:primary',
|
|
314
|
+
'header_font_color': 'dd:primary:contrast:fg:primary', # Auto WCAG contrast
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Available expressions:**
|
|
321
|
+
|
|
322
|
+
| Expression | Result |
|
|
323
|
+
|---|---|
|
|
324
|
+
| `dd:primary` | Palette color directly |
|
|
325
|
+
| `dd:page` | Page background color |
|
|
326
|
+
| `dd:primary:lighten:80` | 80% lighter |
|
|
327
|
+
| `dd:primary:darken:30` | 30% darker |
|
|
328
|
+
| `dd:primary:contrast:fg:primary` | Foreground adjusted for WCAG contrast |
|
|
329
|
+
| `dd:page:contrast:bg:primary` | Background adjusted for contrast |
|
|
330
|
+
| `dd:this:title_background_color` | Another key in the same merged section |
|
|
331
|
+
| `dd:theme:title_background_color` | Value from the theme's current section |
|
|
332
|
+
| `dd:core:title_background_color` | Value from the core's current section |
|
|
333
|
+
| `dd:#FFCC0025:lighten:80` | Inline hex literal with operation |
|
|
334
|
+
| `dd:admonitions.warning[theme]:title_background_color` | Explicit cross-section path |
|
|
335
|
+
|
|
336
|
+
**Shorthand collision:** `dd:warning:` is ambiguous — it could mean the palette key or the admonition type. Use `dd:admonitions.warning:title_background_color` for the admonition, or `dd:warning` alone for the palette.
|
|
337
|
+
|
|
338
|
+
**WCAG override suffix:**
|
|
339
|
+
|
|
340
|
+
```python
|
|
341
|
+
'color': 'dd:primary:contrast:fg:primary:aaa' # Force AAA (7:1)
|
|
342
|
+
'color': 'dd:primary:contrast:fg:primary:aa' # Force AA (4.5:1)
|
|
343
|
+
'color': 'dd:primary:contrast:fg:primary:7' # Explicit ratio
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Resolution rules:**
|
|
347
|
+
- Core configs cannot reference theme configs. Theme configs cannot reference user configs.
|
|
348
|
+
- Two-pass resolution: values are resolved before inheritance, then re-resolved after.
|
|
349
|
+
- Static hex values (no `dd:` prefix) pass through unchanged.
|
|
350
|
+
|
|
351
|
+
### Registering Custom AST Processors
|
|
352
|
+
|
|
353
|
+
Theme authors and downstream extensions can hook into the AST processing pipeline without monkey-patching, using `register_ast_processor()`. Registered processors run at priority 992, after all core processors.
|
|
354
|
+
|
|
355
|
+
```python
|
|
356
|
+
from doxtr_pdf_theme_core import register_ast_processor
|
|
357
|
+
from docutils import nodes
|
|
358
|
+
|
|
359
|
+
def my_processor(app, doctree, docname):
|
|
360
|
+
"""Called for every resolved doctree during a latex build."""
|
|
361
|
+
for node in doctree.traverse(nodes.paragraph):
|
|
362
|
+
# Custom processing here
|
|
363
|
+
pass
|
|
364
|
+
|
|
365
|
+
register_ast_processor(my_processor)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
The function signature must be `fn(app, doctree, docname) -> None`. Processors are called in registration order and errors are caught and logged as warnings without aborting the build.
|
|
369
|
+
|
|
370
|
+
### Install and Test
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
# Install in development mode
|
|
374
|
+
pip install -e /path/to/my_company_theme
|
|
375
|
+
|
|
376
|
+
# Add to your Sphinx conf.py
|
|
377
|
+
# extensions = ['my_company_theme']
|
|
378
|
+
|
|
379
|
+
# Build PDF
|
|
380
|
+
sphinx-build -b latex source/ build/latex/
|
|
381
|
+
cd build/latex && latexmk -pdf -lualatex *.tex
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Package and Distribute
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
# Build the wheel
|
|
388
|
+
python -m build
|
|
389
|
+
|
|
390
|
+
# Publish to PyPI (or private registry)
|
|
391
|
+
twine upload dist/*
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Architecture
|
|
397
|
+
|
|
398
|
+
### Three-Tier Merge
|
|
399
|
+
|
|
400
|
+
All configuration flows through a three-layer cascade:
|
|
401
|
+
|
|
402
|
+
```
|
|
403
|
+
┌─────────────────────────────────────────────────┐
|
|
404
|
+
│ User conf.py │ ← Highest priority
|
|
405
|
+
│ (doxtr_headings = {'chapter': {'color': ...}}) │
|
|
406
|
+
├─────────────────────────────────────────────────┤
|
|
407
|
+
│ Theme Defaults │ ← Middle layer
|
|
408
|
+
│ (app.config.doxtr_theme_defaults = {...}) │
|
|
409
|
+
├─────────────────────────────────────────────────┤
|
|
410
|
+
│ Core Defaults │ ← Lowest priority
|
|
411
|
+
│ (core_config.py CORE_CONFIG_MANIFEST) │
|
|
412
|
+
└─────────────────────────────────────────────────┘
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Each layer only specifies the keys it wants to override. The `deep_update()` function recursively merges nested dictionaries, so setting one key inside `headings.chapter` doesn't wipe out the other keys in that section.
|
|
416
|
+
|
|
417
|
+
### Semantic Color Palette
|
|
418
|
+
|
|
419
|
+
Control the entire document's look by setting 6 palette colors:
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
doxtr_semantic_palette = {
|
|
423
|
+
'primary': '#2E3959', # Structural — headings, borders
|
|
424
|
+
'secondary': '#A64985', # Accents — highlights
|
|
425
|
+
'info': '#9BE2F2', # Info — notes, specs
|
|
426
|
+
'success': '#66D98E', # Positive — hints, tips
|
|
427
|
+
'warning': '#EA9B62', # Caution — warnings
|
|
428
|
+
'danger': '#F2545B', # Danger — errors
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
All other colors derive from these via `dd:` expressions in the configuration.
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## Features & Customization
|
|
437
|
+
|
|
438
|
+
### Structural Layout Settings
|
|
439
|
+
|
|
440
|
+
By default, the theme pushes chapter and section numbers into the page margins and *alternates* their placement based on the page number.
|
|
441
|
+
|
|
442
|
+
```python
|
|
443
|
+
doxtr_headings = {
|
|
444
|
+
'align': 'alternate', # 'alternate', 'left', 'right', 'center'
|
|
445
|
+
'numbers_in_margin': True, # Push numbers into the margin
|
|
446
|
+
'margin_space': '1.5em', # Gap between number and title text
|
|
447
|
+
|
|
448
|
+
'chapter': {
|
|
449
|
+
'align': 'right', # Override just for chapters
|
|
450
|
+
'number_margin': True,
|
|
451
|
+
'number_line': True, # Decorative colored bar
|
|
452
|
+
'line_height': '10cm',
|
|
453
|
+
'line_color': '#FF0000',
|
|
454
|
+
'margin_space': '0.75em',
|
|
455
|
+
},
|
|
456
|
+
'section': {
|
|
457
|
+
'number_margin': False,
|
|
458
|
+
'number_line': False,
|
|
459
|
+
},
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Document Inheritance Hierarchy
|
|
464
|
+
|
|
465
|
+
Font, color, and size properties inherit top-down through the hierarchy (`part` → `chapter` → `section` → `subsection` → `subsubsection`):
|
|
466
|
+
|
|
467
|
+
```python
|
|
468
|
+
doxtr_inherit_all = True # Global kill-switch for inheritance
|
|
469
|
+
doxtr_inherit_font = True # Inherit font families downward
|
|
470
|
+
doxtr_inherit_color = True # Inherit hex colors downward
|
|
471
|
+
doxtr_inherit_size = False # Let KOMA handle font scaling by default
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Core Fonts
|
|
475
|
+
|
|
476
|
+
```python
|
|
477
|
+
doxtr_main_font = 'Spectral'
|
|
478
|
+
doxtr_main_font_options = 'BoldFont={Spectral SemiBold}, ItalicFont={Spectral Italic}, BoldItalicFont={Spectral SemiBold Italic}'
|
|
479
|
+
doxtr_sans_font = 'Montserrat'
|
|
480
|
+
doxtr_sans_font_options = '' # fontspec options for sans font
|
|
481
|
+
doxtr_mono_font = 'FiraCode Nerd Font'
|
|
482
|
+
doxtr_mono_font_options = 'Scale=MatchLowercase' # fontspec options for mono font
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Sizes & Spacing
|
|
486
|
+
|
|
487
|
+
Use Python raw strings for LaTeX commands:
|
|
488
|
+
|
|
489
|
+
```python
|
|
490
|
+
doxtr_headings = {
|
|
491
|
+
'chapter': {
|
|
492
|
+
'size': r'\fontsize{32pt}{36pt}\selectfont',
|
|
493
|
+
},
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
The `\fontsize{}{}\selectfont` command takes:
|
|
498
|
+
1. **Font size** (e.g., `32pt`) — character height
|
|
499
|
+
2. **Baselineskip** (e.g., `36pt`) — line-to-line distance
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## Configuration Reference
|
|
504
|
+
|
|
505
|
+
### Config Sections
|
|
506
|
+
|
|
507
|
+
Each section can be set via `doxtr_theme_defaults` (in a theme) or directly in `conf.py`:
|
|
508
|
+
|
|
509
|
+
| Section | `conf.py` variable | Controls |
|
|
510
|
+
|---|---|---|
|
|
511
|
+
| `title_page` | `doxtr_title_page` | Cover page colors, fonts, background image |
|
|
512
|
+
| `headings` | `doxtr_headings` | Chapter/section/subsection styling |
|
|
513
|
+
| `parts` | `doxtr_parts` | Part page styling and numbering |
|
|
514
|
+
| `epigraphs` | `doxtr_epigraphs` | Quote block styling |
|
|
515
|
+
| `draft` | `doxtr_draft` | Watermark text and styling |
|
|
516
|
+
| `microtype` | `doxtr_microtype` | Typographic refinement settings |
|
|
517
|
+
| `admonitions` | `doxtr_admonitions` | Note/warning/tip/etc. boxes |
|
|
518
|
+
| `tables` | `doxtr_tables` | Table header, row, and caption colors |
|
|
519
|
+
| `figures` | `doxtr_figures` | Figure caption styling |
|
|
520
|
+
| `code` | `doxtr_code` | Code block per-language styling |
|
|
521
|
+
| `containers` | `doxtr_containers` | Custom stylebox containers |
|
|
522
|
+
| `needs` | `doxtr_needs` | sphinx-needs box styling |
|
|
523
|
+
| `sidebar` | `doxtr_sidebar` | RST `.. sidebar::` directive styling |
|
|
524
|
+
| `highlights` | `doxtr_highlights` | RST `.. highlights::` directive styling |
|
|
525
|
+
| `toc` | `doxtr_toc` | Table of Contents entry styling |
|
|
526
|
+
| `bibliography` | `doxtr_bibliography` | Bibliography/citation entry styling |
|
|
527
|
+
| `index` | `doxtr_index` | Back-of-book index styling |
|
|
528
|
+
| `glossary` | `doxtr_glossary` | Glossary term/definition styling |
|
|
529
|
+
|
|
530
|
+
### Global Variables
|
|
531
|
+
|
|
532
|
+
| Variable | Default | Purpose |
|
|
533
|
+
|---|---|---|
|
|
534
|
+
| `doxtr_main_font` | `'Spectral'` | Body text font |
|
|
535
|
+
| `doxtr_main_font_options` | `''` | fontspec options for main font weight mapping |
|
|
536
|
+
| `doxtr_sans_font` | `'Montserrat'` | Sans-serif font |
|
|
537
|
+
| `doxtr_sans_font_options` | `''` | fontspec options for sans font (e.g. `Scale=MatchLowercase`) |
|
|
538
|
+
| `doxtr_mono_font` | `'FiraCode Nerd Font'` | Monospace font |
|
|
539
|
+
| `doxtr_mono_font_options` | `'Scale=MatchLowercase'` | fontspec options for mono font |
|
|
540
|
+
| `doxtr_semantic_palette` | *(6 colors)* | Semantic color palette |
|
|
541
|
+
| `doxtr_page_background` | `'#FFFFFF'` | Page background used in contrast calculations |
|
|
542
|
+
| `doxtr_wcag_level` | `7` | Minimum contrast ratio for `contrast:` ops (4.5=AA, 7=AAA) |
|
|
543
|
+
| `doxtr_wcag_color_debug` | `False` | Log every WCAG contrast adjustment during build |
|
|
544
|
+
| `doxtr_inherit_all` | `True` | Master switch for style inheritance |
|
|
545
|
+
| `doxtr_inherit_font` | `True` | Inherit fonts down the heading hierarchy |
|
|
546
|
+
| `doxtr_inherit_color` | `True` | Inherit colors down the heading hierarchy |
|
|
547
|
+
| `doxtr_inherit_size` | `False` | Inherit sizes down the heading hierarchy |
|
|
548
|
+
| `doxtr_show_release` | `True` | Show release version on the title page |
|
|
549
|
+
| `doxtr_show_list_of_figures` | `True` | Print List of Figures before Index |
|
|
550
|
+
| `doxtr_show_list_of_tables` | `True` | Print List of Tables before Index |
|
|
551
|
+
| `doxtr_show_list_of_listings` | `True` | Print List of Code Blocks before Index |
|
|
552
|
+
| `doxtr_appendix_chapter_numbering` | `True` | Number appendix chapters as A.1, A.2, etc. |
|
|
553
|
+
| `doxtr_headsep` | `'8mm'` | Space between header and text body |
|
|
554
|
+
| `doxtr_footskip` | `'10mm'` | Space between text body and footer |
|
|
555
|
+
| `doxtr_headheight` | `'18pt'` | Height of the header line |
|
|
556
|
+
| `doxtr_footheight` | `'25pt'` | Height of the footer |
|
|
557
|
+
| `doxtr_footer_logo` | *(doxtr icon)* | Path to footer logo image |
|
|
558
|
+
| `doxtr_footer_logo_height` | `'1.5em'` | Height of the footer logo |
|
|
559
|
+
| `doxtr_landscape_package` | `'pdflscape'` | Package for landscape pages: `'pdflscape'`, `'lscape'`, or `''` to disable |
|
|
560
|
+
| `doxtr_strict_mode` | `False` | Raise an error on missing templates instead of falling back |
|
|
561
|
+
| `doxtr_cache_templates` | `True` | Cache compiled Jinja2 templates across pages |
|
|
562
|
+
|
|
563
|
+
### Custom Resolution Paths (for Theme Authors)
|
|
564
|
+
|
|
565
|
+
`doxtr_theme_style_paths` is a **list** of directories searched for all style types. The per-type variables are single **strings** pointing to a specific folder and take precedence over `doxtr_theme_style_paths` for their type.
|
|
566
|
+
|
|
567
|
+
| Variable | Type | Purpose |
|
|
568
|
+
|---|---|---|
|
|
569
|
+
| `doxtr_theme_style_paths` | list | Ordered list of directories to search for any `.tex_t` file |
|
|
570
|
+
| `doxtr_container_title_style_path` | string | Container title `.tex_t` files |
|
|
571
|
+
| `doxtr_container_style_path` | string | Container body `.tex_t` files |
|
|
572
|
+
| `doxtr_table_style_path` | string | Table `.tex_t` files |
|
|
573
|
+
| `doxtr_figure_style_path` | string | Figure `.tex_t` files |
|
|
574
|
+
| `doxtr_code_style_path` | string | Code block `.tex_t` files |
|
|
575
|
+
| `doxtr_admonition_style_path` | string | Admonition `.tex_t` files |
|
|
576
|
+
| `doxtr_need_style_path` | string | sphinx-needs `.tex_t` files |
|
|
577
|
+
| `doxtr_sidebar_style_path` | string | Sidebar `.tex_t` files |
|
|
578
|
+
| `doxtr_title_page_template_path` | string | Title page `.tex_t` files |
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
### `doxtr_title_page`
|
|
583
|
+
|
|
584
|
+
```python
|
|
585
|
+
doxtr_title_page = {
|
|
586
|
+
'template': 'default', # Name of the .tex_t file to load for the cover
|
|
587
|
+
'page_color': '#183060', # Solid background color
|
|
588
|
+
'background_image': 'bg.png', # Path to background image (added to latex_additional_files)
|
|
589
|
+
'background_image_mode': 'fit', # 'fit', 'stretch', or 'tile'
|
|
590
|
+
'background_image_align': 'center', # 'center', 'top', 'bottom', 'left', 'right'
|
|
591
|
+
'color_opacity': '0.5', # Opacity of the page_color overlay (0.0–1.0 as string)
|
|
592
|
+
'top_line': False, # Render Sphinx's default top black line
|
|
593
|
+
'subtitle': 'My Subtitle', # Custom subtitle text
|
|
594
|
+
|
|
595
|
+
# Font styling per element (title, subtitle, author, date, release_version):
|
|
596
|
+
'title_font': 'Rye',
|
|
597
|
+
'title_size': r'\fontsize{38pt}{44pt}\selectfont',
|
|
598
|
+
'title_color': '#F0D890',
|
|
599
|
+
'subtitle_font': 'Comfortaa',
|
|
600
|
+
'subtitle_size': r'\fontsize{16pt}{20pt}\selectfont',
|
|
601
|
+
'subtitle_color': '#78D8F0',
|
|
602
|
+
'author_font': 'Josefin Sans',
|
|
603
|
+
'author_size': r'\fontsize{14pt}{18pt}\selectfont',
|
|
604
|
+
'author_color': '#90F0F0',
|
|
605
|
+
'date_font': 'Montserrat',
|
|
606
|
+
'date_size': r'\fontsize{11pt}{14pt}\selectfont',
|
|
607
|
+
'date_color': '#F0D890',
|
|
608
|
+
'release_version_font': 'Comfortaa',
|
|
609
|
+
'release_version_size': r'\fontsize{11pt}{14pt}\selectfont',
|
|
610
|
+
'release_version_color': '#F0C078',
|
|
611
|
+
}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
`background_image_mode` controls how the image fills the page:
|
|
615
|
+
- `'fit'` — scale to fit while preserving aspect ratio
|
|
616
|
+
- `'stretch'` — scale to fill the entire page, ignoring aspect ratio
|
|
617
|
+
- `'tile'` — tile the image across the page
|
|
618
|
+
|
|
619
|
+
### `doxtr_headings`
|
|
620
|
+
|
|
621
|
+
```python
|
|
622
|
+
doxtr_headings = {
|
|
623
|
+
# Global defaults applied to all levels unless overridden per-level:
|
|
624
|
+
'align': 'alternate', # 'alternate', 'left', 'right', 'center'
|
|
625
|
+
'numbers_in_margin': True, # Push numbers into the page margin
|
|
626
|
+
'margin_space': '0em', # Gap between number and title text
|
|
627
|
+
|
|
628
|
+
# Per-level overrides — all keys below are accepted by every level:
|
|
629
|
+
'part': {
|
|
630
|
+
'font': 'Cinzel',
|
|
631
|
+
'size': r'\fontsize{42pt}{48pt}\selectfont',
|
|
632
|
+
'color': '#FFFFFF',
|
|
633
|
+
'align': 'center',
|
|
634
|
+
'number_line': False, # Decorative colored structural bar
|
|
635
|
+
'line_height': '10cm', # Length of the structural line
|
|
636
|
+
'line_color': '#78D8F0',
|
|
637
|
+
'margin_space': '0.75em',
|
|
638
|
+
'number_font': 'Kranky',
|
|
639
|
+
'number_size': r'\fontsize{32pt}{38pt}\selectfont',
|
|
640
|
+
'number_color': '#184878',
|
|
641
|
+
'background_color': '#183060', # Part page background color
|
|
642
|
+
'epigraph_color': '#D8F0F0', # Epigraph text color on part pages
|
|
643
|
+
'epigraph_author_color': '#F0C078', # Epigraph attribution color on part pages
|
|
644
|
+
},
|
|
645
|
+
'chapter': {
|
|
646
|
+
'font': 'Story Script',
|
|
647
|
+
'size': r'\fontsize{26pt}{32pt}\selectfont',
|
|
648
|
+
'color': '#183060',
|
|
649
|
+
'number_margin': True, # Push chapter number into margin
|
|
650
|
+
'number_line': True,
|
|
651
|
+
'line_height': '7cm',
|
|
652
|
+
'line_color': '#78D8F0',
|
|
653
|
+
'margin_space': '0.75em',
|
|
654
|
+
'number_font': 'Kranky',
|
|
655
|
+
'number_size': r'\fontsize{32pt}{38pt}\selectfont',
|
|
656
|
+
'number_color': '#184878',
|
|
657
|
+
},
|
|
658
|
+
# 'section': { ... }, # Same keys as chapter, number_line defaults to False
|
|
659
|
+
# 'subsection': { ... },
|
|
660
|
+
# 'subsubsection': { ... },
|
|
661
|
+
}
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
### `doxtr_parts`
|
|
665
|
+
|
|
666
|
+
Parts are numbered pages that divide the book into major sections. Global keys set defaults for all parts; integer keys override individual parts by number.
|
|
667
|
+
|
|
668
|
+
```python
|
|
669
|
+
doxtr_parts = {
|
|
670
|
+
# Global defaults for all part pages:
|
|
671
|
+
'font': 'Cinzel',
|
|
672
|
+
'size': r'\fontsize{48pt}{54pt}\selectfont',
|
|
673
|
+
'color': '#FFFFFF',
|
|
674
|
+
'part_number_font': 'Comfortaa', # Font for the "Part" prefix label
|
|
675
|
+
'part_number_size': r'\fontsize{24pt}{28pt}\selectfont',
|
|
676
|
+
'part_number_color': '#78D8F0',
|
|
677
|
+
'part_number_part_font': 'Comfortaa', # Font for the word "Part"
|
|
678
|
+
'part_number_part_size': r'\fontsize{18pt}{22pt}\selectfont',
|
|
679
|
+
'part_number_part_color': '#78D8F0',
|
|
680
|
+
'part_number_number_font': 'Cinzel', # Font for the numeral itself
|
|
681
|
+
'part_number_number_size': r'\fontsize{36pt}{42pt}\selectfont',
|
|
682
|
+
'part_number_number_color': '#F0D890',
|
|
683
|
+
|
|
684
|
+
# Per-part overrides (integer key = part number):
|
|
685
|
+
1: {
|
|
686
|
+
'appendix': True, # Switch to letter numbering from this part
|
|
687
|
+
'image': 'wizard-of-docs.png', # Full-page background image
|
|
688
|
+
'background_color': '#00000088', # 8-digit hex: last 2 digits = opacity
|
|
689
|
+
'epigraph_color': '#FFF',
|
|
690
|
+
'epigraph_author_color': '#CCC',
|
|
691
|
+
'font': 'Cinzel',
|
|
692
|
+
'color': '#FFFFFF',
|
|
693
|
+
'size': r'\fontsize{48pt}{54pt}\selectfont',
|
|
694
|
+
'number_font': 'Comfortaa',
|
|
695
|
+
'number_color': '#78D8F0',
|
|
696
|
+
'number_part_font': 'Comfortaa',
|
|
697
|
+
'number_part_color': '#78D8F0',
|
|
698
|
+
'number_number_font': 'Cinzel',
|
|
699
|
+
'number_number_color': '#F0D890',
|
|
700
|
+
},
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### `doxtr_epigraphs`
|
|
705
|
+
|
|
706
|
+
```python
|
|
707
|
+
doxtr_epigraphs = {
|
|
708
|
+
'width': r'0.55\textwidth',
|
|
709
|
+
'format': '— #1', # #1 is replaced by the attribution text
|
|
710
|
+
'align_box': 'right', # 'left', 'center', 'right'
|
|
711
|
+
'align_text': 'left',
|
|
712
|
+
'align_author': 'right',
|
|
713
|
+
'font': 'Cormorant Garamond',
|
|
714
|
+
'size': r'\itshape\large',
|
|
715
|
+
'color': '#303048',
|
|
716
|
+
'author_font': 'Merienda',
|
|
717
|
+
'author_size': r'\small',
|
|
718
|
+
'author_color': '#184878',
|
|
719
|
+
|
|
720
|
+
# Per-level overrides (inherit from global when not set):
|
|
721
|
+
# 'part': { 'width': r'0.6\textwidth', 'color': '#FFFFFF', ... },
|
|
722
|
+
# 'chapter': { ... },
|
|
723
|
+
# 'section': { ... },
|
|
724
|
+
# 'subsection': { ... },
|
|
725
|
+
# 'subsubsection': { ... },
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
### `doxtr_draft`
|
|
730
|
+
|
|
731
|
+
The watermark is **activated by setting `'text'`**. Without it, no watermark is rendered.
|
|
732
|
+
|
|
733
|
+
```python
|
|
734
|
+
doxtr_draft = {
|
|
735
|
+
'text': 'DRAFT - {date} - V: {project_version}', # Activates the watermark
|
|
736
|
+
# Placeholders: {date}, {project_version}, {ext_version}
|
|
737
|
+
'date_format': '%Y-%m-%d %H:%M:%S %Z',
|
|
738
|
+
'timezone': 'local', # 'local', 'UTC', or any IANA zone e.g. 'Europe/Berlin'
|
|
739
|
+
'color': '#00000044', # 8-digit hex — last 2 digits control opacity
|
|
740
|
+
'font_size': r'\normalsize',
|
|
741
|
+
'font': 'Offside',
|
|
742
|
+
}
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
Watermark is automatically disabled when `microtype` is active (draft mode implies fast iteration; microtype is for final output). Microtype is re-enabled when `'text'` is removed.
|
|
746
|
+
|
|
747
|
+
### `doxtr_microtype`
|
|
748
|
+
|
|
749
|
+
Microtype is active by default when no draft watermark is set.
|
|
750
|
+
|
|
751
|
+
```python
|
|
752
|
+
doxtr_microtype = {
|
|
753
|
+
'enabled': True, # Master switch (also disabled automatically in draft mode)
|
|
754
|
+
'protrusion': True, # Hanging punctuation — characters protrude slightly into margin
|
|
755
|
+
'expansion': True, # Font expansion — eliminates uneven word spacing
|
|
756
|
+
'kerning': False, # Fine character-pair kerning (requires microtype >= 2.6a for LuaTeX)
|
|
757
|
+
'stretch': 10, # Maximum stretch percentage
|
|
758
|
+
'shrink': 10, # Maximum shrink percentage
|
|
759
|
+
}
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
---
|
|
763
|
+
|
|
764
|
+
### `doxtr_admonitions`
|
|
765
|
+
|
|
766
|
+
All admonition types inherit from `'generic'`. Override only the keys you want to change for a specific type.
|
|
767
|
+
|
|
768
|
+
**Built-in types:** `generic`, `note`, `tip`, `hint`, `important`, `warning`, `caution`, `danger`, `error`, `attention`, `seealso`
|
|
769
|
+
|
|
770
|
+
```python
|
|
771
|
+
doxtr_admonitions = {
|
|
772
|
+
'generic': {
|
|
773
|
+
'style': 'default', # Name of the .tex_t template to use
|
|
774
|
+
'title_icon': r'\faIcon{info-circle}', # LaTeX command or image path
|
|
775
|
+
'title_icon_color': '#FFFFFF',
|
|
776
|
+
'title_icon_size': '', # LaTeX size command (empty = inherit)
|
|
777
|
+
'title_icon_padding': '3ex',
|
|
778
|
+
'title_decoration_spacing': '2mm',
|
|
779
|
+
'title_font': 'Montserrat',
|
|
780
|
+
'title_font_size': r'\large\bfseries',
|
|
781
|
+
'title_font_color': '#FFFFFF',
|
|
782
|
+
'title_background_color': '#184878',
|
|
783
|
+
'title_icon_box_background_color': '#183060',
|
|
784
|
+
'content_font': 'Spectral',
|
|
785
|
+
'content_font_size': r'\normalsize',
|
|
786
|
+
'content_font_color': '#1A1A2E',
|
|
787
|
+
'content_background_color': '#F0F8FF',
|
|
788
|
+
'content_background_color_nested': '#FFFFFF', # Background when admonition is nested
|
|
789
|
+
'before_skip': '2em plus 0.5em minus 0.5em',
|
|
790
|
+
'after_skip': '1.5em plus 0.5em minus 0.5em',
|
|
791
|
+
},
|
|
792
|
+
# Per-type overrides (merge on top of generic):
|
|
793
|
+
'note': {
|
|
794
|
+
'title_icon': r'\faIcon{bookmark}',
|
|
795
|
+
'title_background_color': '#2060A0',
|
|
796
|
+
'title_icon_box_background_color': '#184878',
|
|
797
|
+
'content_background_color': '#EEF5FC',
|
|
798
|
+
},
|
|
799
|
+
'warning': {
|
|
800
|
+
'title_icon': r'\faIcon{exclamation-triangle}',
|
|
801
|
+
'title_background_color': '#D48030',
|
|
802
|
+
'content_background_color': '#FFF8F0',
|
|
803
|
+
},
|
|
804
|
+
# 'tip', 'hint', 'important', 'caution', 'danger', 'error', 'attention', 'seealso'
|
|
805
|
+
# all accept the same keys as 'generic'
|
|
806
|
+
}
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
If `title_icon` is a file path (not a LaTeX command starting with `\`), it is automatically included as `\includegraphics[height=1em, keepaspectratio]{file}`.
|
|
810
|
+
|
|
811
|
+
### `doxtr_needs`
|
|
812
|
+
|
|
813
|
+
Controls [sphinx-needs](https://sphinx-needs.readthedocs.io/) box styling. Types beyond `generic` are auto-detected from `needs_types` in your `conf.py`.
|
|
814
|
+
|
|
815
|
+
**Built-in type overrides:** `generic`, `req`, `spec`, `decision`, `risk`
|
|
816
|
+
|
|
817
|
+
```python
|
|
818
|
+
doxtr_needs = {
|
|
819
|
+
'generic': {
|
|
820
|
+
'style': 'default',
|
|
821
|
+
'title_font': 'Montserrat',
|
|
822
|
+
'title_font_size': r'\large\bfseries',
|
|
823
|
+
'title_color': '#FFFFFF',
|
|
824
|
+
'title_background_color': '#184878',
|
|
825
|
+
'title_icon': r'\faIcon{clipboard-check}',
|
|
826
|
+
'title_icon_color': '#FFFFFF',
|
|
827
|
+
'title_icon_size': '',
|
|
828
|
+
'title_icon_raise': '0pt', # Manual vertical adjustment for icon
|
|
829
|
+
'title_icon_raise_offset': '0pt', # Additional offset added to raise
|
|
830
|
+
'title_vertical_position': 'middle', # 'top', 'middle', 'bottom', or manual
|
|
831
|
+
'segmentation_style': 'solid', # 'solid', 'dashed', 'dotted', 'dashdotted', 'none'
|
|
832
|
+
'segmentation_color': '#184878',
|
|
833
|
+
'metadata_background_color': '#E8F4FC',
|
|
834
|
+
'metadata_font': 'Montserrat',
|
|
835
|
+
'metadata_font_size': r'\small',
|
|
836
|
+
'metadata_font_color': '#183060',
|
|
837
|
+
'metadata_key_font': 'Montserrat',
|
|
838
|
+
'metadata_key_font_size': r'\bfseries',
|
|
839
|
+
'metadata_key_color': '#183060',
|
|
840
|
+
'content_background_color': '#FFFFFF',
|
|
841
|
+
'content_font': 'Spectral',
|
|
842
|
+
'content_font_size': r'\normalsize',
|
|
843
|
+
'content_font_color': '#1A1A2E',
|
|
844
|
+
'before_skip': '1.5em plus 0.5em minus 0.5em',
|
|
845
|
+
'after_skip': '1.5em plus 0.5em minus 0.5em',
|
|
846
|
+
},
|
|
847
|
+
# Per-type overrides:
|
|
848
|
+
'req': {
|
|
849
|
+
'title_background_color': 'dd:secondary',
|
|
850
|
+
'segmentation_color': 'dd:secondary',
|
|
851
|
+
'metadata_background_color': 'dd:secondary:lighten:85',
|
|
852
|
+
},
|
|
853
|
+
# 'spec', 'decision', 'risk' follow the same pattern
|
|
854
|
+
}
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
`title_vertical_position` values:
|
|
858
|
+
- `'middle'` — vertically centered (uses `\dimexpr 0.5\fontcharht...`)
|
|
859
|
+
- `'top'` — aligned to cap height
|
|
860
|
+
- `'bottom'` — baseline aligned
|
|
861
|
+
- Any other string — treated as a raw LaTeX raise dimension
|
|
862
|
+
|
|
863
|
+
### `doxtr_tables`
|
|
864
|
+
|
|
865
|
+
```python
|
|
866
|
+
doxtr_tables = {
|
|
867
|
+
'generic': {
|
|
868
|
+
'style': 'default',
|
|
869
|
+
'title_style': 'classic',
|
|
870
|
+
'caption_position': 'side', # 'side', 'top', or 'bottom'
|
|
871
|
+
'caption_top_offset': '-0.5ex',
|
|
872
|
+
'title_padding': '1.5ex',
|
|
873
|
+
'title_text_offset': '0pt', # Horizontal offset of caption text
|
|
874
|
+
'title_fade_dots': False, # Fade dot leaders in caption
|
|
875
|
+
'title_background_fade_mask_color': '#FFFFFF',
|
|
876
|
+
'title_background_fade_length': '1.5ex',
|
|
877
|
+
'title_background_fade_shape': 'rectangle', # 'rectangle' or 'triangle'
|
|
878
|
+
'header_background_color': '#183060',
|
|
879
|
+
'header_font_color': '#FFFFFF',
|
|
880
|
+
'header_font': 'Montserrat',
|
|
881
|
+
'header_font_size': r'\bfseries',
|
|
882
|
+
'row_color_odd': '#F8FAFF',
|
|
883
|
+
'row_color_even': '#FFFFFF',
|
|
884
|
+
'title_background_color': '#184878',
|
|
885
|
+
'title_font_color': '#FFFFFF',
|
|
886
|
+
'title_font': 'Montserrat',
|
|
887
|
+
'title_font_size': r'\bfseries',
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
### `doxtr_figures`
|
|
893
|
+
|
|
894
|
+
```python
|
|
895
|
+
doxtr_figures = {
|
|
896
|
+
'generic': {
|
|
897
|
+
'style': 'default',
|
|
898
|
+
'caption_background_color': '#F0F8FF',
|
|
899
|
+
'caption_font_color': '#183060',
|
|
900
|
+
'caption_font': 'Montserrat',
|
|
901
|
+
'caption_font_size': r'\small\sffamily\bfseries',
|
|
902
|
+
'caption_padding': '1.5ex',
|
|
903
|
+
'caption_align': 'center', # 'left', 'center', 'right'
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
---
|
|
909
|
+
|
|
910
|
+
### `doxtr_code`
|
|
911
|
+
|
|
912
|
+
Code blocks are styled per language. All language entries inherit from `'generic'` for any key not explicitly set.
|
|
913
|
+
|
|
914
|
+
**Built-in language overrides:** `python`, `java`, `kotlin`, `rust`, `c`, `cpp`, `csharp`, `go`, `rst`, `sh`, `bash`, `zsh`, `powershell`, `markdown`, `html`, `css`, `javascript`, `typescript`, `text`, `json`, `yaml`, `sql`, `xml`, `latex`, `dockerfile`, `toml`, `ini`, `ruby`, `php`, `lua`, `swift`, `make`
|
|
915
|
+
|
|
916
|
+
```python
|
|
917
|
+
doxtr_code = {
|
|
918
|
+
'generic': {
|
|
919
|
+
'style': 'default',
|
|
920
|
+
'border_width': '0.8pt',
|
|
921
|
+
'show_mac_dots': False, # Red/yellow/green terminal dots (auto-enabled for shell languages)
|
|
922
|
+
'language_label': '', # Override the auto-detected language name in the title bar
|
|
923
|
+
'icon': r'\faIcon{code}', # LaTeX command or image path
|
|
924
|
+
'icon_color': '#78D8F0',
|
|
925
|
+
'icon_size': '', # LaTeX size command (empty = inherit)
|
|
926
|
+
'icon_position': 'after_mac_dots', # 'before_mac_dots' or 'after_mac_dots'
|
|
927
|
+
'title_background_color': '#183060',
|
|
928
|
+
'title_font_color': '#78D8F0',
|
|
929
|
+
'title_font': 'Montserrat',
|
|
930
|
+
'title_font_size': r'\small\sffamily\bfseries',
|
|
931
|
+
'content_background_color': '#F8FAFF',
|
|
932
|
+
'content_font_color': '#1A1A2E',
|
|
933
|
+
'content_font': 'FiraCode Nerd Font', # Per-language monospace font override
|
|
934
|
+
'content_font_size': r'\small',
|
|
935
|
+
'border_color': '#78D8F0',
|
|
936
|
+
},
|
|
937
|
+
# Per-language overrides (any key from generic is accepted):
|
|
938
|
+
'python': {
|
|
939
|
+
'icon': r'\faIcon{python}',
|
|
940
|
+
'title_background_color': '#306998',
|
|
941
|
+
'title_font_color': '#FFD43B',
|
|
942
|
+
'icon_color': '#FFD43B',
|
|
943
|
+
'border_color': '#306998',
|
|
944
|
+
},
|
|
945
|
+
# Add your own language override:
|
|
946
|
+
# 'mylang': {
|
|
947
|
+
# 'title_background_color': '#123456',
|
|
948
|
+
# 'title_font_color': '#FFFFFF',
|
|
949
|
+
# 'icon': r'\faIcon{file-code}',
|
|
950
|
+
# 'language_label': 'My Language',
|
|
951
|
+
# },
|
|
952
|
+
}
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
Terminal/shell languages (`sh`, `bash`, `zsh`, `powershell`) have `show_mac_dots: True` by default. For all others it defaults to `False`.
|
|
956
|
+
|
|
957
|
+
If `icon` is a file path (not a LaTeX command), it is included as `\includegraphics[height=1em, keepaspectratio]{file}`.
|
|
958
|
+
|
|
959
|
+
### `doxtr_containers`
|
|
960
|
+
|
|
961
|
+
Containers are custom styled boxes created with the `.. stylebox::` RST directive. The core ships several built-in containers that you can use directly or use as examples for your own.
|
|
962
|
+
|
|
963
|
+
**Built-in container types:** `default`, `typewriter`, `highlight-section`, `alice`, `bob`, `folder`
|
|
964
|
+
|
|
965
|
+
#### RST Usage
|
|
966
|
+
|
|
967
|
+
```rst
|
|
968
|
+
.. stylebox:: my_container
|
|
969
|
+
:title: My Title
|
|
970
|
+
|
|
971
|
+
Content goes here.
|
|
972
|
+
|
|
973
|
+
.. stylebox:: my_container
|
|
974
|
+
:notitle:
|
|
975
|
+
|
|
976
|
+
No title shown (suppresses even a static title configured in the theme).
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
Options for the `.. stylebox::` directive:
|
|
980
|
+
|
|
981
|
+
| Option | Purpose |
|
|
982
|
+
|---|---|
|
|
983
|
+
| *(first argument)* | Container type name — must match a key in `doxtr_containers` |
|
|
984
|
+
| `:title: Text` | Override the title for this instance |
|
|
985
|
+
| `:notitle:` | Suppress all title sources, including a static `title` from config |
|
|
986
|
+
| `:name: anchor` | RST cross-reference anchor |
|
|
987
|
+
| `:class: css-class` | Additional docutils class |
|
|
988
|
+
|
|
989
|
+
#### Container Configuration
|
|
990
|
+
|
|
991
|
+
```python
|
|
992
|
+
doxtr_containers = {
|
|
993
|
+
'my_container': {
|
|
994
|
+
'style': 'default', # Body .tex_t template name
|
|
995
|
+
'title_style': 'classic', # Title geometry .tex_t template name
|
|
996
|
+
'title': '', # Static title shown when no :title: in RST (empty = no title)
|
|
997
|
+
'title_raw': False, # Pass title as raw LaTeX without escaping
|
|
998
|
+
'container_frame': True, # Draw an outer border
|
|
999
|
+
'match_text_width': False, # Align box width to body text column
|
|
1000
|
+
'title_icon': r'\faIcon{info}',
|
|
1001
|
+
'title_font': 'Montserrat',
|
|
1002
|
+
'title_font_size': r'\large\bfseries',
|
|
1003
|
+
'title_color': '#1E3A8A', # Title bar background color
|
|
1004
|
+
'title_font_color': '#FFFFFF',
|
|
1005
|
+
'title_icon_color': '#FFFFFF',
|
|
1006
|
+
'title_icon_font_size': '',
|
|
1007
|
+
'content_font': 'Spectral',
|
|
1008
|
+
'content_font_size': r'\normalsize',
|
|
1009
|
+
'content_font_color': '#000000',
|
|
1010
|
+
'content_background_color': '#F8FAFC',
|
|
1011
|
+
'before_skip': '2em plus 0.5em minus 0.5em',
|
|
1012
|
+
'after_skip': '1.5em plus 0.5em minus 0.5em',
|
|
1013
|
+
},
|
|
1014
|
+
|
|
1015
|
+
# Folder style adds shadow and tab title:
|
|
1016
|
+
'folder': {
|
|
1017
|
+
'style': 'folder',
|
|
1018
|
+
'title': 'Background Information',
|
|
1019
|
+
'title_color': '#808080', # Frame/border color
|
|
1020
|
+
'title_font_color': '#000000',
|
|
1021
|
+
'title_background_color': '#FFFFFF', # Tab background
|
|
1022
|
+
'content_background_color': '#FFFFFF',
|
|
1023
|
+
'border_width': '0.4pt',
|
|
1024
|
+
'show_shadow': True,
|
|
1025
|
+
'shadow_color': '#C0C0C0',
|
|
1026
|
+
},
|
|
1027
|
+
|
|
1028
|
+
# Participant style (alice/bob) adds a floating name badge:
|
|
1029
|
+
'alice': {
|
|
1030
|
+
'style': 'participant',
|
|
1031
|
+
'title': 'Alice',
|
|
1032
|
+
'frame_width': '0.2mm', # Border thickness
|
|
1033
|
+
'frame_arc': '0mm', # Corner radius (0mm = sharp)
|
|
1034
|
+
'title_position': 'left', # Badge position: 'left', 'center', 'right', or LaTeX dim
|
|
1035
|
+
'title_xshift': '1cm', # Additional horizontal offset
|
|
1036
|
+
'title_max_width': '-3cm', # varwidth constraint for title pill
|
|
1037
|
+
},
|
|
1038
|
+
}
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
### `doxtr_sidebar`
|
|
1042
|
+
|
|
1043
|
+
Controls the RST `.. sidebar::` directive. Sidebars float alongside the main text using `wrapfig`.
|
|
1044
|
+
|
|
1045
|
+
```rst
|
|
1046
|
+
.. sidebar:: My Sidebar Title
|
|
1047
|
+
:subtitle: Optional Subtitle
|
|
1048
|
+
|
|
1049
|
+
Sidebar content here.
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
```python
|
|
1053
|
+
doxtr_sidebar = {
|
|
1054
|
+
'style': 'default',
|
|
1055
|
+
'width': r'0.4\textwidth',
|
|
1056
|
+
'float_position': 'R', # 'R'=right exact, 'L'=left exact, 'O'=outer, 'I'=inner
|
|
1057
|
+
# Lowercase (r/l/o/i) allows LaTeX to reposition
|
|
1058
|
+
'border_radius': '4pt',
|
|
1059
|
+
'border_width': '0.8pt',
|
|
1060
|
+
'border_color': '#184878',
|
|
1061
|
+
'title_icon': r'\faIcon{columns}',
|
|
1062
|
+
'title_font': 'Montserrat',
|
|
1063
|
+
'title_font_size': r'\large\bfseries',
|
|
1064
|
+
'title_background_color': '#184878',
|
|
1065
|
+
'title_font_color': '#FFFFFF',
|
|
1066
|
+
'title_icon_color': '#78D8F0',
|
|
1067
|
+
'subtitle_font': 'Montserrat',
|
|
1068
|
+
'subtitle_font_size': r'\small\itshape',
|
|
1069
|
+
'subtitle_font_color': '#306090',
|
|
1070
|
+
'content_font': 'Spectral',
|
|
1071
|
+
'content_font_size': r'\small',
|
|
1072
|
+
'content_font_color': '#1A1A2E',
|
|
1073
|
+
'content_background_color': '#F0F8FF',
|
|
1074
|
+
'before_skip': '1.5em plus 0.5em minus 0.5em',
|
|
1075
|
+
'after_skip': '1.5em plus 0.5em minus 0.5em',
|
|
1076
|
+
}
|
|
1077
|
+
```
|
|
1078
|
+
|
|
1079
|
+
### `doxtr_highlights`
|
|
1080
|
+
|
|
1081
|
+
Controls the RST `.. highlights::` directive, rendered as an accent-bordered summary box.
|
|
1082
|
+
|
|
1083
|
+
```rst
|
|
1084
|
+
.. highlights::
|
|
1085
|
+
|
|
1086
|
+
Key takeaway content here.
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
```python
|
|
1090
|
+
doxtr_highlights = {
|
|
1091
|
+
'style': 'default',
|
|
1092
|
+
'title_text': 'Highlights', # Text shown at top of box
|
|
1093
|
+
'title_icon': '', # Optional icon (e.g. r'\faIcon{star}')
|
|
1094
|
+
'title_font': 'Montserrat',
|
|
1095
|
+
'title_font_size': r'\large\bfseries',
|
|
1096
|
+
'title_font_color': '#8B6914',
|
|
1097
|
+
'border_color': '#8B6914',
|
|
1098
|
+
'border_width': '3pt',
|
|
1099
|
+
'content_font': '', # Empty = inherit body font
|
|
1100
|
+
'content_font_size': r'\normalsize',
|
|
1101
|
+
'content_font_color': '#1A1A2E',
|
|
1102
|
+
'content_background_color': '#FFF8DC',
|
|
1103
|
+
'before_skip': '1.5em plus 0.5em minus 0.5em',
|
|
1104
|
+
'after_skip': '1.5em plus 0.5em minus 0.5em',
|
|
1105
|
+
}
|
|
1106
|
+
```
|
|
1107
|
+
|
|
1108
|
+
### `doxtr_toc`
|
|
1109
|
+
|
|
1110
|
+
Controls Table of Contents entry fonts, sizes, and colors.
|
|
1111
|
+
|
|
1112
|
+
```python
|
|
1113
|
+
doxtr_toc = {
|
|
1114
|
+
'title_font': None, # Font for the "Contents" heading (None = inherit)
|
|
1115
|
+
'title_size': None,
|
|
1116
|
+
'title_color': None,
|
|
1117
|
+
|
|
1118
|
+
'chapter_font': None,
|
|
1119
|
+
'chapter_size': r'\large',
|
|
1120
|
+
'chapter_color': None, # dd: expressions supported
|
|
1121
|
+
'chapter_bold': True,
|
|
1122
|
+
|
|
1123
|
+
'section_font': None,
|
|
1124
|
+
'section_size': r'\normalsize',
|
|
1125
|
+
'section_color': None,
|
|
1126
|
+
|
|
1127
|
+
'subsection_font': None,
|
|
1128
|
+
'subsection_size': r'\small',
|
|
1129
|
+
'subsection_color': None,
|
|
1130
|
+
|
|
1131
|
+
'dot_leader_color': None, # Color of dot leaders (……)
|
|
1132
|
+
'dot_leader_char': r'\normalfont.',
|
|
1133
|
+
|
|
1134
|
+
'page_number_font': None,
|
|
1135
|
+
'page_number_color': None,
|
|
1136
|
+
}
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
### `doxtr_bibliography`
|
|
1140
|
+
|
|
1141
|
+
```python
|
|
1142
|
+
doxtr_bibliography = {
|
|
1143
|
+
'title_font': None,
|
|
1144
|
+
'title_size': None,
|
|
1145
|
+
'title_color': None,
|
|
1146
|
+
'entry_font': None,
|
|
1147
|
+
'entry_size': None,
|
|
1148
|
+
'entry_color': None,
|
|
1149
|
+
'label_color': None, # Color of [AuthorYear] citation labels
|
|
1150
|
+
'label_font': None,
|
|
1151
|
+
}
|
|
1152
|
+
```
|
|
1153
|
+
|
|
1154
|
+
### `doxtr_index`
|
|
1155
|
+
|
|
1156
|
+
```python
|
|
1157
|
+
doxtr_index = {
|
|
1158
|
+
'title_font': None,
|
|
1159
|
+
'title_size': None,
|
|
1160
|
+
'title_color': None,
|
|
1161
|
+
'entry_font': None,
|
|
1162
|
+
'entry_size': None,
|
|
1163
|
+
'subentry_font': None,
|
|
1164
|
+
'subentry_size': None,
|
|
1165
|
+
'letter_group_font': None, # The A, B, C group headers
|
|
1166
|
+
'letter_group_color': None,
|
|
1167
|
+
}
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
### `doxtr_glossary`
|
|
1171
|
+
|
|
1172
|
+
```python
|
|
1173
|
+
doxtr_glossary = {
|
|
1174
|
+
'term_font': None,
|
|
1175
|
+
'term_size': None,
|
|
1176
|
+
'term_color': None,
|
|
1177
|
+
'definition_font': None,
|
|
1178
|
+
'definition_size': None,
|
|
1179
|
+
'definition_color': None,
|
|
1180
|
+
'separator': r'\quad—\quad', # Between term and definition
|
|
1181
|
+
}
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
---
|
|
1185
|
+
|
|
1186
|
+
## Building for Release
|
|
1187
|
+
|
|
1188
|
+
```bash
|
|
1189
|
+
export VERSION=v0.1.10 && git tag $VERSION && git push origin $VERSION
|
|
1190
|
+
```
|
|
1191
|
+
|
|
1192
|
+
GitHub Actions will publish to PyPI automatically on release.
|
|
1193
|
+
|
|
1194
|
+
## License
|
|
1195
|
+
|
|
1196
|
+
MIT
|