Skip to content

Commit 0cbdd98

Browse files
jmbowmanJeremy BowmanAA-Turner
authored
Correctly support custom gettext output templates (#12645)
Co-authored-by: Jeremy Bowman <jmbowman@alum.mit.edu> Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
1 parent 646a5d7 commit 0cbdd98

File tree

7 files changed

+59
-5
lines changed

7 files changed

+59
-5
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ Bugs fixed
4747
Patch by James Addison.
4848
* #12639: Fix singular and plural search results text.
4949
Patch by Hugo van Kemenade.
50+
* #12645: Correctly support custom gettext output templates.
51+
Patch by Jeremy Bowman.
5052

5153
Testing
5254
-------

doc/usage/advanced/intl.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ section describe an easy way to translate with *sphinx-intl*.
119119
$ make gettext
120120
121121
The generated pot files will be placed in the ``_build/gettext`` directory.
122+
If you want to customize the output beyond what can be done via the
123+
:ref:`intl-options`, the
124+
:download:`default pot file template <../../../sphinx/templates/gettext/message.pot.jinja>`
125+
can be replaced by a custom :file:`message.pot.jinja` file placed in any
126+
directory listed in :confval:`templates_path`.
122127

123128
#. Generate po files.
124129

sphinx/builders/gettext.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from codecs import open
88
from collections import defaultdict
99
from os import getenv, path, walk
10+
from pathlib import Path
1011
from typing import TYPE_CHECKING, Any, Literal
1112
from uuid import uuid4
1213

@@ -28,14 +29,16 @@
2829

2930
if TYPE_CHECKING:
3031
import os
31-
from collections.abc import Iterable, Iterator
32+
from collections.abc import Iterable, Iterator, Sequence
3233

3334
from docutils.nodes import Element
3435

3536
from sphinx.application import Sphinx
3637
from sphinx.config import Config
3738
from sphinx.util.typing import ExtensionMetadata
3839

40+
DEFAULT_TEMPLATE_PATH = Path(package_dir, 'templates', 'gettext')
41+
3942
logger = logging.getLogger(__name__)
4043

4144

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

9295
class GettextRenderer(SphinxRenderer):
9396
def __init__(
94-
self, template_path: list[str | os.PathLike[str]] | None = None,
97+
self, template_path: Sequence[str | os.PathLike[str]] | None = None,
9598
outdir: str | os.PathLike[str] | None = None,
9699
) -> None:
97100
self.outdir = outdir
98101
if template_path is None:
99-
template_path = [path.join(package_dir, 'templates', 'gettext')]
100-
super().__init__(template_path)
102+
super().__init__([DEFAULT_TEMPLATE_PATH])
103+
else:
104+
super().__init__([*template_path, DEFAULT_TEMPLATE_PATH])
101105

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

289293
context['messages'] = list(catalog)
290-
content = GettextRenderer(outdir=self.outdir).render('message.pot.jinja', context)
294+
template_path = [
295+
self.app.srcdir / rel_path
296+
for rel_path in self.config.templates_path
297+
]
298+
renderer = GettextRenderer(template_path, outdir=self.outdir)
299+
content = renderer.render('message.pot.jinja', context)
291300

292301
pofn = path.join(self.outdir, textdomain + '.pot')
293302
if should_write(pofn, content):
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# EVEN MORE DESCRIPTIVE TITLE.
2+
# Copyright (C) {{ copyright }}
3+
# This file is distributed under the same license as the {{ project }} package.
4+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5+
#
6+
#, fuzzy
7+
msgid ""
8+
msgstr ""
9+
"Project-Id-Version: {{ project|e }} {{ version|e }}\n"
10+
"Report-Msgid-Bugs-To: \n"
11+
"POT-Creation-Date: {{ ctime|e }}\n"
12+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13+
"Last-Translator: {{ last_translator|e }}\n"
14+
"Language-Team: {{ language_team|e }}\n"
15+
"MIME-Version: 1.0\n"
16+
"Content-Type: text/plain; charset=UTF-8\n"
17+
"Content-Transfer-Encoding: 8bit\n"
18+
{% for message in messages %}
19+
msgid "{{ message.text|e }}"
20+
msgstr ""
21+
{% endfor -%}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
templates_path = ['_templates']
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CONTENTS
2+
========
3+
4+
.. toctree::
5+
:maxdepth: 2
6+
:numbered:
7+
:caption: Table of Contents

tests/test_builders/test_build_gettext.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@ def test_gettext_template_msgid_order_in_sphinxpot(app):
201201
)
202202

203203

204+
@pytest.mark.sphinx('gettext', testroot='gettext-custom-output-template')
205+
def test_gettext_custom_output_template(app):
206+
app.build(force_all=True)
207+
assert (app.outdir / 'index.pot').is_file()
208+
209+
result = (app.outdir / 'index.pot').read_text(encoding='utf8')
210+
assert 'EVEN MORE DESCRIPTIVE TITLE' in result
211+
212+
204213
@pytest.mark.sphinx(
205214
'gettext',
206215
srcdir='root-gettext',

0 commit comments

Comments
 (0)