From 2922201193150784a85a06340e348fbc1199f767 Mon Sep 17 00:00:00 2001 From: sneakers-the-rat Date: Tue, 19 May 2026 16:08:12 -0700 Subject: [PATCH] make button text translatable --- .gitignore | 1 + docs/snippets/myst/button-link.txt | 6 +++ sphinx_design/badges_buttons.py | 11 +++++- tests/conftest.py | 8 ++-- tests/test_snippets.py | 38 +++++++++++++++++++ .../snippet_i18n_button-link.pot | 7 ++++ .../snippet_post_button-link.xml | 16 ++++---- .../test_snippets/snippet_pre_button-link.xml | 16 ++++---- 8 files changed, 84 insertions(+), 19 deletions(-) create mode 100644 tests/test_snippets/snippet_i18n_button-link.pot diff --git a/.gitignore b/.gitignore index 32bd99f..68b9321 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ cover/ # Translations *.mo *.pot +!tests/test_snippets/*.pot # Django stuff: *.log diff --git a/docs/snippets/myst/button-link.txt b/docs/snippets/myst/button-link.txt index ed372cf..056e6be 100644 --- a/docs/snippets/myst/button-link.txt +++ b/docs/snippets/myst/button-link.txt @@ -5,6 +5,12 @@ Button text ``` +```{button-link} https://example.com +:color: primary + +Button text with options +``` + ```{button-link} https://example.com :color: primary :shadow: diff --git a/sphinx_design/badges_buttons.py b/sphinx_design/badges_buttons.py index 61b83a0..449ecf4 100644 --- a/sphinx_design/badges_buttons.py +++ b/sphinx_design/badges_buttons.py @@ -178,8 +178,13 @@ def run_with_defaults(self) -> list[nodes.Node]: textnodes, _ = self.state.inline_text( "\n".join(self.content), self.lineno + self.content_offset ) - content = nodes.inline("", "") + content = nodes.inline("", "", translatable=True) content.extend(textnodes) + + # make link text translatable - + # target gettext to the content lines, not the outer directive + self.set_source_info(content) + content.line += self.content_offset else: content = nodes.inline(target, target) node.append(content) @@ -191,7 +196,9 @@ def run_with_defaults(self) -> list[nodes.Node]: node = grid_container # `visit_reference` requires that a reference be inside a `TextElement` parent - container = nodes.paragraph(classes=self.options.get("align", [])) + container = nodes.paragraph( + classes=self.options.get("align", []), translatable=False + ) self.set_source_info(container) container += node diff --git a/tests/conftest.py b/tests/conftest.py index cc112c7..fa318fb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -68,10 +68,12 @@ def get_doctree( return doctree -@pytest.fixture() -def sphinx_builder(tmp_path: Path, make_app, monkeypatch): +@pytest.fixture(params=[pytest.param("html", id="html")]) +def sphinx_builder( + tmp_path: Path, make_app, monkeypatch, request: pytest.FixtureRequest +): def _create_project( - buildername: str = "html", conf_kwargs: dict[str, Any] | None = None + buildername: str = request.param, conf_kwargs: dict[str, Any] | None = None ): src_path = tmp_path / "srcdir" src_path.mkdir() diff --git a/tests/test_snippets.py b/tests/test_snippets.py index fde2b4f..884264c 100644 --- a/tests/test_snippets.py +++ b/tests/test_snippets.py @@ -17,6 +17,12 @@ SNIPPETS_PATH = Path(__file__).parent.parent / "docs" / "snippets" SNIPPETS_GLOB_RST = list((SNIPPETS_PATH / "rst").glob("[!_]*")) SNIPPETS_GLOB_MYST = list((SNIPPETS_PATH / "myst").glob("[!_]*")) +EXPECTED_PATH = Path(__file__).parent / "test_snippets" +I18N_GLOB_MYST = [ + p + for p in SNIPPETS_GLOB_MYST + if (EXPECTED_PATH / f"snippet_i18n_{p.stem}.pot").exists() +] def write_assets(src_path: Path): @@ -205,3 +211,35 @@ def test_sd_custom_directives( extension=".xml", encoding="utf8", ) + + +@pytest.mark.parametrize("sphinx_builder", ["gettext"], indirect=True) +@pytest.mark.parametrize( + "path", + I18N_GLOB_MYST, + ids=[path.stem for path in I18N_GLOB_MYST], +) +@pytest.mark.skipif(not MYST_INSTALLED, reason="myst-parser not installed") +def test_i18n_myst( + sphinx_builder: Callable[..., SphinxBuilder], + path: Path, + normalize_doctree_xml, + file_regression, +): + builder = sphinx_builder() + content = path.read_text(encoding="utf8") + builder.src_path.joinpath("index.md").write_text(content, encoding="utf8") + write_assets(builder.src_path) + builder.build() + + # strip metadata (that includes a constantly-varying timestamp) + out_path = builder.out_path / "index.pot" + out = out_path.read_text() + out = out[out.find("#: ../../index") :] + + file_regression.check( + out, + basename=f"snippet_i18n_{path.stem}", + extension=".pot", + encoding="utf8", + ) diff --git a/tests/test_snippets/snippet_i18n_button-link.pot b/tests/test_snippets/snippet_i18n_button-link.pot new file mode 100644 index 0000000..d33018d --- /dev/null +++ b/tests/test_snippets/snippet_i18n_button-link.pot @@ -0,0 +1,7 @@ +#: ../../index.md:4 +msgid "Button text" +msgstr "" + +#: ../../index.md:10 +msgid "Button text with options" +msgstr "" diff --git a/tests/test_snippets/snippet_post_button-link.xml b/tests/test_snippets/snippet_post_button-link.xml index b0e1a79..21fd8a2 100644 --- a/tests/test_snippets/snippet_post_button-link.xml +++ b/tests/test_snippets/snippet_post_button-link.xml @@ -2,23 +2,25 @@
Heading - <paragraph> + <paragraph translatable="0"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap" refuri="https://example.com"> <inline> https://example.com - <paragraph> + <paragraph translatable="0"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap" refuri="https://example.com"> - <inline> - Button text - <paragraph> + Button text + <paragraph translatable="0"> + <reference classes="sd-sphinx-override sd-btn sd-text-wrap sd-btn-primary" refuri="https://example.com"> + Button text with options + <paragraph translatable="0"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap sd-btn-primary sd-shadow-sm" refuri="https://example.com"> <inline> https://example.com - <paragraph> + <paragraph translatable="0"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap sd-btn-outline-primary" refuri="https://example.com"> <inline> https://example.com - <paragraph> + <paragraph translatable="0"> <inline classes="sd-d-grid"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap sd-btn-secondary" refuri="https://example.com"> <inline> diff --git a/tests/test_snippets/snippet_pre_button-link.xml b/tests/test_snippets/snippet_pre_button-link.xml index b0e1a79..21fd8a2 100644 --- a/tests/test_snippets/snippet_pre_button-link.xml +++ b/tests/test_snippets/snippet_pre_button-link.xml @@ -2,23 +2,25 @@ <section ids="heading" names="heading"> <title> Heading - <paragraph> + <paragraph translatable="0"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap" refuri="https://example.com"> <inline> https://example.com - <paragraph> + <paragraph translatable="0"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap" refuri="https://example.com"> - <inline> - Button text - <paragraph> + Button text + <paragraph translatable="0"> + <reference classes="sd-sphinx-override sd-btn sd-text-wrap sd-btn-primary" refuri="https://example.com"> + Button text with options + <paragraph translatable="0"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap sd-btn-primary sd-shadow-sm" refuri="https://example.com"> <inline> https://example.com - <paragraph> + <paragraph translatable="0"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap sd-btn-outline-primary" refuri="https://example.com"> <inline> https://example.com - <paragraph> + <paragraph translatable="0"> <inline classes="sd-d-grid"> <reference classes="sd-sphinx-override sd-btn sd-text-wrap sd-btn-secondary" refuri="https://example.com"> <inline>