From b269055a6acce98e204f45668038aac097693cf5 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Thu, 18 Jun 2026 18:40:21 +0800 Subject: [PATCH] feat: Add :data:render: inline role Add DataRenderRole as the inline counterpart of DataRenderDirective, allowing inline template rendering with :data:render: role. Co-authored-by: DeepSeek --- docs/usage.rst | 18 ++++++++++++++++++ src/sphinxnotes/render/ext/adhoc.py | 16 ++++++++++++++++ tests/roots/test-data-render-role/conf.py | 1 + tests/roots/test-data-render-role/index.rst | 6 ++++++ tests/test_e2e.py | 11 +++++++++++ 5 files changed, 52 insertions(+) create mode 100644 tests/roots/test-data-render-role/conf.py create mode 100644 tests/roots/test-data-render-role/index.rst diff --git a/docs/usage.rst b/docs/usage.rst index fd3162b..857c32b 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -121,6 +121,24 @@ Directives ``1 + 1 = {{ 1 + 1 }}`` +.. _ext-usage-roles: + +Roles +===== + +.. rst:role:: data.render + + Render a template inline without defining data. + This is the inline counterpart of :rst:dir:`data.render` directive. + + The role content is used as the Jinja2 template with an empty context. + Refer to :doc:`tmpl` for guide of writing template. + + .. example:: + :style: grid + + :data.render:`{{ 1 + 1 }}` equals 2. + .. _usage-custom-directive: Defining Custom Directives diff --git a/src/sphinxnotes/render/ext/adhoc.py b/src/sphinxnotes/render/ext/adhoc.py index 2a8c3e7..b8c9680 100644 --- a/src/sphinxnotes/render/ext/adhoc.py +++ b/src/sphinxnotes/render/ext/adhoc.py @@ -25,6 +25,7 @@ BaseContextDirective, BaseDataDefineDirective, BaseDataDefineRole, + BaseContextRole, ) from ..utils.freestyle import FreeStyleDirective @@ -200,6 +201,20 @@ def install(self, app: Sphinx, docname: str, source: list[str]) -> None: self.enable() +class DataRenderRole(BaseContextRole): + @override + def current_context(self) -> UnresolvedContext | ResolvedContext: + return {} + + @override + def current_template(self) -> Template: + return Template( + self.text, + phase=self.options.get('on', Phase.default()), + debug='debug' in self.options, + ) + + def setup(app: Sphinx) -> None: app.add_directive('data.define', FreeDataDefineDirective) app.add_directive('data.template', TemplateDefineDirective) @@ -207,5 +222,6 @@ def setup(app: Sphinx) -> None: app.add_directive('data.render', DataRenderDirective) app.add_role('data.define', FreeDataDefineRole) + app.add_role('data.render', DataRenderRole()) app.connect('source-read', FreeDataDefineRoleDispatcher().install) diff --git a/tests/roots/test-data-render-role/conf.py b/tests/roots/test-data-render-role/conf.py new file mode 100644 index 0000000..294e8a2 --- /dev/null +++ b/tests/roots/test-data-render-role/conf.py @@ -0,0 +1 @@ +extensions = ['sphinxnotes.render.ext'] diff --git a/tests/roots/test-data-render-role/index.rst b/tests/roots/test-data-render-role/index.rst new file mode 100644 index 0000000..e44ca34 --- /dev/null +++ b/tests/roots/test-data-render-role/index.rst @@ -0,0 +1,6 @@ +Data Render Role Test +===================== + +This is a test of :data.render:`**bold**`. + +Inline math: :data.render:`{{ 1 + 1 }}`. diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 6ae9724..23ed3bd 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -107,6 +107,17 @@ def test_render_ext_data_define_directives(app, status, warning, phase): assert 'RenderedContent' in html +@pytest.mark.sphinx('html', testroot='data-render-role') +def test_render_ext_data_render_role(app, status, warning): + """Test that :data:render: role works correctly.""" + app.build() + + html = (app.outdir / 'index.html').read_text(encoding='utf-8') + + assert 'bold' in html + assert '2' in html + + @pytest.mark.sphinx('html', testroot='derive') def test_derived_render_ext_data_define_directives(app, status, warning): """Test that render_ext_data_define_directives generates directives correctly."""