change: Make readable-text a priority.

If the number of reference does not match then some links will be broken.
This commit is contained in:
Takayuki Shimizukawa 2012-12-05 19:35:07 +09:00
parent e9f3ad438b
commit e9275d3f0c
2 changed files with 50 additions and 64 deletions

View File

@ -195,44 +195,6 @@ class Locale(Transform):
""" """
default_priority = 0 default_priority = 0
@classmethod
def _collect_nodes(cls, nodelist, node_types, custom_cond_func=None):
if custom_cond_func is None:
custom_cond_func = lambda x: True
collected = [node for node in nodelist
if isinstance(node, node_types)
and custom_cond_func(node)]
return collected
@classmethod
def _collect_footnote_ref_nodes(cls, nodelist):
return cls._collect_nodes(
nodelist,
nodes.footnote_reference,
lambda n: n.get('auto') == 1)
@classmethod
def _collect_ref_nodes(cls, nodelist):
return cls._collect_nodes(nodelist, nodes.reference)
def _is_ref_inconsistency(self, node1, node2):
"""
check equality of the number of reference in both the translated
form and the untranslated form.
"""
env = self.document.settings.env
for f in [self._collect_footnote_ref_nodes,
self._collect_ref_nodes,
]:
if len(f(node1.children)) != len(f(node2.children)):
env.warn_node('The number of reference are inconsistent '
'in both the translated form and the '
'untranslated form. skip translation.', node1)
return True
return False
def apply(self): def apply(self):
env = self.document.settings.env env = self.document.settings.env
settings, source = self.document.settings, self.document['source'] settings, source = self.document.settings, self.document['source']
@ -265,32 +227,40 @@ class Locale(Transform):
if not isinstance(patch, nodes.paragraph): if not isinstance(patch, nodes.paragraph):
continue # skip for now continue # skip for now
if self._is_ref_inconsistency(node, patch): # auto-numbered foot note reference should use original 'ids'.
continue #skip translation. is_autonumber_footnote_ref = lambda node: \
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):
env.warn_node('The number of reference are inconsistent '
'in both the translated form and the '
'untranslated form. skip translation.', node)
for old, new in zip(old_foot_refs, new_foot_refs):
new['ids'] = old['ids']
self.document.autofootnote_refs.remove(old)
self.document.note_autofootnote_ref(new)
footnote_refs = self._collect_footnote_ref_nodes(node.children)
refs = self._collect_ref_nodes(node.children)
for i, child in enumerate(patch.children): # update leaves
if isinstance(child, nodes.footnote_reference) \
and child.get('auto') == 1:
# use original 'footnote_reference' object.
# this object is already registered in self.document.autofootnote_refs
patch.children[i] = footnote_refs.pop(0)
elif isinstance(child, nodes.reference):
# reference should use original 'refname'. # reference should use original 'refname'.
# * reference target ".. _Python: ..." is not translatable. # * reference target ".. _Python: ..." is not translatable.
# * section refname is not translatable. # * section refname is not translatable.
# * inline reference "`Python <...>`_" has no 'refname'. # * inline reference "`Python <...>`_" has no 'refname'.
if refs and 'refname' in refs[0]: is_refnamed_ref = lambda node: \
refname = child['refname'] = refs.pop(0)['refname'] isinstance(node, nodes.reference) \
self.document.refnames.setdefault( and 'refname' in node
refname, []).append(child) old_refs = node.traverse(is_refnamed_ref)
# if number of reference nodes had been changed, that new_refs = patch.traverse(is_refnamed_ref)
# would often generate unknown link target warning. if len(old_refs) != len(new_refs):
env.warn_node('The number of reference are inconsistent '
'in both the translated form and the '
'untranslated form. skip translation.', node)
for old, new in zip(old_refs, new_refs):
new['refname'] = old['refname']
self.document.note_refname(new)
for child in patch.children: # update leaves # update leaves
for child in patch.children:
child.parent = node child.parent = node
node.children = patch.children node.children = patch.children

View File

@ -111,8 +111,8 @@ def test_i18n_warn_for_number_of_references_inconsistency(app):
result = (app.outdir / 'i18n' / 'refs_inconsistency.txt').text(encoding='utf-8') result = (app.outdir / 'i18n' / 'refs_inconsistency.txt').text(encoding='utf-8')
expect = (u"\nI18N WITH REFS INCONSISTENCY" expect = (u"\nI18N WITH REFS INCONSISTENCY"
u"\n****************************\n" u"\n****************************\n"
u"\n* [100] for [1] footnote [ref2].\n" u"\n* FOR FOOTNOTE [ref2].\n"
u"\n* for reference.\n" u"\n* reference FOR reference.\n"
u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n" u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n"
u"\n[ref2] THIS IS A NAMED FOOTNOTE.\n" u"\n[ref2] THIS IS A NAMED FOOTNOTE.\n"
u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n") u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n")
@ -123,6 +123,22 @@ def test_i18n_warn_for_number_of_references_inconsistency(app):
assert len(re.findall(expected_warning_expr, warnings)) == 2 assert len(re.findall(expected_warning_expr, warnings)) == 2
@with_app(buildername='html', cleanenv=True,
confoverrides={'language': 'xx', 'locale_dirs': ['.'],
'gettext_compact': False})
def test_i18n_link_to_undefined_reference(app):
app.builder.build(['i18n/refs_inconsistency'])
result = (app.outdir / 'i18n' / 'refs_inconsistency.html').text(encoding='utf-8')
expected_expr = """<a class="reference external" href="http://www.example.com">reference</a>"""
assert len(re.findall(expected_expr, result)) == 1
# the 2nd 'reference_' is to be internal-link instead of external-link.
# TODO: Can we re-use the same name named-reference?
expected_expr = """<a class="reference internal" href="#reference">reference</a>"""
assert len(re.findall(expected_expr, result)) == 1
@with_app(buildername='html', cleanenv=True, @with_app(buildername='html', cleanenv=True,
confoverrides={'language': 'xx', 'locale_dirs': ['.'], confoverrides={'language': 'xx', 'locale_dirs': ['.'],
'gettext_compact': False}) 'gettext_compact': False})