Takayuki Shimizukawa avatar Takayuki Shimizukawa committed e5ad8ce

Fix i18n: footnote reference number missing for auto numbered named footnote and auto symbol footnote. Closes #1176

Comments (0)

Files changed (5)

   characters to "Project name" on quickstart.
 * #1190: Output TeX/texinfo/man filename has no basename (only extention)
   when using multibyte characters to "Project name" on quickstart.
-* #1090: Fix multiple cross references (term, ref, doc) in the same line
-  return the same link with i18n.
-* #1193: Fix multiple link references in the same line return the same
-  link with i18n.
+* #1090: Fix i18n: multiple cross references (term, ref, doc) in the same line
+  return the same link.
+* #1193: Fix i18n: multiple link references in the same line return the same
+  link.
+* #1176: Fix i18n: footnote reference number missing for auto numbered named
+  footnote and auto symbol footnote.
 
 
 Release 1.2 (beta1 released Mar 31, 2013)

sphinx/transforms.py

             def is_autonumber_footnote_ref(node):
                 return isinstance(node, nodes.footnote_reference) and \
                     node.get('auto') == 1
+            def list_replace_or_append(lst, old, new):
+                if old in lst:
+                    lst[lst.index(old)] = new
+                else:
+                    lst.append(new)
             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):
                 env.warn_node('inconsistent footnote references in '
                               'translated message', node)
-            for old, new in zip(old_foot_refs, new_foot_refs):
+            old_foot_namerefs = {}
+            for r in old_foot_refs:
+                old_foot_namerefs.setdefault(r.get('refname'), []).append(r)
+            for new in new_foot_refs:
+                refname = new.get('refname')
+                refs = old_foot_namerefs.get(refname, [])
+                if not refs:
+                    continue
+
+                old = refs.pop(0)
                 new['ids'] = old['ids']
                 for id in new['ids']:
                     self.document.ids[id] = new
-                self.document.autofootnote_refs.remove(old)
-                self.document.note_autofootnote_ref(new)
+                list_replace_or_append(
+                        self.document.autofootnote_refs, old, new)
+                if refname:
+                    list_replace_or_append(
+                        self.document.footnote_refs.setdefault(refname, []),
+                        old, new)
+                    list_replace_or_append(
+                        self.document.refnames.setdefault(refname, []),
+                        old, new)
 
             # reference should use new (translated) 'refname'.
             # * reference target ".. _Python: ..." is not translatable.

tests/roots/test-intl/footnote.po

 msgid "i18n with Footnote"
 msgstr "I18N WITH FOOTNOTE"
 
-msgid "[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_"
-msgstr "`I18N WITH FOOTNOTE`_ INCLUDE THIS CONTENTS [ref]_ [#]_ [100]_"
+msgid "[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_ [#named]_."
+msgstr "`I18N WITH FOOTNOTE`_ INCLUDE THIS CONTENTS [#named]_ [ref]_ [#]_ [100]_."
 
 msgid "This is a auto numbered footnote."
 msgstr "THIS IS A AUTO NUMBERED FOOTNOTE."
 msgid "This is a numbered footnote."
 msgstr "THIS IS A NUMBERED FOOTNOTE."
 
+msgid "This is a auto numbered named footnote."
+msgstr "THIS IS A AUTO NUMBERED NAMED FOOTNOTE."
+

tests/roots/test-intl/footnote.txt

 ==================
 .. #955 cant-build-html-with-footnotes-when-using
 
-[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_
+[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_ [#named]_.
 
 .. [#] This is a auto numbered footnote.
 .. [ref] This is a named footnote.
 .. [100] This is a numbered footnote.
+.. [#named] This is a auto numbered named footnote.

tests/test_intl.py

 
 @with_intl_app(buildername='xml', warning=warnfile)
 def test_i18n_footnote_regression(app):
-    # regression test for fix #955
+    # regression test for fix #955, #1176
     app.builddir.rmtree(True)
     app.builder.build(['footnote'])
     et = ElementTree.parse(app.outdir / 'footnote.xml')
     assert_elem(
             para0[0],
             texts=['I18N WITH FOOTNOTE', 'INCLUDE THIS CONTENTS',
-                  '[ref]', '1', '100'],
+                  '2', '[ref]', '1', '100', '.'],
             refs=['i18n-with-footnote', 'ref'])
 
     footnote0 = secs[0].findall('footnote')
             footnote0[1],
             texts=['100','THIS IS A NUMBERED FOOTNOTE.'],
             names=['100'])
+    assert_elem(
+            footnote0[2],
+            texts=['2','THIS IS A AUTO NUMBERED NAMED FOOTNOTE.'],
+            names=['named'])
 
     citation0 = secs[0].findall('citation')
     assert_elem(
     assert not re.search(warning_expr, warnings)
 
 
-@with_intl_app(buildername='html', cleanenv=True)
+@with_intl_app(buildername='xml', cleanenv=True)
 def test_i18n_footnote_backlink(app):
-    """i18n test for #1058"""
+    # i18n test for #1058
     app.builder.build(['footnote'])
-    result = (app.outdir / 'footnote.html').text(encoding='utf-8')
-    expects = [
-        '<a class="footnote-reference" href="#id5" id="id1">[100]</a>',
-        '<a class="footnote-reference" href="#id4" id="id2">[1]</a>',
-        '<a class="reference internal" href="#ref" id="id3">[ref]</a>',
-        '<a class="fn-backref" href="#id2">[1]</a>',
-        '<a class="fn-backref" href="#id3">[ref]</a>',
-        '<a class="fn-backref" href="#id1">[100]</a>',
-        ]
-    for expect in expects:
-        matches = re.findall(re.escape(expect), result)
-        assert len(matches) == 1
+    et = ElementTree.parse(app.outdir / 'footnote.xml')
+    secs = et.findall('section')
+
+    para0 = secs[0].findall('paragraph')
+    refs0 = para0[0].findall('footnote_reference')
+    refid2id = dict([
+        (r.attrib.get('refid'), r.attrib.get('ids')) for r in refs0])
+
+    footnote0 = secs[0].findall('footnote')
+    for footnote in footnote0:
+        ids = footnote.attrib.get('ids')
+        backrefs = footnote.attrib.get('backrefs')
+        assert refid2id[ids] == backrefs
 
 
 @with_intl_app(buildername='text', warning=warnfile, cleanenv=True)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.