Sphinx 8.1.2__py3-none-any.whl → 8.2.0rc1__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.
Potentially problematic release.
This version of Sphinx might be problematic. Click here for more details.
- sphinx/__init__.py +8 -4
- sphinx/__main__.py +2 -0
- sphinx/_cli/__init__.py +2 -5
- sphinx/_cli/util/colour.py +34 -11
- sphinx/_cli/util/errors.py +128 -61
- sphinx/addnodes.py +51 -35
- sphinx/application.py +362 -230
- sphinx/builders/__init__.py +87 -64
- sphinx/builders/_epub_base.py +65 -56
- sphinx/builders/changes.py +17 -23
- sphinx/builders/dirhtml.py +8 -13
- sphinx/builders/epub3.py +70 -38
- sphinx/builders/gettext.py +93 -73
- sphinx/builders/html/__init__.py +240 -186
- sphinx/builders/html/_assets.py +9 -2
- sphinx/builders/html/_build_info.py +3 -0
- sphinx/builders/latex/__init__.py +64 -54
- sphinx/builders/latex/constants.py +14 -11
- sphinx/builders/latex/nodes.py +2 -0
- sphinx/builders/latex/theming.py +8 -9
- sphinx/builders/latex/transforms.py +7 -5
- sphinx/builders/linkcheck.py +193 -149
- sphinx/builders/manpage.py +17 -17
- sphinx/builders/singlehtml.py +28 -16
- sphinx/builders/texinfo.py +28 -21
- sphinx/builders/text.py +10 -15
- sphinx/builders/xml.py +10 -19
- sphinx/cmd/build.py +49 -119
- sphinx/cmd/make_mode.py +35 -31
- sphinx/cmd/quickstart.py +78 -62
- sphinx/config.py +265 -163
- sphinx/directives/__init__.py +51 -54
- sphinx/directives/admonitions.py +107 -0
- sphinx/directives/code.py +24 -19
- sphinx/directives/other.py +21 -42
- sphinx/directives/patches.py +28 -16
- sphinx/domains/__init__.py +54 -31
- sphinx/domains/_domains_container.py +22 -17
- sphinx/domains/_index.py +5 -8
- sphinx/domains/c/__init__.py +366 -245
- sphinx/domains/c/_ast.py +378 -256
- sphinx/domains/c/_ids.py +89 -31
- sphinx/domains/c/_parser.py +283 -214
- sphinx/domains/c/_symbol.py +269 -198
- sphinx/domains/changeset.py +39 -24
- sphinx/domains/citation.py +54 -24
- sphinx/domains/cpp/__init__.py +517 -362
- sphinx/domains/cpp/_ast.py +999 -682
- sphinx/domains/cpp/_ids.py +133 -65
- sphinx/domains/cpp/_parser.py +746 -588
- sphinx/domains/cpp/_symbol.py +692 -489
- sphinx/domains/index.py +10 -8
- sphinx/domains/javascript.py +152 -74
- sphinx/domains/math.py +48 -40
- sphinx/domains/python/__init__.py +402 -211
- sphinx/domains/python/_annotations.py +114 -57
- sphinx/domains/python/_object.py +151 -67
- sphinx/domains/rst.py +94 -49
- sphinx/domains/std/__init__.py +510 -249
- sphinx/environment/__init__.py +345 -61
- sphinx/environment/adapters/asset.py +7 -1
- sphinx/environment/adapters/indexentries.py +15 -20
- sphinx/environment/adapters/toctree.py +19 -9
- sphinx/environment/collectors/__init__.py +3 -1
- sphinx/environment/collectors/asset.py +18 -15
- sphinx/environment/collectors/dependencies.py +8 -10
- sphinx/environment/collectors/metadata.py +6 -4
- sphinx/environment/collectors/title.py +3 -1
- sphinx/environment/collectors/toctree.py +4 -4
- sphinx/errors.py +1 -3
- sphinx/events.py +4 -4
- sphinx/ext/apidoc/__init__.py +21 -0
- sphinx/ext/apidoc/__main__.py +9 -0
- sphinx/ext/apidoc/_cli.py +356 -0
- sphinx/ext/apidoc/_generate.py +356 -0
- sphinx/ext/apidoc/_shared.py +66 -0
- sphinx/ext/autodoc/__init__.py +837 -483
- sphinx/ext/autodoc/directive.py +57 -21
- sphinx/ext/autodoc/importer.py +184 -67
- sphinx/ext/autodoc/mock.py +25 -10
- sphinx/ext/autodoc/preserve_defaults.py +17 -9
- sphinx/ext/autodoc/type_comment.py +56 -29
- sphinx/ext/autodoc/typehints.py +49 -26
- sphinx/ext/autosectionlabel.py +28 -11
- sphinx/ext/autosummary/__init__.py +271 -143
- sphinx/ext/autosummary/generate.py +121 -51
- sphinx/ext/coverage.py +152 -91
- sphinx/ext/doctest.py +169 -101
- sphinx/ext/duration.py +12 -6
- sphinx/ext/extlinks.py +33 -21
- sphinx/ext/githubpages.py +8 -8
- sphinx/ext/graphviz.py +175 -109
- sphinx/ext/ifconfig.py +11 -6
- sphinx/ext/imgconverter.py +48 -25
- sphinx/ext/imgmath.py +127 -97
- sphinx/ext/inheritance_diagram.py +177 -103
- sphinx/ext/intersphinx/__init__.py +22 -13
- sphinx/ext/intersphinx/__main__.py +3 -1
- sphinx/ext/intersphinx/_cli.py +18 -14
- sphinx/ext/intersphinx/_load.py +91 -82
- sphinx/ext/intersphinx/_resolve.py +108 -74
- sphinx/ext/intersphinx/_shared.py +2 -2
- sphinx/ext/linkcode.py +28 -12
- sphinx/ext/mathjax.py +60 -29
- sphinx/ext/napoleon/__init__.py +19 -7
- sphinx/ext/napoleon/docstring.py +229 -231
- sphinx/ext/todo.py +44 -49
- sphinx/ext/viewcode.py +105 -57
- sphinx/extension.py +3 -1
- sphinx/highlighting.py +13 -7
- sphinx/io.py +9 -13
- sphinx/jinja2glue.py +29 -26
- sphinx/locale/__init__.py +8 -9
- sphinx/parsers.py +8 -7
- sphinx/project.py +2 -2
- sphinx/pycode/__init__.py +31 -21
- sphinx/pycode/ast.py +6 -3
- sphinx/pycode/parser.py +14 -8
- sphinx/pygments_styles.py +4 -5
- sphinx/registry.py +192 -92
- sphinx/roles.py +58 -7
- sphinx/search/__init__.py +75 -54
- sphinx/search/en.py +11 -13
- sphinx/search/fi.py +1 -1
- sphinx/search/ja.py +8 -6
- sphinx/search/nl.py +1 -1
- sphinx/search/zh.py +19 -21
- sphinx/testing/fixtures.py +26 -29
- sphinx/testing/path.py +26 -62
- sphinx/testing/restructuredtext.py +14 -8
- sphinx/testing/util.py +21 -19
- sphinx/texinputs/make.bat.jinja +50 -50
- sphinx/texinputs/sphinx.sty +4 -3
- sphinx/texinputs/sphinxlatexadmonitions.sty +1 -1
- sphinx/texinputs/sphinxlatexobjects.sty +29 -10
- sphinx/themes/basic/static/searchtools.js +8 -5
- sphinx/theming.py +49 -61
- sphinx/transforms/__init__.py +17 -38
- sphinx/transforms/compact_bullet_list.py +5 -3
- sphinx/transforms/i18n.py +8 -21
- sphinx/transforms/post_transforms/__init__.py +142 -93
- sphinx/transforms/post_transforms/code.py +5 -5
- sphinx/transforms/post_transforms/images.py +28 -24
- sphinx/transforms/references.py +3 -1
- sphinx/util/__init__.py +109 -60
- sphinx/util/_files.py +39 -23
- sphinx/util/_importer.py +4 -1
- sphinx/util/_inventory_file_reader.py +76 -0
- sphinx/util/_io.py +2 -2
- sphinx/util/_lines.py +6 -3
- sphinx/util/_pathlib.py +40 -2
- sphinx/util/build_phase.py +2 -0
- sphinx/util/cfamily.py +19 -14
- sphinx/util/console.py +44 -179
- sphinx/util/display.py +9 -10
- sphinx/util/docfields.py +140 -122
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +118 -77
- sphinx/util/fileutil.py +25 -26
- sphinx/util/http_date.py +2 -0
- sphinx/util/i18n.py +77 -64
- sphinx/util/images.py +8 -6
- sphinx/util/inspect.py +147 -38
- sphinx/util/inventory.py +215 -116
- sphinx/util/logging.py +33 -33
- sphinx/util/matching.py +12 -4
- sphinx/util/nodes.py +18 -13
- sphinx/util/osutil.py +38 -39
- sphinx/util/parallel.py +22 -13
- sphinx/util/parsing.py +2 -1
- sphinx/util/png.py +6 -2
- sphinx/util/requests.py +33 -2
- sphinx/util/rst.py +3 -2
- sphinx/util/tags.py +1 -1
- sphinx/util/template.py +18 -10
- sphinx/util/texescape.py +8 -6
- sphinx/util/typing.py +148 -122
- sphinx/versioning.py +3 -3
- sphinx/writers/html.py +3 -1
- sphinx/writers/html5.py +61 -50
- sphinx/writers/latex.py +80 -65
- sphinx/writers/manpage.py +19 -38
- sphinx/writers/texinfo.py +44 -45
- sphinx/writers/text.py +48 -30
- sphinx/writers/xml.py +11 -8
- {sphinx-8.1.2.dist-info → sphinx-8.2.0rc1.dist-info}/LICENSE.rst +1 -1
- {sphinx-8.1.2.dist-info → sphinx-8.2.0rc1.dist-info}/METADATA +23 -15
- {sphinx-8.1.2.dist-info → sphinx-8.2.0rc1.dist-info}/RECORD +190 -186
- {sphinx-8.1.2.dist-info → sphinx-8.2.0rc1.dist-info}/WHEEL +1 -1
- sphinx/builders/html/transforms.py +0 -90
- sphinx/ext/apidoc.py +0 -721
- sphinx/util/exceptions.py +0 -74
- {sphinx-8.1.2.dist-info → sphinx-8.2.0rc1.dist-info}/entry_points.txt +0 -0
sphinx/theming.py
CHANGED
|
@@ -6,13 +6,13 @@ __all__ = ('Theme', 'HTMLThemeFactory')
|
|
|
6
6
|
|
|
7
7
|
import configparser
|
|
8
8
|
import contextlib
|
|
9
|
-
import os
|
|
10
9
|
import shutil
|
|
11
10
|
import sys
|
|
12
11
|
import tempfile
|
|
12
|
+
import tomllib
|
|
13
13
|
from importlib.metadata import entry_points
|
|
14
|
-
from
|
|
15
|
-
from typing import TYPE_CHECKING
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
16
16
|
from zipfile import ZipFile
|
|
17
17
|
|
|
18
18
|
from sphinx import package_dir
|
|
@@ -20,19 +20,12 @@ from sphinx.config import check_confval_types as _config_post_init
|
|
|
20
20
|
from sphinx.errors import ThemeError
|
|
21
21
|
from sphinx.locale import __
|
|
22
22
|
from sphinx.util import logging
|
|
23
|
+
from sphinx.util._pathlib import _StrPath
|
|
23
24
|
from sphinx.util.osutil import ensuredir
|
|
24
25
|
|
|
25
|
-
if sys.version_info >= (3, 11):
|
|
26
|
-
import tomllib
|
|
27
|
-
else:
|
|
28
|
-
import tomli as tomllib
|
|
29
|
-
|
|
30
|
-
|
|
31
26
|
if TYPE_CHECKING:
|
|
32
27
|
from collections.abc import Callable
|
|
33
|
-
from typing import TypedDict
|
|
34
|
-
|
|
35
|
-
from typing_extensions import Required
|
|
28
|
+
from typing import Any, Required, TypedDict
|
|
36
29
|
|
|
37
30
|
from sphinx.application import Sphinx
|
|
38
31
|
|
|
@@ -69,8 +62,8 @@ class Theme:
|
|
|
69
62
|
name: str,
|
|
70
63
|
*,
|
|
71
64
|
configs: dict[str, _ConfigFile],
|
|
72
|
-
paths: list[
|
|
73
|
-
tmp_dirs: list[
|
|
65
|
+
paths: list[Path],
|
|
66
|
+
tmp_dirs: list[Path],
|
|
74
67
|
) -> None:
|
|
75
68
|
self.name = name
|
|
76
69
|
self._dirs = tuple(paths)
|
|
@@ -94,11 +87,11 @@ class Theme:
|
|
|
94
87
|
|
|
95
88
|
self._options = options
|
|
96
89
|
|
|
97
|
-
def get_theme_dirs(self) -> list[
|
|
90
|
+
def get_theme_dirs(self) -> list[_StrPath]:
|
|
98
91
|
"""Return a list of theme directories, beginning with this theme's,
|
|
99
92
|
then the base theme's, then that one's base theme's, etc.
|
|
100
93
|
"""
|
|
101
|
-
return list(self._dirs)
|
|
94
|
+
return list(map(_StrPath, self._dirs))
|
|
102
95
|
|
|
103
96
|
def get_config(self, section: str, name: str, default: Any = _NO_DEFAULT) -> Any:
|
|
104
97
|
"""Return the value for a theme configuration setting, searching the
|
|
@@ -166,17 +159,17 @@ class HTMLThemeFactory:
|
|
|
166
159
|
|
|
167
160
|
def _load_builtin_themes(self) -> None:
|
|
168
161
|
"""Load built-in themes."""
|
|
169
|
-
themes = self._find_themes(
|
|
162
|
+
themes = self._find_themes(package_dir / 'themes')
|
|
170
163
|
for name, theme in themes.items():
|
|
171
|
-
self._themes[name] = theme
|
|
164
|
+
self._themes[name] = _StrPath(theme)
|
|
172
165
|
|
|
173
166
|
def _load_additional_themes(self, theme_paths: list[str]) -> None:
|
|
174
167
|
"""Load additional themes placed at specified directories."""
|
|
175
168
|
for theme_path in theme_paths:
|
|
176
|
-
abs_theme_path =
|
|
169
|
+
abs_theme_path = (self._app.confdir / theme_path).resolve()
|
|
177
170
|
themes = self._find_themes(abs_theme_path)
|
|
178
171
|
for name, theme in themes.items():
|
|
179
|
-
self._themes[name] = theme
|
|
172
|
+
self._themes[name] = _StrPath(theme)
|
|
180
173
|
|
|
181
174
|
def _load_entry_point_themes(self) -> None:
|
|
182
175
|
"""Try to load a theme with the specified name.
|
|
@@ -198,18 +191,17 @@ class HTMLThemeFactory:
|
|
|
198
191
|
self._entry_point_themes[entry_point.name] = _load_theme_closure
|
|
199
192
|
|
|
200
193
|
@staticmethod
|
|
201
|
-
def _find_themes(theme_path:
|
|
194
|
+
def _find_themes(theme_path: Path) -> dict[str, Path]:
|
|
202
195
|
"""Search themes from specified directory."""
|
|
203
|
-
themes: dict[str,
|
|
204
|
-
if not
|
|
196
|
+
themes: dict[str, Path] = {}
|
|
197
|
+
if not theme_path.is_dir():
|
|
205
198
|
return themes
|
|
206
199
|
|
|
207
|
-
for
|
|
208
|
-
|
|
209
|
-
if
|
|
200
|
+
for pathname in theme_path.iterdir():
|
|
201
|
+
entry = pathname.name
|
|
202
|
+
if pathname.is_file() and pathname.suffix.lower() == '.zip':
|
|
210
203
|
if _is_archived_theme(pathname):
|
|
211
|
-
|
|
212
|
-
themes[name] = pathname
|
|
204
|
+
themes[pathname.stem] = pathname
|
|
213
205
|
else:
|
|
214
206
|
logger.warning(
|
|
215
207
|
__(
|
|
@@ -219,9 +211,9 @@ class HTMLThemeFactory:
|
|
|
219
211
|
entry,
|
|
220
212
|
)
|
|
221
213
|
else:
|
|
222
|
-
toml_path =
|
|
223
|
-
conf_path =
|
|
224
|
-
if
|
|
214
|
+
toml_path = pathname / _THEME_TOML
|
|
215
|
+
conf_path = pathname / _THEME_CONF
|
|
216
|
+
if toml_path.is_file() or conf_path.is_file():
|
|
225
217
|
themes[entry] = pathname
|
|
226
218
|
|
|
227
219
|
return themes
|
|
@@ -243,7 +235,7 @@ class HTMLThemeFactory:
|
|
|
243
235
|
return Theme(name, configs=themes, paths=theme_dirs, tmp_dirs=tmp_dirs)
|
|
244
236
|
|
|
245
237
|
|
|
246
|
-
def _is_archived_theme(filename:
|
|
238
|
+
def _is_archived_theme(filename: Path, /) -> bool:
|
|
247
239
|
"""Check whether the specified file is an archived theme file or not."""
|
|
248
240
|
try:
|
|
249
241
|
with ZipFile(filename) as f:
|
|
@@ -255,13 +247,13 @@ def _is_archived_theme(filename: str, /) -> bool:
|
|
|
255
247
|
|
|
256
248
|
def _load_theme_with_ancestors(
|
|
257
249
|
name: str,
|
|
258
|
-
theme_paths: dict[str,
|
|
250
|
+
theme_paths: dict[str, _StrPath],
|
|
259
251
|
entry_point_themes: dict[str, Callable[[], None]],
|
|
260
252
|
/,
|
|
261
|
-
) -> tuple[dict[str, _ConfigFile], list[
|
|
253
|
+
) -> tuple[dict[str, _ConfigFile], list[Path], list[Path]]:
|
|
262
254
|
themes: dict[str, _ConfigFile] = {}
|
|
263
|
-
theme_dirs: list[
|
|
264
|
-
tmp_dirs: list[
|
|
255
|
+
theme_dirs: list[Path] = []
|
|
256
|
+
tmp_dirs: list[Path] = []
|
|
265
257
|
|
|
266
258
|
# having 10+ theme ancestors is ludicrous
|
|
267
259
|
for _ in range(10):
|
|
@@ -294,23 +286,23 @@ def _load_theme_with_ancestors(
|
|
|
294
286
|
|
|
295
287
|
|
|
296
288
|
def _load_theme(
|
|
297
|
-
name: str, theme_path:
|
|
298
|
-
) -> tuple[str,
|
|
299
|
-
if
|
|
289
|
+
name: str, theme_path: Path, /
|
|
290
|
+
) -> tuple[str, Path, Path | None, _ConfigFile]:
|
|
291
|
+
if theme_path.is_dir():
|
|
300
292
|
# already a directory, do nothing
|
|
301
293
|
tmp_dir = None
|
|
302
294
|
theme_dir = theme_path
|
|
303
295
|
else:
|
|
304
296
|
# extract the theme to a temp directory
|
|
305
|
-
tmp_dir = tempfile.mkdtemp('sxt')
|
|
306
|
-
theme_dir =
|
|
297
|
+
tmp_dir = Path(tempfile.mkdtemp('sxt'))
|
|
298
|
+
theme_dir = tmp_dir / name
|
|
307
299
|
_extract_zip(theme_path, theme_dir)
|
|
308
300
|
|
|
309
|
-
if
|
|
301
|
+
if (toml_path := theme_dir / _THEME_TOML).is_file():
|
|
310
302
|
_cfg_table = _load_theme_toml(toml_path)
|
|
311
303
|
inherit = _validate_theme_toml(_cfg_table, name)
|
|
312
304
|
config = _convert_theme_toml(_cfg_table)
|
|
313
|
-
elif
|
|
305
|
+
elif (conf_path := theme_dir / _THEME_CONF).is_file():
|
|
314
306
|
_cfg_parser = _load_theme_conf(conf_path)
|
|
315
307
|
inherit = _validate_theme_conf(_cfg_parser, name)
|
|
316
308
|
config = _convert_theme_conf(_cfg_parser)
|
|
@@ -320,7 +312,7 @@ def _load_theme(
|
|
|
320
312
|
return inherit, theme_dir, tmp_dir, config
|
|
321
313
|
|
|
322
314
|
|
|
323
|
-
def _extract_zip(filename:
|
|
315
|
+
def _extract_zip(filename: Path, target_dir: Path, /) -> None:
|
|
324
316
|
"""Extract zip file to target directory."""
|
|
325
317
|
ensuredir(target_dir)
|
|
326
318
|
|
|
@@ -328,16 +320,13 @@ def _extract_zip(filename: str, target_dir: str, /) -> None:
|
|
|
328
320
|
for name in archive.namelist():
|
|
329
321
|
if name.endswith('/'):
|
|
330
322
|
continue
|
|
331
|
-
entry =
|
|
332
|
-
ensuredir(
|
|
333
|
-
|
|
334
|
-
fp.write(archive.read(name))
|
|
323
|
+
entry = target_dir / name
|
|
324
|
+
ensuredir(entry.parent)
|
|
325
|
+
entry.write_bytes(archive.read(name))
|
|
335
326
|
|
|
336
327
|
|
|
337
|
-
def _load_theme_toml(config_file_path:
|
|
338
|
-
|
|
339
|
-
config_text = f.read()
|
|
340
|
-
c = tomllib.loads(config_text)
|
|
328
|
+
def _load_theme_toml(config_file_path: Path, /) -> _ThemeToml:
|
|
329
|
+
c = tomllib.loads(config_file_path.read_text(encoding='utf-8'))
|
|
341
330
|
return {s: c[s] for s in ('theme', 'options') if s in c} # type: ignore[return-value]
|
|
342
331
|
|
|
343
332
|
|
|
@@ -388,7 +377,7 @@ def _convert_theme_toml(cfg: _ThemeToml, /) -> _ConfigFile:
|
|
|
388
377
|
)
|
|
389
378
|
|
|
390
379
|
|
|
391
|
-
def _load_theme_conf(config_file_path:
|
|
380
|
+
def _load_theme_conf(config_file_path: Path, /) -> configparser.RawConfigParser:
|
|
392
381
|
c = configparser.RawConfigParser()
|
|
393
382
|
c.read(config_file_path, encoding='utf-8')
|
|
394
383
|
return c
|
|
@@ -494,9 +483,9 @@ def _migrate_conf_to_toml(argv: list[str]) -> int:
|
|
|
494
483
|
if len(argv) != 1:
|
|
495
484
|
print('Usage: python -m sphinx.theming conf_to_toml <theme path>') # NoQA: T201
|
|
496
485
|
raise SystemExit(1)
|
|
497
|
-
theme_dir =
|
|
498
|
-
conf_path =
|
|
499
|
-
if not
|
|
486
|
+
theme_dir = Path(argv[0]).resolve()
|
|
487
|
+
conf_path = theme_dir / _THEME_CONF
|
|
488
|
+
if not theme_dir.is_dir() or not conf_path.is_file():
|
|
500
489
|
print( # NoQA: T201
|
|
501
490
|
f'{theme_dir!r} must be a path to a theme directory containing a "theme.conf" file'
|
|
502
491
|
)
|
|
@@ -516,7 +505,7 @@ def _migrate_conf_to_toml(argv: list[str]) -> int:
|
|
|
516
505
|
]
|
|
517
506
|
|
|
518
507
|
stylesheet = _cfg_parser.get('theme', 'stylesheet', fallback=...)
|
|
519
|
-
if stylesheet
|
|
508
|
+
if not stylesheet:
|
|
520
509
|
toml_lines.append('stylesheets = []')
|
|
521
510
|
elif stylesheet is not ...:
|
|
522
511
|
toml_lines.append('stylesheets = [')
|
|
@@ -524,7 +513,7 @@ def _migrate_conf_to_toml(argv: list[str]) -> int:
|
|
|
524
513
|
toml_lines.append(']')
|
|
525
514
|
|
|
526
515
|
sidebar = _cfg_parser.get('theme', 'sidebars', fallback=...)
|
|
527
|
-
if sidebar
|
|
516
|
+
if not sidebar:
|
|
528
517
|
toml_lines.append('sidebars = []')
|
|
529
518
|
elif sidebar is not ...:
|
|
530
519
|
toml_lines.append('sidebars = [')
|
|
@@ -550,9 +539,8 @@ def _migrate_conf_to_toml(argv: list[str]) -> int:
|
|
|
550
539
|
if (d := default.replace('"', r'\"')) or True
|
|
551
540
|
]
|
|
552
541
|
|
|
553
|
-
toml_path =
|
|
554
|
-
|
|
555
|
-
f.write('\n'.join(toml_lines) + '\n')
|
|
542
|
+
toml_path = theme_dir / _THEME_TOML
|
|
543
|
+
toml_path.write_text('\n'.join(toml_lines) + '\n', encoding='utf-8')
|
|
556
544
|
print(f'Written converted settings to {toml_path!r}') # NoQA: T201
|
|
557
545
|
return 0
|
|
558
546
|
|
sphinx/transforms/__init__.py
CHANGED
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import re
|
|
6
6
|
import unicodedata
|
|
7
|
-
from typing import TYPE_CHECKING,
|
|
7
|
+
from typing import TYPE_CHECKING, cast
|
|
8
8
|
|
|
9
9
|
from docutils import nodes
|
|
10
10
|
from docutils.transforms import Transform, Transformer
|
|
@@ -23,7 +23,7 @@ from sphinx.util.nodes import apply_source_workaround, is_smartquotable
|
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
25
|
from collections.abc import Iterator
|
|
26
|
-
from typing import Literal, TypeAlias
|
|
26
|
+
from typing import Any, Literal, TypeAlias
|
|
27
27
|
|
|
28
28
|
from docutils.nodes import Node, Text
|
|
29
29
|
from typing_extensions import TypeIs
|
|
@@ -76,9 +76,7 @@ class SphinxTransform(Transform):
|
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
class SphinxTransformer(Transformer):
|
|
79
|
-
"""
|
|
80
|
-
A transformer for Sphinx.
|
|
81
|
-
"""
|
|
79
|
+
"""A transformer for Sphinx."""
|
|
82
80
|
|
|
83
81
|
document: nodes.document
|
|
84
82
|
env: BuildEnvironment | None = None
|
|
@@ -106,9 +104,7 @@ class SphinxTransformer(Transformer):
|
|
|
106
104
|
|
|
107
105
|
|
|
108
106
|
class DefaultSubstitutions(SphinxTransform):
|
|
109
|
-
"""
|
|
110
|
-
Replace some substitutions if they aren't defined in the document.
|
|
111
|
-
"""
|
|
107
|
+
"""Replace some substitutions if they aren't defined in the document."""
|
|
112
108
|
|
|
113
109
|
# run before the default Substitutions
|
|
114
110
|
default_priority = 210
|
|
@@ -150,8 +146,7 @@ def _calculate_translation_progress(document: nodes.document) -> str:
|
|
|
150
146
|
|
|
151
147
|
|
|
152
148
|
class MoveModuleTargets(SphinxTransform):
|
|
153
|
-
"""
|
|
154
|
-
Move module targets that are the first thing in a section to the section
|
|
149
|
+
"""Move module targets that are the first thing in a section to the section
|
|
155
150
|
title.
|
|
156
151
|
|
|
157
152
|
XXX Python specific
|
|
@@ -176,9 +171,7 @@ class MoveModuleTargets(SphinxTransform):
|
|
|
176
171
|
|
|
177
172
|
|
|
178
173
|
class HandleCodeBlocks(SphinxTransform):
|
|
179
|
-
"""
|
|
180
|
-
Several code block related transformations.
|
|
181
|
-
"""
|
|
174
|
+
"""Several code block related transformations."""
|
|
182
175
|
|
|
183
176
|
default_priority = 210
|
|
184
177
|
|
|
@@ -200,9 +193,7 @@ class HandleCodeBlocks(SphinxTransform):
|
|
|
200
193
|
|
|
201
194
|
|
|
202
195
|
class AutoNumbering(SphinxTransform):
|
|
203
|
-
"""
|
|
204
|
-
Register IDs of tables, figures and literal_blocks to assign numbers.
|
|
205
|
-
"""
|
|
196
|
+
"""Register IDs of tables, figures and literal_blocks to assign numbers."""
|
|
206
197
|
|
|
207
198
|
default_priority = 210
|
|
208
199
|
|
|
@@ -219,9 +210,7 @@ class AutoNumbering(SphinxTransform):
|
|
|
219
210
|
|
|
220
211
|
|
|
221
212
|
class SortIds(SphinxTransform):
|
|
222
|
-
"""
|
|
223
|
-
Sort section IDs so that the "id[0-9]+" one comes last.
|
|
224
|
-
"""
|
|
213
|
+
"""Sort section IDs so that the "id[0-9]+" one comes last."""
|
|
225
214
|
|
|
226
215
|
default_priority = 261
|
|
227
216
|
|
|
@@ -241,9 +230,7 @@ TRANSLATABLE_NODES = {
|
|
|
241
230
|
|
|
242
231
|
|
|
243
232
|
class ApplySourceWorkaround(SphinxTransform):
|
|
244
|
-
"""
|
|
245
|
-
Update source and rawsource attributes
|
|
246
|
-
"""
|
|
233
|
+
"""Update source and rawsource attributes"""
|
|
247
234
|
|
|
248
235
|
default_priority = 10
|
|
249
236
|
|
|
@@ -254,9 +241,7 @@ class ApplySourceWorkaround(SphinxTransform):
|
|
|
254
241
|
|
|
255
242
|
|
|
256
243
|
class AutoIndexUpgrader(SphinxTransform):
|
|
257
|
-
"""
|
|
258
|
-
Detect old style (4 column based indices) and automatically upgrade to new style.
|
|
259
|
-
"""
|
|
244
|
+
"""Detect old style (4 column based indices) and automatically upgrade to new style."""
|
|
260
245
|
|
|
261
246
|
default_priority = 210
|
|
262
247
|
|
|
@@ -277,9 +262,7 @@ class AutoIndexUpgrader(SphinxTransform):
|
|
|
277
262
|
|
|
278
263
|
|
|
279
264
|
class ExtraTranslatableNodes(SphinxTransform):
|
|
280
|
-
"""
|
|
281
|
-
Make nodes translatable
|
|
282
|
-
"""
|
|
265
|
+
"""Make nodes translatable"""
|
|
283
266
|
|
|
284
267
|
default_priority = 10
|
|
285
268
|
|
|
@@ -297,9 +280,7 @@ class ExtraTranslatableNodes(SphinxTransform):
|
|
|
297
280
|
|
|
298
281
|
|
|
299
282
|
class UnreferencedFootnotesDetector(SphinxTransform):
|
|
300
|
-
"""
|
|
301
|
-
Detect unreferenced footnotes and emit warnings
|
|
302
|
-
"""
|
|
283
|
+
"""Detect unreferenced footnotes and emit warnings"""
|
|
303
284
|
|
|
304
285
|
default_priority = Footnotes.default_priority + 2
|
|
305
286
|
|
|
@@ -361,8 +342,7 @@ class FilterSystemMessages(SphinxTransform):
|
|
|
361
342
|
|
|
362
343
|
|
|
363
344
|
class SphinxContentsFilter(ContentsFilter):
|
|
364
|
-
"""
|
|
365
|
-
Used with BuildEnvironment.add_toc_from() to discard cross-file links
|
|
345
|
+
"""Used with BuildEnvironment.add_toc_from() to discard cross-file links
|
|
366
346
|
within table-of-contents link nodes.
|
|
367
347
|
"""
|
|
368
348
|
|
|
@@ -373,8 +353,7 @@ class SphinxContentsFilter(ContentsFilter):
|
|
|
373
353
|
|
|
374
354
|
|
|
375
355
|
class SphinxSmartQuotes(SmartQuotes, SphinxTransform):
|
|
376
|
-
"""
|
|
377
|
-
Customized SmartQuotes to avoid transform for some extra node types.
|
|
356
|
+
"""Customized SmartQuotes to avoid transform for some extra node types.
|
|
378
357
|
|
|
379
358
|
refs: sphinx.parsers.RSTParser
|
|
380
359
|
"""
|
|
@@ -430,7 +409,7 @@ class DoctreeReadEvent(SphinxTransform):
|
|
|
430
409
|
default_priority = 880
|
|
431
410
|
|
|
432
411
|
def apply(self, **kwargs: Any) -> None:
|
|
433
|
-
self.app.emit('doctree-read', self.document)
|
|
412
|
+
self.app.events.emit('doctree-read', self.document)
|
|
434
413
|
|
|
435
414
|
|
|
436
415
|
class GlossarySorter(SphinxTransform):
|
|
@@ -443,11 +422,11 @@ class GlossarySorter(SphinxTransform):
|
|
|
443
422
|
def apply(self, **kwargs: Any) -> None:
|
|
444
423
|
for glossary in self.document.findall(addnodes.glossary):
|
|
445
424
|
if glossary['sorted']:
|
|
446
|
-
definition_list = cast(nodes.definition_list, glossary[0])
|
|
425
|
+
definition_list = cast('nodes.definition_list', glossary[0])
|
|
447
426
|
definition_list[:] = sorted(
|
|
448
427
|
definition_list,
|
|
449
428
|
key=lambda item: unicodedata.normalize(
|
|
450
|
-
'NFD', cast(nodes.term, item)[0].astext().lower()
|
|
429
|
+
'NFD', cast('nodes.term', item)[0].astext().lower()
|
|
451
430
|
),
|
|
452
431
|
)
|
|
453
432
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import TYPE_CHECKING,
|
|
5
|
+
from typing import TYPE_CHECKING, cast
|
|
6
6
|
|
|
7
7
|
from docutils import nodes
|
|
8
8
|
|
|
@@ -10,6 +10,8 @@ from sphinx import addnodes
|
|
|
10
10
|
from sphinx.transforms import SphinxTransform
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
13
15
|
from docutils.nodes import Node
|
|
14
16
|
|
|
15
17
|
from sphinx.application import Sphinx
|
|
@@ -75,8 +77,8 @@ class RefOnlyBulletListTransform(SphinxTransform):
|
|
|
75
77
|
for node in self.document.findall(nodes.bullet_list):
|
|
76
78
|
if check_refonly_list(node):
|
|
77
79
|
for item in node.findall(nodes.list_item):
|
|
78
|
-
para = cast(nodes.paragraph, item[0])
|
|
79
|
-
ref = cast(nodes.reference, para[0])
|
|
80
|
+
para = cast('nodes.paragraph', item[0])
|
|
81
|
+
ref = cast('nodes.reference', para[0])
|
|
80
82
|
compact_para = addnodes.compact_paragraph()
|
|
81
83
|
compact_para += ref
|
|
82
84
|
item.replace(para, compact_para)
|
sphinx/transforms/i18n.py
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import contextlib
|
|
6
|
-
from os import path
|
|
7
6
|
from re import DOTALL, match
|
|
8
7
|
from textwrap import indent
|
|
9
8
|
from typing import TYPE_CHECKING, Any, TypeVar
|
|
@@ -101,9 +100,7 @@ def parse_noqa(source: str) -> tuple[str, bool]:
|
|
|
101
100
|
|
|
102
101
|
|
|
103
102
|
class PreserveTranslatableMessages(SphinxTransform):
|
|
104
|
-
"""
|
|
105
|
-
Preserve original translatable messages before translation
|
|
106
|
-
"""
|
|
103
|
+
"""Preserve original translatable messages before translation"""
|
|
107
104
|
|
|
108
105
|
default_priority = 10 # this MUST be invoked before Locale transform
|
|
109
106
|
|
|
@@ -381,9 +378,7 @@ class _NodeUpdater:
|
|
|
381
378
|
|
|
382
379
|
|
|
383
380
|
class Locale(SphinxTransform):
|
|
384
|
-
"""
|
|
385
|
-
Replace translatable nodes with their translated doctree.
|
|
386
|
-
"""
|
|
381
|
+
"""Replace translatable nodes with their translated doctree."""
|
|
387
382
|
|
|
388
383
|
default_priority = 20
|
|
389
384
|
|
|
@@ -394,10 +389,8 @@ class Locale(SphinxTransform):
|
|
|
394
389
|
textdomain = docname_to_domain(self.env.docname, self.config.gettext_compact)
|
|
395
390
|
|
|
396
391
|
# fetch translations
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
for directory in self.config.locale_dirs
|
|
400
|
-
]
|
|
392
|
+
srcdir = self.env.srcdir
|
|
393
|
+
dirs = [srcdir / directory for directory in self.config.locale_dirs]
|
|
401
394
|
catalog, has_catalog = init_locale(dirs, self.config.language, textdomain)
|
|
402
395
|
if not has_catalog:
|
|
403
396
|
return
|
|
@@ -420,7 +413,7 @@ class Locale(SphinxTransform):
|
|
|
420
413
|
if not isinstance(node, LITERAL_TYPE_NODES):
|
|
421
414
|
msgstr, _ = parse_noqa(msgstr)
|
|
422
415
|
|
|
423
|
-
if msgstr.strip()
|
|
416
|
+
if not msgstr.strip():
|
|
424
417
|
# as-of-yet untranslated
|
|
425
418
|
node['translated'] = False
|
|
426
419
|
continue
|
|
@@ -612,9 +605,7 @@ class Locale(SphinxTransform):
|
|
|
612
605
|
|
|
613
606
|
|
|
614
607
|
class TranslationProgressTotaliser(SphinxTransform):
|
|
615
|
-
"""
|
|
616
|
-
Calculate the number of translated and untranslated nodes.
|
|
617
|
-
"""
|
|
608
|
+
"""Calculate the number of translated and untranslated nodes."""
|
|
618
609
|
|
|
619
610
|
default_priority = 25 # MUST happen after Locale
|
|
620
611
|
|
|
@@ -637,9 +628,7 @@ class TranslationProgressTotaliser(SphinxTransform):
|
|
|
637
628
|
|
|
638
629
|
|
|
639
630
|
class AddTranslationClasses(SphinxTransform):
|
|
640
|
-
"""
|
|
641
|
-
Add ``translated`` or ``untranslated`` classes to indicate translation status.
|
|
642
|
-
"""
|
|
631
|
+
"""Add ``translated`` or ``untranslated`` classes to indicate translation status."""
|
|
643
632
|
|
|
644
633
|
default_priority = 950
|
|
645
634
|
|
|
@@ -677,9 +666,7 @@ class AddTranslationClasses(SphinxTransform):
|
|
|
677
666
|
|
|
678
667
|
|
|
679
668
|
class RemoveTranslatableInline(SphinxTransform):
|
|
680
|
-
"""
|
|
681
|
-
Remove inline nodes used for translation as placeholders.
|
|
682
|
-
"""
|
|
669
|
+
"""Remove inline nodes used for translation as placeholders."""
|
|
683
670
|
|
|
684
671
|
default_priority = 999
|
|
685
672
|
|