From ccd8067ee50b28a89d1457ac39da0bb183a92c20 Mon Sep 17 00:00:00 2001 From: Nozomu Kaneko Date: Wed, 19 Dec 2012 07:49:17 +0900 Subject: [PATCH] fix #1058: footnote backlinks with i18n --- sphinx/environment.py | 31 +++++++++++++++++++++++++------ tests/test_intl.py | 20 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/sphinx/environment.py b/sphinx/environment.py index 36ab36d40..a7ce8d5a6 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -237,9 +237,9 @@ class Locale(Transform): continue # skip for now # auto-numbered foot note reference should use original 'ids'. - is_autonumber_footnote_ref = lambda node: \ - isinstance(node, nodes.footnote_reference) \ - and node.get('auto') == 1 + def is_autonumber_footnote_ref(node): + return isinstance(node, nodes.footnote_reference) and \ + node.get('auto') == 1 old_foot_refs = node.traverse(is_autonumber_footnote_ref) new_foot_refs = patch.traverse(is_autonumber_footnote_ref) if len(old_foot_refs) != len(new_foot_refs): @@ -254,9 +254,9 @@ class Locale(Transform): # * reference target ".. _Python: ..." is not translatable. # * section refname is not translatable. # * inline reference "`Python <...>`_" has no 'refname'. - is_refnamed_ref = lambda node: \ - isinstance(node, nodes.reference) \ - and 'refname' in node + def is_refnamed_ref(node): + return isinstance(node, nodes.reference) and \ + 'refname' in node old_refs = node.traverse(is_refnamed_ref) new_refs = patch.traverse(is_refnamed_ref) applied_refname_map = {} @@ -279,6 +279,25 @@ class Locale(Transform): self.document.note_refname(new) + # refnamed footnote and citation should use original 'ids'. + def is_refnamed_footnote_ref(node): + footnote_ref_classes = (nodes.footnote_reference, + nodes.citation_reference) + return isinstance(node, footnote_ref_classes) and \ + 'refname' in node + old_refs = node.traverse(is_refnamed_footnote_ref) + new_refs = patch.traverse(is_refnamed_footnote_ref) + refname_ids_map = {} + if len(old_refs) != len(new_refs): + env.warn_node('inconsistent references in ' + 'translated message', node) + for old in old_refs: + refname_ids_map[old["refname"]] = old["ids"] + for new in new_refs: + refname = new["refname"] + if refname in refname_ids_map: + new["ids"] = refname_ids_map[refname] + # update leaves for child in patch.children: child.parent = node diff --git a/tests/test_intl.py b/tests/test_intl.py index 67507ed11..e8d74714b 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -101,6 +101,26 @@ def test_i18n_footnote_regression(app): assert result == expect +@with_app(buildername='html', cleanenv=True, + confoverrides={'language': 'xx', 'locale_dirs': ['.'], + 'gettext_compact': False}) +def test_i18n_footnote_backlink(app): + """i18n test for #1058""" + app.builder.build(['i18n/footnote']) + result = (app.outdir / 'i18n' / 'footnote.html').text(encoding='utf-8') + expects = [ + '[100]', # id="id3" + '[1]', # id="id2" + '[ref]', # id="id1" + '[1]', + '[ref]', + '[100]', + ] + for expect in expects: + matches = re.findall(re.escape(expect), result) + assert len(matches) == 1 + + @with_app(buildername='text', warning=warnfile, cleanenv=True, confoverrides={'language': 'xx', 'locale_dirs': ['.'], 'gettext_compact': False})