diff options
author | shimizukawa <shimizukawa@gmail.com> | 2013-10-04 05:07:09 +0900 |
---|---|---|
committer | shimizukawa <shimizukawa@gmail.com> | 2013-10-04 05:07:09 +0900 |
commit | c3e34e0e59f9f1e16a7eed958685c854c666b96e (patch) | |
tree | 0c0e2d2a71ef4854b60deb4113cbb78f41243af0 | |
parent | c0ec30bb423782d83b55e7cd1590fb20d396901a (diff) | |
download | sphinx-c3e34e0e59f9f1e16a7eed958685c854c666b96e.tar.gz |
Now gettext translates label target name. Fix i18n: crash when using a indirect target and translating a target section name. Closes #1265
-rw-r--r-- | CHANGES | 19 | ||||
-rw-r--r-- | sphinx/builders/gettext.py | 9 | ||||
-rw-r--r-- | sphinx/transforms.py | 44 | ||||
-rw-r--r-- | sphinx/util/nodes.py | 7 | ||||
-rw-r--r-- | tests/roots/test-intl/label_target.po | 21 | ||||
-rw-r--r-- | tests/roots/test-intl/label_target.txt | 4 | ||||
-rw-r--r-- | tests/test_intl.py | 15 |
7 files changed, 95 insertions, 24 deletions
@@ -1,3 +1,22 @@ +Release 1.2 (in development) +============================ + +Features added +-------------- + +* i18n: gettext translates label target name. + +Incompatible changes +-------------------- + + +Bugs fixed +---------- + +* #1265: Fix i18n: crash when using a indirect target and translating a target + section name. + + Release 1.2 beta3 (released Oct 3, 2013) ======================================== diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index 50d5163b..5d358665 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -18,7 +18,11 @@ from uuid import uuid4 from sphinx.builders import Builder from sphinx.util import split_index_msg -from sphinx.util.nodes import extract_messages, traverse_translatable_index +from sphinx.util.nodes import ( + extract_messages, + traverse_translatable_target, + traverse_translatable_index, +) from sphinx.util.osutil import safe_relpath, ensuredir, find_catalog, SEP from sphinx.util.console import darkgreen, purple, bold from sphinx.locale import pairindextypes @@ -97,6 +101,9 @@ class I18nBuilder(Builder): for node, msg in extract_messages(doctree): catalog.add(msg, node) + for node, msg in traverse_translatable_target(doctree): + catalog.add(msg, node) + # Extract translatable messages from index entries. for node, entries in traverse_translatable_index(doctree): for typ, msg, tid, main in entries: diff --git a/sphinx/transforms.py b/sphinx/transforms.py index 338d4739..37952dd6 100644 --- a/sphinx/transforms.py +++ b/sphinx/transforms.py @@ -20,7 +20,11 @@ from docutils.transforms.parts import ContentsFilter from sphinx import addnodes from sphinx.locale import _, init as init_locale from sphinx.util import split_index_msg -from sphinx.util.nodes import traverse_translatable_index, extract_messages +from sphinx.util.nodes import ( + traverse_translatable_target, + traverse_translatable_index, + extract_messages, +) from sphinx.util.osutil import ustrftime, find_catalog from sphinx.util.compat import docutils_version from sphinx.util.pycompat import all @@ -178,6 +182,34 @@ class Locale(Transform): parser = RSTParser() #phase1: replace reference ids with translated names + for node, msg in traverse_translatable_target(self.document): + msgstr = catalog.gettext(msg) + # XXX add marker to untranslated parts + if not msgstr or msgstr == msg or not msgstr.strip(): + # as-of-yet untranslated + continue + + patch = new_document(source, settings) + CustomLocaleReporter(node.source, node.line).set_reporter(patch) + parser.parse(msgstr, patch) + patch = patch[0] + + # XXX doctest and other block markup + if not isinstance(patch, nodes.paragraph): + continue # skip for now + + old_name = msg + new_name = nodes.fully_normalize_name(patch.astext()) + + if old_name in self.document.nameids: + self.document.nameids[new_name] = ( + self.document.nameids[old_name]) + self.document.nametypes[new_name] = ( + self.document.nametypes[old_name]) + self.document.refnames[new_name] = ( + self.document.refnames[old_name]) + + #phase2: replace reference ids with translated names for node, msg in extract_messages(self.document): msgstr = catalog.gettext(msg) # XXX add marker to untranslated parts @@ -234,9 +266,9 @@ class Locale(Transform): # _id was not duplicated. # remove old_name entry from document ids database # to reuse original _id. - self.document.nameids.pop(old_name, None) - self.document.nametypes.pop(old_name, None) - self.document.ids.pop(_id, None) + self.document.nameids.pop(old_name, None) #supplemental + self.document.nametypes.pop(old_name, None) #supplemental + self.document.ids.pop(_id, None) # must remove # re-entry with new named section node. self.document.note_implicit_target( @@ -278,7 +310,7 @@ class Locale(Transform): node['translated'] = True - #phase2: translation + #phase3: translation for node, msg in extract_messages(self.document): if node.get('translated', False): continue @@ -422,7 +454,7 @@ class Locale(Transform): node.children = patch.children node['translated'] = True - # Extract and translate messages for index entries. + #phase4: Extract and translate messages for index entries. for node, entries in traverse_translatable_index(self.document): new_entries = [] for type, msg, tid, main in entries: diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index a8395f60..2690cf3a 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -77,6 +77,13 @@ def extract_messages(doctree): yield node, msg +def traverse_translatable_target(doctree): + """Extract translatable target from a document tree.""" + for node in doctree.traverse(nodes.target): + if 'names' in node and node['names']: + yield node, node['names'][0] + + def traverse_translatable_index(doctree): """Traverse translatable index node from a document tree.""" def is_block_index(node): diff --git a/tests/roots/test-intl/label_target.po b/tests/roots/test-intl/label_target.po index 60d7c3e5..7255dd98 100644 --- a/tests/roots/test-intl/label_target.po +++ b/tests/roots/test-intl/label_target.po @@ -31,10 +31,10 @@ msgstr "X EXPLICIT-TARGET" msgid "" ":ref:`explicit-target` point to ``explicit-target`` and `explicit-target`_" -" point to duplicated id like ``id1``." +" point to ``explicit-target`` too." msgstr "" ":ref:`explicit-target` POINT TO ``explicit-target`` AND `X EXPLICIT-TARGET`_" -" POINT TO DUPLICATED ID LIKE ``id1``." +" POINT TO ``explicit-target`` TOO." msgid "implicit section name" msgstr "X IMPLICIT SECTION NAME" @@ -53,14 +53,21 @@ msgstr "" msgid "label bridged target section" msgstr "X LABEL BRIDGED TARGET SECTION" -msgid "`bridge label`_ is not translatable but linked to translated section title." -msgstr "X `bridge label`_ IS NOT TRANSLATABLE BUT LINKED TO TRANSLATED SECTION TITLE." +msgid "`bridge label`_ is also translatable and linked to translated section title." +msgstr "X `Y BRIDGE LABEL`_ IS ALSO TRANSLATABLE AND LINKED TO TRANSLATED SECTION TITLE." msgid "" "`bridge label2`_ point to ``section and label`` and `bridge label`_ point to " "``label bridged target section``. The second appeared `bridge label2`_ point " "to correct target." msgstr "" -"X `bridge label`_ POINT TO ``LABEL BRIDGED TARGET SECTION`` AND " -"`bridge label2`_ POINT TO ``SECTION AND LABEL``. THE SECOND APPEARED " -"`bridge label2`_ POINT TO CORRECT TARGET." +"X `Y BRIDGE LABEL`_ POINT TO ``LABEL BRIDGED TARGET SECTION`` AND " +"`Z BRIDGE LABEL2`_ POINT TO ``SECTION AND LABEL``. THE SECOND APPEARED " +"`Z BRIDGE LABEL2`_ POINT TO CORRECT TARGET." + +msgid "bridge label" +msgstr "Y BRIDGE LABEL" + +msgid "bridge label2" +msgstr "Z BRIDGE LABEL2" + diff --git a/tests/roots/test-intl/label_target.txt b/tests/roots/test-intl/label_target.txt index ac000849..93378d36 100644 --- a/tests/roots/test-intl/label_target.txt +++ b/tests/roots/test-intl/label_target.txt @@ -21,7 +21,7 @@ explicit-target .. This case, a duplicated target id is generated by docutils. :ref:`explicit-target` point to ``explicit-target`` and -`explicit-target`_ point to duplicated id like ``id1``. +`explicit-target`_ point to ``explicit-target`` too. implicit section name @@ -61,7 +61,7 @@ label bridged target section .. This section is targeted through label definition. -`bridge label`_ is not translatable but linked to translated section title. +`bridge label`_ is also translatable and linked to translated section title. `bridge label2`_ point to ``section and label`` and `bridge label`_ point to ``label bridged target section``. The second appeared `bridge label2`_ point to correct target. diff --git a/tests/test_intl.py b/tests/test_intl.py index 744e1679..1fb2ae1d 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -436,9 +436,8 @@ def test_i18n_label_target(app): assert_elem( para1[0], texts=['X EXPLICIT-TARGET', 'POINT TO', 'explicit-target', 'AND', - 'X EXPLICIT-TARGET', 'POINT TO DUPLICATED ID LIKE', 'id1', - '.'], - refs=['explicit-target', 'id1']) + 'X EXPLICIT-TARGET', 'POINT TO', 'explicit-target', 'TOO.'], + refs=['explicit-target', 'explicit-target']) para2 = secs[2].findall('paragraph') assert_elem( @@ -458,16 +457,16 @@ def test_i18n_label_target(app): para3 = secs[3].findall('paragraph') assert_elem( para3[0], - texts=['X', 'bridge label', - 'IS NOT TRANSLATABLE BUT LINKED TO TRANSLATED ' + + texts=['X', 'Y BRIDGE LABEL', + 'IS ALSO TRANSLATABLE AND LINKED TO TRANSLATED ' + 'SECTION TITLE.'], refs=['label-bridged-target-section']) assert_elem( para3[1], - texts=['X', 'bridge label', 'POINT TO', - 'LABEL BRIDGED TARGET SECTION', 'AND', 'bridge label2', + texts=['X', 'Y BRIDGE LABEL', 'POINT TO', + 'LABEL BRIDGED TARGET SECTION', 'AND', 'Z BRIDGE LABEL2', 'POINT TO', 'SECTION AND LABEL', '. THE SECOND APPEARED', - 'bridge label2', 'POINT TO CORRECT TARGET.'], + 'Z BRIDGE LABEL2', 'POINT TO CORRECT TARGET.'], refs=['label-bridged-target-section', 'section-and-label', 'section-and-label']) |