mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix duplicated labels in TeX output (#11093)
This commit is contained in:
@@ -1499,7 +1499,26 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
pass
|
||||
else:
|
||||
add_target(node['refid'])
|
||||
for id in node['ids']:
|
||||
# Temporary fix for https://github.com/sphinx-doc/sphinx/issues/11093
|
||||
# TODO: investigate if a more elegant solution exists (see comments of #11093)
|
||||
if node.get('ismod', False):
|
||||
# Detect if the previous nodes are label targets. If so, remove
|
||||
# the refid thereof from node['ids'] to avoid duplicated ids.
|
||||
def has_dup_label(sib: Element | None) -> bool:
|
||||
return isinstance(sib, nodes.target) and sib.get('refid') in node['ids']
|
||||
|
||||
prev: Element | None = get_prev_node(node)
|
||||
if has_dup_label(prev):
|
||||
ids = node['ids'][:] # copy to avoid side-effects
|
||||
while has_dup_label(prev):
|
||||
ids.remove(prev['refid'])
|
||||
prev = get_prev_node(prev)
|
||||
else:
|
||||
ids = iter(node['ids']) # read-only iterator
|
||||
else:
|
||||
ids = iter(node['ids']) # read-only iterator
|
||||
|
||||
for id in ids:
|
||||
add_target(id)
|
||||
|
||||
def depart_target(self, node: Element) -> None:
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
"""docstring"""
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
"""docstring"""
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
"""docstring"""
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
"""docstring"""
|
||||
|
||||
8
tests/roots/test-latex-labels-before-module/conf.py
Normal file
8
tests/roots/test-latex-labels-before-module/conf.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
|
||||
nitpicky = True
|
||||
48
tests/roots/test-latex-labels-before-module/index.rst
Normal file
48
tests/roots/test-latex-labels-before-module/index.rst
Normal file
@@ -0,0 +1,48 @@
|
||||
latex-labels-before-module
|
||||
==========================
|
||||
|
||||
.. _label_1a:
|
||||
.. _label_1b:
|
||||
|
||||
.. module:: module1
|
||||
|
||||
text
|
||||
|
||||
.. _label_2:
|
||||
|
||||
.. module:: module2a
|
||||
|
||||
text
|
||||
|
||||
.. module:: module2b
|
||||
|
||||
text
|
||||
|
||||
.. _label_3:
|
||||
|
||||
.. module:: module3
|
||||
|
||||
text
|
||||
|
||||
.. _label_auto_1a:
|
||||
.. _label_auto_1b:
|
||||
|
||||
.. automodule:: automodule1
|
||||
|
||||
text
|
||||
|
||||
.. _label_auto_2:
|
||||
|
||||
.. automodule:: automodule2a
|
||||
|
||||
text
|
||||
|
||||
.. automodule:: automodule2b
|
||||
|
||||
text
|
||||
|
||||
.. _label_auto_3:
|
||||
|
||||
.. automodule:: automodule3
|
||||
|
||||
text
|
||||
@@ -1708,3 +1708,30 @@ def test_copy_images(app, status, warning):
|
||||
'rimg.png',
|
||||
'testimäge.png',
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.sphinx('latex', testroot='latex-labels-before-module')
|
||||
def test_duplicated_labels_before_module(app, status, warning):
|
||||
app.build()
|
||||
content: str = (app.outdir / 'python.tex').read_text()
|
||||
|
||||
def count_label(name):
|
||||
text = r'\phantomsection\label{\detokenize{%s}}' % name
|
||||
return content.count(text)
|
||||
|
||||
pattern = r'\\phantomsection\\label\{\\detokenize\{index:label-(?:auto-)?\d+[a-z]*}}'
|
||||
expect_labels = {match.group() for match in re.finditer(pattern, content)}
|
||||
result_labels = set()
|
||||
|
||||
# iterate over the (explicit) labels in the corresponding index.rst
|
||||
for rst_label_name in {
|
||||
'label_1a', 'label_1b', 'label_2', 'label_3',
|
||||
'label_auto_1a', 'label_auto_1b', 'label_auto_2', 'label_auto_3',
|
||||
}:
|
||||
tex_label_name = 'index:' + rst_label_name.replace('_', '-')
|
||||
tex_label_code = r'\phantomsection\label{\detokenize{%s}}' % tex_label_name
|
||||
assert content.count(tex_label_code) == 1, f'duplicated label: {tex_label_name!r}'
|
||||
result_labels.add(tex_label_code)
|
||||
|
||||
# sort the labels for a better visual diff, if any
|
||||
assert sorted(result_labels) == sorted(expect_labels)
|
||||
|
||||
Reference in New Issue
Block a user