Fix #7301: epub: duplicated node_ids are generated

This commit is contained in:
Takeshi KOMIYA 2020-03-29 23:55:45 +09:00
parent 7aa5584a47
commit 32b256dc2f
3 changed files with 13 additions and 13 deletions

View File

@ -27,6 +27,7 @@ Bugs fixed
* #7219: py domain: The index entry generated by ``py:function`` directive is
different with one from ``index`` directive with "builtin" type
* #7301: capital characters are not allowed for node_id
* #7301: epub: duplicated node_ids are generated
Testing
--------

View File

@ -259,6 +259,15 @@ class EpubBuilder(StandaloneHTMLBuilder):
Some readers crash because they interpret the part as a
transport protocol specification.
"""
def update_node_id(node: Element) -> None:
"""Update IDs of given *node*."""
new_ids = []
for node_id in node['ids']:
new_id = self.fix_fragment('', node_id)
if new_id not in new_ids:
new_ids.append(new_id)
node['ids'] = new_ids
for reference in tree.traverse(nodes.reference):
if 'refuri' in reference:
m = self.refuri_re.match(reference['refuri'])
@ -268,22 +277,14 @@ class EpubBuilder(StandaloneHTMLBuilder):
reference['refid'] = self.fix_fragment('', reference['refid'])
for target in tree.traverse(nodes.target):
for i, node_id in enumerate(target['ids']):
if ':' in node_id:
target['ids'][i] = self.fix_fragment('', node_id)
update_node_id(target)
next_node = target.next_node(ascend=True) # type: Node
if isinstance(next_node, nodes.Element):
for i, node_id in enumerate(next_node['ids']):
if ':' in node_id:
next_node['ids'][i] = self.fix_fragment('', node_id)
update_node_id(next_node)
for desc_signature in tree.traverse(addnodes.desc_signature):
ids = desc_signature.attributes['ids']
newids = []
for id in ids:
newids.append(self.fix_fragment('', id))
desc_signature.attributes['ids'] = newids
update_node_id(desc_signature)
def add_visible_links(self, tree: nodes.document, show_urls: str = 'inline') -> None:
"""Add visible link targets for external links"""

View File

@ -321,10 +321,8 @@ def test_epub_anchor_id(app):
html = (app.outdir / 'index.xhtml').read_text()
assert ('<p id="std-setting-STATICFILES_FINDERS">'
'<span id="std-setting-STATICFILES_FINDERS"></span>'
'blah blah blah</p>' in html)
assert ('<span id="std-setting-STATICFILES_SECTION"></span>'
'<span id="std-setting-STATICFILES_SECTION"></span>'
'<h1>blah blah blah</h1>' in html)
assert 'see <a class="reference internal" href="#std-setting-STATICFILES_FINDERS">' in html