Sphinx 8.1.2__py3-none-any.whl → 8.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.

Files changed (328) hide show
  1. sphinx/__init__.py +8 -4
  2. sphinx/__main__.py +2 -0
  3. sphinx/_cli/__init__.py +2 -5
  4. sphinx/_cli/util/colour.py +34 -11
  5. sphinx/_cli/util/errors.py +128 -61
  6. sphinx/addnodes.py +51 -35
  7. sphinx/application.py +362 -230
  8. sphinx/builders/__init__.py +87 -64
  9. sphinx/builders/_epub_base.py +65 -56
  10. sphinx/builders/changes.py +17 -23
  11. sphinx/builders/dirhtml.py +8 -13
  12. sphinx/builders/epub3.py +70 -38
  13. sphinx/builders/gettext.py +93 -73
  14. sphinx/builders/html/__init__.py +240 -186
  15. sphinx/builders/html/_assets.py +9 -2
  16. sphinx/builders/html/_build_info.py +3 -0
  17. sphinx/builders/latex/__init__.py +64 -54
  18. sphinx/builders/latex/constants.py +14 -11
  19. sphinx/builders/latex/nodes.py +2 -0
  20. sphinx/builders/latex/theming.py +8 -9
  21. sphinx/builders/latex/transforms.py +7 -5
  22. sphinx/builders/linkcheck.py +193 -149
  23. sphinx/builders/manpage.py +17 -17
  24. sphinx/builders/singlehtml.py +28 -16
  25. sphinx/builders/texinfo.py +28 -21
  26. sphinx/builders/text.py +10 -15
  27. sphinx/builders/xml.py +10 -19
  28. sphinx/cmd/build.py +49 -119
  29. sphinx/cmd/make_mode.py +35 -31
  30. sphinx/cmd/quickstart.py +78 -62
  31. sphinx/config.py +265 -163
  32. sphinx/directives/__init__.py +51 -54
  33. sphinx/directives/admonitions.py +107 -0
  34. sphinx/directives/code.py +24 -19
  35. sphinx/directives/other.py +21 -42
  36. sphinx/directives/patches.py +28 -16
  37. sphinx/domains/__init__.py +54 -31
  38. sphinx/domains/_domains_container.py +22 -17
  39. sphinx/domains/_index.py +5 -8
  40. sphinx/domains/c/__init__.py +366 -245
  41. sphinx/domains/c/_ast.py +378 -256
  42. sphinx/domains/c/_ids.py +89 -31
  43. sphinx/domains/c/_parser.py +283 -214
  44. sphinx/domains/c/_symbol.py +269 -198
  45. sphinx/domains/changeset.py +39 -24
  46. sphinx/domains/citation.py +54 -24
  47. sphinx/domains/cpp/__init__.py +517 -362
  48. sphinx/domains/cpp/_ast.py +999 -682
  49. sphinx/domains/cpp/_ids.py +133 -65
  50. sphinx/domains/cpp/_parser.py +746 -588
  51. sphinx/domains/cpp/_symbol.py +692 -489
  52. sphinx/domains/index.py +10 -8
  53. sphinx/domains/javascript.py +152 -74
  54. sphinx/domains/math.py +50 -40
  55. sphinx/domains/python/__init__.py +402 -211
  56. sphinx/domains/python/_annotations.py +134 -61
  57. sphinx/domains/python/_object.py +155 -68
  58. sphinx/domains/rst.py +94 -49
  59. sphinx/domains/std/__init__.py +510 -249
  60. sphinx/environment/__init__.py +345 -61
  61. sphinx/environment/adapters/asset.py +7 -1
  62. sphinx/environment/adapters/indexentries.py +15 -20
  63. sphinx/environment/adapters/toctree.py +19 -9
  64. sphinx/environment/collectors/__init__.py +3 -1
  65. sphinx/environment/collectors/asset.py +18 -15
  66. sphinx/environment/collectors/dependencies.py +8 -10
  67. sphinx/environment/collectors/metadata.py +6 -4
  68. sphinx/environment/collectors/title.py +3 -1
  69. sphinx/environment/collectors/toctree.py +4 -4
  70. sphinx/errors.py +1 -3
  71. sphinx/events.py +4 -4
  72. sphinx/ext/apidoc/__init__.py +66 -0
  73. sphinx/ext/apidoc/__main__.py +9 -0
  74. sphinx/ext/apidoc/_cli.py +356 -0
  75. sphinx/ext/apidoc/_extension.py +262 -0
  76. sphinx/ext/apidoc/_generate.py +356 -0
  77. sphinx/ext/apidoc/_shared.py +99 -0
  78. sphinx/ext/autodoc/__init__.py +837 -483
  79. sphinx/ext/autodoc/directive.py +57 -21
  80. sphinx/ext/autodoc/importer.py +184 -67
  81. sphinx/ext/autodoc/mock.py +25 -10
  82. sphinx/ext/autodoc/preserve_defaults.py +17 -9
  83. sphinx/ext/autodoc/type_comment.py +56 -29
  84. sphinx/ext/autodoc/typehints.py +49 -26
  85. sphinx/ext/autosectionlabel.py +28 -11
  86. sphinx/ext/autosummary/__init__.py +281 -142
  87. sphinx/ext/autosummary/generate.py +121 -51
  88. sphinx/ext/coverage.py +152 -91
  89. sphinx/ext/doctest.py +169 -101
  90. sphinx/ext/duration.py +12 -6
  91. sphinx/ext/extlinks.py +33 -21
  92. sphinx/ext/githubpages.py +8 -8
  93. sphinx/ext/graphviz.py +175 -109
  94. sphinx/ext/ifconfig.py +11 -6
  95. sphinx/ext/imgconverter.py +48 -25
  96. sphinx/ext/imgmath.py +127 -97
  97. sphinx/ext/inheritance_diagram.py +177 -103
  98. sphinx/ext/intersphinx/__init__.py +22 -13
  99. sphinx/ext/intersphinx/__main__.py +3 -1
  100. sphinx/ext/intersphinx/_cli.py +18 -14
  101. sphinx/ext/intersphinx/_load.py +91 -82
  102. sphinx/ext/intersphinx/_resolve.py +108 -74
  103. sphinx/ext/intersphinx/_shared.py +2 -2
  104. sphinx/ext/linkcode.py +28 -12
  105. sphinx/ext/mathjax.py +60 -29
  106. sphinx/ext/napoleon/__init__.py +19 -7
  107. sphinx/ext/napoleon/docstring.py +229 -231
  108. sphinx/ext/todo.py +44 -49
  109. sphinx/ext/viewcode.py +105 -57
  110. sphinx/extension.py +3 -1
  111. sphinx/highlighting.py +13 -7
  112. sphinx/io.py +9 -13
  113. sphinx/jinja2glue.py +29 -26
  114. sphinx/locale/__init__.py +8 -9
  115. sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
  116. sphinx/locale/ar/LC_MESSAGES/sphinx.po +2155 -2050
  117. sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
  118. sphinx/locale/bg/LC_MESSAGES/sphinx.po +2045 -1940
  119. sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
  120. sphinx/locale/bn/LC_MESSAGES/sphinx.po +2175 -2070
  121. sphinx/locale/ca/LC_MESSAGES/sphinx.js +3 -3
  122. sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
  123. sphinx/locale/ca/LC_MESSAGES/sphinx.po +2690 -2585
  124. sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.js +63 -0
  125. sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.mo +0 -0
  126. sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.po +4216 -0
  127. sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
  128. sphinx/locale/cak/LC_MESSAGES/sphinx.po +2096 -1991
  129. sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
  130. sphinx/locale/cs/LC_MESSAGES/sphinx.po +2248 -2143
  131. sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
  132. sphinx/locale/cy/LC_MESSAGES/sphinx.po +2201 -2096
  133. sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
  134. sphinx/locale/da/LC_MESSAGES/sphinx.po +2282 -2177
  135. sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
  136. sphinx/locale/de/LC_MESSAGES/sphinx.po +2261 -2156
  137. sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
  138. sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +2045 -1940
  139. sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
  140. sphinx/locale/el/LC_MESSAGES/sphinx.po +2604 -2499
  141. sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
  142. sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +2045 -1940
  143. sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
  144. sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +2045 -1940
  145. sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
  146. sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +2631 -2526
  147. sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
  148. sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +2045 -1940
  149. sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
  150. sphinx/locale/eo/LC_MESSAGES/sphinx.po +2078 -1973
  151. sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
  152. sphinx/locale/es/LC_MESSAGES/sphinx.po +2633 -2528
  153. sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
  154. sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +2045 -1940
  155. sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
  156. sphinx/locale/et/LC_MESSAGES/sphinx.po +2449 -2344
  157. sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
  158. sphinx/locale/eu/LC_MESSAGES/sphinx.po +2241 -2136
  159. sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
  160. sphinx/locale/fa/LC_MESSAGES/sphinx.po +504 -500
  161. sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
  162. sphinx/locale/fi/LC_MESSAGES/sphinx.po +499 -495
  163. sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
  164. sphinx/locale/fr/LC_MESSAGES/sphinx.po +513 -509
  165. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
  166. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +499 -495
  167. sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
  168. sphinx/locale/gl/LC_MESSAGES/sphinx.po +2644 -2539
  169. sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
  170. sphinx/locale/he/LC_MESSAGES/sphinx.po +499 -495
  171. sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
  172. sphinx/locale/hi/LC_MESSAGES/sphinx.po +504 -500
  173. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
  174. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +499 -495
  175. sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
  176. sphinx/locale/hr/LC_MESSAGES/sphinx.po +501 -497
  177. sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
  178. sphinx/locale/hu/LC_MESSAGES/sphinx.po +499 -495
  179. sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
  180. sphinx/locale/id/LC_MESSAGES/sphinx.po +2609 -2504
  181. sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
  182. sphinx/locale/is/LC_MESSAGES/sphinx.po +499 -495
  183. sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
  184. sphinx/locale/it/LC_MESSAGES/sphinx.po +2265 -2160
  185. sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
  186. sphinx/locale/ja/LC_MESSAGES/sphinx.po +2621 -2516
  187. sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
  188. sphinx/locale/ka/LC_MESSAGES/sphinx.po +2567 -2462
  189. sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
  190. sphinx/locale/ko/LC_MESSAGES/sphinx.po +2631 -2526
  191. sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
  192. sphinx/locale/lt/LC_MESSAGES/sphinx.po +2214 -2109
  193. sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
  194. sphinx/locale/lv/LC_MESSAGES/sphinx.po +2218 -2113
  195. sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
  196. sphinx/locale/mk/LC_MESSAGES/sphinx.po +2088 -1983
  197. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
  198. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +2247 -2142
  199. sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
  200. sphinx/locale/ne/LC_MESSAGES/sphinx.po +2227 -2122
  201. sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
  202. sphinx/locale/nl/LC_MESSAGES/sphinx.po +2316 -2211
  203. sphinx/locale/pl/LC_MESSAGES/sphinx.js +2 -2
  204. sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
  205. sphinx/locale/pl/LC_MESSAGES/sphinx.po +2442 -2336
  206. sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
  207. sphinx/locale/pt/LC_MESSAGES/sphinx.po +2045 -1940
  208. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
  209. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +2657 -2552
  210. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
  211. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +2243 -2138
  212. sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
  213. sphinx/locale/ro/LC_MESSAGES/sphinx.po +2244 -2139
  214. sphinx/locale/ru/LC_MESSAGES/sphinx.js +1 -1
  215. sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
  216. sphinx/locale/ru/LC_MESSAGES/sphinx.po +2660 -2555
  217. sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
  218. sphinx/locale/si/LC_MESSAGES/sphinx.po +2134 -2029
  219. sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
  220. sphinx/locale/sk/LC_MESSAGES/sphinx.po +2614 -2509
  221. sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
  222. sphinx/locale/sl/LC_MESSAGES/sphinx.po +2167 -2062
  223. sphinx/locale/sphinx.pot +2069 -1964
  224. sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
  225. sphinx/locale/sq/LC_MESSAGES/sphinx.po +2661 -2556
  226. sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
  227. sphinx/locale/sr/LC_MESSAGES/sphinx.po +2213 -2108
  228. sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
  229. sphinx/locale/sv/LC_MESSAGES/sphinx.po +2229 -2124
  230. sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
  231. sphinx/locale/te/LC_MESSAGES/sphinx.po +2045 -1940
  232. sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
  233. sphinx/locale/tr/LC_MESSAGES/sphinx.po +2608 -2503
  234. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
  235. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +2167 -2062
  236. sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
  237. sphinx/locale/ur/LC_MESSAGES/sphinx.po +2045 -1940
  238. sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
  239. sphinx/locale/vi/LC_MESSAGES/sphinx.po +2204 -2099
  240. sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
  241. sphinx/locale/yue/LC_MESSAGES/sphinx.po +2045 -1940
  242. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
  243. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +2045 -1940
  244. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
  245. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +2659 -2554
  246. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
  247. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +2045 -1940
  248. sphinx/parsers.py +8 -7
  249. sphinx/project.py +2 -2
  250. sphinx/pycode/__init__.py +31 -21
  251. sphinx/pycode/ast.py +6 -3
  252. sphinx/pycode/parser.py +14 -8
  253. sphinx/pygments_styles.py +4 -5
  254. sphinx/registry.py +192 -92
  255. sphinx/roles.py +58 -7
  256. sphinx/search/__init__.py +75 -54
  257. sphinx/search/en.py +11 -13
  258. sphinx/search/fi.py +1 -1
  259. sphinx/search/ja.py +8 -6
  260. sphinx/search/nl.py +1 -1
  261. sphinx/search/zh.py +19 -21
  262. sphinx/testing/fixtures.py +26 -29
  263. sphinx/testing/path.py +26 -62
  264. sphinx/testing/restructuredtext.py +14 -8
  265. sphinx/testing/util.py +21 -19
  266. sphinx/texinputs/make.bat.jinja +50 -50
  267. sphinx/texinputs/sphinx.sty +4 -3
  268. sphinx/texinputs/sphinxlatexadmonitions.sty +1 -1
  269. sphinx/texinputs/sphinxlatexobjects.sty +29 -10
  270. sphinx/themes/basic/static/searchtools.js +8 -5
  271. sphinx/theming.py +49 -61
  272. sphinx/transforms/__init__.py +17 -38
  273. sphinx/transforms/compact_bullet_list.py +5 -3
  274. sphinx/transforms/i18n.py +8 -21
  275. sphinx/transforms/post_transforms/__init__.py +142 -93
  276. sphinx/transforms/post_transforms/code.py +5 -5
  277. sphinx/transforms/post_transforms/images.py +28 -24
  278. sphinx/transforms/references.py +3 -1
  279. sphinx/util/__init__.py +109 -60
  280. sphinx/util/_files.py +39 -23
  281. sphinx/util/_importer.py +4 -1
  282. sphinx/util/_inventory_file_reader.py +76 -0
  283. sphinx/util/_io.py +2 -2
  284. sphinx/util/_lines.py +6 -3
  285. sphinx/util/_pathlib.py +40 -2
  286. sphinx/util/build_phase.py +2 -0
  287. sphinx/util/cfamily.py +19 -14
  288. sphinx/util/console.py +44 -179
  289. sphinx/util/display.py +9 -10
  290. sphinx/util/docfields.py +140 -122
  291. sphinx/util/docstrings.py +1 -1
  292. sphinx/util/docutils.py +118 -77
  293. sphinx/util/fileutil.py +25 -26
  294. sphinx/util/http_date.py +2 -0
  295. sphinx/util/i18n.py +77 -64
  296. sphinx/util/images.py +8 -6
  297. sphinx/util/inspect.py +147 -38
  298. sphinx/util/inventory.py +215 -116
  299. sphinx/util/logging.py +33 -33
  300. sphinx/util/matching.py +12 -4
  301. sphinx/util/nodes.py +18 -13
  302. sphinx/util/osutil.py +38 -39
  303. sphinx/util/parallel.py +22 -13
  304. sphinx/util/parsing.py +2 -1
  305. sphinx/util/png.py +6 -2
  306. sphinx/util/requests.py +33 -2
  307. sphinx/util/rst.py +3 -2
  308. sphinx/util/tags.py +1 -1
  309. sphinx/util/template.py +18 -10
  310. sphinx/util/texescape.py +8 -6
  311. sphinx/util/typing.py +148 -122
  312. sphinx/versioning.py +3 -3
  313. sphinx/writers/html.py +3 -1
  314. sphinx/writers/html5.py +63 -52
  315. sphinx/writers/latex.py +83 -67
  316. sphinx/writers/manpage.py +19 -38
  317. sphinx/writers/texinfo.py +47 -47
  318. sphinx/writers/text.py +50 -32
  319. sphinx/writers/xml.py +11 -8
  320. {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/LICENSE.rst +1 -1
  321. {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/METADATA +25 -15
  322. sphinx-8.2.0.dist-info/RECORD +606 -0
  323. {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/WHEEL +1 -1
  324. sphinx/builders/html/transforms.py +0 -90
  325. sphinx/ext/apidoc.py +0 -721
  326. sphinx/util/exceptions.py +0 -74
  327. sphinx-8.1.2.dist-info/RECORD +0 -598
  328. {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/entry_points.txt +0 -0
sphinx/writers/html5.py CHANGED
@@ -2,12 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import os
6
5
  import posixpath
7
6
  import re
8
7
  import urllib.parse
9
- from collections.abc import Iterable
10
- from typing import TYPE_CHECKING, cast
8
+ from typing import TYPE_CHECKING
11
9
 
12
10
  from docutils import nodes
13
11
  from docutils.writers.html5_polyglot import HTMLTranslator as BaseTranslator
@@ -44,9 +42,7 @@ def multiply_length(length: str, scale: int) -> str:
44
42
 
45
43
 
46
44
  class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
47
- """
48
- Our custom HTML translator.
49
- """
45
+ """Our custom HTML translator."""
50
46
 
51
47
  builder: StandaloneHTMLBuilder
52
48
  # Override docutils.writers.html5_polyglot:HTMLTranslator
@@ -66,6 +62,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
66
62
  self._table_row_indices = [0]
67
63
  self._fieldlist_row_indices = [0]
68
64
  self.required_params_left = 0
65
+ self._has_maths_elements: bool = False
69
66
 
70
67
  def visit_start_of_file(self, node: Element) -> None:
71
68
  # only occurs in the single-file builder
@@ -175,6 +172,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
175
172
  self.required_params_left = sum(self.list_is_required_param)
176
173
  self.param_separator = node.child_text_separator
177
174
  self.multi_line_parameter_list = node.get('multi_line_parameter_list', False)
175
+ self.trailing_comma = node.get('multi_line_trailing_comma', False)
178
176
  if self.multi_line_parameter_list:
179
177
  self.body.append('\n\n')
180
178
  self.body.append(self.starttag(node, 'dl'))
@@ -201,10 +199,11 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
201
199
 
202
200
  # If required parameters are still to come, then put the comma after
203
201
  # the parameter. Otherwise, put the comma before. This ensures that
204
- # signatures like the following render correctly (see issue #1001):
202
+ # signatures like the following render correctly:
205
203
  #
206
204
  # foo([a, ]b, c[, d])
207
205
  #
206
+ # See: https://github.com/sphinx-doc/sphinx/issues/1001
208
207
  def visit_desc_parameter(self, node: Element) -> None:
209
208
  on_separate_line = self.multi_line_parameter_list
210
209
  if on_separate_line and not (
@@ -232,14 +231,15 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
232
231
  next_is_required = (
233
232
  not is_last_group
234
233
  and self.list_is_required_param[self.param_group_index + 1]
235
- ) # fmt: skip
234
+ )
236
235
  opt_param_left_at_level = self.params_left_at_level > 0
237
236
  if (
238
237
  opt_param_left_at_level
239
238
  or is_required
240
239
  and (is_last_group or next_is_required)
241
240
  ):
242
- self.body.append(self.param_separator)
241
+ if not is_last_group or opt_param_left_at_level or self.trailing_comma:
242
+ self.body.append(self.param_separator)
243
243
  self.body.append('</dd>\n')
244
244
 
245
245
  elif self.required_params_left:
@@ -282,19 +282,26 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
282
282
 
283
283
  def depart_desc_optional(self, node: Element) -> None:
284
284
  self.optional_param_level -= 1
285
+ level = self.optional_param_level
285
286
  if self.multi_line_parameter_list:
286
- # If it's the first time we go down one level, add the separator
287
- # before the bracket.
288
- if self.optional_param_level == self.max_optional_param_level - 1:
287
+ max_level = self.max_optional_param_level
288
+ len_lirp = len(self.list_is_required_param)
289
+ is_last_group = self.param_group_index + 1 == len_lirp
290
+ # If it's the first time we go down one level, add the separator before the
291
+ # bracket, except if this is the last parameter and the parameter list
292
+ # should not feature a trailing comma.
293
+ if level == max_level - 1 and (
294
+ not is_last_group or level > 0 or self.trailing_comma
295
+ ):
289
296
  self.body.append(self.param_separator)
290
297
  self.body.append('<span class="optional">]</span>')
291
298
  # End the line if we have just closed the last bracket of this
292
299
  # optional parameter group.
293
- if self.optional_param_level == 0:
300
+ if level == 0:
294
301
  self.body.append('</dd>\n')
295
302
  else:
296
303
  self.body.append('<span class="optional">]</span>')
297
- if self.optional_param_level == 0:
304
+ if level == 0:
298
305
  self.param_group_index += 1
299
306
 
300
307
  def visit_desc_annotation(self, node: Element) -> None:
@@ -327,9 +334,9 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
327
334
  atts['href'] = self.cloak_mailto(atts['href'])
328
335
  self.in_mailto = True
329
336
  else:
330
- assert (
331
- 'refid' in node
332
- ), 'References must have "refuri" or "refid" attribute.'
337
+ assert 'refid' in node, (
338
+ 'References must have "refuri" or "refid" attribute.'
339
+ )
333
340
  atts['href'] = '#' + node['refid']
334
341
  if not isinstance(node.parent, nodes.TextElement):
335
342
  assert len(node) == 1 and isinstance(node[0], nodes.image) # NoQA: PT018
@@ -359,12 +366,21 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
359
366
 
360
367
  # overwritten
361
368
  def visit_admonition(self, node: Element, name: str = '') -> None:
362
- self.body.append(self.starttag(node, 'div', CLASS=('admonition ' + name)))
369
+ attributes = {}
370
+ tag_name = 'div'
371
+ if collapsible := node.get('collapsible'):
372
+ tag_name = 'details'
373
+ if collapsible == 'open':
374
+ attributes['open'] = 'open'
375
+ self.body.append(
376
+ self.starttag(node, tag_name, CLASS=f'admonition {name}', **attributes)
377
+ )
378
+ self.context.append(f'</{tag_name}>\n')
363
379
  if name:
364
380
  node.insert(0, nodes.title(name, admonitionlabels[name]))
365
381
 
366
382
  def depart_admonition(self, node: Element | None = None) -> None:
367
- self.body.append('</div>\n')
383
+ self.body.append(self.context.pop())
368
384
 
369
385
  def visit_seealso(self, node: Element) -> None:
370
386
  self.visit_admonition(node, 'seealso')
@@ -379,7 +395,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
379
395
  if isinstance(node.parent, nodes.section):
380
396
  if self.builder.name == 'singlehtml':
381
397
  docname = self.docnames[-1]
382
- anchorname = f"{docname}/#{node.parent['ids'][0]}"
398
+ anchorname = f'{docname}/#{node.parent["ids"][0]}'
383
399
  if anchorname not in self.builder.secnumbers:
384
400
  # try first heading which has no anchor
385
401
  anchorname = f'{docname}/'
@@ -419,9 +435,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
419
435
  self.body.append(prefix % '.'.join(map(str, numbers)) + ' ')
420
436
  self.body.append('</span>')
421
437
 
422
- figtype = self.builder.env.domains.standard_domain.get_enumerable_node_type(
423
- node
424
- )
438
+ figtype = self._domains.standard_domain.get_enumerable_node_type(node)
425
439
  if figtype:
426
440
  if len(node['ids']) == 0:
427
441
  msg = __('Any IDs not assigned for %s node') % node.tagname
@@ -494,6 +508,15 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
494
508
  )
495
509
  self.body.append('<span class="caption-text">')
496
510
  self.context.append('</span></p>\n')
511
+ elif (
512
+ isinstance(node.parent, nodes.Admonition)
513
+ and isinstance(node.parent, nodes.Element)
514
+ and 'collapsible' in node.parent
515
+ ):
516
+ self.body.append(
517
+ self.starttag(node, 'summary', '', CLASS='admonition-title')
518
+ )
519
+ self.context.append('</summary>\n')
497
520
  else:
498
521
  super().visit_title(node)
499
522
  self.add_secnumber(node)
@@ -671,24 +694,9 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
671
694
 
672
695
  def visit_productionlist(self, node: Element) -> None:
673
696
  self.body.append(self.starttag(node, 'pre'))
674
- productionlist = cast(Iterable[addnodes.production], node)
675
- names = (production['tokenname'] for production in productionlist)
676
- maxlen = max(len(name) for name in names)
677
- lastname = None
678
- for production in productionlist:
679
- if production['tokenname']:
680
- lastname = production['tokenname'].ljust(maxlen)
681
- self.body.append(self.starttag(production, 'strong', ''))
682
- self.body.append(lastname + '</strong> ::= ')
683
- elif lastname is not None:
684
- self.body.append('%s ' % (' ' * len(lastname)))
685
- production.walkabout(self)
686
- self.body.append('\n')
687
- self.body.append('</pre>\n')
688
- raise nodes.SkipNode
689
697
 
690
698
  def depart_productionlist(self, node: Element) -> None:
691
- pass
699
+ self.body.append('</pre>\n')
692
700
 
693
701
  def visit_production(self, node: Element) -> None:
694
702
  pass
@@ -752,8 +760,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
752
760
  # but it tries the final file name, which does not necessarily exist
753
761
  # yet at the time the HTML file is written.
754
762
  if not ('width' in node and 'height' in node):
755
- path = os.path.join(self.builder.srcdir, olduri) # type: ignore[has-type]
756
- size = get_image_size(path)
763
+ size = get_image_size(self.builder.srcdir / olduri)
757
764
  if size is None:
758
765
  logger.warning(
759
766
  __('Could not obtain image size. :scale: option is ignored.'),
@@ -820,7 +827,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
820
827
  if token.strip():
821
828
  # protect literal text from line wrapping
822
829
  self.body.append('<span class="pre">%s</span>' % token)
823
- elif token in ' \n':
830
+ elif token in {' ', '\n'}:
824
831
  # allow breaks at whitespace
825
832
  self.body.append(token)
826
833
  else:
@@ -899,8 +906,8 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
899
906
 
900
907
  def visit_abbreviation(self, node: Element) -> None:
901
908
  attrs = {}
902
- if node.hasattr('explanation'):
903
- attrs['title'] = node['explanation']
909
+ if explanation := node.get('explanation', ''):
910
+ attrs['title'] = explanation
904
911
  self.body.append(self.starttag(node, 'abbr', '', **attrs))
905
912
 
906
913
  def depart_abbreviation(self, node: Element) -> None:
@@ -957,29 +964,33 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
957
964
  else:
958
965
  node['classes'].append('field-odd')
959
966
 
960
- def visit_math(self, node: Element, math_env: str = '') -> None:
967
+ def visit_math(self, node: nodes.math, math_env: str = '') -> None:
968
+ self._has_maths_elements = True
969
+
961
970
  # see validate_math_renderer
962
971
  name: str = self.builder.math_renderer_name # type: ignore[assignment]
963
- visit, _ = self.builder.app.registry.html_inline_math_renderers[name]
972
+ visit, _ = self.builder.env._registry.html_inline_math_renderers[name]
964
973
  visit(self, node)
965
974
 
966
- def depart_math(self, node: Element, math_env: str = '') -> None:
975
+ def depart_math(self, node: nodes.math, math_env: str = '') -> None:
967
976
  # see validate_math_renderer
968
977
  name: str = self.builder.math_renderer_name # type: ignore[assignment]
969
- _, depart = self.builder.app.registry.html_inline_math_renderers[name]
978
+ _, depart = self.builder.env._registry.html_inline_math_renderers[name]
970
979
  if depart:
971
980
  depart(self, node)
972
981
 
973
- def visit_math_block(self, node: Element, math_env: str = '') -> None:
982
+ def visit_math_block(self, node: nodes.math_block, math_env: str = '') -> None:
983
+ self._has_maths_elements = True
984
+
974
985
  # see validate_math_renderer
975
986
  name: str = self.builder.math_renderer_name # type: ignore[assignment]
976
- visit, _ = self.builder.app.registry.html_block_math_renderers[name]
987
+ visit, _ = self.builder.env._registry.html_block_math_renderers[name]
977
988
  visit(self, node)
978
989
 
979
- def depart_math_block(self, node: Element, math_env: str = '') -> None:
990
+ def depart_math_block(self, node: nodes.math_block, math_env: str = '') -> None:
980
991
  # see validate_math_renderer
981
992
  name: str = self.builder.math_renderer_name # type: ignore[assignment]
982
- _, depart = self.builder.app.registry.html_block_math_renderers[name]
993
+ _, depart = self.builder.env._registry.html_block_math_renderers[name]
983
994
  if depart:
984
995
  depart(self, node)
985
996