Takayuki Shimizukawa avatar Takayuki Shimizukawa committed b4abca7

fix: translation mechanism break label target if label and section name are same. refs #1193

Comments (0)

Files changed (4)

sphinx/transforms.py

                     if old_name in names:
                         names.remove(old_name)
 
-                    _id = self.document.nameids.pop(old_name, None)
-                    _type = self.document.nametypes.pop(old_name, None)
-                    self.document.set_name_id_map(
-                            section_node, _id, section_node, explicit=_type)
+                    _id = self.document.nameids.get(old_name, None)
+                    explicit = self.document.nametypes.get(old_name, None)
+
+                    # * if explicit: _id is label. title node need another id.
+                    # * if not explicit:
+                    #
+                    #   * _id is None:
+                    #
+                    #     _id is None means _id was duplicated.
+                    #     old_name entry still exists in nameids and
+                    #     nametypes for another duplicated entry.
+                    #
+                    #   * _id is provided: bellow process
+                    if not explicit and _id:
+                        # _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)
+
+                    # re-entry with new named section node.
+                    self.document.note_implicit_target(
+                            section_node, section_node)
+
                     processed = True
 
             # glossary terms update refid

tests/roots/test-intl/label_target.po

+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) 2013, sphinx
+# This file is distributed under the same license as the sphinx package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 1.2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-06-19 00:33+0000\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 "section and label"
+msgstr "X SECTION AND LABEL"
+
+msgid ""
+":ref:`implicit-target` point to ``implicit-target`` and "
+"`section and label`_ point to ``section-and-label``."
+msgstr ""
+":ref:`implicit-target` POINT TO ``implicit-target`` AND "
+"`X SECTION AND LABEL`_ POINT TO ``section-and-label``."
+
+msgid "explicit-target"
+msgstr "X EXPLICIT-TARGET"
+
+msgid ""
+":ref:`explicit-target` point to ``explicit-target`` and `explicit-target`_"
+" point to duplicated id like ``id1``."
+msgstr ""
+":ref:`explicit-target` POINT TO ``explicit-target`` AND `X EXPLICIT-TARGET`_"
+" POINT TO DUPLICATED ID LIKE ``id1``."
+
+msgid "implicit section name"
+msgstr "X IMPLICIT SECTION NAME"
+
+msgid "`implicit section name`_ point to ``implicit-section-name``."
+msgstr "`X IMPLICIT SECTION NAME`_ POINT TO ``implicit-section-name``."
+
+msgid "duplicated sub section"
+msgstr "X DUPLICATED SUB SECTION"
+
+msgid ""
+"`duplicated sub section`_ is broken link."
+msgstr ""
+"`X DUPLICATED SUB SECTION`_ IS BROKEN LINK."
+

tests/roots/test-intl/label_target.txt

+:tocdepth: 2
+
+.. _implicit-target:
+
+section and label
+==================
+
+.. This section's label and section title are different.
+.. This case, the section have 2 target id.
+
+:ref:`implicit-target` point to ``implicit-target`` and
+`section and label`_ point to ``section-and-label``.
+
+
+.. _explicit-target:
+
+explicit-target
+================
+
+.. This section's label equals to section title.
+.. 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``.
+
+
+implicit section name
+======================
+
+.. This section have no label.
+.. This case, the section have one id.
+
+`implicit section name`_ point to ``implicit-section-name``.
+
+duplicated sub section
+------------------------
+
+.. This section have no label, but name will be duplicated by next section.
+.. This case, the section have one id.
+
+`duplicated sub section`_ is broken link.
+
+.. There is no way to link to this section's ``duplicated-sub-section``` by
+.. using formal reStructuredText markup.
+
+duplicated sub section
+------------------------
+
+.. This section have no label, but the section was a duplicate name.
+.. THis case, a duplicated target id is generated by docutils.
+
+.. There is no way to link to this section's duplicated id like ``id2`` by
+.. using formal reStructuredText markup.
+

tests/test_intl.py

     assert 'unknown document' not in warnings
 
 
+@with_intl_app(buildername='xml', warning=warnfile)
+def test_i18n_label_target(app):
+    # regression test for #1193
+    app.builder.build(['label_target'])
+    et = ElementTree.parse(app.outdir / 'label_target.xml')
+    secs = et.findall('section')
+
+    #debug
+    print (app.outdir / 'label_target.xml').text()
+
+    para0 = secs[0].findall('paragraph')
+    assert_elem_text_refs(
+            para0[0],
+            ['X SECTION AND LABEL', 'POINT TO', 'implicit-target', 'AND',
+             'X SECTION AND LABEL', 'POINT TO', 'section-and-label', '.'],
+            ['implicit-target', 'section-and-label'])
+
+    para1 = secs[1].findall('paragraph')
+    assert_elem_text_refs(
+            para1[0],
+            ['X EXPLICIT-TARGET', 'POINT TO', 'explicit-target', 'AND',
+             'X EXPLICIT-TARGET', 'POINT TO DUPLICATED ID LIKE', 'id1', '.'],
+            ['explicit-target', 'id1'])
+
+    para2 = secs[2].findall('paragraph')
+    assert_elem_text_refs(
+            para2[0],
+            ['X IMPLICIT SECTION NAME', 'POINT TO', 'implicit-section-name',
+             '.'],
+            ['implicit-section-name'])
+
+    sec2 = secs[2].findall('section')
+
+    para2_0 = sec2[0].findall('paragraph')
+    assert_elem_text_refs(
+            para2_0[0],
+            ['`X DUPLICATED SUB SECTION`_', 'IS BROKEN LINK.'],
+            [])
+
+
 @with_intl_app(buildername='text', warning=warnfile)
 def test_i18n_glossary_terms_inconsistency(app):
     # regression test for #1090
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.