From 5aee836dc18eee7d50e9c9601cd98ec7759922a3 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 1 Nov 2019 22:00:11 +0900 Subject: [PATCH] Close #4683: i18n: make explicit titles in toctree translatable --- CHANGES | 1 + sphinx/addnodes.py | 24 ++++++++++++-- tests/roots/test-intl/toctree.txt | 10 ++++++ .../roots/test-intl/xx/LC_MESSAGES/toctree.po | 31 +++++++++++++++++++ tests/test_intl.py | 24 ++++++++++++++ 5 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 tests/roots/test-intl/toctree.txt create mode 100644 tests/roots/test-intl/xx/LC_MESSAGES/toctree.po diff --git a/CHANGES b/CHANGES index 5497d94a2..0323ddc85 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Features added * #267: html: Eliminate prompt characters of doctest block from copyable text * #6729: html theme: agogo theme now supports ``rightsidebar`` option * #6780: Add PEP-561 Support +* #6483: i18n: make explicit titles in toctree translatable Bugs fixed ---------- diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index ef3bf3f9e..750e11c20 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -63,20 +63,38 @@ class toctree(nodes.General, nodes.Element, translatable): def preserve_original_messages(self): # type: () -> None + # toctree entries + rawentries = self.setdefault('rawentries', []) + for title, docname in self['entries']: + if title: + rawentries.append(title) + + # :caption: option if self.get('caption'): self['rawcaption'] = self['caption'] def apply_translated_message(self, original_message, translated_message): # type: (str, str) -> None + # toctree entries + for i, (title, docname) in enumerate(self['entries']): + if title == original_message: + self['entries'][i] = (translated_message, docname) + + # :caption: option if self.get('rawcaption') == original_message: self['caption'] = translated_message def extract_original_messages(self): # type: () -> List[str] + messages = [] # type: List[str] + + # toctree entries + messages.extend(self.get('rawentries', [])) + + # :caption: option if 'rawcaption' in self: - return [self['rawcaption']] - else: - return [] + messages.append(self['rawcaption']) + return messages # domain-specific object descriptions (class, function etc.) diff --git a/tests/roots/test-intl/toctree.txt b/tests/roots/test-intl/toctree.txt new file mode 100644 index 000000000..35c956a03 --- /dev/null +++ b/tests/roots/test-intl/toctree.txt @@ -0,0 +1,10 @@ +i18n with toctree +================= + +.. toctree:: + :caption: caption + + figure
+ table + https://www.sphinx-doc.org/ + self diff --git a/tests/roots/test-intl/xx/LC_MESSAGES/toctree.po b/tests/roots/test-intl/xx/LC_MESSAGES/toctree.po new file mode 100644 index 000000000..8ca1dc52c --- /dev/null +++ b/tests/roots/test-intl/xx/LC_MESSAGES/toctree.po @@ -0,0 +1,31 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) +# This file is distributed under the same license as the Sphinx intl package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Sphinx intl 2013.120\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-11-01 10:24+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../toctree.txt:4 +msgid "figure" +msgstr "FIGURE" + +#: ../../toctree.txt:4 +#: ../../toctree.txt:4 +msgid "caption" +msgstr "CAPTION" + +#: ../../toctree.txt:2 +msgid "i18n with toctree" +msgstr "I18N WITH TOCTREE" + diff --git a/tests/test_intl.py b/tests/test_intl.py index 3815f8357..a6bd17512 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -465,6 +465,30 @@ def test_text_table(app): assert expect_msg.string in result +@sphinx_intl +@pytest.mark.sphinx('gettext') +@pytest.mark.test_params(shared_result='test_intl_gettext') +def test_gettext_toctree(app): + app.build() + # --- toctree + expect = read_po(app.srcdir / 'xx' / 'LC_MESSAGES' / 'toctree.po') + actual = read_po(app.outdir / 'toctree.pot') + for expect_msg in [m for m in expect if m.id]: + assert expect_msg.id in [m.id for m in actual if m.id] + + +@sphinx_intl +@pytest.mark.sphinx('text') +@pytest.mark.test_params(shared_result='test_intl_basic') +def test_text_toctree(app): + app.build() + # --- toctree + result = (app.outdir / 'toctree.txt').text() + expect = read_po(app.srcdir / 'xx' / 'LC_MESSAGES' / 'toctree.po') + for expect_msg in [m for m in expect if m.id]: + assert expect_msg.string in result + + @sphinx_intl @pytest.mark.sphinx('gettext') @pytest.mark.test_params(shared_result='test_intl_gettext')