From a4e2981f9b64ee5da29971c610b186f7f92a5a70 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Fri, 6 Feb 2026 21:21:19 +0800 Subject: [PATCH 1/3] chore: Split two extensions: sphinxnotes.data{,.render} --- src/sphinxnotes/data/__init__.py | 7 ++--- src/sphinxnotes/data/meta.py | 4 +-- .../data/{examples/datadomain.py => poc.py} | 28 +++++++++++++------ src/sphinxnotes/data/render/__init__.py | 17 ++++++++++- 4 files changed, 39 insertions(+), 17 deletions(-) rename src/sphinxnotes/data/{examples/datadomain.py => poc.py} (88%) diff --git a/src/sphinxnotes/data/__init__.py b/src/sphinxnotes/data/__init__.py index a2bed29..4f1d49c 100644 --- a/src/sphinxnotes/data/__init__.py +++ b/src/sphinxnotes/data/__init__.py @@ -89,10 +89,7 @@ def extra_context(cls) -> ExtraContextRegistry: def setup(app: Sphinx): meta.pre_setup(app) - from . import render - from .examples import datadomain - - render.setup(app) - datadomain.setup(app) + from . import poc + poc.setup(app) return meta.post_setup(app) diff --git a/src/sphinxnotes/data/meta.py b/src/sphinxnotes/data/meta.py index e1f6fed..da46f53 100644 --- a/src/sphinxnotes/data/meta.py +++ b/src/sphinxnotes/data/meta.py @@ -8,12 +8,12 @@ from __future__ import annotations from importlib import metadata -__project__ = 'sphinxnotes-dataview' +__project__ = 'sphinxnotes-data' __author__ = 'Shengyu Zhang' __desc__ = 'Create and view data in Sphinx documentation' try: - __version__ = metadata.version('sphinxnotes-dataview') + __version__ = metadata.version('sphinxnotes-data') except metadata.PackageNotFoundError: __version__ = 'unknown' diff --git a/src/sphinxnotes/data/examples/datadomain.py b/src/sphinxnotes/data/poc.py similarity index 88% rename from src/sphinxnotes/data/examples/datadomain.py rename to src/sphinxnotes/data/poc.py index 3358b76..b13263b 100644 --- a/src/sphinxnotes/data/examples/datadomain.py +++ b/src/sphinxnotes/data/poc.py @@ -1,13 +1,16 @@ """ -sphinxnotes.data.examples.datadomain -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Allow user define, validate, and render data in pure markup and Jinja template. - -All directives and roles are added to a domain to prevent naming conflicts. +sphinxnotes.data.poc +~~~~~~~~~~~~~~~~~~~~ :copyright: Copyright 2025~2026 by the Shengyu Zhang. :license: BSD, see LICENSE for details. + +POC (Proof of Concept) of the "sphinxnotes.data.render" extension. + +This extension provides directives and roles for user to define, validate, and +render data. + +All directives and roles are added to a "data" domain to prevent naming conflicts. """ from __future__ import annotations @@ -18,9 +21,10 @@ from sphinx.util.docutils import SphinxDirective, CustomReSTDispatcher from sphinx.domains import Domain -from ..data import RawData, Field, Schema -from ..render import Phase, Template, BaseDataDefineDirective, BaseDataDefineRole -from ..utils.freestyle import FreeStyleDirective, FreeStyleOptionSpec +from . import meta +from .data import RawData, Field, Schema +from .render import Phase, Template, BaseDataDefineDirective, BaseDataDefineRole +from .utils.freestyle import FreeStyleDirective, FreeStyleOptionSpec if TYPE_CHECKING: from sphinx.application import Sphinx @@ -196,5 +200,11 @@ def _install_dispatcher(app: Sphinx, docname: str, source: list[str]) -> None: def setup(app: Sphinx): + if __name__.startswith(meta.__project__): + app.setup_extension('sphinxnotes.data.render') + else: + # For debug, see also :file:`docs/conf.py`. + app.setup_extension('data.render') + app.add_domain(DataDomain) app.connect('source-read', _install_dispatcher) diff --git a/src/sphinxnotes/data/render/__init__.py b/src/sphinxnotes/data/render/__init__.py index b6856fc..9d52321 100644 --- a/src/sphinxnotes/data/render/__init__.py +++ b/src/sphinxnotes/data/render/__init__.py @@ -1,6 +1,17 @@ +""" +sphinxnotes.data.render +~~~~~~~~~~~~~~~~~~~~~~~ + +:copyright: Copyright 2026 by the Shengyu Zhang. +:license: BSD, see LICENSE for details. + +Sphinx extension entry point. +""" + from __future__ import annotations from typing import TYPE_CHECKING +from .. import meta from .render import ( Phase, Template, @@ -42,9 +53,13 @@ ] -def setup(app: Sphinx) -> None: +def setup(app: Sphinx): + meta.pre_setup(app) + from . import pipeline, extractx, template pipeline.setup(app) extractx.setup(app) template.setup(app) + + return meta.post_setup(app) From 4f84223083ed22d444ad868af9d529af3883a7de Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Sat, 7 Feb 2026 13:38:29 +0800 Subject: [PATCH 2/3] fix: Fix __name__ compare --- src/sphinxnotes/data/poc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sphinxnotes/data/poc.py b/src/sphinxnotes/data/poc.py index b13263b..d4aaa9a 100644 --- a/src/sphinxnotes/data/poc.py +++ b/src/sphinxnotes/data/poc.py @@ -200,7 +200,7 @@ def _install_dispatcher(app: Sphinx, docname: str, source: list[str]) -> None: def setup(app: Sphinx): - if __name__.startswith(meta.__project__): + if __name__.startswith(meta.__project__.replace('-', '.')): app.setup_extension('sphinxnotes.data.render') else: # For debug, see also :file:`docs/conf.py`. From 15b710dcbdffd1bebdad7dc62fed32ed39ba295e Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Sat, 7 Feb 2026 14:20:00 +0800 Subject: [PATCH 3/3] fix: Copy pending_node now returns dummy node Otherwise, if someone copied pending_node (such as ablog), the returned pending_node does not make sense and will cause error: AttributeError: 'pending_node' object has no attribute 'xxx' --- src/sphinxnotes/data/render/ctxnodes.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/sphinxnotes/data/render/ctxnodes.py b/src/sphinxnotes/data/render/ctxnodes.py index 811104d..aa37b2b 100644 --- a/src/sphinxnotes/data/render/ctxnodes.py +++ b/src/sphinxnotes/data/render/ctxnodes.py @@ -1,5 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, override from pprint import pformat from docutils import nodes @@ -235,3 +235,16 @@ def hook_markup_text(self, hook: MarkupTextHook) -> None: def hook_rendered_nodes(self, hook: RenderedNodesHook) -> None: self._rendered_nodes_hooks.append(hook) + + + """Methods override from parent.""" + + @override + def copy(self) -> Any: + # NOTE: pending_node is no supposed to be copy as it does not make sense. + # + # For example: ablog extension may copy this node. + if self.inline: + return nodes.Text('') + else: + return nodes.paragraph()