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

This commit is contained in:
Takayuki Shimizukawa 2013-06-21 03:28:32 +00:00
parent 2cdb6b03c9
commit 7904b0678a
5 changed files with 58 additions and 26 deletions

10
CHANGES
View File

@ -32,10 +32,12 @@ Bugs fixed
characters to "Project name" on quickstart. characters to "Project name" on quickstart.
* #1190: Output TeX/texinfo/man filename has no basename (only extention) * #1190: Output TeX/texinfo/man filename has no basename (only extention)
when using multibyte characters to "Project name" on quickstart. when using multibyte characters to "Project name" on quickstart.
* #1090: Fix multiple cross references (term, ref, doc) in the same line * #1090: Fix i18n: multiple cross references (term, ref, doc) in the same line
return the same link with i18n. return the same link.
* #1193: Fix multiple link references in the same line return the same * #1193: Fix i18n: multiple link references in the same line return the same
link with i18n. 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) Release 1.2 (beta1 released Mar 31, 2013)

View File

@ -300,17 +300,38 @@ class Locale(Transform):
def is_autonumber_footnote_ref(node): def is_autonumber_footnote_ref(node):
return isinstance(node, nodes.footnote_reference) and \ return isinstance(node, nodes.footnote_reference) and \
node.get('auto') == 1 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) old_foot_refs = node.traverse(is_autonumber_footnote_ref)
new_foot_refs = patch.traverse(is_autonumber_footnote_ref) new_foot_refs = patch.traverse(is_autonumber_footnote_ref)
if len(old_foot_refs) != len(new_foot_refs): if len(old_foot_refs) != len(new_foot_refs):
env.warn_node('inconsistent footnote references in ' env.warn_node('inconsistent footnote references in '
'translated message', node) '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'] new['ids'] = old['ids']
for id in new['ids']: for id in new['ids']:
self.document.ids[id] = new self.document.ids[id] = new
self.document.autofootnote_refs.remove(old) list_replace_or_append(
self.document.note_autofootnote_ref(new) 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 should use new (translated) 'refname'.
# * reference target ".. _Python: ..." is not translatable. # * reference target ".. _Python: ..." is not translatable.

View File

@ -19,8 +19,8 @@ msgstr ""
msgid "i18n with Footnote" msgid "i18n with Footnote"
msgstr "I18N WITH FOOTNOTE" msgstr "I18N WITH FOOTNOTE"
msgid "[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_" msgid "[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_ [#named]_."
msgstr "`I18N WITH FOOTNOTE`_ INCLUDE THIS CONTENTS [ref]_ [#]_ [100]_" msgstr "`I18N WITH FOOTNOTE`_ INCLUDE THIS CONTENTS [#named]_ [ref]_ [#]_ [100]_."
msgid "This is a auto numbered footnote." msgid "This is a auto numbered footnote."
msgstr "THIS IS A AUTO NUMBERED FOOTNOTE." msgstr "THIS IS A AUTO NUMBERED FOOTNOTE."
@ -31,3 +31,6 @@ msgstr "THIS IS A NAMED FOOTNOTE."
msgid "This is a numbered footnote." msgid "This is a numbered footnote."
msgstr "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."

View File

@ -4,8 +4,9 @@ i18n with Footnote
================== ==================
.. #955 cant-build-html-with-footnotes-when-using .. #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. .. [#] This is a auto numbered footnote.
.. [ref] This is a named footnote. .. [ref] This is a named footnote.
.. [100] This is a numbered footnote. .. [100] This is a numbered footnote.
.. [#named] This is a auto numbered named footnote.

View File

@ -149,7 +149,7 @@ def test_i18n_footnote_break_refid(app):
@with_intl_app(buildername='xml', warning=warnfile) @with_intl_app(buildername='xml', warning=warnfile)
def test_i18n_footnote_regression(app): def test_i18n_footnote_regression(app):
# regression test for fix #955 # regression test for fix #955, #1176
app.builddir.rmtree(True) app.builddir.rmtree(True)
app.builder.build(['footnote']) app.builder.build(['footnote'])
et = ElementTree.parse(app.outdir / 'footnote.xml') et = ElementTree.parse(app.outdir / 'footnote.xml')
@ -159,7 +159,7 @@ def test_i18n_footnote_regression(app):
assert_elem( assert_elem(
para0[0], para0[0],
texts=['I18N WITH FOOTNOTE', 'INCLUDE THIS CONTENTS', texts=['I18N WITH FOOTNOTE', 'INCLUDE THIS CONTENTS',
'[ref]', '1', '100'], '2', '[ref]', '1', '100', '.'],
refs=['i18n-with-footnote', 'ref']) refs=['i18n-with-footnote', 'ref'])
footnote0 = secs[0].findall('footnote') footnote0 = secs[0].findall('footnote')
@ -171,6 +171,10 @@ def test_i18n_footnote_regression(app):
footnote0[1], footnote0[1],
texts=['100','THIS IS A NUMBERED FOOTNOTE.'], texts=['100','THIS IS A NUMBERED FOOTNOTE.'],
names=['100']) names=['100'])
assert_elem(
footnote0[2],
texts=['2','THIS IS A AUTO NUMBERED NAMED FOOTNOTE.'],
names=['named'])
citation0 = secs[0].findall('citation') citation0 = secs[0].findall('citation')
assert_elem( assert_elem(
@ -183,22 +187,23 @@ def test_i18n_footnote_regression(app):
assert not re.search(warning_expr, warnings) 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): def test_i18n_footnote_backlink(app):
"""i18n test for #1058""" # i18n test for #1058
app.builder.build(['footnote']) app.builder.build(['footnote'])
result = (app.outdir / 'footnote.html').text(encoding='utf-8') et = ElementTree.parse(app.outdir / 'footnote.xml')
expects = [ secs = et.findall('section')
'<a class="footnote-reference" href="#id5" id="id1">[100]</a>',
'<a class="footnote-reference" href="#id4" id="id2">[1]</a>', para0 = secs[0].findall('paragraph')
'<a class="reference internal" href="#ref" id="id3">[ref]</a>', refs0 = para0[0].findall('footnote_reference')
'<a class="fn-backref" href="#id2">[1]</a>', refid2id = dict([
'<a class="fn-backref" href="#id3">[ref]</a>', (r.attrib.get('refid'), r.attrib.get('ids')) for r in refs0])
'<a class="fn-backref" href="#id1">[100]</a>',
] footnote0 = secs[0].findall('footnote')
for expect in expects: for footnote in footnote0:
matches = re.findall(re.escape(expect), result) ids = footnote.attrib.get('ids')
assert len(matches) == 1 backrefs = footnote.attrib.get('backrefs')
assert refid2id[ids] == backrefs
@with_intl_app(buildername='text', warning=warnfile, cleanenv=True) @with_intl_app(buildername='text', warning=warnfile, cleanenv=True)