1. Georg Brandl
  2. sphinx

Commits

Takayuki Shimizukawa  committed 0986d4e

checking whether the number of references is equal in both the translated form and the untranslated form? If they're not equal, emit a warning and don't bother trying to transfer the references.

  • Participants
  • Parent commits 21a4239
  • Branches #955

Comments (0)

Files changed (5)

File sphinx/environment.py

View file
     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.
+
             footnote_refs = self._collect_footnote_ref_nodes(node.children)
             refs = self._collect_ref_nodes(node.children)
 
                     # use original 'footnote_reference' object.
                     # this object is already registered in self.document.autofootnote_refs
                     patch.children[i] = footnote_refs.pop(0)
-                    # Some duplicated footnote_reference in msgstr cause
-                    # IndexError in .pop(0). That is invalid msgstr.
 
                 elif isinstance(child, nodes.reference):
                     # reference should use original 'refname'.

File tests/root/contents.txt

View file
    only
    i18n_footnote
    i18n_external_links
+   i18n_refs_inconsistency
 
    Python <http://python.org/>
 

File tests/root/i18n_refs_inconsistency.po

View file
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) 2012, foof
+# This file is distributed under the same license as the foo package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: sphinx 1.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-12-05 08:28\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "i18n with refs inconsistency"
+msgstr "I18N WITH REFS INCONSISTENCY"
+
+msgid "[100]_ for [#]_ footnote [ref2]_."
+msgstr "FOR FOOTNOTE [ref2]_."
+
+msgid "for reference_."
+msgstr "reference_ FOR reference_."
+
+msgid "This is a auto numbered footnote."
+msgstr "THIS IS A AUTO NUMBERED FOOTNOTE."
+
+msgid "This is a named footnote."
+msgstr "THIS IS A NAMED FOOTNOTE."
+
+msgid "This is a numbered footnote."
+msgstr "THIS IS A NUMBERED FOOTNOTE."
+

File tests/root/i18n_refs_inconsistency.txt

View file
+:tocdepth: 2
+
+i18n with refs inconsistency
+=============================
+
+* [100]_ for [#]_ footnote [ref2]_.
+* for reference_.
+
+.. [#] This is a auto numbered footnote.
+.. [ref2] This is a named footnote.
+.. [100] This is a numbered footnote.
+.. _reference: http://www.example.com

File tests/test_intl.py

View file
 
 from subprocess import Popen, PIPE
 import re
+import os
+from StringIO import StringIO
 
 from util import *
 from util import SkipTest
 
 
+warnfile = StringIO()
+
+
 def setup_module():
     (test_root / 'xx' / 'LC_MESSAGES').makedirs()
     # Compile all required catalogs into binary format (*.mo).
-    for catalog in 'bom', 'subdir', 'i18n_footnote', 'i18n_external_links':
+    for catalog in ('bom', 'subdir', 'i18n_footnote', 'i18n_external_links',
+            'i18n_refs_inconsistency'):
         try:
             p = Popen(['msgfmt', test_root / '%s.po' % catalog, '-o',
                 test_root / 'xx' / 'LC_MESSAGES' / '%s.mo' % catalog],
     assert result == expect
 
 
+@with_app(buildername='text', warning=warnfile,
+          confoverrides={'language': 'xx', 'locale_dirs': ['.']})
+def test_i18n_warn_for_number_of_references_inconsistency(app):
+    app.builddir.rmtree(True)
+    app.builder.build(['i18n_refs_inconsistency'])
+    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[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")
+    assert result == expect
+
+    warnings = warnfile.getvalue().replace(os.sep, '/')
+    expected_warning_expr = "i18n_refs_inconsistency.txt:\d+: WARNING: The number of reference are inconsistent in both the translated form and the untranslated form. skip translation."
+    assert len(re.findall(expected_warning_expr, warnings)) == 2
+
+
 @with_app(buildername='html',
           confoverrides={'language': 'xx', 'locale_dirs': ['.']})
 def test_i18n_keep_external_links(app):