Sphinx 8.0.2__py3-none-any.whl → 8.1.1__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 -3
- sphinx/_cli/__init__.py +40 -20
- sphinx/_cli/util/colour.py +5 -4
- sphinx/_cli/util/errors.py +28 -11
- sphinx/application.py +361 -38
- sphinx/builders/__init__.py +229 -83
- sphinx/builders/_epub_base.py +118 -71
- sphinx/builders/changes.py +39 -21
- sphinx/builders/dirhtml.py +4 -4
- sphinx/builders/dummy.py +2 -5
- sphinx/builders/epub3.py +43 -22
- sphinx/builders/gettext.py +43 -25
- sphinx/builders/html/__init__.py +284 -218
- sphinx/builders/html/_assets.py +62 -26
- sphinx/builders/html/_build_info.py +76 -0
- sphinx/builders/html/transforms.py +11 -9
- sphinx/builders/latex/__init__.py +139 -81
- sphinx/builders/latex/constants.py +7 -7
- sphinx/builders/latex/nodes.py +3 -2
- sphinx/builders/latex/theming.py +7 -5
- sphinx/builders/latex/transforms.py +27 -19
- sphinx/builders/linkcheck.py +146 -72
- sphinx/builders/manpage.py +30 -13
- sphinx/builders/singlehtml.py +22 -14
- sphinx/builders/texinfo.py +67 -37
- sphinx/builders/text.py +5 -5
- sphinx/builders/xml.py +6 -9
- sphinx/cmd/build.py +282 -103
- sphinx/cmd/make_mode.py +106 -63
- sphinx/cmd/quickstart.py +341 -145
- sphinx/config.py +45 -12
- sphinx/deprecation.py +8 -2
- sphinx/directives/__init__.py +28 -19
- sphinx/directives/code.py +86 -56
- sphinx/directives/other.py +50 -36
- sphinx/directives/patches.py +29 -19
- sphinx/domains/__init__.py +20 -120
- sphinx/domains/_domains_container.py +281 -0
- sphinx/domains/_index.py +110 -0
- sphinx/domains/c/__init__.py +3 -3
- sphinx/domains/c/_parser.py +10 -6
- sphinx/domains/changeset.py +5 -3
- sphinx/domains/citation.py +5 -3
- sphinx/domains/cpp/__init__.py +9 -11
- sphinx/domains/cpp/_parser.py +8 -7
- sphinx/domains/index.py +3 -3
- sphinx/domains/javascript.py +12 -7
- sphinx/domains/math.py +2 -2
- sphinx/domains/python/__init__.py +10 -5
- sphinx/domains/python/_object.py +1 -1
- sphinx/domains/rst.py +5 -5
- sphinx/domains/std/__init__.py +16 -11
- sphinx/environment/__init__.py +202 -146
- sphinx/environment/adapters/asset.py +3 -2
- sphinx/environment/adapters/indexentries.py +74 -33
- sphinx/environment/adapters/toctree.py +100 -43
- sphinx/environment/collectors/__init__.py +19 -8
- sphinx/environment/collectors/asset.py +47 -15
- sphinx/environment/collectors/dependencies.py +8 -4
- sphinx/environment/collectors/metadata.py +7 -2
- sphinx/environment/collectors/title.py +7 -2
- sphinx/environment/collectors/toctree.py +54 -22
- sphinx/errors.py +4 -1
- sphinx/events.py +314 -7
- sphinx/ext/apidoc.py +42 -18
- sphinx/ext/autodoc/__init__.py +52 -24
- sphinx/ext/autodoc/importer.py +6 -9
- sphinx/ext/autosectionlabel.py +1 -2
- sphinx/ext/autosummary/__init__.py +3 -1
- sphinx/ext/autosummary/generate.py +28 -14
- sphinx/ext/coverage.py +7 -7
- sphinx/ext/doctest.py +4 -8
- sphinx/ext/duration.py +6 -5
- sphinx/ext/inheritance_diagram.py +1 -1
- sphinx/ext/intersphinx/_cli.py +6 -4
- sphinx/ext/intersphinx/_load.py +77 -32
- sphinx/ext/intersphinx/_resolve.py +173 -79
- sphinx/ext/intersphinx/_shared.py +7 -5
- sphinx/ext/linkcode.py +7 -1
- sphinx/ext/mathjax.py +1 -2
- sphinx/ext/napoleon/__init__.py +37 -24
- sphinx/ext/napoleon/docstring.py +202 -134
- sphinx/ext/todo.py +5 -3
- sphinx/highlighting.py +9 -2
- sphinx/io.py +1 -1
- sphinx/jinja2glue.py +27 -6
- sphinx/locale/__init__.py +6 -2
- sphinx/locale/ar/LC_MESSAGES/sphinx.js +8 -1
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +2246 -2288
- sphinx/locale/bg/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/bn/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +2349 -2395
- sphinx/locale/ca/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +2846 -2892
- sphinx/locale/cak/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +2213 -2259
- sphinx/locale/cs/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +2225 -2269
- sphinx/locale/cy/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +2403 -2447
- sphinx/locale/da/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +2214 -2260
- sphinx/locale/de/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +2230 -2276
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/el/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +2619 -2665
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +2519 -2565
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/eo/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +2232 -2278
- sphinx/locale/es/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +2516 -2561
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +2114 -2159
- sphinx/locale/et/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +2317 -2363
- sphinx/locale/eu/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +2218 -2264
- sphinx/locale/fa/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +2505 -2551
- sphinx/locale/fi/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +2303 -2349
- sphinx/locale/fr/LC_MESSAGES/sphinx.js +6 -2
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +2863 -2908
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +2114 -2159
- sphinx/locale/gl/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +2571 -2617
- sphinx/locale/he/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +2307 -2352
- sphinx/locale/hi/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +2580 -2626
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/hr/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +2238 -2283
- sphinx/locale/hu/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +2228 -2274
- sphinx/locale/id/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +2787 -2834
- sphinx/locale/is/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +2224 -2270
- sphinx/locale/it/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +2231 -2276
- sphinx/locale/ja/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +2507 -2554
- sphinx/locale/ka/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +2428 -2474
- sphinx/locale/ko/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +2516 -2563
- sphinx/locale/lt/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +2425 -2469
- sphinx/locale/lv/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +2362 -2407
- sphinx/locale/mk/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +2121 -2167
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +2220 -2266
- sphinx/locale/ne/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +2221 -2267
- sphinx/locale/nl/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +2240 -2286
- sphinx/locale/pl/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +2319 -2363
- sphinx/locale/pt/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +2114 -2159
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +2854 -2899
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +2224 -2269
- sphinx/locale/ro/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +2226 -2271
- sphinx/locale/ru/LC_MESSAGES/sphinx.js +8 -3
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +2841 -2885
- sphinx/locale/si/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +2294 -2340
- sphinx/locale/sk/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +2497 -2541
- sphinx/locale/sl/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +2331 -2375
- sphinx/locale/sphinx.pot +2121 -2167
- sphinx/locale/sq/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +2855 -2901
- sphinx/locale/sr/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +2203 -2248
- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +2423 -2469
- sphinx/locale/te/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/tr/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +2443 -2489
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +2329 -2373
- sphinx/locale/ur/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/vi/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +2199 -2246
- sphinx/locale/yue/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +2112 -2159
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +2112 -2159
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +2845 -2892
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +2112 -2159
- sphinx/parsers.py +3 -1
- sphinx/project.py +6 -2
- sphinx/pycode/__init__.py +11 -4
- sphinx/pycode/ast.py +58 -58
- sphinx/pycode/parser.py +49 -28
- sphinx/pygments_styles.py +49 -49
- sphinx/registry.py +8 -3
- sphinx/roles.py +136 -13
- sphinx/search/__init__.py +146 -87
- sphinx/search/da.py +2 -4
- sphinx/search/de.py +2 -4
- sphinx/search/en.py +4 -4
- sphinx/search/es.py +2 -4
- sphinx/search/fi.py +2 -4
- sphinx/search/fr.py +2 -4
- sphinx/search/hu.py +2 -4
- sphinx/search/it.py +2 -4
- sphinx/search/ja.py +55 -32
- sphinx/search/nl.py +2 -4
- sphinx/search/no.py +2 -4
- sphinx/search/pt.py +2 -4
- sphinx/search/ro.py +0 -2
- sphinx/search/ru.py +2 -4
- sphinx/search/sv.py +2 -4
- sphinx/search/tr.py +0 -2
- sphinx/search/zh.py +18 -13
- sphinx/templates/graphviz/graphviz.css +0 -7
- sphinx/testing/fixtures.py +6 -5
- sphinx/testing/path.py +7 -5
- sphinx/testing/util.py +63 -29
- sphinx/texinputs/sphinx.sty +115 -50
- sphinx/texinputs/sphinxlatexadmonitions.sty +56 -38
- sphinx/texinputs/sphinxlatexcontainers.sty +1 -1
- sphinx/texinputs/sphinxlatexgraphics.sty +3 -2
- sphinx/texinputs/sphinxlatexindbibtoc.sty +1 -1
- sphinx/texinputs/sphinxlatexlists.sty +1 -1
- sphinx/texinputs/sphinxlatexliterals.sty +4 -1
- sphinx/texinputs/sphinxlatexnumfig.sty +22 -9
- sphinx/texinputs/sphinxlatexobjects.sty +1 -1
- sphinx/texinputs/sphinxlatexshadowbox.sty +72 -10
- sphinx/texinputs/sphinxlatexstyleheadings.sty +7 -2
- sphinx/texinputs/sphinxlatexstylepage.sty +2 -8
- sphinx/texinputs/sphinxlatexstyletext.sty +2 -4
- sphinx/texinputs/sphinxlatextables.sty +1 -1
- sphinx/texinputs/sphinxoptionsgeometry.sty +1 -1
- sphinx/texinputs/sphinxoptionshyperref.sty +1 -1
- sphinx/themes/agogo/layout.html +1 -10
- sphinx/themes/agogo/static/agogo.css.jinja +0 -7
- sphinx/themes/basic/defindex.html +1 -8
- sphinx/themes/basic/domainindex.html +1 -9
- sphinx/themes/basic/genindex-single.html +1 -9
- sphinx/themes/basic/genindex-split.html +1 -9
- sphinx/themes/basic/genindex.html +1 -9
- sphinx/themes/basic/globaltoc.html +1 -9
- sphinx/themes/basic/layout.html +1 -9
- sphinx/themes/basic/localtoc.html +1 -9
- sphinx/themes/basic/page.html +1 -9
- sphinx/themes/basic/relations.html +1 -9
- sphinx/themes/basic/search.html +1 -9
- sphinx/themes/basic/searchbox.html +1 -9
- sphinx/themes/basic/searchfield.html +4 -10
- sphinx/themes/basic/sourcelink.html +1 -9
- sphinx/themes/basic/static/basic.css.jinja +2 -13
- sphinx/themes/basic/static/doctools.js +0 -7
- sphinx/themes/basic/static/language_data.js.jinja +0 -7
- sphinx/themes/basic/static/searchtools.js +25 -13
- sphinx/themes/bizstyle/layout.html +1 -9
- sphinx/themes/bizstyle/static/bizstyle.css.jinja +0 -7
- sphinx/themes/bizstyle/static/bizstyle.js.jinja +5 -11
- sphinx/themes/classic/layout.html +1 -9
- sphinx/themes/classic/static/classic.css.jinja +0 -7
- sphinx/themes/classic/static/sidebar.js.jinja +0 -6
- sphinx/themes/epub/epub-cover.html +1 -9
- sphinx/themes/epub/layout.html +1 -9
- sphinx/themes/epub/static/epub.css.jinja +0 -7
- sphinx/themes/haiku/layout.html +1 -9
- sphinx/themes/haiku/static/haiku.css.jinja +0 -6
- sphinx/themes/nature/static/nature.css.jinja +0 -7
- sphinx/themes/nonav/layout.html +1 -9
- sphinx/themes/nonav/static/nonav.css.jinja +0 -7
- sphinx/themes/pyramid/static/epub.css.jinja +0 -7
- sphinx/themes/pyramid/static/pyramid.css.jinja +0 -7
- sphinx/themes/scrolls/layout.html +1 -10
- sphinx/themes/scrolls/static/scrolls.css.jinja +0 -7
- sphinx/themes/sphinxdoc/static/sphinxdoc.css.jinja +2 -7
- sphinx/themes/traditional/static/traditional.css.jinja +0 -7
- sphinx/theming.py +18 -6
- sphinx/transforms/__init__.py +56 -35
- sphinx/transforms/compact_bullet_list.py +3 -2
- sphinx/transforms/i18n.py +132 -50
- sphinx/transforms/post_transforms/__init__.py +94 -43
- sphinx/transforms/post_transforms/code.py +7 -6
- sphinx/transforms/post_transforms/images.py +71 -54
- sphinx/transforms/references.py +1 -2
- sphinx/util/__init__.py +23 -194
- sphinx/util/_files.py +80 -0
- sphinx/util/_importer.py +27 -0
- sphinx/util/_io.py +1 -2
- sphinx/util/_lines.py +26 -0
- sphinx/util/_pathlib.py +5 -2
- sphinx/util/_serialise.py +53 -0
- sphinx/util/_timestamps.py +2 -1
- sphinx/util/_uri.py +16 -0
- sphinx/util/cfamily.py +48 -25
- sphinx/util/console.py +1 -0
- sphinx/util/display.py +1 -1
- sphinx/util/docfields.py +125 -45
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +118 -44
- sphinx/util/exceptions.py +11 -5
- sphinx/util/fileutil.py +53 -32
- sphinx/util/http_date.py +9 -7
- sphinx/util/i18n.py +49 -16
- sphinx/util/images.py +7 -6
- sphinx/util/inspect.py +29 -12
- sphinx/util/inventory.py +47 -29
- sphinx/util/logging.py +58 -85
- sphinx/util/matching.py +3 -3
- sphinx/util/math.py +1 -1
- sphinx/util/nodes.py +176 -108
- sphinx/util/osutil.py +13 -10
- sphinx/util/parallel.py +5 -4
- sphinx/util/parsing.py +5 -3
- sphinx/util/png.py +3 -3
- sphinx/util/requests.py +8 -4
- sphinx/util/rst.py +5 -3
- sphinx/util/tags.py +5 -2
- sphinx/util/template.py +26 -11
- sphinx/util/texescape.py +2 -2
- sphinx/util/typing.py +89 -38
- sphinx/versioning.py +3 -1
- sphinx/writers/html.py +22 -7
- sphinx/writers/html5.py +113 -64
- sphinx/writers/latex.py +408 -221
- sphinx/writers/manpage.py +25 -15
- sphinx/writers/texinfo.py +94 -82
- sphinx/writers/text.py +87 -53
- sphinx/writers/xml.py +5 -4
- sphinx-8.1.1.dist-info/LICENSE.rst +31 -0
- {sphinx-8.0.2.dist-info → sphinx-8.1.1.dist-info}/METADATA +13 -11
- sphinx-8.1.1.dist-info/RECORD +598 -0
- sphinx-8.0.2.dist-info/LICENSE.rst +0 -67
- sphinx-8.0.2.dist-info/RECORD +0 -590
- {sphinx-8.0.2.dist-info → sphinx-8.1.1.dist-info}/WHEEL +0 -0
- {sphinx-8.0.2.dist-info → sphinx-8.1.1.dist-info}/entry_points.txt +0 -0
sphinx/writers/latex.py
CHANGED
|
@@ -10,12 +10,11 @@ import re
|
|
|
10
10
|
from collections import defaultdict
|
|
11
11
|
from collections.abc import Iterable
|
|
12
12
|
from os import path
|
|
13
|
-
from typing import TYPE_CHECKING, Any, cast
|
|
13
|
+
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
|
14
14
|
|
|
15
15
|
from docutils import nodes, writers
|
|
16
16
|
|
|
17
17
|
from sphinx import addnodes, highlighting
|
|
18
|
-
from sphinx.domains.std import StandardDomain
|
|
19
18
|
from sphinx.errors import SphinxError
|
|
20
19
|
from sphinx.locale import _, __, admonitionlabels
|
|
21
20
|
from sphinx.util import logging, texescape
|
|
@@ -42,16 +41,25 @@ if TYPE_CHECKING:
|
|
|
42
41
|
logger = logging.getLogger(__name__)
|
|
43
42
|
|
|
44
43
|
MAX_CITATION_LABEL_LENGTH = 8
|
|
45
|
-
LATEXSECTIONNAMES = [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
LATEXSECTIONNAMES = [
|
|
45
|
+
'part',
|
|
46
|
+
'chapter',
|
|
47
|
+
'section',
|
|
48
|
+
'subsection',
|
|
49
|
+
'subsubsection',
|
|
50
|
+
'paragraph',
|
|
51
|
+
'subparagraph',
|
|
52
|
+
]
|
|
53
|
+
ENUMERATE_LIST_STYLE = defaultdict(
|
|
54
|
+
lambda: r'\arabic',
|
|
55
|
+
{
|
|
56
|
+
'arabic': r'\arabic',
|
|
57
|
+
'loweralpha': r'\alph',
|
|
58
|
+
'upperalpha': r'\Alph',
|
|
59
|
+
'lowerroman': r'\roman',
|
|
60
|
+
'upperroman': r'\Roman',
|
|
61
|
+
},
|
|
62
|
+
)
|
|
55
63
|
|
|
56
64
|
CR = '\n'
|
|
57
65
|
BLANKLINE = '\n\n'
|
|
@@ -66,16 +74,19 @@ class UnsupportedError(SphinxError):
|
|
|
66
74
|
category = 'Markup is unsupported in LaTeX'
|
|
67
75
|
|
|
68
76
|
|
|
69
|
-
class LaTeXWriter(writers.Writer): # type: ignore[
|
|
70
|
-
|
|
77
|
+
class LaTeXWriter(writers.Writer): # type: ignore[type-arg]
|
|
71
78
|
supported = ('sphinxlatex',)
|
|
72
79
|
|
|
73
|
-
settings_spec = (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
(
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
settings_spec = (
|
|
81
|
+
'LaTeX writer options',
|
|
82
|
+
'',
|
|
83
|
+
(
|
|
84
|
+
('Document name', ['--docname'], {'default': ''}),
|
|
85
|
+
('Document class', ['--docclass'], {'default': 'manual'}),
|
|
86
|
+
('Author', ['--author'], {'default': ''}),
|
|
87
|
+
),
|
|
88
|
+
)
|
|
89
|
+
settings_defaults: ClassVar[dict[str, Any]] = {}
|
|
79
90
|
|
|
80
91
|
theme: Theme
|
|
81
92
|
|
|
@@ -84,13 +95,17 @@ class LaTeXWriter(writers.Writer): # type: ignore[misc]
|
|
|
84
95
|
self.builder = builder
|
|
85
96
|
|
|
86
97
|
def translate(self) -> None:
|
|
87
|
-
|
|
98
|
+
assert isinstance(self.document, nodes.document)
|
|
99
|
+
visitor = self.builder.create_translator(
|
|
100
|
+
self.document, self.builder, self.theme
|
|
101
|
+
)
|
|
88
102
|
self.document.walkabout(visitor)
|
|
89
103
|
self.output = cast(LaTeXTranslator, visitor).astext()
|
|
90
104
|
|
|
91
105
|
|
|
92
106
|
# Helper classes
|
|
93
107
|
|
|
108
|
+
|
|
94
109
|
class Table:
|
|
95
110
|
"""A table data"""
|
|
96
111
|
|
|
@@ -152,7 +167,9 @@ class Table:
|
|
|
152
167
|
return 'tabular'
|
|
153
168
|
elif self.colspec:
|
|
154
169
|
return 'tabulary'
|
|
155
|
-
elif self.has_problematic or (
|
|
170
|
+
elif self.has_problematic or (
|
|
171
|
+
self.colwidths and 'colwidths-given' in self.classes
|
|
172
|
+
):
|
|
156
173
|
return 'tabular'
|
|
157
174
|
else:
|
|
158
175
|
return 'tabulary'
|
|
@@ -177,14 +194,20 @@ class Table:
|
|
|
177
194
|
colspecs = [r'\X{%d}{%d}' % (width, total) for width in self.colwidths]
|
|
178
195
|
return f'{{{_colsep}{_colsep.join(colspecs)}{_colsep}}}' + CR
|
|
179
196
|
elif self.has_problematic:
|
|
180
|
-
return
|
|
181
|
-
|
|
197
|
+
return (
|
|
198
|
+
r'{%s*{%d}{\X{1}{%d}%s}}'
|
|
199
|
+
% (_colsep, self.colcount, self.colcount, _colsep)
|
|
200
|
+
+ CR
|
|
201
|
+
)
|
|
182
202
|
elif self.get_table_type() == 'tabulary':
|
|
183
203
|
# sphinx.sty sets T to be J by default.
|
|
184
204
|
return '{' + _colsep + (('T' + _colsep) * self.colcount) + '}' + CR
|
|
185
205
|
elif self.has_oldproblematic:
|
|
186
|
-
return
|
|
187
|
-
|
|
206
|
+
return (
|
|
207
|
+
r'{%s*{%d}{\X{1}{%d}%s}}'
|
|
208
|
+
% (_colsep, self.colcount, self.colcount, _colsep)
|
|
209
|
+
+ CR
|
|
210
|
+
)
|
|
188
211
|
else:
|
|
189
212
|
return '{' + _colsep + (('l' + _colsep) * self.colcount) + '}' + CR
|
|
190
213
|
|
|
@@ -200,7 +223,9 @@ class Table:
|
|
|
200
223
|
self.cells[(self.row + row, self.col + col)] = self.cell_id
|
|
201
224
|
|
|
202
225
|
def cell(
|
|
203
|
-
self,
|
|
226
|
+
self,
|
|
227
|
+
row: int | None = None,
|
|
228
|
+
col: int | None = None,
|
|
204
229
|
) -> TableCell | None:
|
|
205
230
|
"""Returns a cell object (i.e. rectangular area) containing given position.
|
|
206
231
|
|
|
@@ -266,22 +291,22 @@ def rstdim_to_latexdim(width_str: str, scale: int = 100) -> str:
|
|
|
266
291
|
amount, unit = match.groups()[:2]
|
|
267
292
|
if scale == 100:
|
|
268
293
|
float(amount) # validate amount is float
|
|
269
|
-
if unit in ('',
|
|
270
|
-
res = r
|
|
294
|
+
if unit in ('', 'px'):
|
|
295
|
+
res = r'%s\sphinxpxdimen' % amount
|
|
271
296
|
elif unit == 'pt':
|
|
272
297
|
res = '%sbp' % amount # convert to 'bp'
|
|
273
|
-
elif unit ==
|
|
274
|
-
res = r
|
|
298
|
+
elif unit == '%':
|
|
299
|
+
res = r'%.3f\linewidth' % (float(amount) / 100.0)
|
|
275
300
|
else:
|
|
276
301
|
amount_float = float(amount) * scale / 100.0
|
|
277
|
-
if unit in ('',
|
|
278
|
-
res = r
|
|
302
|
+
if unit in ('', 'px'):
|
|
303
|
+
res = r'%.5f\sphinxpxdimen' % amount_float
|
|
279
304
|
elif unit == 'pt':
|
|
280
305
|
res = '%.5fbp' % amount_float
|
|
281
|
-
elif unit ==
|
|
282
|
-
res = r
|
|
306
|
+
elif unit == '%':
|
|
307
|
+
res = r'%.5f\linewidth' % (amount_float / 100.0)
|
|
283
308
|
else:
|
|
284
|
-
res = f
|
|
309
|
+
res = f'{amount_float:.5f}{unit}'
|
|
285
310
|
return res
|
|
286
311
|
|
|
287
312
|
|
|
@@ -292,8 +317,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
292
317
|
# default is originally 3. For book/report, 2 is already LaTeX default.
|
|
293
318
|
ignore_missing_images = False
|
|
294
319
|
|
|
295
|
-
def __init__(
|
|
296
|
-
|
|
320
|
+
def __init__(
|
|
321
|
+
self, document: nodes.document, builder: LaTeXBuilder, theme: Theme
|
|
322
|
+
) -> None:
|
|
297
323
|
super().__init__(document, builder)
|
|
298
324
|
self.body: list[str] = []
|
|
299
325
|
self.theme = theme
|
|
@@ -330,46 +356,63 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
330
356
|
self.top_sectionlevel = 1
|
|
331
357
|
if self.config.latex_toplevel_sectioning:
|
|
332
358
|
try:
|
|
333
|
-
self.top_sectionlevel =
|
|
334
|
-
self.
|
|
359
|
+
self.top_sectionlevel = self.sectionnames.index(
|
|
360
|
+
self.config.latex_toplevel_sectioning
|
|
361
|
+
)
|
|
335
362
|
except ValueError:
|
|
336
|
-
logger.warning(
|
|
337
|
-
|
|
363
|
+
logger.warning(
|
|
364
|
+
__('unknown %r toplevel_sectioning for class %r'),
|
|
365
|
+
self.config.latex_toplevel_sectioning,
|
|
366
|
+
self.theme.docclass,
|
|
367
|
+
)
|
|
338
368
|
|
|
339
369
|
if self.config.numfig:
|
|
340
370
|
self.numfig_secnum_depth = self.config.numfig_secnum_depth
|
|
341
371
|
if self.numfig_secnum_depth > 0: # default is 1
|
|
342
372
|
# numfig_secnum_depth as passed to sphinx.sty indices same names as in
|
|
343
373
|
# LATEXSECTIONNAMES but with -1 for part, 0 for chapter, 1 for section...
|
|
344
|
-
if
|
|
345
|
-
|
|
374
|
+
if (
|
|
375
|
+
len(self.sectionnames) < len(LATEXSECTIONNAMES)
|
|
376
|
+
and self.top_sectionlevel > 0
|
|
377
|
+
):
|
|
346
378
|
self.numfig_secnum_depth += self.top_sectionlevel
|
|
347
379
|
else:
|
|
348
380
|
self.numfig_secnum_depth += self.top_sectionlevel - 1
|
|
349
381
|
# this (minus one) will serve as minimum to LaTeX's secnumdepth
|
|
350
|
-
self.numfig_secnum_depth = min(
|
|
351
|
-
|
|
382
|
+
self.numfig_secnum_depth = min(
|
|
383
|
+
self.numfig_secnum_depth, len(LATEXSECTIONNAMES) - 1
|
|
384
|
+
)
|
|
352
385
|
# if passed key value is < 1 LaTeX will act as if 0; see sphinx.sty
|
|
353
386
|
sphinxpkgoptions.append('numfigreset=%s' % self.numfig_secnum_depth)
|
|
354
387
|
else:
|
|
355
388
|
sphinxpkgoptions.append('nonumfigreset')
|
|
356
389
|
|
|
357
390
|
if self.config.numfig and self.config.math_numfig:
|
|
358
|
-
sphinxpkgoptions.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
391
|
+
sphinxpkgoptions.extend([
|
|
392
|
+
'mathnumfig',
|
|
393
|
+
'mathnumsep={%s}' % self.config.math_numsep,
|
|
394
|
+
])
|
|
395
|
+
|
|
396
|
+
if (
|
|
397
|
+
self.config.language not in {'en', 'ja'}
|
|
398
|
+
and 'fncychap' not in self.config.latex_elements
|
|
399
|
+
):
|
|
362
400
|
# use Sonny style if any language specified (except English)
|
|
363
|
-
self.elements['fncychap'] = (
|
|
364
|
-
|
|
365
|
-
|
|
401
|
+
self.elements['fncychap'] = (
|
|
402
|
+
r'\usepackage[Sonny]{fncychap}'
|
|
403
|
+
+ CR
|
|
404
|
+
+ r'\ChNameVar{\Large\normalfont\sffamily}'
|
|
405
|
+
+ CR
|
|
406
|
+
+ r'\ChTitleVar{\Large\normalfont\sffamily}'
|
|
407
|
+
)
|
|
366
408
|
|
|
367
409
|
self.babel = self.builder.babel
|
|
368
410
|
if not self.babel.is_supported_language():
|
|
369
411
|
# emit warning if specified language is invalid
|
|
370
412
|
# (only emitting, nothing changed to processing)
|
|
371
|
-
logger.warning(
|
|
372
|
-
|
|
413
|
+
logger.warning(
|
|
414
|
+
__('no Babel option known for language %r'), self.config.language
|
|
415
|
+
)
|
|
373
416
|
|
|
374
417
|
minsecnumdepth = self.secnumdepth # 2 from legacy sphinx manual/howto
|
|
375
418
|
if self.document.get('tocdepth'):
|
|
@@ -380,8 +423,10 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
380
423
|
# tocdepth = 2: show parts, chapters, sections and subsections
|
|
381
424
|
# ...
|
|
382
425
|
tocdepth = self.document.get('tocdepth', 999) + self.top_sectionlevel - 2
|
|
383
|
-
if
|
|
384
|
-
|
|
426
|
+
if (
|
|
427
|
+
len(self.sectionnames) < len(LATEXSECTIONNAMES)
|
|
428
|
+
and self.top_sectionlevel > 0
|
|
429
|
+
):
|
|
385
430
|
tocdepth += 1 # because top_sectionlevel is shifted by -1
|
|
386
431
|
if tocdepth > len(LATEXSECTIONNAMES) - 2: # default is 5 <-> subparagraph
|
|
387
432
|
logger.warning(__('too large :maxdepth:, ignored.'))
|
|
@@ -394,26 +439,30 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
394
439
|
minsecnumdepth = max(minsecnumdepth, self.numfig_secnum_depth - 1)
|
|
395
440
|
|
|
396
441
|
if minsecnumdepth > self.secnumdepth:
|
|
397
|
-
self.elements['secnumdepth'] =
|
|
398
|
-
|
|
442
|
+
self.elements['secnumdepth'] = (
|
|
443
|
+
r'\setcounter{secnumdepth}{%d}' % minsecnumdepth
|
|
444
|
+
)
|
|
399
445
|
|
|
400
446
|
contentsname = document.get('contentsname')
|
|
401
447
|
if contentsname:
|
|
402
|
-
self.elements['contentsname'] = self.babel_renewcommand(
|
|
403
|
-
|
|
448
|
+
self.elements['contentsname'] = self.babel_renewcommand(
|
|
449
|
+
r'\contentsname', contentsname
|
|
450
|
+
)
|
|
404
451
|
|
|
405
452
|
if self.elements['maxlistdepth']:
|
|
406
453
|
sphinxpkgoptions.append('maxlistdepth=%s' % self.elements['maxlistdepth'])
|
|
407
454
|
if sphinxpkgoptions:
|
|
408
455
|
self.elements['sphinxpkgoptions'] = '[,%s]' % ','.join(sphinxpkgoptions)
|
|
409
456
|
if self.elements['sphinxsetup']:
|
|
410
|
-
self.elements['sphinxsetup'] = (
|
|
457
|
+
self.elements['sphinxsetup'] = (
|
|
458
|
+
r'\sphinxsetup{%s}' % self.elements['sphinxsetup']
|
|
459
|
+
)
|
|
411
460
|
if self.elements['extraclassoptions']:
|
|
412
|
-
self.elements['classoptions'] += ',' +
|
|
413
|
-
self.elements['extraclassoptions']
|
|
461
|
+
self.elements['classoptions'] += ',' + self.elements['extraclassoptions']
|
|
414
462
|
|
|
415
|
-
self.highlighter = highlighting.PygmentsBridge(
|
|
416
|
-
|
|
463
|
+
self.highlighter = highlighting.PygmentsBridge(
|
|
464
|
+
'latex', self.config.pygments_style, latex_engine=self.config.latex_engine
|
|
465
|
+
)
|
|
417
466
|
self.context: list[Any] = []
|
|
418
467
|
self.descstack: list[str] = []
|
|
419
468
|
self.tables: list[Table] = []
|
|
@@ -443,10 +492,13 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
443
492
|
def hypertarget(self, id: str, withdoc: bool = True, anchor: bool = True) -> str:
|
|
444
493
|
if withdoc:
|
|
445
494
|
id = self.curfilestack[-1] + ':' + id
|
|
446
|
-
|
|
495
|
+
escaped_id = self.idescape(id)
|
|
496
|
+
return (r'\phantomsection' if anchor else '') + r'\label{%s}' % escaped_id
|
|
447
497
|
|
|
448
498
|
def hypertarget_to(self, node: Element, anchor: bool = False) -> str:
|
|
449
|
-
labels = ''.join(
|
|
499
|
+
labels = ''.join(
|
|
500
|
+
self.hypertarget(node_id, anchor=False) for node_id in node['ids']
|
|
501
|
+
)
|
|
450
502
|
if anchor:
|
|
451
503
|
return r'\phantomsection' + labels
|
|
452
504
|
else:
|
|
@@ -462,9 +514,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
462
514
|
return texescape.escape(s, self.config.latex_engine)
|
|
463
515
|
|
|
464
516
|
def idescape(self, id: str) -> str:
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
517
|
+
id = str(id).translate(tex_replace_map)
|
|
518
|
+
id = id.encode('ascii', 'backslashreplace').decode('ascii')
|
|
519
|
+
return r'\detokenize{%s}' % id.replace('\\', '_')
|
|
468
520
|
|
|
469
521
|
def babel_renewcommand(self, command: str, definition: str) -> str:
|
|
470
522
|
if self.elements['multilingual']:
|
|
@@ -474,10 +526,12 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
474
526
|
prefix = ''
|
|
475
527
|
suffix = ''
|
|
476
528
|
|
|
477
|
-
return
|
|
529
|
+
return rf'{prefix}\renewcommand{{{command}}}{{{definition}}}{suffix}' + CR
|
|
478
530
|
|
|
479
531
|
def generate_indices(self) -> str:
|
|
480
|
-
def generate(
|
|
532
|
+
def generate(
|
|
533
|
+
content: list[tuple[str, list[IndexEntry]]], collapsed: bool
|
|
534
|
+
) -> None:
|
|
481
535
|
ret.append(r'\begin{sphinxtheindex}' + CR)
|
|
482
536
|
ret.append(r'\let\bigletter\sphinxstyleindexlettergroup' + CR)
|
|
483
537
|
for i, (letter, entries) in enumerate(content):
|
|
@@ -487,13 +541,19 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
487
541
|
for entry in entries:
|
|
488
542
|
if not entry[3]:
|
|
489
543
|
continue
|
|
490
|
-
ret.append(
|
|
491
|
-
|
|
544
|
+
ret.append(
|
|
545
|
+
r'\item\relax\sphinxstyleindexentry{%s}' % self.encode(entry[0])
|
|
546
|
+
)
|
|
492
547
|
if entry[4]:
|
|
493
548
|
# add "extra" info
|
|
494
|
-
ret.append(
|
|
495
|
-
|
|
496
|
-
|
|
549
|
+
ret.append(
|
|
550
|
+
r'\sphinxstyleindexextra{%s}' % self.encode(entry[4])
|
|
551
|
+
)
|
|
552
|
+
ret.append(
|
|
553
|
+
r'\sphinxstyleindexpageref{%s:%s}'
|
|
554
|
+
% (entry[2], self.idescape(entry[3]))
|
|
555
|
+
+ CR
|
|
556
|
+
)
|
|
497
557
|
ret.append(r'\end{sphinxtheindex}' + CR)
|
|
498
558
|
|
|
499
559
|
ret = []
|
|
@@ -504,16 +564,18 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
504
564
|
indices_config = frozenset(indices_config)
|
|
505
565
|
else:
|
|
506
566
|
check_names = False
|
|
507
|
-
for
|
|
508
|
-
domain = self.builder.env.domains[domain_name]
|
|
567
|
+
for domain in self.builder.env.domains.sorted():
|
|
509
568
|
for index_cls in domain.indices:
|
|
510
569
|
index_name = f'{domain.name}-{index_cls.name}'
|
|
511
570
|
if check_names and index_name not in indices_config:
|
|
512
571
|
continue
|
|
513
572
|
content, collapsed = index_cls(domain).generate(
|
|
514
|
-
self.builder.docnames
|
|
573
|
+
self.builder.docnames
|
|
574
|
+
)
|
|
515
575
|
if content:
|
|
516
|
-
ret.append(
|
|
576
|
+
ret.append(
|
|
577
|
+
r'\renewcommand{\indexname}{%s}' % index_cls.localname + CR
|
|
578
|
+
)
|
|
517
579
|
generate(content, collapsed)
|
|
518
580
|
|
|
519
581
|
return ''.join(ret)
|
|
@@ -521,15 +583,17 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
521
583
|
def render(self, template_name: str, variables: dict[str, Any]) -> str:
|
|
522
584
|
renderer = LaTeXRenderer(latex_engine=self.config.latex_engine)
|
|
523
585
|
for template_dir in self.config.templates_path:
|
|
524
|
-
template = path.join(self.builder.confdir, template_dir,
|
|
525
|
-
template_name)
|
|
586
|
+
template = path.join(self.builder.confdir, template_dir, template_name)
|
|
526
587
|
if path.exists(template):
|
|
527
588
|
return renderer.render(template, variables)
|
|
528
589
|
elif template.endswith('.jinja'):
|
|
529
590
|
legacy_template = template.removesuffix('.jinja') + '_t'
|
|
530
591
|
if path.exists(legacy_template):
|
|
531
|
-
logger.warning(
|
|
532
|
-
|
|
592
|
+
logger.warning(
|
|
593
|
+
__('template %s not found; loading from legacy %s instead'),
|
|
594
|
+
template_name,
|
|
595
|
+
legacy_template,
|
|
596
|
+
)
|
|
533
597
|
return renderer.render(legacy_template, variables)
|
|
534
598
|
|
|
535
599
|
return renderer.render(template_name, variables)
|
|
@@ -572,8 +636,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
572
636
|
self.body.append(BLANKLINE)
|
|
573
637
|
|
|
574
638
|
def depart_section(self, node: Element) -> None:
|
|
575
|
-
self.sectionlevel = max(self.sectionlevel - 1,
|
|
576
|
-
self.top_sectionlevel - 1)
|
|
639
|
+
self.sectionlevel = max(self.sectionlevel - 1, self.top_sectionlevel - 1)
|
|
577
640
|
|
|
578
641
|
def visit_problematic(self, node: Element) -> None:
|
|
579
642
|
self.body.append(r'{\color{red}\bfseries{}')
|
|
@@ -582,13 +645,23 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
582
645
|
self.body.append('}')
|
|
583
646
|
|
|
584
647
|
def visit_topic(self, node: Element) -> None:
|
|
585
|
-
self.in_minipage
|
|
586
|
-
|
|
648
|
+
self.in_minipage += 1
|
|
649
|
+
if 'contents' in node.get('classes', []):
|
|
650
|
+
self.body.append(CR + r'\begin{sphinxcontents}' + CR)
|
|
651
|
+
self.context.append(r'\end{sphinxcontents}' + CR)
|
|
652
|
+
else:
|
|
653
|
+
self.body.append(CR + r'\begin{sphinxtopic}' + CR)
|
|
654
|
+
self.context.append(r'\end{sphinxtopic}' + CR)
|
|
587
655
|
|
|
588
656
|
def depart_topic(self, node: Element) -> None:
|
|
589
|
-
self.in_minipage
|
|
590
|
-
self.body.append(
|
|
591
|
-
|
|
657
|
+
self.in_minipage -= 1
|
|
658
|
+
self.body.append(self.context.pop())
|
|
659
|
+
|
|
660
|
+
def visit_sidebar(self, node: Element) -> None:
|
|
661
|
+
self.in_minipage += 1
|
|
662
|
+
self.body.append(CR + r'\begin{sphinxsidebar}' + CR)
|
|
663
|
+
self.context.append(r'\end{sphinxsidebar}' + CR)
|
|
664
|
+
|
|
592
665
|
depart_sidebar = depart_topic
|
|
593
666
|
|
|
594
667
|
def visit_glossary(self, node: Element) -> None:
|
|
@@ -630,10 +703,13 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
630
703
|
raise nodes.SkipNode
|
|
631
704
|
if isinstance(parent, nodes.section):
|
|
632
705
|
if self.this_is_the_title:
|
|
633
|
-
if
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
706
|
+
if (
|
|
707
|
+
len(node.children) != 1
|
|
708
|
+
and not isinstance(node.children[0], nodes.Text)
|
|
709
|
+
): # fmt: skip
|
|
710
|
+
logger.warning(
|
|
711
|
+
__('document title is not a single Text node'), location=node
|
|
712
|
+
)
|
|
637
713
|
if not self.elements['title']:
|
|
638
714
|
# text needs to be escaped since it is inserted into
|
|
639
715
|
# the output literally
|
|
@@ -642,16 +718,19 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
642
718
|
raise nodes.SkipNode
|
|
643
719
|
short = ''
|
|
644
720
|
if any(node.findall(nodes.image)):
|
|
645
|
-
short =
|
|
721
|
+
short = '[%s]' % self.escape(' '.join(clean_astext(node).split()))
|
|
646
722
|
|
|
647
723
|
try:
|
|
648
|
-
self.body.append(
|
|
724
|
+
self.body.append(rf'\{self.sectionnames[self.sectionlevel]}{short}{{')
|
|
649
725
|
except IndexError:
|
|
650
726
|
# just use "subparagraph", it's not numbered anyway
|
|
651
|
-
self.body.append(
|
|
727
|
+
self.body.append(rf'\{self.sectionnames[-1]}{short}{{')
|
|
652
728
|
self.context.append('}' + CR + self.hypertarget_to(node.parent))
|
|
653
729
|
elif isinstance(parent, nodes.topic):
|
|
654
|
-
|
|
730
|
+
if 'contents' in parent.get('classes', []):
|
|
731
|
+
self.body.append(r'\sphinxstylecontentstitle{')
|
|
732
|
+
else:
|
|
733
|
+
self.body.append(r'\sphinxstyletopictitle{')
|
|
655
734
|
self.context.append('}' + CR)
|
|
656
735
|
elif isinstance(parent, nodes.sidebar):
|
|
657
736
|
self.body.append(r'\sphinxstylesidebartitle{')
|
|
@@ -663,9 +742,13 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
663
742
|
# Redirect body output until title is finished.
|
|
664
743
|
self.pushbody([])
|
|
665
744
|
else:
|
|
666
|
-
logger.warning(
|
|
667
|
-
|
|
668
|
-
|
|
745
|
+
logger.warning(
|
|
746
|
+
__(
|
|
747
|
+
'encountered title node not in section, topic, table, '
|
|
748
|
+
'admonition or sidebar'
|
|
749
|
+
),
|
|
750
|
+
location=node,
|
|
751
|
+
)
|
|
669
752
|
self.body.append(r'\sphinxstyleothertitle{')
|
|
670
753
|
self.context.append('}' + CR)
|
|
671
754
|
self.in_title = 1
|
|
@@ -743,26 +826,37 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
743
826
|
|
|
744
827
|
if multi_tp_list:
|
|
745
828
|
if multi_arglist:
|
|
746
|
-
self.body.append(
|
|
829
|
+
self.body.append(
|
|
830
|
+
CR
|
|
831
|
+
+ r'\pysigwithonelineperargwithonelinepertparg'
|
|
832
|
+
+ CR
|
|
833
|
+
+ '{'
|
|
834
|
+
)
|
|
747
835
|
else:
|
|
748
|
-
self.body.append(
|
|
836
|
+
self.body.append(
|
|
837
|
+
CR + r'\pysiglinewithargsretwithonelinepertparg' + CR + '{'
|
|
838
|
+
)
|
|
749
839
|
else:
|
|
750
840
|
if multi_arglist:
|
|
751
|
-
self.body.append(
|
|
841
|
+
self.body.append(
|
|
842
|
+
CR + r'\pysigwithonelineperargwithtypelist' + CR + '{'
|
|
843
|
+
)
|
|
752
844
|
else:
|
|
753
|
-
self.body.append(
|
|
845
|
+
self.body.append(
|
|
846
|
+
CR + r'\pysiglinewithargsretwithtypelist' + CR + '{'
|
|
847
|
+
)
|
|
754
848
|
break
|
|
755
849
|
|
|
756
850
|
if isinstance(child, addnodes.desc_parameterlist):
|
|
757
851
|
# arglist only: \macro{name}{arglist}{retann}
|
|
758
852
|
if has_multi_line(child):
|
|
759
|
-
self.body.append(CR + r'\pysigwithonelineperarg{')
|
|
853
|
+
self.body.append(CR + r'\pysigwithonelineperarg' + CR + '{')
|
|
760
854
|
else:
|
|
761
|
-
self.body.append(CR + r'\pysiglinewithargsret{')
|
|
855
|
+
self.body.append(CR + r'\pysiglinewithargsret' + CR + '{')
|
|
762
856
|
break
|
|
763
857
|
else:
|
|
764
858
|
# no tp_list, no arglist: \macro{name}
|
|
765
|
-
self.body.append(CR + r'\pysigline{')
|
|
859
|
+
self.body.append(CR + r'\pysigline' + CR + '{')
|
|
766
860
|
|
|
767
861
|
def _depart_signature_line(self, node: Element) -> None:
|
|
768
862
|
self.body.append('}')
|
|
@@ -838,7 +932,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
838
932
|
def depart_desc_returns(self, node: Element) -> None:
|
|
839
933
|
self.body.append(r'}')
|
|
840
934
|
|
|
841
|
-
def _visit_sig_parameter_list(
|
|
935
|
+
def _visit_sig_parameter_list(
|
|
936
|
+
self, node: Element, parameter_group: type[Element]
|
|
937
|
+
) -> None:
|
|
842
938
|
"""Visit a signature parameters or type parameters list.
|
|
843
939
|
|
|
844
940
|
The *parameter_group* value is the type of a child node acting as a required parameter
|
|
@@ -853,7 +949,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
853
949
|
self.param_group_index = 0
|
|
854
950
|
# Counts as what we call a parameter group either a required parameter, or a
|
|
855
951
|
# set of contiguous optional ones.
|
|
856
|
-
self.list_is_required_param = [
|
|
952
|
+
self.list_is_required_param = [
|
|
953
|
+
isinstance(c, parameter_group) for c in node.children
|
|
954
|
+
]
|
|
857
955
|
# How many required parameters are left.
|
|
858
956
|
self.required_params_left = sum(self.list_is_required_param)
|
|
859
957
|
self.param_separator = r'\sphinxparamcomma '
|
|
@@ -863,26 +961,32 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
863
961
|
if self.has_tp_list:
|
|
864
962
|
if self.orphan_tp_list:
|
|
865
963
|
# close type parameters list (#2)
|
|
866
|
-
self.body.append('}{')
|
|
964
|
+
self.body.append('}' + CR + '{')
|
|
867
965
|
# empty parameters list argument (#3)
|
|
868
966
|
return
|
|
869
967
|
else:
|
|
870
968
|
# close name argument (#1), open parameters list argument (#2)
|
|
871
|
-
self.body.append('}{')
|
|
969
|
+
self.body.append('}' + CR + '{')
|
|
872
970
|
self._visit_sig_parameter_list(node, addnodes.desc_parameter)
|
|
873
971
|
|
|
874
972
|
def depart_desc_parameterlist(self, node: Element) -> None:
|
|
875
973
|
# close parameterlist, open return annotation
|
|
876
|
-
self.
|
|
974
|
+
assert not self.orphan_tp_list
|
|
975
|
+
self.body.append('}' + CR + '{')
|
|
877
976
|
|
|
878
977
|
def visit_desc_type_parameter_list(self, node: Element) -> None:
|
|
879
978
|
# close name argument (#1), open type parameters list argument (#2)
|
|
880
|
-
self.body.append('}{')
|
|
979
|
+
self.body.append('}' + CR + '{')
|
|
881
980
|
self._visit_sig_parameter_list(node, addnodes.desc_type_parameter)
|
|
882
981
|
|
|
883
982
|
def depart_desc_type_parameter_list(self, node: Element) -> None:
|
|
884
|
-
|
|
885
|
-
|
|
983
|
+
if self.orphan_tp_list:
|
|
984
|
+
# this node next sibling isn't a desc_parameterlist, there are no parameters:
|
|
985
|
+
# close the type list, output an empty parameter list, open return annotation.
|
|
986
|
+
self.body.append('}' + CR + '{}' + CR + '{')
|
|
987
|
+
else:
|
|
988
|
+
# close type parameters list, open parameters list argument (#3)
|
|
989
|
+
self.body.append('}' + CR + '{')
|
|
886
990
|
|
|
887
991
|
def _visit_sig_parameter(self, node: Element, parameter_macro: str) -> None:
|
|
888
992
|
if self.is_first_param:
|
|
@@ -901,13 +1005,18 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
901
1005
|
self.body.append('}')
|
|
902
1006
|
is_required = self.list_is_required_param[self.param_group_index]
|
|
903
1007
|
if self.multi_line_parameter_list:
|
|
904
|
-
|
|
1008
|
+
len_lirp = len(self.list_is_required_param)
|
|
1009
|
+
is_last_group = self.param_group_index + 1 == len_lirp
|
|
905
1010
|
next_is_required = (
|
|
906
1011
|
not is_last_group
|
|
907
1012
|
and self.list_is_required_param[self.param_group_index + 1]
|
|
908
1013
|
)
|
|
909
1014
|
opt_param_left_at_level = self.params_left_at_level > 0
|
|
910
|
-
if
|
|
1015
|
+
if (
|
|
1016
|
+
opt_param_left_at_level
|
|
1017
|
+
or is_required
|
|
1018
|
+
and (is_last_group or next_is_required)
|
|
1019
|
+
):
|
|
911
1020
|
self.body.append(self.param_separator)
|
|
912
1021
|
|
|
913
1022
|
elif self.required_params_left:
|
|
@@ -929,8 +1038,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
929
1038
|
self._depart_sig_parameter(node)
|
|
930
1039
|
|
|
931
1040
|
def visit_desc_optional(self, node: Element) -> None:
|
|
932
|
-
self.params_left_at_level = sum(
|
|
933
|
-
|
|
1041
|
+
self.params_left_at_level = sum(
|
|
1042
|
+
isinstance(c, addnodes.desc_parameter) for c in node.children
|
|
1043
|
+
)
|
|
934
1044
|
self.optional_param_level += 1
|
|
935
1045
|
self.max_optional_param_level = self.optional_param_level
|
|
936
1046
|
if self.multi_line_parameter_list:
|
|
@@ -966,7 +1076,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
966
1076
|
|
|
967
1077
|
def visit_seealso(self, node: Element) -> None:
|
|
968
1078
|
self.body.append(BLANKLINE)
|
|
969
|
-
self.body.append(
|
|
1079
|
+
self.body.append(
|
|
1080
|
+
r'\begin{sphinxseealso}{%s:}' % admonitionlabels['seealso'] + CR
|
|
1081
|
+
)
|
|
970
1082
|
self.no_latex_floats += 1
|
|
971
1083
|
if self.table:
|
|
972
1084
|
self.table.has_problematic = True
|
|
@@ -990,7 +1102,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
990
1102
|
__('unsupported rubric heading level: %s'),
|
|
991
1103
|
level,
|
|
992
1104
|
type='latex',
|
|
993
|
-
location=node
|
|
1105
|
+
location=node,
|
|
994
1106
|
)
|
|
995
1107
|
|
|
996
1108
|
self.body.append(rf'\{tag}*{{')
|
|
@@ -1034,15 +1146,17 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1034
1146
|
assert self.table is not None
|
|
1035
1147
|
if self.table.get_table_type() == 'longtable':
|
|
1036
1148
|
raise UnsupportedError(
|
|
1037
|
-
'%s:%s: longtable does not support nesting a table.'
|
|
1038
|
-
(self.curfilestack[-1], node.line or '')
|
|
1149
|
+
'%s:%s: longtable does not support nesting a table.'
|
|
1150
|
+
% (self.curfilestack[-1], node.line or '')
|
|
1151
|
+
)
|
|
1039
1152
|
# change type of parent table to tabular
|
|
1040
1153
|
# see https://groups.google.com/d/msg/sphinx-users/7m3NeOBixeo/9LKP2B4WBQAJ
|
|
1041
1154
|
self.table.has_problematic = True
|
|
1042
1155
|
elif len(self.tables) > 2:
|
|
1043
1156
|
raise UnsupportedError(
|
|
1044
|
-
'%s:%s: deeply nested tables are not implemented.'
|
|
1045
|
-
(self.curfilestack[-1], node.line or '')
|
|
1157
|
+
'%s:%s: deeply nested tables are not implemented.'
|
|
1158
|
+
% (self.curfilestack[-1], node.line or '')
|
|
1159
|
+
)
|
|
1046
1160
|
|
|
1047
1161
|
table = Table(node)
|
|
1048
1162
|
self.tables.append(table)
|
|
@@ -1060,16 +1174,22 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1060
1174
|
table.styles.append('novlines')
|
|
1061
1175
|
table.colsep = ''
|
|
1062
1176
|
if 'colwidths-given' in node.get('classes', []):
|
|
1063
|
-
logger.info(
|
|
1064
|
-
|
|
1177
|
+
logger.info(
|
|
1178
|
+
__(
|
|
1179
|
+
'both tabularcolumns and :widths: option are given. '
|
|
1180
|
+
':widths: is ignored.'
|
|
1181
|
+
),
|
|
1182
|
+
location=node,
|
|
1183
|
+
)
|
|
1065
1184
|
self.next_table_colspec = None
|
|
1066
1185
|
|
|
1067
1186
|
def depart_table(self, node: Element) -> None:
|
|
1068
1187
|
assert self.table is not None
|
|
1069
1188
|
labels = self.hypertarget_to(node)
|
|
1070
1189
|
table_type = self.table.get_table_type()
|
|
1071
|
-
table = self.render(
|
|
1072
|
-
|
|
1190
|
+
table = self.render(
|
|
1191
|
+
table_type + '.tex.jinja', {'table': self.table, 'labels': labels}
|
|
1192
|
+
)
|
|
1073
1193
|
self.body.append(BLANKLINE)
|
|
1074
1194
|
self.body.append(table)
|
|
1075
1195
|
self.body.append(CR)
|
|
@@ -1130,15 +1250,19 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1130
1250
|
# insert suitable strut for equalizing row heights in given multirow
|
|
1131
1251
|
self.body.append(r'\sphinxtablestrut{%d}' % cell.cell_id)
|
|
1132
1252
|
else: # use \multicolumn for wide multirow cell
|
|
1133
|
-
self.body.append(
|
|
1134
|
-
|
|
1253
|
+
self.body.append(
|
|
1254
|
+
r'\multicolumn{%d}{%sl%s}{\sphinxtablestrut{%d}}'
|
|
1255
|
+
% (cell.width, _colsep, _colsep, cell.cell_id)
|
|
1256
|
+
)
|
|
1135
1257
|
|
|
1136
1258
|
def depart_row(self, node: Element) -> None:
|
|
1137
1259
|
assert self.table is not None
|
|
1138
1260
|
self.body.append(r'\\' + CR)
|
|
1139
1261
|
cells = [self.table.cell(self.table.row, i) for i in range(self.table.colcount)]
|
|
1140
|
-
underlined = [
|
|
1141
|
-
|
|
1262
|
+
underlined = [
|
|
1263
|
+
cell.row + cell.height == self.table.row + 1 # type: ignore[union-attr]
|
|
1264
|
+
for cell in cells
|
|
1265
|
+
]
|
|
1142
1266
|
if all(underlined):
|
|
1143
1267
|
self.body.append(r'\sphinxhline')
|
|
1144
1268
|
else:
|
|
@@ -1175,28 +1299,46 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1175
1299
|
if cell.width > 1:
|
|
1176
1300
|
if self.config.latex_use_latex_multicolumn:
|
|
1177
1301
|
if self.table.col == 0:
|
|
1178
|
-
self.body.append(
|
|
1179
|
-
|
|
1302
|
+
self.body.append(
|
|
1303
|
+
r'\multicolumn{%d}{%sl%s}{%%' % (cell.width, _colsep, _colsep)
|
|
1304
|
+
+ CR
|
|
1305
|
+
)
|
|
1180
1306
|
else:
|
|
1181
|
-
self.body.append(
|
|
1307
|
+
self.body.append(
|
|
1308
|
+
r'\multicolumn{%d}{l%s}{%%' % (cell.width, _colsep) + CR
|
|
1309
|
+
)
|
|
1182
1310
|
context = '}%' + CR
|
|
1183
1311
|
else:
|
|
1184
1312
|
self.body.append(r'\sphinxstartmulticolumn{%d}%%' % cell.width + CR)
|
|
1185
1313
|
context = r'\sphinxstopmulticolumn' + CR
|
|
1186
1314
|
if cell.height > 1:
|
|
1187
1315
|
# \sphinxmultirow 2nd arg "cell_id" will serve as id for LaTeX macros as well
|
|
1188
|
-
self.body.append(
|
|
1316
|
+
self.body.append(
|
|
1317
|
+
r'\sphinxmultirow{%d}{%d}{%%' % (cell.height, cell.cell_id) + CR
|
|
1318
|
+
)
|
|
1189
1319
|
context = '}%' + CR + context
|
|
1190
1320
|
if cell.width > 1 or cell.height > 1:
|
|
1191
|
-
self.body.append(
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1321
|
+
self.body.append(
|
|
1322
|
+
r'\begin{varwidth}[t]{\sphinxcolwidth{%d}{%d}}'
|
|
1323
|
+
% (cell.width, self.table.colcount)
|
|
1324
|
+
+ CR
|
|
1325
|
+
)
|
|
1326
|
+
context = (
|
|
1327
|
+
r'\par' + CR + r'\vskip-\baselineskip'
|
|
1328
|
+
r'\vbox{\hbox{\strut}}\end{varwidth}%' + CR + context
|
|
1329
|
+
)
|
|
1195
1330
|
self.needs_linetrimming = 1
|
|
1196
1331
|
if len(list(node.findall(nodes.paragraph))) >= 2:
|
|
1197
1332
|
self.table.has_oldproblematic = True
|
|
1198
|
-
if
|
|
1199
|
-
|
|
1333
|
+
if (
|
|
1334
|
+
isinstance(node.parent.parent, nodes.thead)
|
|
1335
|
+
or (cell.col in self.table.stubs)
|
|
1336
|
+
): # fmt: skip
|
|
1337
|
+
if (
|
|
1338
|
+
len(node) == 1
|
|
1339
|
+
and isinstance(node[0], nodes.paragraph)
|
|
1340
|
+
and node.astext() == ''
|
|
1341
|
+
):
|
|
1200
1342
|
pass
|
|
1201
1343
|
else:
|
|
1202
1344
|
self.body.append(r'\sphinxstyletheadfamily ')
|
|
@@ -1235,8 +1377,10 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1235
1377
|
self.body.append(r'\sphinxtablestrut{%d}' % nextcell.cell_id)
|
|
1236
1378
|
else:
|
|
1237
1379
|
# use \multicolumn for not first row of wide multirow cell
|
|
1238
|
-
self.body.append(
|
|
1239
|
-
|
|
1380
|
+
self.body.append(
|
|
1381
|
+
r'\multicolumn{%d}{l%s}{\sphinxtablestrut{%d}}'
|
|
1382
|
+
% (nextcell.width, _colsep, nextcell.cell_id)
|
|
1383
|
+
)
|
|
1240
1384
|
self.table.col += nextcell.width
|
|
1241
1385
|
|
|
1242
1386
|
def visit_acks(self, node: Element) -> None:
|
|
@@ -1276,15 +1420,18 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1276
1420
|
else:
|
|
1277
1421
|
return get_nested_level(node.parent)
|
|
1278
1422
|
|
|
1279
|
-
enum =
|
|
1280
|
-
enumnext =
|
|
1423
|
+
enum = 'enum%s' % toRoman(get_nested_level(node)).lower()
|
|
1424
|
+
enumnext = 'enum%s' % toRoman(get_nested_level(node) + 1).lower()
|
|
1281
1425
|
style = ENUMERATE_LIST_STYLE.get(get_enumtype(node))
|
|
1282
1426
|
prefix = node.get('prefix', '')
|
|
1283
1427
|
suffix = node.get('suffix', '.')
|
|
1284
1428
|
|
|
1285
1429
|
self.body.append(r'\begin{enumerate}' + CR)
|
|
1286
|
-
self.body.append(
|
|
1287
|
-
|
|
1430
|
+
self.body.append(
|
|
1431
|
+
r'\sphinxsetlistlabels{%s}{%s}{%s}{%s}{%s}%%'
|
|
1432
|
+
% (style, enum, enumnext, prefix, suffix)
|
|
1433
|
+
+ CR
|
|
1434
|
+
)
|
|
1288
1435
|
if 'start' in node:
|
|
1289
1436
|
self.body.append(r'\setcounter{%s}{%d}' % (enum, node['start'] - 1) + CR)
|
|
1290
1437
|
if self.table:
|
|
@@ -1364,9 +1511,12 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1364
1511
|
|
|
1365
1512
|
def visit_paragraph(self, node: Element) -> None:
|
|
1366
1513
|
index = node.parent.index(node)
|
|
1367
|
-
if (
|
|
1368
|
-
|
|
1369
|
-
|
|
1514
|
+
if (
|
|
1515
|
+
index > 0
|
|
1516
|
+
and isinstance(node.parent, nodes.compound)
|
|
1517
|
+
and not isinstance(node.parent[index - 1], nodes.paragraph)
|
|
1518
|
+
and not isinstance(node.parent[index - 1], nodes.compound)
|
|
1519
|
+
):
|
|
1370
1520
|
# insert blank line, if the paragraph follows a non-paragraph node in a compound
|
|
1371
1521
|
self.body.append(r'\noindent' + CR)
|
|
1372
1522
|
elif index == 1 and isinstance(node.parent, nodes.footnote | footnotetext):
|
|
@@ -1396,8 +1546,10 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1396
1546
|
if self.compact_list > 1:
|
|
1397
1547
|
self.body.append(r'\setlength{\multicolsep}{0pt}' + CR)
|
|
1398
1548
|
self.body.append(r'\begin{multicols}{' + ncolumns + r'}\raggedright' + CR)
|
|
1399
|
-
self.body.append(
|
|
1400
|
-
|
|
1549
|
+
self.body.append(
|
|
1550
|
+
r'\begin{itemize}\setlength{\itemsep}{0pt}'
|
|
1551
|
+
r'\setlength{\parskip}{0pt}' + CR
|
|
1552
|
+
)
|
|
1401
1553
|
if self.table:
|
|
1402
1554
|
self.table.has_problematic = True
|
|
1403
1555
|
|
|
@@ -1454,8 +1606,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1454
1606
|
if not include_graphics_options:
|
|
1455
1607
|
# if no "width" nor "height", \sphinxincludegraphics will fit
|
|
1456
1608
|
# to the available text width if oversized after rescaling.
|
|
1457
|
-
include_graphics_options.append(
|
|
1458
|
-
|
|
1609
|
+
include_graphics_options.append(
|
|
1610
|
+
'scale=%s' % (float(node['scale']) / 100.0)
|
|
1611
|
+
)
|
|
1459
1612
|
if 'align' in node:
|
|
1460
1613
|
align_prepost = {
|
|
1461
1614
|
# By default latex aligns the top of an image.
|
|
@@ -1500,9 +1653,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1500
1653
|
if self.in_title and base:
|
|
1501
1654
|
# Lowercase tokens forcely because some fncychap themes capitalize
|
|
1502
1655
|
# the options of \sphinxincludegraphics unexpectedly (ex. WIDTH=...).
|
|
1503
|
-
cmd =
|
|
1656
|
+
cmd = rf'\lowercase{{\sphinxincludegraphics{options}}}{{{{{base}}}{ext}}}'
|
|
1504
1657
|
else:
|
|
1505
|
-
cmd =
|
|
1658
|
+
cmd = rf'\sphinxincludegraphics{options}{{{{{base}}}{ext}}}'
|
|
1506
1659
|
# escape filepath for includegraphics, https://tex.stackexchange.com/a/202714/41112
|
|
1507
1660
|
if '#' in base:
|
|
1508
1661
|
cmd = r'{\catcode`\#=12' + cmd + '}'
|
|
@@ -1515,7 +1668,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1515
1668
|
def visit_figure(self, node: Element) -> None:
|
|
1516
1669
|
align = self.elements['figure_align']
|
|
1517
1670
|
if self.no_latex_floats:
|
|
1518
|
-
align =
|
|
1671
|
+
align = 'H'
|
|
1519
1672
|
if self.table:
|
|
1520
1673
|
# Blank line is needed if text precedes
|
|
1521
1674
|
self.body.append(BLANKLINE)
|
|
@@ -1540,13 +1693,18 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1540
1693
|
# Insert a blank line to prevent an infinite loop
|
|
1541
1694
|
# https://github.com/sphinx-doc/sphinx/issues/7059
|
|
1542
1695
|
self.body.append(BLANKLINE)
|
|
1543
|
-
self.body.append(
|
|
1544
|
-
|
|
1696
|
+
self.body.append(
|
|
1697
|
+
r'\begin{wrapfigure}{%s}{%s}'
|
|
1698
|
+
% ('r' if node['align'] == 'right' else 'l', length or '0pt')
|
|
1699
|
+
+ CR
|
|
1700
|
+
)
|
|
1545
1701
|
self.body.append(r'\centering')
|
|
1546
|
-
self.context.append(
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1702
|
+
self.context.append(
|
|
1703
|
+
r'\end{wrapfigure}'
|
|
1704
|
+
+ BLANKLINE
|
|
1705
|
+
+ r'\mbox{}\par\vskip-\dimexpr\baselineskip+\parskip\relax'
|
|
1706
|
+
+ CR
|
|
1707
|
+
) # avoid disappearance if no text next issues/11079
|
|
1550
1708
|
elif self.in_minipage:
|
|
1551
1709
|
self.body.append(CR + r'\begin{center}')
|
|
1552
1710
|
self.context.append(r'\end{center}' + CR)
|
|
@@ -1596,8 +1754,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1596
1754
|
|
|
1597
1755
|
def _visit_named_admonition(self, node: Element) -> None:
|
|
1598
1756
|
label = admonitionlabels[node.tagname]
|
|
1599
|
-
self.body.append(
|
|
1600
|
-
|
|
1757
|
+
self.body.append(
|
|
1758
|
+
CR + r'\begin{sphinxadmonition}{%s}{%s:}' % (node.tagname, label)
|
|
1759
|
+
)
|
|
1601
1760
|
self.no_latex_floats += 1
|
|
1602
1761
|
if self.table:
|
|
1603
1762
|
self.table.has_problematic = True
|
|
@@ -1657,10 +1816,13 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1657
1816
|
while isinstance(next_node, nodes.target):
|
|
1658
1817
|
next_node = next_node.next_node(ascend=True)
|
|
1659
1818
|
|
|
1660
|
-
domain =
|
|
1819
|
+
domain = self.builder.env.domains.standard_domain
|
|
1661
1820
|
if isinstance(next_node, HYPERLINK_SUPPORT_NODES):
|
|
1662
1821
|
return
|
|
1663
|
-
if
|
|
1822
|
+
if (
|
|
1823
|
+
domain.get_enumerable_node_type(next_node)
|
|
1824
|
+
and domain.get_numfig_title(next_node)
|
|
1825
|
+
): # fmt: skip
|
|
1664
1826
|
return
|
|
1665
1827
|
|
|
1666
1828
|
if 'refuri' in node:
|
|
@@ -1669,7 +1831,10 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1669
1831
|
return
|
|
1670
1832
|
if node.get('refid'):
|
|
1671
1833
|
prev_node = get_prev_node(node)
|
|
1672
|
-
if
|
|
1834
|
+
if (
|
|
1835
|
+
isinstance(prev_node, nodes.reference)
|
|
1836
|
+
and node['refid'] == prev_node['refid']
|
|
1837
|
+
):
|
|
1673
1838
|
# a target for a hyperlink reference having alias
|
|
1674
1839
|
pass
|
|
1675
1840
|
else:
|
|
@@ -1738,27 +1903,30 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1738
1903
|
try:
|
|
1739
1904
|
p1, p2 = parts
|
|
1740
1905
|
P1, P2 = styled
|
|
1741
|
-
self.body.append(
|
|
1906
|
+
self.body.append(rf'\index{{{p1}@{P1}!{p2}@{P2}{m}}}')
|
|
1742
1907
|
except ValueError:
|
|
1743
|
-
p, = parts
|
|
1744
|
-
P, = styled
|
|
1745
|
-
self.body.append(
|
|
1908
|
+
(p,) = parts
|
|
1909
|
+
(P,) = styled
|
|
1910
|
+
self.body.append(rf'\index{{{p}@{P}{m}}}')
|
|
1746
1911
|
elif type == 'pair':
|
|
1747
1912
|
p1, p2 = parts
|
|
1748
1913
|
P1, P2 = styled
|
|
1749
|
-
self.body.append(
|
|
1750
|
-
|
|
1914
|
+
self.body.append(
|
|
1915
|
+
rf'\index{{{p1}@{P1}!{p2}@{P2}{m}}}'
|
|
1916
|
+
rf'\index{{{p2}@{P2}!{p1}@{P1}{m}}}'
|
|
1917
|
+
)
|
|
1751
1918
|
elif type == 'triple':
|
|
1752
1919
|
p1, p2, p3 = parts
|
|
1753
1920
|
P1, P2, P3 = styled
|
|
1754
1921
|
self.body.append(
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1922
|
+
rf'\index{{{p1}@{P1}!{p2} {p3}@{P2} {P3}{m}}}'
|
|
1923
|
+
rf'\index{{{p2}@{P2}!{p3}, {p1}@{P3}, {P1}{m}}}'
|
|
1924
|
+
rf'\index{{{p3}@{P3}!{p1} {p2}@{P1} {P2}{m}}}'
|
|
1925
|
+
)
|
|
1758
1926
|
elif type in {'see', 'seealso'}:
|
|
1759
1927
|
p1, p2 = parts
|
|
1760
1928
|
P1, _P2 = styled
|
|
1761
|
-
self.body.append(
|
|
1929
|
+
self.body.append(rf'\index{{{p1}@{P1}|see{{{p2}}}}}')
|
|
1762
1930
|
else:
|
|
1763
1931
|
logger.warning(__('unknown index entry type %s found'), type)
|
|
1764
1932
|
except ValueError as err:
|
|
@@ -1793,8 +1961,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1793
1961
|
id = self.curfilestack[-1] + ':' + uri[1:]
|
|
1794
1962
|
self.body.append(self.hyperlink(id))
|
|
1795
1963
|
self.body.append(r'\sphinxsamedocref{')
|
|
1796
|
-
if self.config.latex_show_pagerefs and not
|
|
1797
|
-
self.in_production_list:
|
|
1964
|
+
if self.config.latex_show_pagerefs and not self.in_production_list:
|
|
1798
1965
|
self.context.append('}}} (%s)' % self.hyperpageref(id))
|
|
1799
1966
|
else:
|
|
1800
1967
|
self.context.append('}}}')
|
|
@@ -1808,9 +1975,11 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1808
1975
|
# reference to a label
|
|
1809
1976
|
id = uri[1:].replace('#', ':')
|
|
1810
1977
|
self.body.append(self.hyperlink(id))
|
|
1811
|
-
if (
|
|
1812
|
-
|
|
1813
|
-
|
|
1978
|
+
if (
|
|
1979
|
+
len(node)
|
|
1980
|
+
and isinstance(node[0], nodes.Element)
|
|
1981
|
+
and 'std-term' in node[0].get('classes', [])
|
|
1982
|
+
):
|
|
1814
1983
|
# don't add a pageref for glossary terms
|
|
1815
1984
|
self.context.append('}}}')
|
|
1816
1985
|
# mark up as termreference
|
|
@@ -1846,13 +2015,17 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1846
2015
|
title = self.escape(node.get('title', '%s')).replace(r'\%s', '%s')
|
|
1847
2016
|
if r'\{name\}' in title or r'\{number\}' in title:
|
|
1848
2017
|
# new style format (cf. "Fig.%{number}")
|
|
1849
|
-
title = title.replace(r'\{name\}', '{name}').replace(
|
|
1850
|
-
|
|
1851
|
-
|
|
2018
|
+
title = title.replace(r'\{name\}', '{name}').replace(
|
|
2019
|
+
r'\{number\}', '{number}'
|
|
2020
|
+
)
|
|
2021
|
+
text = escape_abbr(title).format(
|
|
2022
|
+
name=r'\nameref{%s}' % self.idescape(id),
|
|
2023
|
+
number=r'\ref{%s}' % self.idescape(id),
|
|
2024
|
+
)
|
|
1852
2025
|
else:
|
|
1853
2026
|
# old style format (cf. "Fig.%{number}")
|
|
1854
2027
|
text = escape_abbr(title) % (r'\ref{%s}' % self.idescape(id))
|
|
1855
|
-
hyperref =
|
|
2028
|
+
hyperref = rf'\hyperref[{self.idescape(id)}]{{{text}}}'
|
|
1856
2029
|
self.body.append(hyperref)
|
|
1857
2030
|
|
|
1858
2031
|
raise nodes.SkipNode
|
|
@@ -1926,16 +2099,19 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1926
2099
|
# adjust max width of citation labels not to break the layout
|
|
1927
2100
|
longest_label = longest_label[:MAX_CITATION_LABEL_LENGTH]
|
|
1928
2101
|
|
|
1929
|
-
self.body.append(
|
|
1930
|
-
|
|
2102
|
+
self.body.append(
|
|
2103
|
+
CR + r'\begin{sphinxthebibliography}{%s}' % self.encode(longest_label) + CR
|
|
2104
|
+
)
|
|
1931
2105
|
|
|
1932
2106
|
def depart_thebibliography(self, node: Element) -> None:
|
|
1933
2107
|
self.body.append(r'\end{sphinxthebibliography}' + CR)
|
|
1934
2108
|
|
|
1935
2109
|
def visit_citation(self, node: Element) -> None:
|
|
1936
2110
|
label = cast(nodes.label, node[0])
|
|
1937
|
-
self.body.append(
|
|
1938
|
-
|
|
2111
|
+
self.body.append(
|
|
2112
|
+
rf'\bibitem[{self.encode(label.astext())}]'
|
|
2113
|
+
rf'{{{node["docname"]}:{node["ids"][0]}}}'
|
|
2114
|
+
)
|
|
1939
2115
|
|
|
1940
2116
|
def depart_citation(self, node: Element) -> None:
|
|
1941
2117
|
pass
|
|
@@ -1944,7 +2120,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1944
2120
|
if self.in_title:
|
|
1945
2121
|
pass
|
|
1946
2122
|
else:
|
|
1947
|
-
self.body.append(
|
|
2123
|
+
self.body.append(rf'\sphinxcite{{{node["docname"]}:{node["refname"]}}}')
|
|
1948
2124
|
raise nodes.SkipNode
|
|
1949
2125
|
|
|
1950
2126
|
def depart_citation_reference(self, node: Element) -> None:
|
|
@@ -1957,17 +2133,18 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
1957
2133
|
elif 'kbd' in node['classes']:
|
|
1958
2134
|
self.body.append(r'\sphinxkeyboard{\sphinxupquote{')
|
|
1959
2135
|
return
|
|
1960
|
-
lang = node.get(
|
|
2136
|
+
lang = node.get('language', None)
|
|
1961
2137
|
if 'code' not in node['classes'] or not lang:
|
|
1962
2138
|
self.body.append(r'\sphinxcode{\sphinxupquote{')
|
|
1963
2139
|
return
|
|
1964
2140
|
|
|
1965
2141
|
opts = self.config.highlight_options.get(lang, {})
|
|
1966
2142
|
hlcode = self.highlighter.highlight_block(
|
|
1967
|
-
node.astext(), lang, opts=opts, location=node, nowrap=True
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2143
|
+
node.astext(), lang, opts=opts, location=node, nowrap=True
|
|
2144
|
+
)
|
|
2145
|
+
self.body.append(
|
|
2146
|
+
r'\sphinxcode{\sphinxupquote{%' + CR + hlcode.rstrip() + '%' + CR + '}}'
|
|
2147
|
+
)
|
|
1971
2148
|
raise nodes.SkipNode
|
|
1972
2149
|
|
|
1973
2150
|
def depart_literal(self, node: Element) -> None:
|
|
@@ -2018,23 +2195,26 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
2018
2195
|
opts = self.config.highlight_options.get(lang, {})
|
|
2019
2196
|
|
|
2020
2197
|
hlcode = self.highlighter.highlight_block(
|
|
2021
|
-
node.rawsource,
|
|
2022
|
-
|
|
2198
|
+
node.rawsource,
|
|
2199
|
+
lang,
|
|
2200
|
+
opts=opts,
|
|
2201
|
+
linenos=linenos,
|
|
2202
|
+
location=node,
|
|
2203
|
+
**highlight_args,
|
|
2023
2204
|
)
|
|
2024
2205
|
if self.in_footnote:
|
|
2025
2206
|
self.body.append(CR + r'\sphinxSetupCodeBlockInFootnote')
|
|
2026
|
-
hlcode = hlcode.replace(r'\begin{Verbatim}',
|
|
2027
|
-
r'\begin{sphinxVerbatim}')
|
|
2207
|
+
hlcode = hlcode.replace(r'\begin{Verbatim}', r'\begin{sphinxVerbatim}')
|
|
2028
2208
|
# if in table raise verbatim flag to avoid "tabulary" environment
|
|
2029
2209
|
# and opt for sphinxVerbatimintable to handle caption & long lines
|
|
2030
2210
|
elif self.table:
|
|
2031
2211
|
self.table.has_problematic = True
|
|
2032
2212
|
self.table.has_verbatim = True
|
|
2033
|
-
hlcode = hlcode.replace(
|
|
2034
|
-
|
|
2213
|
+
hlcode = hlcode.replace(
|
|
2214
|
+
r'\begin{Verbatim}', r'\begin{sphinxVerbatimintable}'
|
|
2215
|
+
)
|
|
2035
2216
|
else:
|
|
2036
|
-
hlcode = hlcode.replace(r'\begin{Verbatim}',
|
|
2037
|
-
r'\begin{sphinxVerbatim}')
|
|
2217
|
+
hlcode = hlcode.replace(r'\begin{Verbatim}', r'\begin{sphinxVerbatim}')
|
|
2038
2218
|
# get consistent trailer
|
|
2039
2219
|
hlcode = hlcode.rstrip()[:-14] # strip \end{Verbatim}
|
|
2040
2220
|
if self.table and not self.in_footnote:
|
|
@@ -2053,6 +2233,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
2053
2233
|
def depart_literal_block(self, node: Element) -> None:
|
|
2054
2234
|
self.body.append(CR + r'\end{sphinxalltt}' + CR)
|
|
2055
2235
|
self.in_parsed_literal -= 1
|
|
2236
|
+
|
|
2056
2237
|
visit_doctest_block = visit_literal_block
|
|
2057
2238
|
depart_doctest_block = depart_literal_block
|
|
2058
2239
|
|
|
@@ -2173,8 +2354,8 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
2173
2354
|
self.body.append(r'\sphinxaccelerator{')
|
|
2174
2355
|
self.context.append('}')
|
|
2175
2356
|
elif classes and not self.in_title:
|
|
2176
|
-
self.body.append(r'\DUrole{
|
|
2177
|
-
self.context.append('}')
|
|
2357
|
+
self.body.append(r'\DUrole{' + r'}{\DUrole{'.join(classes) + '}{')
|
|
2358
|
+
self.context.append('}' * len(classes))
|
|
2178
2359
|
else:
|
|
2179
2360
|
self.context.append('')
|
|
2180
2361
|
|
|
@@ -2235,9 +2416,12 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
2235
2416
|
# this must be checked against hyperref package exact dealings
|
|
2236
2417
|
# mainly, %, #, {, } and \ need escaping via a \ escape
|
|
2237
2418
|
# in \href, the tilde is allowed and must be represented literally
|
|
2238
|
-
return
|
|
2239
|
-
|
|
2240
|
-
replace(r'\
|
|
2419
|
+
return (
|
|
2420
|
+
self.encode(text)
|
|
2421
|
+
.replace(r'\textasciitilde{}', '~')
|
|
2422
|
+
.replace(r'\sphinxhyphen{}', '-')
|
|
2423
|
+
.replace(r'\textquotesingle{}', "'")
|
|
2424
|
+
)
|
|
2241
2425
|
|
|
2242
2426
|
def visit_Text(self, node: Text) -> None:
|
|
2243
2427
|
text = self.encode(node.astext())
|
|
@@ -2278,8 +2462,10 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
2278
2462
|
self.body.append(node.astext())
|
|
2279
2463
|
else:
|
|
2280
2464
|
from sphinx.util.math import wrap_displaymath
|
|
2281
|
-
|
|
2282
|
-
|
|
2465
|
+
|
|
2466
|
+
self.body.append(
|
|
2467
|
+
wrap_displaymath(node.astext(), label, self.config.math_number_all)
|
|
2468
|
+
)
|
|
2283
2469
|
raise nodes.SkipNode
|
|
2284
2470
|
|
|
2285
2471
|
def visit_math_reference(self, node: Element) -> None:
|
|
@@ -2290,8 +2476,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
2290
2476
|
ref = r'\ref{%s}' % label
|
|
2291
2477
|
self.body.append(eqref_format.format(number=ref))
|
|
2292
2478
|
except KeyError as exc:
|
|
2293
|
-
logger.warning(__('Invalid math_eqref_format: %r'), exc,
|
|
2294
|
-
location=node)
|
|
2479
|
+
logger.warning(__('Invalid math_eqref_format: %r'), exc, location=node)
|
|
2295
2480
|
self.body.append(r'\eqref{%s}' % label)
|
|
2296
2481
|
else:
|
|
2297
2482
|
self.body.append(r'\eqref{%s}' % label)
|
|
@@ -2303,5 +2488,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|
|
2303
2488
|
# FIXME: Workaround to avoid circular import
|
|
2304
2489
|
# refs: https://github.com/sphinx-doc/sphinx/issues/5433
|
|
2305
2490
|
from sphinx.builders.latex.nodes import ( # NoQA: E402 # isort:skip
|
|
2306
|
-
HYPERLINK_SUPPORT_NODES,
|
|
2491
|
+
HYPERLINK_SUPPORT_NODES,
|
|
2492
|
+
captioned_literal_block,
|
|
2493
|
+
footnotetext,
|
|
2307
2494
|
)
|