From 5d9b2c00c4dc573fe920b80d66ec6376d540be46 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Tue, 17 Feb 2026 18:41:45 +0800 Subject: [PATCH 1/4] chore: Remove all ``from __future__ import annotations`` --- src/sphinxnotes/render/__init__.py | 2 +- src/sphinxnotes/render/ctx.py | 1 - src/sphinxnotes/render/ctxnodes.py | 4 +--- src/sphinxnotes/render/data.py | 3 +-- src/sphinxnotes/render/extractx.py | 1 - src/sphinxnotes/render/markup.py | 1 - src/sphinxnotes/render/meta.py | 1 - src/sphinxnotes/render/pipeline.py | 1 - src/sphinxnotes/render/render.py | 3 +-- src/sphinxnotes/render/sources.py | 8 ++------ src/sphinxnotes/render/template.py | 1 - src/sphinxnotes/render/utils/__init__.py | 1 - 12 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/sphinxnotes/render/__init__.py b/src/sphinxnotes/render/__init__.py index ae5f3bb..5801f5b 100644 --- a/src/sphinxnotes/render/__init__.py +++ b/src/sphinxnotes/render/__init__.py @@ -6,7 +6,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import annotations from typing import TYPE_CHECKING from . import meta @@ -81,6 +80,7 @@ def extra_context(cls) -> ExtraContextRegistry: REGISTRY = Registry() + def setup(app: Sphinx): meta.pre_setup(app) diff --git a/src/sphinxnotes/render/ctx.py b/src/sphinxnotes/render/ctx.py index 2a4cdc4..b2a4807 100644 --- a/src/sphinxnotes/render/ctx.py +++ b/src/sphinxnotes/render/ctx.py @@ -8,7 +8,6 @@ This module wraps the :mod:`data` into context for rendering the template. """ -from __future__ import annotations from typing import Any from abc import ABC, abstractmethod from collections.abc import Hashable diff --git a/src/sphinxnotes/render/ctxnodes.py b/src/sphinxnotes/render/ctxnodes.py index 0dfff79..2590865 100644 --- a/src/sphinxnotes/render/ctxnodes.py +++ b/src/sphinxnotes/render/ctxnodes.py @@ -1,4 +1,3 @@ -from __future__ import annotations from typing import TYPE_CHECKING, override from pprint import pformat @@ -6,7 +5,7 @@ from docutils.parsers.rst.states import Inliner from .render import Template -from .ctx import PendingContextRef, PendingContext, PendingContextStorage +from .ctx import PendingContextRef, PendingContext, PendingContextStorage, ResolvedContext from .markup import MarkupRenderer from .template import TemplateRenderer from .utils import ( @@ -18,7 +17,6 @@ if TYPE_CHECKING: from typing import Any, Callable, ClassVar from .markup import Host - from .ctx import ResolvedContext class pending_node(nodes.Element): diff --git a/src/sphinxnotes/render/data.py b/src/sphinxnotes/render/data.py index a8cb19f..6a15692 100644 --- a/src/sphinxnotes/render/data.py +++ b/src/sphinxnotes/render/data.py @@ -8,7 +8,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import annotations from typing import TYPE_CHECKING, Literal import re from dataclasses import dataclass, asdict, field as dataclass_field @@ -225,7 +224,7 @@ def add_by_option( ) -> None: """Register a by-option. - :param name: The name for this option, available as a :ref:`By-Option` + :param name: The name for this option, available as a :term:`By-Option` in the DSL :param etype: The value type for this option :param default: The default value for this option diff --git a/src/sphinxnotes/render/extractx.py b/src/sphinxnotes/render/extractx.py index 8eccbaf..90cb711 100644 --- a/src/sphinxnotes/render/extractx.py +++ b/src/sphinxnotes/render/extractx.py @@ -1,4 +1,3 @@ -from __future__ import annotations from typing import TYPE_CHECKING, override from abc import ABC, abstractmethod diff --git a/src/sphinxnotes/render/markup.py b/src/sphinxnotes/render/markup.py index 5fed845..3931d71 100644 --- a/src/sphinxnotes/render/markup.py +++ b/src/sphinxnotes/render/markup.py @@ -8,7 +8,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import annotations from dataclasses import dataclass from typing import TYPE_CHECKING diff --git a/src/sphinxnotes/render/meta.py b/src/sphinxnotes/render/meta.py index 8af588d..299779f 100644 --- a/src/sphinxnotes/render/meta.py +++ b/src/sphinxnotes/render/meta.py @@ -5,7 +5,6 @@ # Project meta infos. ################################################################################ -from __future__ import annotations from importlib import metadata __project__ = 'sphinxnotes-render' diff --git a/src/sphinxnotes/render/pipeline.py b/src/sphinxnotes/render/pipeline.py index 154f9e6..5d78425 100644 --- a/src/sphinxnotes/render/pipeline.py +++ b/src/sphinxnotes/render/pipeline.py @@ -44,7 +44,6 @@ """ -from __future__ import annotations from typing import TYPE_CHECKING, override, final, cast from abc import abstractmethod, ABC diff --git a/src/sphinxnotes/render/render.py b/src/sphinxnotes/render/render.py index 93c0d39..310a443 100644 --- a/src/sphinxnotes/render/render.py +++ b/src/sphinxnotes/render/render.py @@ -1,4 +1,3 @@ -from __future__ import annotations from dataclasses import dataclass from enum import Enum @@ -13,7 +12,7 @@ class Phase(Enum): Resolving = 'resolving' @classmethod - def default(cls) -> Phase: + def default(cls) -> 'Phase': return cls.Parsing diff --git a/src/sphinxnotes/render/sources.py b/src/sphinxnotes/render/sources.py index 1e71425..e0f4f51 100644 --- a/src/sphinxnotes/render/sources.py +++ b/src/sphinxnotes/render/sources.py @@ -8,8 +8,7 @@ This module provides helpful BaseContextSource subclasses. """ -from __future__ import annotations -from typing import TYPE_CHECKING, override +from typing import override from abc import abstractmethod from dataclasses import dataclass @@ -20,9 +19,6 @@ from .render import Template from .pipeline import BaseContextSource, BaseContextDirective, BaseContextRole -if TYPE_CHECKING: - pass - @dataclass class UnparsedData(PendingContext): @@ -93,7 +89,7 @@ def current_schema(self) -> Schema: @classmethod def derive( cls, name: str, schema: Schema, tmpl: Template - ) -> type[StrictDataDefineDirective]: + ) -> type['StrictDataDefineDirective']: if not schema.name: required_arguments = 0 optional_arguments = 0 diff --git a/src/sphinxnotes/render/template.py b/src/sphinxnotes/render/template.py index 8a0f94b..767f735 100644 --- a/src/sphinxnotes/render/template.py +++ b/src/sphinxnotes/render/template.py @@ -8,7 +8,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import annotations from dataclasses import dataclass from pprint import pformat from typing import TYPE_CHECKING, override diff --git a/src/sphinxnotes/render/utils/__init__.py b/src/sphinxnotes/render/utils/__init__.py index 6e9b67a..70a6ca3 100644 --- a/src/sphinxnotes/render/utils/__init__.py +++ b/src/sphinxnotes/render/utils/__init__.py @@ -1,4 +1,3 @@ -from __future__ import annotations from dataclasses import dataclass from typing import TYPE_CHECKING, TypeVar, cast import pickle From fc17d0ebd1095502026ec943c93e60230b1da311 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Tue, 17 Feb 2026 18:44:20 +0800 Subject: [PATCH 2/4] docs: Fix terms --- docs/dsl.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/dsl.rst b/docs/dsl.rst index 0c1f945..7480983 100644 --- a/docs/dsl.rst +++ b/docs/dsl.rst @@ -34,17 +34,17 @@ Syntax Modifier There are four categories of modifiers: - Type modifier - Specifies the element type (scalar value) + Type modifier + Specifies the element type (scalar value) - Form modifier - Specifies a container type with element type + Form modifier + Specifies a container type with element type - Flag - A boolean flag (either on or off) + Flag + A boolean flag (either on or off) - By-Option - A key-value option + By-Option + A key-value option Type ==== From 1a3ca732e16969576e75fadaf3d3f33ac89e6b66 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Tue, 17 Feb 2026 21:16:52 +0800 Subject: [PATCH 3/4] save it for now, I am tired --- docs/api.rst | 31 ++++++++++++++---------- docs/conf.py | 44 ++++++++++++++++++++++++---------- src/sphinxnotes/render/data.py | 6 ++--- 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index b153370..7a79f3c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,27 +1,32 @@ -============= -API Reference -============= +============== +API References +============== -Data Types -========== +Value, Data, Field and Schema +============================= -.. autotype:: sphinxnotes.render.PlainValue -.. autotype:: sphinxnotes.render.Value +.. autoclass:: sphinxnotes.render.PlainValue +.. autoclass:: sphinxnotes.render.Value .. autoclass:: sphinxnotes.render.RawData + :members: name, attrs, content + :undoc-members: + .. autoclass:: sphinxnotes.render.ParsedData + :members: name, attrs, content + :undoc-members: .. autoclass:: sphinxnotes.render.Field + :members: parse + .. autoclass:: sphinxnotes.render.Schema + :members: name, attrs, content + :undoc-members: .. autoclass:: sphinxnotes.render.data.Registry + :members: - .. automethod:: add_type - .. automethod:: add_form - .. automethod:: add_flag - .. automethod:: add_by_option - - .. autotype:: sphinxnotes.render.data.ByOptionStore + .. autotype:: sphinxnotes.render.data.ByOptionStore The Render Pipeline =================== diff --git a/docs/conf.py b/docs/conf.py index 893b5a3..3c171b6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,7 +11,7 @@ project = 'sphinxnotes-render' author = 'Shengyu Zhang' -copyright = "2025, " + author +copyright = '2025, ' + author # The full version, including alpha/beta/rc tags version = release = '1.0a0' @@ -57,9 +57,9 @@ html_theme = 'furo' html_theme_options = { - "source_repository": "https://github.com/sphinx-notes/data/", - "source_branch": "master", - "source_directory": "docs/", + 'source_repository': 'https://github.com/sphinx-notes/data/', + 'source_branch': 'master', + 'source_directory': 'docs/', } # The URL which points to the root of the HTML documentation. @@ -88,15 +88,17 @@ gtagjs_ids = ['G-E4SNX0WZYV'] extensions.append('sphinx.ext.autodoc') -autoclass_content = 'init' -autodoc_typehints = 'description' +# autoclass_content = 'init' +autodoc_typehints = 'signature' +autodoc_typehints_format = 'short' +autodoc_inherit_docstrings = False extensions.append('sphinx.ext.intersphinx') intersphinx_mapping = {} extensions.append('sphinx_sitemap') -sitemap_filename = "sitemap.xml" -sitemap_url_scheme = "{link}" +sitemap_filename = 'sitemap.xml' +sitemap_url_scheme = '{link}' extensions.append('sphinxext.opengraph') ogp_site_url = html_baseurl @@ -118,12 +120,30 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. import os import sys -sys.path.insert(0, os.path.abspath('../src/sphinxnotes')) -extensions.append('render') + +sys.path.insert(0, os.path.abspath('../src/')) +extensions.append('sphinxnotes.render') + +# Override type aliases for autodoc (PEP 695 type statement not well supported) +# import sphinxnotes.render +# sphinxnotes.render.data.PlainValue = bool | int | float | str | object +# sphinxnotes.render.PlainValue = bool | int | float | str | object +# sphinxnotes.render.data.Value = None | sphinxnotes.render.PlainValue | list[sphinxnotes.render.PlainValue] +# sphinxnotes.render.Value = None | sphinxnotes.render.PlainValue | list[sphinxnotes.render.PlainValue] # CUSTOM CONFIGURATION -_ = extensions.pop() # no need to load extension +_ = extensions.pop() # no need to load extension primary_domain = 'py' -extensions.append('sphinx.ext.doctest') +autodoc_inherit_docstrings = False +autodoc_default_options = { + 'member-order': 'bysource', +} +extensions.append('sphinx_autodoc_typehints') + +autodoc_type_aliases = { + 'sphinxnotes.render.data.PlainValue': 'sphinxnotes.render.PlainValue', + 'sphinxnotes.render.data.Value': 'sphinxnotes.render.Value', + 'sphinxnotes.render.data.PlainValue': 'sphinxnotes.render.PlainValue', +} diff --git a/src/sphinxnotes/render/data.py b/src/sphinxnotes/render/data.py index 6a15692..d5cf91b 100644 --- a/src/sphinxnotes/render/data.py +++ b/src/sphinxnotes/render/data.py @@ -273,10 +273,10 @@ def asdict(self) -> dict[str, Any]: ``self.attrs`` will be automaticlly lifted to top-level context when there is no key conflicts. For example: - - You can access ``Data.attrs['color']`` by "{{ color }}"" instead - of "{{ attrs.color }}". + - You can access ``Data.attrs['color']`` by "{{ color }}" instead + of "{{ attrs.color }}". - You can NOT access ``Data.attrs['name']`` by "{{ name }}" cause - the variable name is taken by ``Data.name``. + the variable name is taken by ``Data.name``. """ ctx = asdict(self) for k, v in self.attrs.items(): From b5d81102a641771c3d737eead722b408d28c59d2 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Mon, 23 Feb 2026 00:29:52 +0800 Subject: [PATCH 4/4] update --- docs/api.rst | 9 ++- docs/conf.py | 17 +++-- docs/dsl.rst | 35 +++++----- docs/index.rst | 1 + docs/tmpl.rst | 100 +++++++++++++++++++++++++++++ src/sphinxnotes/render/__init__.py | 12 +++- src/sphinxnotes/render/ctx.py | 4 +- src/sphinxnotes/render/data.py | 6 +- src/sphinxnotes/render/extractx.py | 11 ++++ src/sphinxnotes/render/render.py | 17 +++-- 10 files changed, 174 insertions(+), 38 deletions(-) create mode 100644 docs/tmpl.rst diff --git a/docs/api.rst b/docs/api.rst index 7a79f3c..b8eec41 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -43,14 +43,21 @@ Context Extra Context ------------- -.. autoclass:: sphinxnotes.render.ExtraContextGenerator +.. autoclass:: sphinxnotes.render.GlobalExtraContxt +.. autoclass:: sphinxnotes.render.ParsePhaseExtraContext +.. autoclass:: sphinxnotes.render.TransformPhaseExtraContext + .. autoclass:: sphinxnotes.render.ExtraContextRegistry + :members: Template -------- .. autoclass:: sphinxnotes.render.Template + :members: + .. autoclass:: sphinxnotes.render.Phase + :members: Pipeline -------- diff --git a/docs/conf.py b/docs/conf.py index 3c171b6..d793fc7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -133,17 +133,16 @@ # CUSTOM CONFIGURATION -_ = extensions.pop() # no need to load extension -primary_domain = 'py' - -autodoc_inherit_docstrings = False autodoc_default_options = { 'member-order': 'bysource', } -extensions.append('sphinx_autodoc_typehints') -autodoc_type_aliases = { - 'sphinxnotes.render.data.PlainValue': 'sphinxnotes.render.PlainValue', - 'sphinxnotes.render.data.Value': 'sphinxnotes.render.Value', - 'sphinxnotes.render.data.PlainValue': 'sphinxnotes.render.PlainValue', +extensions.append('sphinxnotes.data') + +intersphinx_mapping = { + 'python': ('https://docs.python.org/3', None), + 'sphinx': ('https://www.sphinx-doc.org/en/master', None), } + +def setup(app): + app.add_object_type('event', 'event') diff --git a/docs/dsl.rst b/docs/dsl.rst index 7480983..0617559 100644 --- a/docs/dsl.rst +++ b/docs/dsl.rst @@ -1,6 +1,6 @@ -===================== -Field Declaration DSL -===================== +========================== +Field Description Language +========================== .. default-domain:: py .. highlight:: python @@ -8,20 +8,10 @@ Field Declaration DSL :language: Python -The Field Declaration DSL is a Domain Specific Language (DSL) that used to -define the type and structure of field values. A DSL declaration consists of +The Field Description Language is a Domain Specific Language (DSL) that used to +define the type and structure of field values. An FDL declaration consists of one or more :term:`modifier`\ s separated by commas (``,``). -Python API -========== - -User can create a :class:`sphinxnotes.render.Field` from DSL and use it to parse -string to :type:`sphinxnotes.render.Value`: - ->>> from sphinxnotes.render import Field ->>> Field.from_dsl('list of int').parse('1,2,3') -[1, 2, 3] - Syntax ====== @@ -46,6 +36,17 @@ Syntax By-Option A key-value option +Python API +========== + +User can create a :class:`sphinxnotes.render.Field` from FDL and use it to parse +string to :type:`sphinxnotes.render.Value`: + +>>> from sphinxnotes.render import Field +>>> Field.from_dsl('list of int').parse('1,2,3') +[1, 2, 3] + + Type ==== @@ -179,10 +180,10 @@ DSL Input Result ``int, sep by ':'`` ``1:2:3`` :py:`[1, 2, 3]` =================== ========= ================ -Extending the DSL +Extending the FDL ================= -You can extend the DSL by registering custom types, flags, and by-options +You can extend the FDL by registering custom types, flags, and by-options through the :attr:`~sphinxnotes.render.Registry.data` attribute of :data:`sphinxnotes.render.REGISTRY`. diff --git a/docs/index.rst b/docs/index.rst index 750248c..deec9b3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -53,6 +53,7 @@ Contents .. toctree:: :caption: Contents + tmpl dsl api changelog diff --git a/docs/tmpl.rst b/docs/tmpl.rst new file mode 100644 index 0000000..6467381 --- /dev/null +++ b/docs/tmpl.rst @@ -0,0 +1,100 @@ +========== +Templating +========== + +We use Jinja2_ to rendering templating to markup text (usually reStructuredText). +User should be familiar with Jinja2 before reading this document. + +.. _Jinja2: https://jinja.palletsprojects.com/en/stable/templates/ + +.. _context: + +Data Context +============ + +Context defined by directives and roles consist of following `template variables`_: + +.. glossary:: + + ``{{ name }}`` + For directive, it refer to the only argument, such as ``bar`` of + ``.. foo:: bar``. + + For role, it refer to the name, such as ``foo`` of ``:foo:`bar```. + + ``{{ attrs.xxx }}`` + For directive, they refer to directive options + + For role, it is usually empty. + + .. note:: + + You can also refer them without the ``attr.`` prefix (just ``{{ xxx }}``) + when there is no ambiguity. + + ``{{ content }}`` + For directive, it refers to the directive content. + + For role, it refer to the interpreted text, such as ``bar`` of ``:foo:`bar```. + +The type of variables are depended on the corrsponding :doc:`dsl`. + +.. hint:: For extension developers: + + Directive and roles refer to classes derived from + :py:class:`~sphinxnotes.render.BaseDataDefineRole` and + :py:class:`~sphinxnotes.render.BaseDataDefineDirective`. + + The aboved context is refer to :py:class:`~sphinxnotes.render.ParsedData`. + +.. _template variables: https://jinja.palletsprojects.com/en/stable/templates/#variables + +Extra Contexts +============== + +Extra context can be extending by implmenting one of the following classs: + +:py:class:`~sphinxnotes.render.GlobalExtraContxt` +:py:class:`~sphinxnotes.render.ParsePhaseExtraContext` +:py:class:`~sphinxnotes.render.TransformPhaseExtraContext` + +Phases +====== + +:py:class:`sphinxnotes.render.Phase`. + +.. example:: + :style: grid + + .. data:render:: + :on: parsing + + - The current document has + {{ _doc.sections | length }} section(s). + - The current proejct has + {{ _sphinx.env.all_docs | length }} document(s). + +.. example:: + :style: grid + + .. data:render:: + :on: parsed + + - The current document has + {{ _doc.sections | length }} section(s). + - The current proejct has + {{ _sphinx.env.all_docs | length }} document(s). + +.. example:: + :style: grid + + .. data:render:: + :on: resolving + + - The current document has + {{ _doc.sections | length }} section(s). + - The current proejct has + {{ _sphinx.env.all_docs | length }} document(s). + +TODO +==== diff --git a/src/sphinxnotes/render/__init__.py b/src/sphinxnotes/render/__init__.py index 5801f5b..1e8e421 100644 --- a/src/sphinxnotes/render/__init__.py +++ b/src/sphinxnotes/render/__init__.py @@ -28,7 +28,13 @@ ) from .ctx import PendingContext, ResolvedContext from .ctxnodes import pending_node -from .extractx import ExtraContextRegistry, ExtraContextGenerator +from .extractx import ( + ExtraContextRegistry, + ExtraContextGenerator, + GlobalExtraContxt, + ParsePhaseExtraContext, + TransformPhaseExtraContext, +) from .pipeline import BaseContextRole, BaseContextDirective from .sources import ( UnparsedData, @@ -56,6 +62,10 @@ 'Host', 'PendingContext', 'ResolvedContext', + 'GlobalExtraContxt', + 'ParsePhaseExtraContext', + 'TransformPhaseExtraContext', + 'TransformPhaseExtraContext', 'pending_node', 'BaseContextRole', 'BaseContextDirective', diff --git a/src/sphinxnotes/render/ctx.py b/src/sphinxnotes/render/ctx.py index b2a4807..700a0d7 100644 --- a/src/sphinxnotes/render/ctx.py +++ b/src/sphinxnotes/render/ctx.py @@ -33,7 +33,7 @@ def __hash__(self) -> int: class PendingContext(ABC, Unpicklable, Hashable): """A abstract representation of context that is not currently available. - Call :meth:`resolve` at the right time (depends on the implment) to get + Call :py:meth:`resolve` at the right time (depends on the implment) to get context available. """ @@ -52,7 +52,7 @@ class PendingContextStorage: This class maintains a mapping from :class:`PendingContextRef` -> :cls:`PendingContext`. ``pending_node`` owns the ``PendingContextRef``, and can retrieve the context - by calling :meth:`retrieve`. + by calling :py:meth:`retrieve`. """ _next_id: int diff --git a/src/sphinxnotes/render/data.py b/src/sphinxnotes/render/data.py index d5cf91b..6ad5907 100644 --- a/src/sphinxnotes/render/data.py +++ b/src/sphinxnotes/render/data.py @@ -157,7 +157,7 @@ def add_type( strify: Callable[[PlainValue], str], aliases: list[str] = [], ) -> None: - """Register a value type for :class:`PlainValue`. + """Register a value type for :py:class:`PlainValue`. :param name: The name for this scalar type, available as a :term:`Type modifier` in the DSL @@ -179,12 +179,12 @@ def add_form( self, name: str, ctype: type, sep: str, aliases: list[str] = [] ) -> None: """Register an value form with its container type and separator for - :class:`Value`. + :py:class:`Value`. :param name: The name for this form, available as a :term:`Form modifier` in the DSL :param ctype: The container type. - (for now, it is :class:`list`, :class:`tuple`, or :class:`set`) + (for now, it is :py:class:`list`, :py:class:`tuple`, or :py:class:`set`) :param sep: The separator string used to split/join values :param aliases: Alternative names for this form """ diff --git a/src/sphinxnotes/render/extractx.py b/src/sphinxnotes/render/extractx.py index 90cb711..ad56527 100644 --- a/src/sphinxnotes/render/extractx.py +++ b/src/sphinxnotes/render/extractx.py @@ -17,16 +17,23 @@ class GlobalExtraContxt(ABC): + """Extra context availabled on any phase.""" + @abstractmethod def generate(self) -> Any: ... class ParsePhaseExtraContext(ABC): + """Extra context generated during the :py:class:`~Phase.Parsing` or + :py:class:`~Phase.Parsing` phase.""" + @abstractmethod def generate(self, host: ParseHost) -> Any: ... class TransformPhaseExtraContext(ABC): + """Extra context generated during the :py:class:`~Phase.Resolving` phase.""" + @abstractmethod def generate(self, host: TransformHost) -> Any: ... @@ -65,22 +72,26 @@ def _name_dedup(self, name: str) -> None: def add_parsing_phase_context( self, name: str, ctxgen: ParsePhaseExtraContext ) -> None: + """Register a extra context for :py:class:`~Phase.Parsing` phase.""" self._name_dedup(name) self.parsing['_' + name] = ctxgen def add_parsed_phase_context( self, name: str, ctxgen: TransformPhaseExtraContext ) -> None: + """Register a extra context for :py:class:`~Phase.Parsed` phase.""" self._name_dedup(name) self.parsed['_' + name] = ctxgen def add_post_transform_phase_context( self, name: str, ctxgen: TransformPhaseExtraContext ) -> None: + """Register a extra context for :py:class:`~Phase.Resolving` phase.""" self._name_dedup(name) self.post_transform['_' + name] = ctxgen def add_global_context(self, name: str, ctxgen: GlobalExtraContxt): + """Register a extra context for :py:class:`~Phase.Resolving` phase.""" self._name_dedup(name) self.global_['_' + name] = ctxgen diff --git a/src/sphinxnotes/render/render.py b/src/sphinxnotes/render/render.py index 310a443..1724290 100644 --- a/src/sphinxnotes/render/render.py +++ b/src/sphinxnotes/render/render.py @@ -7,12 +7,19 @@ class Phase(Enum): + """The phase of rendering template.""" + + #: Render template on document parsing. Parsing = 'parsing' + #: Render template immediately after document has parsed + #: (on Sphinx event :external:event:`doctree-read`). Parsed = 'parsed' + #: Render template immediately after all documents have resolving + #: (before Sphinx event :external:event:`doctree-resolved`). Resolving = 'resolving' @classmethod - def default(cls) -> 'Phase': + def default(cls) -> Phase: return cls.Parsing @@ -22,15 +29,15 @@ class Template: text: str #: The render phase. phase: Phase = Phase.default() - #: Enable debug output (shown as :class:`nodes.system_message` in document.) + #: Enable debug output (shown as :py:class:`docutils.nodes.system_message` in document.) debug: bool = False -# Possible render host of :meth:`pending_node.render`. +#: Possible render host of :meth:`pending_node.render`. type Host = ParseHost | TransformHost -# Host of source parse phase (Phase.Parsing, Phase.Parsed). +#: Host of source parse phase (Phase.Parsing, Phase.Parsed). type ParseHost = SphinxDirective | SphinxRole -# Host of source parse phase (Phase.Parsing, Phase.Parsed). +#: Host of source parse phase (Phase.Parsing, Phase.Parsed). type TransformHost = SphinxTransform