Sphinx 7.1.2__py3-none-any.whl → 7.2.0__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 +6 -6
- sphinx/__main__.py +3 -1
- sphinx/addnodes.py +35 -22
- sphinx/application.py +40 -38
- sphinx/builders/__init__.py +16 -12
- sphinx/builders/_epub_base.py +15 -11
- sphinx/builders/changes.py +6 -4
- sphinx/builders/dirhtml.py +4 -2
- sphinx/builders/dummy.py +6 -4
- sphinx/builders/epub3.py +16 -8
- sphinx/builders/gettext.py +40 -43
- sphinx/builders/html/__init__.py +166 -196
- sphinx/builders/html/_assets.py +116 -0
- sphinx/builders/html/transforms.py +4 -2
- sphinx/builders/latex/__init__.py +12 -7
- sphinx/builders/latex/theming.py +5 -2
- sphinx/builders/latex/transforms.py +6 -3
- sphinx/builders/linkcheck.py +18 -11
- sphinx/builders/manpage.py +6 -4
- sphinx/builders/singlehtml.py +16 -9
- sphinx/builders/texinfo.py +11 -6
- sphinx/builders/text.py +8 -3
- sphinx/builders/xml.py +9 -4
- sphinx/cmd/build.py +27 -14
- sphinx/cmd/make_mode.py +13 -4
- sphinx/cmd/quickstart.py +13 -4
- sphinx/config.py +17 -14
- sphinx/deprecation.py +4 -2
- sphinx/directives/__init__.py +44 -12
- sphinx/directives/code.py +5 -4
- sphinx/directives/other.py +92 -44
- sphinx/directives/patches.py +1 -1
- sphinx/domains/__init__.py +11 -8
- sphinx/domains/c.py +67 -57
- sphinx/domains/changeset.py +3 -2
- sphinx/domains/citation.py +2 -1
- sphinx/domains/cpp.py +136 -93
- sphinx/domains/index.py +9 -5
- sphinx/domains/javascript.py +32 -19
- sphinx/domains/math.py +5 -3
- sphinx/domains/python.py +69 -57
- sphinx/domains/rst.py +20 -11
- sphinx/domains/std.py +21 -15
- sphinx/environment/__init__.py +97 -65
- sphinx/environment/adapters/indexentries.py +13 -10
- sphinx/environment/adapters/toctree.py +485 -308
- sphinx/environment/collectors/__init__.py +3 -4
- sphinx/environment/collectors/asset.py +10 -4
- sphinx/environment/collectors/dependencies.py +7 -4
- sphinx/environment/collectors/metadata.py +7 -5
- sphinx/environment/collectors/title.py +5 -3
- sphinx/environment/collectors/toctree.py +13 -8
- sphinx/errors.py +1 -1
- sphinx/events.py +5 -5
- sphinx/ext/apidoc.py +49 -27
- sphinx/ext/autodoc/__init__.py +179 -161
- sphinx/ext/autodoc/directive.py +10 -6
- sphinx/ext/autodoc/importer.py +22 -13
- sphinx/ext/autodoc/mock.py +4 -1
- sphinx/ext/autodoc/preserve_defaults.py +80 -12
- sphinx/ext/autodoc/type_comment.py +14 -10
- sphinx/ext/autodoc/typehints.py +7 -3
- sphinx/ext/autosectionlabel.py +6 -3
- sphinx/ext/autosummary/__init__.py +21 -15
- sphinx/ext/autosummary/generate.py +176 -126
- sphinx/ext/coverage.py +93 -8
- sphinx/ext/doctest.py +28 -17
- sphinx/ext/duration.py +19 -17
- sphinx/ext/extlinks.py +11 -6
- sphinx/ext/githubpages.py +8 -7
- sphinx/ext/graphviz.py +61 -17
- sphinx/ext/ifconfig.py +7 -4
- sphinx/ext/imgconverter.py +4 -2
- sphinx/ext/imgmath.py +29 -23
- sphinx/ext/inheritance_diagram.py +41 -27
- sphinx/ext/intersphinx.py +45 -38
- sphinx/ext/linkcode.py +8 -5
- sphinx/ext/mathjax.py +13 -9
- sphinx/ext/napoleon/__init__.py +3 -3
- sphinx/ext/napoleon/docstring.py +40 -31
- sphinx/ext/todo.py +10 -7
- sphinx/ext/viewcode.py +46 -25
- sphinx/extension.py +1 -1
- sphinx/highlighting.py +20 -12
- sphinx/io.py +5 -4
- sphinx/jinja2glue.py +24 -19
- sphinx/locale/__init__.py +8 -2
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +756 -740
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +758 -742
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +763 -747
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +767 -751
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +762 -746
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +766 -750
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/gl/LC_MESSAGES/sphinx.js +60 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +3695 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +763 -747
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +765 -749
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +767 -751
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +767 -751
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +762 -745
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +765 -749
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/sphinx.pot +748 -740
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/ta/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ta/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +763 -747
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +760 -749
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +759 -748
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +767 -751
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +754 -738
- sphinx/parsers.py +5 -4
- sphinx/project.py +52 -34
- sphinx/pycode/__init__.py +2 -1
- sphinx/pycode/ast.py +7 -13
- sphinx/pycode/parser.py +42 -38
- sphinx/registry.py +35 -29
- sphinx/roles.py +9 -4
- sphinx/search/__init__.py +5 -17
- sphinx/search/da.py +1 -1
- sphinx/search/de.py +1 -1
- sphinx/search/en.py +1 -1
- sphinx/search/es.py +1 -1
- sphinx/search/fi.py +1 -1
- sphinx/search/fr.py +1 -1
- sphinx/search/hu.py +1 -1
- sphinx/search/it.py +1 -1
- sphinx/search/ja.py +1 -1
- sphinx/search/nl.py +1 -1
- sphinx/search/no.py +1 -1
- sphinx/search/pt.py +1 -1
- sphinx/search/ro.py +1 -1
- sphinx/search/ru.py +1 -1
- sphinx/search/sv.py +1 -1
- sphinx/search/tr.py +1 -1
- sphinx/search/zh.py +1 -1
- sphinx/testing/fixtures.py +23 -30
- sphinx/testing/path.py +9 -0
- sphinx/testing/restructuredtext.py +13 -5
- sphinx/testing/util.py +20 -63
- sphinx/texinputs/sphinxlatexobjects.sty +15 -15
- sphinx/themes/agogo/static/agogo.css_t +10 -4
- sphinx/themes/basic/layout.html +1 -1
- sphinx/themes/basic/static/basic.css_t +4 -0
- sphinx/themes/basic/static/documentation_options.js_t +1 -2
- sphinx/themes/basic/static/searchtools.js +17 -9
- sphinx/themes/basic/static/sphinx_highlight.js +13 -3
- sphinx/themes/bizstyle/static/bizstyle.css_t +4 -0
- sphinx/themes/classic/theme.conf +1 -1
- sphinx/themes/epub/static/epub.css_t +6 -1
- sphinx/themes/haiku/theme.conf +1 -1
- sphinx/themes/nature/static/nature.css_t +4 -0
- sphinx/themes/nonav/static/nonav.css_t +6 -1
- sphinx/themes/pyramid/static/pyramid.css_t +4 -0
- sphinx/themes/scrolls/static/scrolls.css_t +4 -0
- sphinx/themes/scrolls/theme.conf +1 -1
- sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +4 -0
- sphinx/theming.py +9 -7
- sphinx/transforms/__init__.py +79 -3
- sphinx/transforms/compact_bullet_list.py +6 -3
- sphinx/transforms/i18n.py +26 -10
- sphinx/transforms/post_transforms/__init__.py +21 -8
- sphinx/transforms/post_transforms/code.py +6 -3
- sphinx/transforms/post_transforms/images.py +13 -9
- sphinx/util/__init__.py +21 -92
- sphinx/util/cfamily.py +7 -4
- sphinx/util/display.py +3 -2
- sphinx/util/docfields.py +7 -6
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +41 -31
- sphinx/util/fileutil.py +9 -6
- sphinx/util/i18n.py +21 -18
- sphinx/util/images.py +2 -1
- sphinx/util/index_entries.py +27 -0
- sphinx/util/inspect.py +83 -67
- sphinx/util/inventory.py +4 -2
- sphinx/util/logging.py +9 -6
- sphinx/util/matching.py +5 -2
- sphinx/util/math.py +6 -3
- sphinx/util/nodes.py +70 -31
- sphinx/util/osutil.py +22 -40
- sphinx/util/parallel.py +4 -1
- sphinx/util/rst.py +7 -3
- sphinx/util/tags.py +11 -4
- sphinx/util/template.py +17 -14
- sphinx/util/typing.py +61 -20
- sphinx/versioning.py +6 -4
- sphinx/writers/html.py +1 -1
- sphinx/writers/html5.py +32 -24
- sphinx/writers/latex.py +67 -53
- sphinx/writers/manpage.py +9 -5
- sphinx/writers/texinfo.py +11 -9
- sphinx/writers/text.py +14 -9
- sphinx/writers/xml.py +3 -2
- {sphinx-7.1.2.dist-info → sphinx-7.2.0.dist-info}/METADATA +7 -5
- sphinx-7.2.0.dist-info/RECORD +568 -0
- sphinx/testing/comparer.py +0 -97
- sphinx-7.1.2.dist-info/RECORD +0 -564
- {sphinx-7.1.2.dist-info → sphinx-7.2.0.dist-info}/LICENSE +0 -0
- {sphinx-7.1.2.dist-info → sphinx-7.2.0.dist-info}/WHEEL +0 -0
- {sphinx-7.1.2.dist-info → sphinx-7.2.0.dist-info}/entry_points.txt +0 -0
sphinx/builders/epub3.py
CHANGED
|
@@ -6,28 +6,30 @@ Originally derived from epub.py.
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
import html
|
|
9
|
+
import os
|
|
9
10
|
import re
|
|
11
|
+
import time
|
|
10
12
|
from os import path
|
|
11
|
-
from typing import Any, NamedTuple
|
|
13
|
+
from typing import TYPE_CHECKING, Any, NamedTuple
|
|
12
14
|
|
|
13
15
|
from sphinx import package_dir
|
|
14
|
-
from sphinx.application import Sphinx
|
|
15
16
|
from sphinx.builders import _epub_base
|
|
16
17
|
from sphinx.config import ENUM, Config
|
|
17
18
|
from sphinx.locale import __
|
|
18
19
|
from sphinx.util import logging
|
|
19
20
|
from sphinx.util.fileutil import copy_asset_file
|
|
20
|
-
from sphinx.util.i18n import format_date
|
|
21
21
|
from sphinx.util.osutil import make_filename
|
|
22
22
|
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from sphinx.application import Sphinx
|
|
25
|
+
|
|
23
26
|
logger = logging.getLogger(__name__)
|
|
24
27
|
|
|
25
28
|
|
|
26
29
|
class NavPoint(NamedTuple):
|
|
27
30
|
text: str
|
|
28
31
|
refuri: str
|
|
29
|
-
children: list[
|
|
30
|
-
# https://github.com/python/mypy/issues/7069
|
|
32
|
+
children: list[NavPoint]
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
# writing modes
|
|
@@ -99,12 +101,17 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|
|
99
101
|
"""
|
|
100
102
|
writing_mode = self.config.epub_writing_mode
|
|
101
103
|
|
|
104
|
+
if (source_date_epoch := os.getenv('SOURCE_DATE_EPOCH')) is not None:
|
|
105
|
+
time_tuple = time.gmtime(int(source_date_epoch))
|
|
106
|
+
else:
|
|
107
|
+
time_tuple = time.gmtime()
|
|
108
|
+
|
|
102
109
|
metadata = super().content_metadata()
|
|
103
110
|
metadata['description'] = html.escape(self.config.epub_description)
|
|
104
111
|
metadata['contributor'] = html.escape(self.config.epub_contributor)
|
|
105
112
|
metadata['page_progression_direction'] = PAGE_PROGRESSION_DIRECTIONS.get(writing_mode)
|
|
106
113
|
metadata['ibook_scroll_axis'] = IBOOK_SCROLL_AXIS.get(writing_mode)
|
|
107
|
-
metadata['date'] = html.escape(
|
|
114
|
+
metadata['date'] = html.escape(time.strftime("%Y-%m-%dT%H:%M:%SZ", time_tuple))
|
|
108
115
|
metadata['version'] = html.escape(self.config.version)
|
|
109
116
|
metadata['epub_version'] = self.config.epub_version
|
|
110
117
|
return metadata
|
|
@@ -156,7 +163,8 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|
|
156
163
|
navstack[-1].children.append(navpoint)
|
|
157
164
|
navstack.append(navpoint)
|
|
158
165
|
else:
|
|
159
|
-
|
|
166
|
+
unreachable = 'Should never reach here. It might be a bug.'
|
|
167
|
+
raise RuntimeError(unreachable)
|
|
160
168
|
|
|
161
169
|
return navstack[0].children
|
|
162
170
|
|
|
@@ -245,7 +253,7 @@ def convert_epub_css_files(app: Sphinx, config: Config) -> None:
|
|
|
245
253
|
logger.warning(__('invalid css_file: %r, ignored'), entry)
|
|
246
254
|
continue
|
|
247
255
|
|
|
248
|
-
config.epub_css_files = epub_css_files # type: ignore
|
|
256
|
+
config.epub_css_files = epub_css_files # type: ignore[attr-defined]
|
|
249
257
|
|
|
250
258
|
|
|
251
259
|
def setup(app: Sphinx) -> dict[str, Any]:
|
sphinx/builders/gettext.py
CHANGED
|
@@ -2,31 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import time
|
|
5
6
|
from codecs import open
|
|
6
7
|
from collections import defaultdict
|
|
7
|
-
from datetime import datetime, timedelta, timezone, tzinfo
|
|
8
8
|
from os import getenv, path, walk
|
|
9
|
-
from
|
|
10
|
-
from typing import Any, Generator, Iterable
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
11
10
|
from uuid import uuid4
|
|
12
11
|
|
|
13
12
|
from docutils import nodes
|
|
14
|
-
from docutils.nodes import Element
|
|
15
13
|
|
|
16
14
|
from sphinx import addnodes, package_dir
|
|
17
|
-
from sphinx.application import Sphinx
|
|
18
15
|
from sphinx.builders import Builder
|
|
19
16
|
from sphinx.errors import ThemeError
|
|
20
17
|
from sphinx.locale import __
|
|
21
|
-
from sphinx.util import logging
|
|
22
|
-
from sphinx.util.console import bold # type: ignore
|
|
18
|
+
from sphinx.util import logging
|
|
19
|
+
from sphinx.util.console import bold # type: ignore[attr-defined]
|
|
23
20
|
from sphinx.util.display import status_iterator
|
|
24
21
|
from sphinx.util.i18n import CatalogInfo, docname_to_domain
|
|
22
|
+
from sphinx.util.index_entries import split_index_msg
|
|
25
23
|
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
|
26
24
|
from sphinx.util.osutil import canon_path, ensuredir, relpath
|
|
27
25
|
from sphinx.util.tags import Tags
|
|
28
26
|
from sphinx.util.template import SphinxRenderer
|
|
29
27
|
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
import os
|
|
30
|
+
from collections.abc import Generator, Iterable
|
|
31
|
+
|
|
32
|
+
from docutils.nodes import Element
|
|
33
|
+
|
|
34
|
+
from sphinx.application import Sphinx
|
|
35
|
+
|
|
30
36
|
logger = logging.getLogger(__name__)
|
|
31
37
|
|
|
32
38
|
|
|
@@ -81,11 +87,12 @@ class MsgOrigin:
|
|
|
81
87
|
|
|
82
88
|
class GettextRenderer(SphinxRenderer):
|
|
83
89
|
def __init__(
|
|
84
|
-
self, template_path: str |
|
|
90
|
+
self, template_path: list[str | os.PathLike[str]] | None = None,
|
|
91
|
+
outdir: str | os.PathLike[str] | None = None,
|
|
85
92
|
) -> None:
|
|
86
93
|
self.outdir = outdir
|
|
87
94
|
if template_path is None:
|
|
88
|
-
template_path = path.join(package_dir, 'templates', 'gettext')
|
|
95
|
+
template_path = [path.join(package_dir, 'templates', 'gettext')]
|
|
89
96
|
super().__init__(template_path)
|
|
90
97
|
|
|
91
98
|
def escape(s: str) -> str:
|
|
@@ -147,11 +154,13 @@ class I18nBuilder(Builder):
|
|
|
147
154
|
|
|
148
155
|
for toctree in self.env.tocs[docname].findall(addnodes.toctree):
|
|
149
156
|
for node, msg in extract_messages(toctree):
|
|
150
|
-
node.uid = '' # type: ignore # Hack UUID model
|
|
157
|
+
node.uid = '' # type: ignore[attr-defined] # Hack UUID model
|
|
151
158
|
catalog.add(msg, node)
|
|
152
159
|
|
|
153
160
|
for node, msg in extract_messages(doctree):
|
|
154
|
-
|
|
161
|
+
# Do not extract messages from within substitution definitions.
|
|
162
|
+
if not _is_node_in_substitution_definition(node):
|
|
163
|
+
catalog.add(msg, node)
|
|
155
164
|
|
|
156
165
|
if 'index' in self.env.config.gettext_additional_targets:
|
|
157
166
|
# Extract translatable messages from index entries.
|
|
@@ -161,36 +170,14 @@ class I18nBuilder(Builder):
|
|
|
161
170
|
catalog.add(m, node)
|
|
162
171
|
|
|
163
172
|
|
|
164
|
-
#
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
source_date_epoch = getenv('SOURCE_DATE_EPOCH')
|
|
173
|
-
if source_date_epoch is not None:
|
|
174
|
-
timestamp = float(source_date_epoch)
|
|
175
|
-
tzdelta = timedelta(0)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
class LocalTimeZone(tzinfo):
|
|
179
|
-
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
180
|
-
super().__init__(*args, **kwargs)
|
|
181
|
-
self.tzdelta = tzdelta
|
|
182
|
-
|
|
183
|
-
def tzname(self, dt: datetime | None) -> str: # purely to satisfy mypy
|
|
184
|
-
return "local"
|
|
185
|
-
|
|
186
|
-
def utcoffset(self, dt: datetime | None) -> timedelta:
|
|
187
|
-
return self.tzdelta
|
|
188
|
-
|
|
189
|
-
def dst(self, dt: datetime | None) -> timedelta:
|
|
190
|
-
return timedelta(0)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
ltz = LocalTimeZone()
|
|
173
|
+
# If set, use the timestamp from SOURCE_DATE_EPOCH
|
|
174
|
+
# https://reproducible-builds.org/specs/source-date-epoch/
|
|
175
|
+
if (source_date_epoch := getenv('SOURCE_DATE_EPOCH')) is not None:
|
|
176
|
+
timestamp = time.gmtime(float(source_date_epoch))
|
|
177
|
+
else:
|
|
178
|
+
# determine timestamp once to remain unaffected by DST changes during build
|
|
179
|
+
timestamp = time.localtime()
|
|
180
|
+
ctime = time.strftime('%Y-%m-%d %H:%M%z', timestamp)
|
|
194
181
|
|
|
195
182
|
|
|
196
183
|
def should_write(filepath: str, new_content: str) -> bool:
|
|
@@ -211,6 +198,15 @@ def should_write(filepath: str, new_content: str) -> bool:
|
|
|
211
198
|
return True
|
|
212
199
|
|
|
213
200
|
|
|
201
|
+
def _is_node_in_substitution_definition(node: nodes.Node) -> bool:
|
|
202
|
+
"""Check "node" to test if it is in a substitution definition."""
|
|
203
|
+
while node.parent:
|
|
204
|
+
if isinstance(node, nodes.substitution_definition):
|
|
205
|
+
return True
|
|
206
|
+
node = node.parent
|
|
207
|
+
return False
|
|
208
|
+
|
|
209
|
+
|
|
214
210
|
class MessageCatalogBuilder(I18nBuilder):
|
|
215
211
|
"""
|
|
216
212
|
Builds gettext-style message catalogs (.pot files).
|
|
@@ -251,7 +247,8 @@ class MessageCatalogBuilder(I18nBuilder):
|
|
|
251
247
|
origin = MsgOrigin(template, line)
|
|
252
248
|
self.catalogs['sphinx'].add(msg, origin)
|
|
253
249
|
except Exception as exc:
|
|
254
|
-
|
|
250
|
+
msg = f'{template}: {exc!r}'
|
|
251
|
+
raise ThemeError(msg) from exc
|
|
255
252
|
|
|
256
253
|
def build(
|
|
257
254
|
self,
|
|
@@ -270,7 +267,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
|
|
270
267
|
'project': self.config.project,
|
|
271
268
|
'last_translator': self.config.gettext_last_translator,
|
|
272
269
|
'language_team': self.config.gettext_language_team,
|
|
273
|
-
'ctime':
|
|
270
|
+
'ctime': ctime,
|
|
274
271
|
'display_location': self.config.gettext_location,
|
|
275
272
|
'display_uuid': self.config.gettext_uuid,
|
|
276
273
|
}
|