Takayuki Shimizukawa avatar Takayuki Shimizukawa committed d236741

change: Make readable-text a priority.
If the number of reference does not match then some links will be broken.

Comments (0)

Files changed (2)

sphinx/environment.py

     """
     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):
         env = self.document.settings.env
         settings, source = self.document.settings, self.document['source']
             if not isinstance(patch, nodes.paragraph):
                 continue # skip for now
 
-            if self._is_ref_inconsistency(node, patch):
-                continue #skip translation.
+            # 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
+            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)
+            # reference should use original 'refname'.
+            # * 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
+            old_refs = node.traverse(is_refnamed_ref)
+            new_refs = patch.traverse(is_refnamed_ref)
+            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 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 target ".. _Python: ..." is not translatable.
-                    # * section refname is not translatable.
-                    # * inline reference "`Python <...>`_" has no 'refname'.
-                    if refs and 'refname' in refs[0]:
-                        refname = child['refname'] = refs.pop(0)['refname']
-                        self.document.refnames.setdefault(
-                                refname, []).append(child)
-                    # if number of reference nodes had been changed, that
-                    # would often generate unknown link target warning.
-
-            for child in patch.children: # update leaves
+            # update leaves
+            for child in patch.children:
                 child.parent = node
             node.children = patch.children
 

tests/test_intl.py

     result = (app.outdir / 'i18n' / 'refs_inconsistency.txt').text(encoding='utf-8')
     expect = (u"\nI18N WITH REFS INCONSISTENCY"
               u"\n****************************\n"
-              u"\n* [100] for [1] footnote [ref2].\n"
-              u"\n* for reference.\n"
+              u"\n* FOR FOOTNOTE [ref2].\n"
+              u"\n* reference FOR reference.\n"
               u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n"
               u"\n[ref2] THIS IS A NAMED FOOTNOTE.\n"
               u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n")
 @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,
+          confoverrides={'language': 'xx', 'locale_dirs': ['.'],
+                         'gettext_compact': False})
 def test_i18n_keep_external_links(app):
     """regression test for #1044"""
     app.builder.build(['i18n/external_links'])
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.