Skip to content

Commit 7459d87

Browse files
committed
Fix HTML: Invalid HTML5 file is generated for glossary (refs: #4611)
Note: It was caused by a glossary having multiple terms for one description.
1 parent b04bfcf commit 7459d87

File tree

4 files changed

+109
-0
lines changed

4 files changed

+109
-0
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ Bugs fixed
155155
if passed as language option?
156156
* #5179: LaTeX: (lualatex only) escaping of ``>`` by ``\textgreater{}`` is not
157157
enough as ``\textgreater{}\textgreater{}`` applies TeX-ligature
158+
* HTML: Invalid HTML5 file is generated for a glossary having multiple terms for
159+
one description (refs: #4611)
158160

159161
Testing
160162
--------

sphinx/writers/html.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,48 @@ def visit_enumerated_list(self, node):
393393
self.generate_targets_for_listing(node)
394394
super().visit_enumerated_list(node)
395395

396+
# overwritten
397+
def visit_definition(self, node):
398+
# type: (nodes.Element) -> None
399+
# don't insert </dt> here.
400+
self.body.append(self.starttag(node, 'dd', ''))
401+
402+
# overwritten
403+
def depart_definition(self, node):
404+
# type: (nodes.Element) -> None
405+
self.body.append('</dd>\n')
406+
407+
# overwritten
408+
def visit_classifier(self, node):
409+
# type: (nodes.Element) -> None
410+
self.body.append(self.starttag(node, 'span', '', CLASS='classifier'))
411+
412+
# overwritten
413+
def depart_classifier(self, node):
414+
# type: (nodes.Element) -> None
415+
self.body.append('</span>')
416+
417+
next_node = node.next_node(descend=False, siblings=True) # type: nodes.Node
418+
if not isinstance(next_node, nodes.classifier):
419+
# close `<dt>` tag at the tail of classifiers
420+
self.body.append('</dt>')
421+
422+
# overwritten
423+
def visit_term(self, node):
424+
# type: (nodes.Element) -> None
425+
self.body.append(self.starttag(node, 'dt', ''))
426+
427+
# overwritten
428+
def depart_term(self, node):
429+
# type: (nodes.Element) -> None
430+
next_node = node.next_node(descend=False, siblings=True) # type: nodes.Node
431+
if isinstance(next_node, nodes.classifier):
432+
# Leave the end tag to `self.depart_classifier()`, in case
433+
# there's a classifier.
434+
pass
435+
else:
436+
self.body.append('</dt>')
437+
396438
# overwritten
397439
def visit_title(self, node):
398440
# type: (nodes.Element) -> None

sphinx/writers/html5.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,48 @@ def visit_bullet_list(self, node):
339339
raise nodes.SkipNode
340340
super().visit_bullet_list(node)
341341

342+
# overwritten
343+
def visit_definition(self, node):
344+
# type: (nodes.Element) -> None
345+
# don't insert </dt> here.
346+
self.body.append(self.starttag(node, 'dd', ''))
347+
348+
# overwritten
349+
def depart_definition(self, node):
350+
# type: (nodes.Element) -> None
351+
self.body.append('</dd>\n')
352+
353+
# overwritten
354+
def visit_classifier(self, node):
355+
# type: (nodes.Element) -> None
356+
self.body.append(self.starttag(node, 'span', '', CLASS='classifier'))
357+
358+
# overwritten
359+
def depart_classifier(self, node):
360+
# type: (nodes.Element) -> None
361+
self.body.append('</span>')
362+
363+
next_node = node.next_node(descend=False, siblings=True) # type: nodes.Node
364+
if not isinstance(next_node, nodes.classifier):
365+
# close `<dt>` tag at the tail of classifiers
366+
self.body.append('</dt>')
367+
368+
# overwritten
369+
def visit_term(self, node):
370+
# type: (nodes.Element) -> None
371+
self.body.append(self.starttag(node, 'dt', ''))
372+
373+
# overwritten
374+
def depart_term(self, node):
375+
# type: (nodes.Element) -> None
376+
next_node = node.next_node(descend=False, siblings=True) # type: nodes.Node
377+
if isinstance(next_node, nodes.classifier):
378+
# Leave the end tag to `self.depart_classifier()`, in case
379+
# there's a classifier.
380+
pass
381+
else:
382+
self.body.append('</dt>')
383+
342384
# overwritten
343385
def visit_title(self, node):
344386
# type: (nodes.Element) -> None

tests/test_markup.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,29 @@ def get(name):
234234
None,
235235
r'\\sphinxhref{http://example.com/~me/}{test}.*',
236236
),
237+
(
238+
# description list: simple
239+
'verify',
240+
'term\n description',
241+
'<dl class="docutils">\n<dt>term</dt><dd>description</dd>\n</dl>',
242+
None,
243+
),
244+
(
245+
# description list: with classifiers
246+
'verify',
247+
'term : class1 : class2\n description',
248+
('<dl class="docutils">\n<dt>term<span class="classifier">class1</span>'
249+
'<span class="classifier">class2</span></dt><dd>description</dd>\n</dl>'),
250+
None,
251+
),
252+
(
253+
# glossary (description list): multiple terms
254+
'verify',
255+
'.. glossary::\n\n term1\n term2\n description',
256+
('<dl class="glossary docutils">\n<dt id="term-term1">term1</dt>'
257+
'<dt id="term-term2">term2</dt><dd>description</dd>\n</dl>'),
258+
None,
259+
),
237260
])
238261
def test_inline(get_verifier, type, rst, html_expected, latex_expected):
239262
verifier = get_verifier(type)

0 commit comments

Comments
 (0)