Fix #2987: Invalid HTML has been generated if multiple IDs are assigned to a list

This commit is contained in:
Takeshi KOMIYA
2016-09-30 23:42:40 +09:00
parent 32981d1048
commit 6a6843096c
2 changed files with 24 additions and 1 deletions

View File

@@ -25,6 +25,7 @@ Bugs fixed
* #3009: Bad rendering of parsed-literals in LaTeX since Sphinx 1.4.4
* #3000: ``option`` directive generates invalid HTML anchors
* #2984: Invalid HTML has been generated if `html_split_index` enabled
* #2987: Invalid HTML has been generated if multiple IDs are assigned to a list
Documentation
-------------

View File

@@ -297,12 +297,33 @@ class HTMLTranslator(BaseTranslator):
format = u'<a class="headerlink" href="#%s" title="%s">%s</a>'
self.body.append(format % (node['ids'][0], title, self.permalink_text))
# overwritten to avoid emitting empty <ul></ul>
def generate_targets_for_listing(self, node):
"""Generate hyperlink targets for listings.
Original visit_bullet_list(), visit_definition_list() and visit_enumerated_list()
generates hyperlink targets inside listing tags (<ul>, <ol> and <dl>) if multiple
IDs are assigned to listings. That is invalid DOM structure.
(This is a bug of docutils <= 0.12)
This exports hyperlink targets before listings to make valid DOM structure.
"""
for id in node['ids'][1:]:
self.body.append('<span id="%s"></span>' % id)
node['ids'].remove(id)
# overwritten
def visit_bullet_list(self, node):
if len(node) == 1 and node[0].tagname == 'toctree':
# avoid emitting empty <ul></ul>
raise nodes.SkipNode
self.generate_targets_for_listing(node)
BaseTranslator.visit_bullet_list(self, node)
# overwritten
def visit_enumerated_list(self, node):
self.generate_targets_for_listing(node)
BaseTranslator.visit_enumerated_list(self, node)
# overwritten
def visit_title(self, node):
BaseTranslator.visit_title(self, node)
@@ -648,6 +669,7 @@ class HTMLTranslator(BaseTranslator):
# overwritten to do not add '</dt>' in 'visit_definition' state.
def visit_definition(self, node):
self.generate_targets_for_listing(node)
self.body.append(self.starttag(node, 'dd', ''))
self.set_first_last(node)