Skip to content

Commit

Permalink
Correctly support custom gettext output templates (sphinx-doc#12645)
Browse files Browse the repository at this point in the history
Co-authored-by: Jeremy Bowman <[email protected]>
Co-authored-by: Adam Turner <[email protected]>
  • Loading branch information
3 people authored Aug 11, 2024
1 parent 646a5d7 commit 0cbdd98
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Bugs fixed
Patch by James Addison.
* #12639: Fix singular and plural search results text.
Patch by Hugo van Kemenade.
* #12645: Correctly support custom gettext output templates.
Patch by Jeremy Bowman.

Testing
-------
Expand Down
5 changes: 5 additions & 0 deletions doc/usage/advanced/intl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ section describe an easy way to translate with *sphinx-intl*.
$ make gettext
The generated pot files will be placed in the ``_build/gettext`` directory.
If you want to customize the output beyond what can be done via the
:ref:`intl-options`, the
:download:`default pot file template <../../../sphinx/templates/gettext/message.pot.jinja>`
can be replaced by a custom :file:`message.pot.jinja` file placed in any
directory listed in :confval:`templates_path`.

#. Generate po files.

Expand Down
19 changes: 14 additions & 5 deletions sphinx/builders/gettext.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from codecs import open
from collections import defaultdict
from os import getenv, path, walk
from pathlib import Path
from typing import TYPE_CHECKING, Any, Literal
from uuid import uuid4

Expand All @@ -28,14 +29,16 @@

if TYPE_CHECKING:
import os
from collections.abc import Iterable, Iterator
from collections.abc import Iterable, Iterator, Sequence

from docutils.nodes import Element

from sphinx.application import Sphinx
from sphinx.config import Config
from sphinx.util.typing import ExtensionMetadata

DEFAULT_TEMPLATE_PATH = Path(package_dir, 'templates', 'gettext')

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -91,13 +94,14 @@ def __init__(self, source: str, line: int) -> None:

class GettextRenderer(SphinxRenderer):
def __init__(
self, template_path: list[str | os.PathLike[str]] | None = None,
self, template_path: Sequence[str | os.PathLike[str]] | None = None,
outdir: str | os.PathLike[str] | None = None,
) -> None:
self.outdir = outdir
if template_path is None:
template_path = [path.join(package_dir, 'templates', 'gettext')]
super().__init__(template_path)
super().__init__([DEFAULT_TEMPLATE_PATH])
else:
super().__init__([*template_path, DEFAULT_TEMPLATE_PATH])

def escape(s: str) -> str:
s = s.replace('\\', r'\\')
Expand Down Expand Up @@ -287,7 +291,12 @@ def finish(self) -> None:
ensuredir(path.join(self.outdir, path.dirname(textdomain)))

context['messages'] = list(catalog)
content = GettextRenderer(outdir=self.outdir).render('message.pot.jinja', context)
template_path = [
self.app.srcdir / rel_path
for rel_path in self.config.templates_path
]
renderer = GettextRenderer(template_path, outdir=self.outdir)
content = renderer.render('message.pot.jinja', context)

pofn = path.join(self.outdir, textdomain + '.pot')
if should_write(pofn, content):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# EVEN MORE DESCRIPTIVE TITLE.
# Copyright (C) {{ copyright }}
# This file is distributed under the same license as the {{ project }} package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: {{ project|e }} {{ version|e }}\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: {{ ctime|e }}\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: {{ last_translator|e }}\n"
"Language-Team: {{ language_team|e }}\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
{% for message in messages %}
msgid "{{ message.text|e }}"
msgstr ""
{% endfor -%}
1 change: 1 addition & 0 deletions tests/roots/test-gettext-custom-output-template/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
templates_path = ['_templates']
7 changes: 7 additions & 0 deletions tests/roots/test-gettext-custom-output-template/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CONTENTS
========

.. toctree::
:maxdepth: 2
:numbered:
:caption: Table of Contents
9 changes: 9 additions & 0 deletions tests/test_builders/test_build_gettext.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ def test_gettext_template_msgid_order_in_sphinxpot(app):
)


@pytest.mark.sphinx('gettext', testroot='gettext-custom-output-template')
def test_gettext_custom_output_template(app):
app.build(force_all=True)
assert (app.outdir / 'index.pot').is_file()

result = (app.outdir / 'index.pot').read_text(encoding='utf8')
assert 'EVEN MORE DESCRIPTIVE TITLE' in result


@pytest.mark.sphinx(
'gettext',
srcdir='root-gettext',
Expand Down

0 comments on commit 0cbdd98

Please sign in to comment.