sphinx-filter-tabs 1.2.6__py3-none-any.whl → 1.3__py3-none-any.whl
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.
- filter_tabs/extension.py +26 -7
- filter_tabs/renderer.py +2 -3
- {sphinx_filter_tabs-1.2.6.dist-info → sphinx_filter_tabs-1.3.dist-info}/METADATA +4 -4
- sphinx_filter_tabs-1.3.dist-info/RECORD +10 -0
- {sphinx_filter_tabs-1.2.6.dist-info → sphinx_filter_tabs-1.3.dist-info}/WHEEL +1 -1
- sphinx_filter_tabs-1.2.6.dist-info/RECORD +0 -10
- {sphinx_filter_tabs-1.2.6.dist-info → sphinx_filter_tabs-1.3.dist-info}/entry_points.txt +0 -0
- {sphinx_filter_tabs-1.2.6.dist-info → sphinx_filter_tabs-1.3.dist-info}/licenses/LICENSE +0 -0
- {sphinx_filter_tabs-1.2.6.dist-info → sphinx_filter_tabs-1.3.dist-info}/top_level.txt +0 -0
filter_tabs/extension.py
CHANGED
|
@@ -7,6 +7,7 @@ Consolidated version containing directives, data models, nodes, and Sphinx integ
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
import copy
|
|
9
9
|
import shutil
|
|
10
|
+
import warnings
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
from docutils import nodes
|
|
12
13
|
from docutils.parsers.rst import Directive, directives
|
|
@@ -21,6 +22,12 @@ from . import __version__
|
|
|
21
22
|
if TYPE_CHECKING:
|
|
22
23
|
from sphinx.environment import BuildEnvironment
|
|
23
24
|
|
|
25
|
+
# Define the warning for Sphinx 9 compatibility
|
|
26
|
+
try:
|
|
27
|
+
from sphinx.deprecation import RemovedInSphinx11Warning
|
|
28
|
+
except ImportError:
|
|
29
|
+
RemovedInSphinx11Warning = DeprecationWarning
|
|
30
|
+
|
|
24
31
|
# =============================================================================
|
|
25
32
|
# Custom Docutils Nodes
|
|
26
33
|
# =============================================================================
|
|
@@ -43,7 +50,6 @@ class SummaryNode(nodes.General, nodes.Element): pass
|
|
|
43
50
|
class TabData:
|
|
44
51
|
"""
|
|
45
52
|
Represents a single tab's data within a filter-tabs directive.
|
|
46
|
-
|
|
47
53
|
Attributes:
|
|
48
54
|
name: Display name of the tab
|
|
49
55
|
is_default: Whether this tab should be selected by default
|
|
@@ -99,7 +105,6 @@ class FilterTabsConfig:
|
|
|
99
105
|
class IDGenerator:
|
|
100
106
|
"""
|
|
101
107
|
Centralized ID generation for consistent element identification.
|
|
102
|
-
|
|
103
108
|
This ensures all IDs follow a consistent pattern and are unique
|
|
104
109
|
within their filter-tabs group.
|
|
105
110
|
"""
|
|
@@ -151,7 +156,7 @@ class TabDirective(Directive):
|
|
|
151
156
|
|
|
152
157
|
# Validate context
|
|
153
158
|
if not hasattr(env, 'sft_context') or not env.sft_context:
|
|
154
|
-
|
|
159
|
+
raise self.error("`tab` can only be used inside a `filter-tabs` directive.")
|
|
155
160
|
|
|
156
161
|
# Parse tab argument - moved from parsers.py
|
|
157
162
|
try:
|
|
@@ -242,7 +247,7 @@ class FilterTabsDirective(Directive):
|
|
|
242
247
|
# Validate tabs - moved from parsers.py
|
|
243
248
|
if not tab_data_list:
|
|
244
249
|
error_message = (
|
|
245
|
-
"No `.. tab::` directives found inside `.. filter-tabs
|
|
250
|
+
"No `.. tab::` directives found inside `.. filter-tabs::`.\n"
|
|
246
251
|
"You must include at least one tab."
|
|
247
252
|
)
|
|
248
253
|
if general_content:
|
|
@@ -264,8 +269,21 @@ class FilterTabsDirective(Directive):
|
|
|
264
269
|
from .renderer import FilterTabsRenderer
|
|
265
270
|
renderer = FilterTabsRenderer(self, tab_data_list, general_content, custom_legend=custom_legend)
|
|
266
271
|
|
|
272
|
+
# Safe builder check that suppresses Sphinx 9 warnings
|
|
273
|
+
builder_name = 'html' # Default assumption
|
|
274
|
+
|
|
275
|
+
try:
|
|
276
|
+
# We catch the specific warning about env.app being deprecated
|
|
277
|
+
with warnings.catch_warnings():
|
|
278
|
+
warnings.filterwarnings("ignore", category=RemovedInSphinx11Warning)
|
|
279
|
+
if hasattr(env, 'app') and env.app:
|
|
280
|
+
builder_name = env.app.builder.name
|
|
281
|
+
except Exception:
|
|
282
|
+
# Fallback for very old Sphinx or edge cases
|
|
283
|
+
pass
|
|
284
|
+
|
|
267
285
|
# Render based on builder
|
|
268
|
-
if
|
|
286
|
+
if builder_name == 'html':
|
|
269
287
|
return renderer.render_html()
|
|
270
288
|
else:
|
|
271
289
|
return renderer.render_fallback()
|
|
@@ -274,7 +292,7 @@ class FilterTabsDirective(Directive):
|
|
|
274
292
|
"""Validate tab data list - moved from parsers.py"""
|
|
275
293
|
if not tab_data_list and not skip_empty_check:
|
|
276
294
|
raise ValueError(
|
|
277
|
-
"No tab directives found inside filter-tabs
|
|
295
|
+
"No tab directives found inside filter-tabs.\n"
|
|
278
296
|
"Add at least one .. tab:: directive."
|
|
279
297
|
)
|
|
280
298
|
names = []
|
|
@@ -382,7 +400,7 @@ def visit_radio_input_node(self: HTML5Translator, node: RadioInputNode) -> None:
|
|
|
382
400
|
self.body.append(self.starttag(node, 'input', **attrs))
|
|
383
401
|
|
|
384
402
|
def depart_radio_input_node(self: HTML5Translator, node: RadioInputNode) -> None:
|
|
385
|
-
pass
|
|
403
|
+
pass # Self-closing tag
|
|
386
404
|
|
|
387
405
|
def visit_label_node(self: HTML5Translator, node: LabelNode) -> None:
|
|
388
406
|
attrs = _get_html_attrs(node)
|
|
@@ -496,3 +514,4 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|
|
496
514
|
'parallel_read_safe': True,
|
|
497
515
|
'parallel_write_safe': True,
|
|
498
516
|
}
|
|
517
|
+
|
filter_tabs/renderer.py
CHANGED
|
@@ -88,13 +88,12 @@ class FilterTabsRenderer:
|
|
|
88
88
|
def __init__(self, directive: Directive, tab_data: List[TabData], general_content: List[nodes.Node], custom_legend: Optional[str] = None):
|
|
89
89
|
self.directive = directive
|
|
90
90
|
self.env: BuildEnvironment = directive.state.document.settings.env
|
|
91
|
-
self.app = self.env.app
|
|
92
91
|
self.tab_data = tab_data
|
|
93
92
|
self.general_content = general_content
|
|
94
93
|
self.custom_legend = custom_legend
|
|
95
94
|
|
|
96
|
-
# 1. Load configuration
|
|
97
|
-
self.config = FilterTabsConfig.from_sphinx_config(self.
|
|
95
|
+
# 1. Load configuration using env.config (Sphinx 9+ safe)
|
|
96
|
+
self.config = FilterTabsConfig.from_sphinx_config(self.env.config)
|
|
98
97
|
|
|
99
98
|
# 2. Safely initialize the counter on the environment if it doesn't exist
|
|
100
99
|
if not hasattr(self.env, 'filter_tabs_counter'):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sphinx-filter-tabs
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3
|
|
4
4
|
Summary: A Sphinx extension for accessible, CSS-first filterable content tabs.
|
|
5
5
|
Author-email: Aputsiak Niels Janussen <aputtu+sphinx@gmail.com>
|
|
6
6
|
License: GNU General Public License v3.0
|
|
@@ -21,7 +21,7 @@ Classifier: Topic :: Software Development :: Documentation
|
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
-
Requires-Dist: Sphinx<
|
|
24
|
+
Requires-Dist: Sphinx<10.0,>=7.0
|
|
25
25
|
Dynamic: license-file
|
|
26
26
|
|
|
27
27
|
# Sphinx Filter Tabs Extension
|
|
@@ -228,8 +228,8 @@ The project includes comprehensive tests covering:
|
|
|
228
228
|
- Cross-browser compatibility
|
|
229
229
|
|
|
230
230
|
Tests run automatically on:
|
|
231
|
-
- Python 3.10, 3.12
|
|
232
|
-
- Sphinx 7.0, 7.4, 8.0, 8.2
|
|
231
|
+
- Python versions 3.10, 3.12
|
|
232
|
+
- Sphinx versions 7.0, 7.4, 8.0, 8.2, 9.0, 9.1
|
|
233
233
|
- Multiple operating systems via GitHub Actions
|
|
234
234
|
|
|
235
235
|
## Architecture
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
filter_tabs/__init__.py,sha256=VPpIhj4HaLeMX7ai7dZFkUm81ii2ePPGjCd9hsMjsN4,397
|
|
2
|
+
filter_tabs/extension.py,sha256=dcSbnQgCy0TL2eOoFvP7eN3gVCRwtLrs4QLHXKK9bGM,19428
|
|
3
|
+
filter_tabs/renderer.py,sha256=sapT3k-pAkVIXRypuTrtuc8XHZB23Sp8mgOSU3ZIqGg,10096
|
|
4
|
+
filter_tabs/static/filter_tabs.css,sha256=ZoiSWcn2YBEWgkQ-vPbIPHwQ7s2TG4aUikyxM1A8b9I,7956
|
|
5
|
+
sphinx_filter_tabs-1.3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
6
|
+
sphinx_filter_tabs-1.3.dist-info/METADATA,sha256=BEz8EQjjQea2bXmfX2OERvbgxsjddTdE_vw69zjUqbs,7635
|
|
7
|
+
sphinx_filter_tabs-1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
8
|
+
sphinx_filter_tabs-1.3.dist-info/entry_points.txt,sha256=za_bQcueY8AHyq7XnnjkW9X3C-LsZjeERVQ_ds7jV1A,62
|
|
9
|
+
sphinx_filter_tabs-1.3.dist-info/top_level.txt,sha256=K0Iy-6EsYYdvlyXdsJT0SQg-BLDBgT5-Y8ZKy5SNAfc,12
|
|
10
|
+
sphinx_filter_tabs-1.3.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
filter_tabs/__init__.py,sha256=VPpIhj4HaLeMX7ai7dZFkUm81ii2ePPGjCd9hsMjsN4,397
|
|
2
|
-
filter_tabs/extension.py,sha256=6mna59Qg1zdk6Vn9eXU_CaaQg1yBq4ktx2jx9O01frM,18679
|
|
3
|
-
filter_tabs/renderer.py,sha256=ublmQSoFewdPGRtEO7gLrxGqCZCjlooeom0wudx4phk,10100
|
|
4
|
-
filter_tabs/static/filter_tabs.css,sha256=ZoiSWcn2YBEWgkQ-vPbIPHwQ7s2TG4aUikyxM1A8b9I,7956
|
|
5
|
-
sphinx_filter_tabs-1.2.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
6
|
-
sphinx_filter_tabs-1.2.6.dist-info/METADATA,sha256=Wk2ZurjL5XIgRdHoyqtcjwFBGXft5K0aKIREoZWHAMA,7608
|
|
7
|
-
sphinx_filter_tabs-1.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
-
sphinx_filter_tabs-1.2.6.dist-info/entry_points.txt,sha256=za_bQcueY8AHyq7XnnjkW9X3C-LsZjeERVQ_ds7jV1A,62
|
|
9
|
-
sphinx_filter_tabs-1.2.6.dist-info/top_level.txt,sha256=K0Iy-6EsYYdvlyXdsJT0SQg-BLDBgT5-Y8ZKy5SNAfc,12
|
|
10
|
-
sphinx_filter_tabs-1.2.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|