0
# HTML Post-Processing
1
2
Comprehensive HTML modification pipeline that enhances the generated Sphinx HTML with interactive features, improved navigation, accessibility enhancements, and modern web behaviors using BeautifulSoup for precise DOM manipulation.
3
4
## Capabilities
5
6
### Document Change Tracking
7
8
Track which documents have changed to optimize post-processing.
9
10
```python { .api }
11
def changed_docs(app: Sphinx, env: BuildEnvironment, docnames: list[str]) -> None:
12
"""
13
Add a list of changed docs to the environment.
14
15
This is useful to make sure postprocessing only runs on changed files,
16
improving build performance by avoiding unnecessary HTML modifications.
17
18
Parameters:
19
- app (Sphinx): The Sphinx application instance
20
- env (BuildEnvironment): The Sphinx build environment
21
- docnames (list[str]): List of document names that have changed
22
"""
23
```
24
25
### HTML File Discovery
26
27
Utility function for finding HTML files in the output directory.
28
29
```python { .api }
30
def get_html_files(outdir: pathlib.Path | str) -> list[str]:
31
"""
32
Get a list of HTML files in the output directory.
33
34
Recursively searches the output directory for all files with .html extension.
35
36
Parameters:
37
- outdir (pathlib.Path | str): Output directory to search
38
39
Returns:
40
list[str]: List of HTML file paths
41
"""
42
```
43
44
### Main Post-Processing Pipeline
45
46
Core function that orchestrates the HTML enhancement process for all changed documents.
47
48
```python { .api }
49
def post_process_html(app: Sphinx, exc: Exception | None) -> None:
50
"""
51
Modify the HTML after building.
52
53
Makes changes that are easier to do in the final HTML rather than
54
the tree of nodes. Only processes files that have changed.
55
56
Parameters:
57
- app (Sphinx): The Sphinx application instance
58
- exc (Exception | None): Build exception if any occurred
59
"""
60
```
61
62
### Document Processing
63
64
Core HTML document modification function that applies all enhancements.
65
66
```python { .api }
67
def modify_html(html_filename: str, app: Sphinx) -> None:
68
"""
69
Modify a single HTML document.
70
71
1. Parse the HTML document into a BeautifulSoup tree
72
2. Apply modifications in order and in place
73
3. Write the modified HTML back to the file
74
75
Parameters:
76
- html_filename (str): Path to the HTML file to modify
77
- app (Sphinx): The Sphinx application instance
78
"""
79
```
80
81
### Navigation Enhancements
82
83
Transform static navigation into interactive, collapsible navigation with Alpine.js directives.
84
85
```python { .api }
86
def collapsible_nav(tree: BeautifulSoup) -> None:
87
"""
88
Make navigation links with children collapsible.
89
90
Adds Alpine.js directives for interactive behavior:
91
- x-data for state management
92
- @click for toggle behavior
93
- x-show for visibility control
94
- :class for dynamic styling
95
96
Parameters:
97
- tree (BeautifulSoup): The parsed HTML document tree
98
"""
99
```
100
101
### Interactive Header Links
102
103
Transform header links into clipboard-copy functionality with user feedback.
104
105
```python { .api }
106
def headerlinks(tree: BeautifulSoup) -> None:
107
"""
108
Make headerlinks copy their URL on click.
109
110
Adds Alpine.js click handler that:
111
- Copies the link URL to clipboard
112
- Shows "Copied!" feedback message
113
- Resets to original message after 2 seconds
114
115
Parameters:
116
- tree (BeautifulSoup): The parsed HTML document tree
117
"""
118
```
119
120
### Scroll Spy Implementation
121
122
Add scroll-based navigation highlighting for table of contents.
123
124
```python { .api }
125
def scrollspy(tree: BeautifulSoup) -> None:
126
"""
127
Add an active class to current TOC links in the right sidebar.
128
129
Uses Alpine.js intersection observer to:
130
- Track which section is currently visible
131
- Update activeSection variable
132
- Apply data-current attribute to matching TOC links
133
134
Parameters:
135
- tree (BeautifulSoup): The parsed HTML document tree
136
"""
137
```
138
139
### External Link Enhancement
140
141
Enhance external links with security attributes and visual indicators.
142
143
```python { .api }
144
def external_links(tree: BeautifulSoup) -> None:
145
"""
146
Add rel="nofollow noopener" to external links and append icons.
147
148
Enhances security by:
149
- Adding rel attributes to prevent page hijacking
150
- Appending visual icons to identify external links
151
152
Parameters:
153
- tree (BeautifulSoup): The parsed HTML document tree
154
"""
155
```
156
157
### Content Cleanup
158
159
Remove unnecessary elements and optimize HTML structure.
160
161
```python { .api }
162
def remove_empty_toctree(tree: BeautifulSoup) -> None:
163
"""
164
Remove empty toctree divs.
165
166
If you include a toctree with the hidden option, an empty div is
167
inserted. This function removes these empty divs that contain only
168
whitespace characters.
169
170
Parameters:
171
- tree (BeautifulSoup): The parsed HTML document tree
172
"""
173
174
def strip_comments(tree: BeautifulSoup) -> None:
175
"""
176
Remove HTML comments from documents.
177
178
Cleans up the final HTML by removing all HTML comment nodes,
179
reducing file size and eliminating unnecessary markup.
180
181
Parameters:
182
- tree (BeautifulSoup): The parsed HTML document tree
183
"""
184
```
185
186
### Material Design Icons
187
188
Pre-defined SVG icons used throughout the post-processing pipeline.
189
190
```python { .api }
191
@dataclass(frozen=True)
192
class Icons:
193
"""Icons from Material Design as SVG strings."""
194
195
external_link: str = '<svg xmlns="http://www.w3.org/2000/svg"...'>
196
"""External link icon SVG"""
197
198
chevron_right: str = '<svg xmlns="http://www.w3.org/2000/svg"...'>
199
"""Right chevron icon for navigation"""
200
201
permalinks_icon: str = '<svg xmlns="http://www.w3.org/2000/svg"...'>
202
"""Permalink icon for header links"""
203
```
204
205
## Processing Pipeline
206
207
The post-processing pipeline applies modifications in this order:
208
209
1. **Collapsible Navigation** - Add interactive behavior to navigation links
210
2. **External Links** - Enhance external links with security and icons (if enabled)
211
3. **Empty TOC Removal** - Clean up empty toctree divs
212
4. **Scroll Spy** - Add intersection observers for TOC highlighting
213
5. **Header Links** - Add clipboard copy functionality (if enabled)
214
6. **Comment Stripping** - Remove HTML comments
215
216
## Configuration
217
218
Enable post-processing features through theme options:
219
220
```python
221
html_theme_options = {
222
"awesome_external_links": True, # Enable external link enhancement
223
"awesome_headerlinks": True, # Enable header link clipboard copy
224
}
225
```
226
227
## Alpine.js Integration
228
229
The post-processing system heavily integrates with Alpine.js for reactive behavior:
230
231
```html
232
<!-- Navigation state management -->
233
<li x-data="{ expanded: $el.classList.contains('current') ? true : false }">
234
<a @click="expanded = !expanded" :class="{ 'expanded' : expanded }">...</a>
235
<ul x-show="expanded">...</ul>
236
</li>
237
238
<!-- Scroll spy tracking -->
239
<h2 x-intersect.margin.0%.0%.-70%.0%="activeSection = '#section-id'">...</h2>
240
<a :data-current="activeSection === '#section-id'">...</a>
241
242
<!-- Clipboard copy -->
243
<a @click.prevent="navigator.clipboard.writeText($el.href)">...</a>
244
```
245
246
## Browser Compatibility
247
248
The post-processing enhancements use modern web APIs:
249
- Clipboard API for header link copying
250
- Intersection Observer API for scroll spy
251
- CSS custom properties for theming
252
- Alpine.js for reactive behavior
253
254
Graceful degradation is provided for older browsers.