0
# Extension Setup
1
2
Core setup functions and builder compatibility detection for the sphinx-tabs Sphinx extension.
3
4
## Capabilities
5
6
### Main Extension Setup
7
8
Primary setup function that registers all sphinx-tabs components with Sphinx.
9
10
```python { .api }
11
def setup(app):
12
"""Set up the sphinx-tabs extension
13
14
Args:
15
app: Sphinx application instance
16
17
Returns:
18
dict: Extension metadata with parallel processing settings
19
{'parallel_read_safe': True, 'parallel_write_safe': True}
20
"""
21
```
22
23
**Registration Actions:**
24
1. **Configuration Values**: Registers three config options
25
2. **Node Types**: Registers four custom docutils nodes with HTML visitors
26
3. **Directives**: Registers four RST directives
27
4. **Static Assets**: Adds static directory to HTML static path
28
5. **Event Handlers**: Connects page context handler for asset loading
29
30
**Usage:**
31
```python
32
# Automatically called when extension is loaded
33
extensions = ['sphinx_tabs.tabs']
34
```
35
36
**Return Value:**
37
```python
38
{
39
"parallel_read_safe": True, # Safe for parallel reading
40
"parallel_write_safe": True, # Safe for parallel writing
41
}
42
```
43
44
### Builder Compatibility Detection
45
46
Determines which Sphinx builders are compatible with sphinx-tabs functionality.
47
48
```python { .api }
49
def get_compatible_builders(app):
50
"""Get list of builders compatible with sphinx-tabs
51
52
Args:
53
app: Sphinx application instance
54
55
Returns:
56
list: List of builder names that support tabs
57
"""
58
```
59
60
**Default Compatible Builders:**
61
- `html` - Standard HTML builder
62
- `singlehtml` - Single-page HTML
63
- `dirhtml` - Directory-based HTML
64
- `readthedocs` - Read the Docs HTML
65
- `readthedocsdirhtml` - RTD directory HTML
66
- `readthedocssinglehtml` - RTD single HTML
67
- `readthedocssinglehtmllocalmedia` - RTD single HTML with local media
68
- `spelling` - Spelling checker (supports tabs for content checking)
69
70
**Extended Compatibility:**
71
```python
72
# Builders are extended with user configuration
73
builders.extend(app.config["sphinx_tabs_valid_builders"])
74
```
75
76
**Usage in Code:**
77
```python
78
# Check if current builder supports tabs
79
if self.env.app.builder.name in get_compatible_builders(self.env.app):
80
# Generate full tab HTML structure
81
else:
82
# Generate simplified fallback structure
83
```
84
85
### Node Registration
86
87
Custom docutils nodes for rendering tab HTML structure.
88
89
```python { .api }
90
# Node classes registered with HTML visitors
91
app.add_node(SphinxTabsContainer, html=(visit, depart))
92
app.add_node(SphinxTabsPanel, html=(visit, depart))
93
app.add_node(SphinxTabsTab, html=(visit, depart))
94
app.add_node(SphinxTabsTablist, html=(visit, depart))
95
```
96
97
**Node Types:**
98
```python { .api }
99
class SphinxTabsContainer(nodes.container):
100
"""Top-level container for tab set"""
101
tagname = "div"
102
103
class SphinxTabsPanel(nodes.container):
104
"""Individual tab content panel"""
105
tagname = "div"
106
107
class SphinxTabsTab(nodes.paragraph):
108
"""Clickable tab button"""
109
tagname = "button"
110
111
class SphinxTabsTablist(nodes.container):
112
"""Container for tab navigation buttons"""
113
tagname = "div"
114
```
115
116
### HTML Visitor Functions
117
118
Functions that generate HTML output for custom nodes.
119
120
```python { .api }
121
def visit(translator, node):
122
"""Generate opening HTML tag for node
123
124
Processes node attributes and generates the opening HTML tag using the
125
translator's starttag method. Filters out docutils-specific attributes
126
before HTML generation.
127
128
Args:
129
translator: HTML translator instance from Sphinx
130
node: docutils node being processed (SphinxTabsContainer, etc.)
131
"""
132
133
def depart(translator, node):
134
"""Generate closing HTML tag for node
135
136
Appends the closing HTML tag for the node using the node's tagname.
137
138
Args:
139
translator: HTML translator instance from Sphinx
140
node: docutils node being processed (SphinxTabsContainer, etc.)
141
"""
142
```
143
144
**HTML Generation Process:**
145
1. **visit()**: Extract node attributes, filter docutils internals (classes, ids, names, dupnames, backrefs)
146
2. **visit()**: Generate opening tag with `translator.starttag(node, node.tagname, **attrs)`
147
3. **visit()**: Append opening tag to translator body
148
4. **depart()**: Generate closing tag `</{node.tagname}>` and append to translator body
149
150
**Attribute Filtering:**
151
The visit function removes these internal docutils attributes before HTML generation:
152
- `classes` - CSS classes (handled separately by Sphinx)
153
- `ids` - Element IDs (handled separately by Sphinx)
154
- `names` - docutils name references
155
- `dupnames` - duplicate name tracking
156
- `backrefs` - back-reference tracking
157
158
### Static Assets Integration
159
160
Automatic integration of CSS and JavaScript files.
161
162
```python { .api }
163
# Static directory registration
164
static_dir = Path(__file__).parent / "static"
165
app.connect(
166
"builder-inited",
167
(lambda app: app.config.html_static_path.insert(0, static_dir.as_posix())),
168
)
169
```
170
171
**Asset Constants:**
172
```python { .api }
173
JS_FILES = ["tabs.js"]
174
CSS_FILES = ["tabs.css"]
175
```
176
177
**Asset Files:**
178
- `tabs.css` - Styling for tab interface
179
- `tabs.js` - JavaScript for tab functionality and interaction
180
181
**Loading Strategy:**
182
- Static path registered during builder initialization
183
- Assets conditionally loaded per page via `update_context` handler
184
- Respects user configuration for CSS loading
185
186
### Event Handler Registration
187
188
Page-level event handling for conditional asset loading.
189
190
```python { .api }
191
app.connect("html-page-context", update_context)
192
193
def update_context(app, pagename, templatename, context, doctree):
194
"""Add CSS/JS assets only to pages that contain tabs
195
196
Args:
197
app: Sphinx application
198
pagename: Current page name
199
templatename: Template being used
200
context: Template context
201
doctree: Document tree for current page
202
"""
203
```
204
205
**Asset Loading Logic:**
206
1. Use visitor pattern to detect tabs in document tree
207
2. Check Sphinx asset policy for global vs conditional loading
208
3. Add CSS file (unless disabled by configuration)
209
4. Add JavaScript file (always required for functionality)
210
211
### Tab Detection Visitor
212
213
Internal visitor class used to detect sphinx-tabs directives in document trees.
214
215
```python { .api }
216
class _FindTabsDirectiveVisitor(nodes.NodeVisitor):
217
"""Visitor pattern that looks for sphinx tabs directive in a document
218
219
Args:
220
document: docutils document to traverse
221
"""
222
223
def __init__(self, document):
224
"""Initialize visitor with document"""
225
226
def unknown_visit(self, node):
227
"""Visit node and check if it contains sphinx-tabs class"""
228
229
@property
230
def found_tabs_directive(self):
231
"""Return whether a sphinx tabs directive was found
232
233
Returns:
234
bool: True if tabs directive found in document
235
"""
236
```
237
238
**Usage in Asset Loading:**
239
```python
240
visitor = _FindTabsDirectiveVisitor(doctree)
241
doctree.walk(visitor)
242
if visitor.found_tabs_directive:
243
# Load tab assets for this page
244
```
245
246
## Extension Lifecycle
247
248
1. **Registration**: `setup()` called when extension loaded
249
2. **Builder Init**: Static paths configured
250
3. **Document Processing**: Directives create node structures
251
4. **HTML Generation**: Visitor functions generate HTML
252
5. **Page Context**: Assets conditionally added per page
253
254
## Compatibility Notes
255
256
**Sphinx Versions:**
257
- Minimum: Sphinx >= 1.8 (per setup.py requirements)
258
- Asset policy check: Sphinx >= 4.1.0 supported
259
- Parallel processing: Safe for both read and write operations
260
261
**Python Versions:**
262
- Minimum: Python >= 3.7 (per setup.py requirements)
263
- Path handling: Uses `pathlib.Path` for cross-platform compatibility
264
265
**Builder Support:**
266
- Primary: HTML-based builders
267
- Fallback: Basic container structure for non-HTML builders
268
- Extensible: User-configurable via `sphinx_tabs_valid_builders`