diff --git a/CHANGES b/CHANGES index 7498d6525..a8afcd40d 100644 --- a/CHANGES +++ b/CHANGES @@ -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 -------- diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py index f86715fcf..b2d8413a8 100644 --- a/sphinx/builders/_epub_base.py +++ b/sphinx/builders/_epub_base.py @@ -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""" diff --git a/tests/test_build_epub.py b/tests/test_build_epub.py index f893e1351..fc4b5329a 100644 --- a/tests/test_build_epub.py +++ b/tests/test_build_epub.py @@ -321,10 +321,8 @@ def test_epub_anchor_id(app): html = (app.outdir / 'index.xhtml').read_text() assert ('
' - '' 'blah blah blah
' in html) assert ('' - '' '