sphinxnotes-render 1.0b3__tar.gz → 1.0b5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/.cruft.json +2 -2
  2. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/.gitignore +1 -0
  3. {sphinxnotes_render-1.0b3/src/sphinxnotes_render.egg-info → sphinxnotes_render-1.0b5}/PKG-INFO +10 -6
  4. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/README.rst +1 -1
  5. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/api.rst +52 -66
  6. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/conf.py +31 -8
  7. sphinxnotes_render-1.0b5/docs/conf.rst +29 -0
  8. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/dsl.rst +0 -58
  9. sphinxnotes_render-1.0b5/docs/ext.rst +248 -0
  10. sphinxnotes_render-1.0b5/docs/index.rst +181 -0
  11. sphinxnotes_render-1.0b5/docs/tmpl.rst +411 -0
  12. sphinxnotes_render-1.0b5/docs/usage.rst +159 -0
  13. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/pyproject.toml +9 -4
  14. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/__init__.py +14 -24
  15. sphinxnotes_render-1.0b5/src/sphinxnotes/render/ctx.py +23 -0
  16. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/ctxnodes.py +65 -48
  17. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/data.py +5 -6
  18. sphinxnotes_render-1.0b5/src/sphinxnotes/render/ext/__init__.py +32 -0
  19. sphinxnotes_render-1.0b5/src/sphinxnotes/render/ext/adhoc.py +211 -0
  20. sphinxnotes_render-1.0b5/src/sphinxnotes/render/ext/derive.py +72 -0
  21. sphinxnotes_render-1.0b5/src/sphinxnotes/render/ext/extractx.py +89 -0
  22. sphinxnotes_render-1.0b5/src/sphinxnotes/render/ext/filters.py +53 -0
  23. sphinxnotes_render-1.0b5/src/sphinxnotes/render/extractx.py +98 -0
  24. sphinxnotes_render-1.0b3/src/sphinxnotes/render/template.py → sphinxnotes_render-1.0b5/src/sphinxnotes/render/jinja.py +36 -60
  25. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/markup.py +1 -1
  26. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/meta.py +1 -1
  27. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/pipeline.py +17 -24
  28. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/sources.py +33 -8
  29. sphinxnotes_render-1.0b3/src/sphinxnotes/render/render.py → sphinxnotes_render-1.0b5/src/sphinxnotes/render/template.py +9 -15
  30. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/utils/freestyle.py +1 -1
  31. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5/src/sphinxnotes_render.egg-info}/PKG-INFO +10 -6
  32. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes_render.egg-info/SOURCES.txt +29 -4
  33. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes_render.egg-info/requires.txt +6 -1
  34. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/tests/conftest.py +3 -0
  35. sphinxnotes_render-1.0b5/tests/roots/test-base-context-directive-example/conf.py +23 -0
  36. sphinxnotes_render-1.0b5/tests/roots/test-base-context-directive-example/index.rst +4 -0
  37. sphinxnotes_render-1.0b5/tests/roots/test-base-data-define-directive-example/conf.py +42 -0
  38. sphinxnotes_render-1.0b5/tests/roots/test-base-data-define-directive-example/index.rst +14 -0
  39. sphinxnotes_render-1.0b5/tests/roots/test-data-define/conf.py +1 -0
  40. sphinxnotes_render-1.0b5/tests/roots/test-data-define/index.rst +18 -0
  41. sphinxnotes_render-1.0b5/tests/roots/test-derive/conf.py +16 -0
  42. sphinxnotes_render-1.0b5/tests/roots/test-derive/index.rst +8 -0
  43. sphinxnotes_render-1.0b5/tests/roots/test-extra-context/cat.json +7 -0
  44. sphinxnotes_render-1.0b5/tests/roots/test-extra-context/conf.py +25 -0
  45. sphinxnotes_render-1.0b5/tests/roots/test-extra-context/index.rst +6 -0
  46. sphinxnotes_render-1.0b5/tests/roots/test-extra-context-rebuild/conf.py +1 -0
  47. sphinxnotes_render-1.0b5/tests/roots/test-extra-context-rebuild/index.rst +11 -0
  48. sphinxnotes_render-1.0b5/tests/roots/test-filter-example/conf.py +22 -0
  49. sphinxnotes_render-1.0b5/tests/roots/test-filter-example/index.rst +6 -0
  50. sphinxnotes_render-1.0b5/tests/roots/test-strict-data-define-directive-example/conf.py +31 -0
  51. sphinxnotes_render-1.0b5/tests/roots/test-strict-data-define-directive-example/index.rst +14 -0
  52. sphinxnotes_render-1.0b5/tests/test_ctx.py +60 -0
  53. sphinxnotes_render-1.0b5/tests/test_e2e.py +109 -0
  54. sphinxnotes_render-1.0b5/tests/test_extractx.py +36 -0
  55. sphinxnotes_render-1.0b5/tests/test_jinja.py +12 -0
  56. sphinxnotes_render-1.0b3/docs/index.rst +0 -82
  57. sphinxnotes_render-1.0b3/docs/tmpl.rst +0 -319
  58. sphinxnotes_render-1.0b3/docs/usage.rst +0 -63
  59. sphinxnotes_render-1.0b3/src/sphinxnotes/render/ctx.py +0 -69
  60. sphinxnotes_render-1.0b3/src/sphinxnotes/render/extractx.py +0 -194
  61. sphinxnotes_render-1.0b3/tests/roots/test-ctxdir-usage/conf.py +0 -15
  62. sphinxnotes_render-1.0b3/tests/roots/test-ctxdir-usage/index.rst +0 -4
  63. sphinxnotes_render-1.0b3/tests/test_smoke.py +0 -28
  64. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/.github/workflows/lint.yml +0 -0
  65. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/.github/workflows/pages.yml +0 -0
  66. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/.github/workflows/pypi.yml +0 -0
  67. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/.github/workflows/release.yml +0 -0
  68. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/.github/workflows/test.yml +0 -0
  69. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/.pre-commit-config.yaml +0 -0
  70. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/LICENSE +0 -0
  71. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/MANIFEST.in +0 -0
  72. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/Makefile +0 -0
  73. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/Makefile +0 -0
  74. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/_images/.gitkeep +0 -0
  75. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/_static/.gitkeep +0 -0
  76. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/_static/custom.css +0 -0
  77. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/_static/sphinx-notes.png +0 -0
  78. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/changelog.rst +0 -0
  79. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/docs/make.bat +0 -0
  80. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/ruff.toml +0 -0
  81. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/setup.cfg +0 -0
  82. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/py.typed +0 -0
  83. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/utils/__init__.py +0 -0
  84. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes/render/utils/ctxproxy.py +0 -0
  85. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes_render.egg-info/dependency_links.txt +0 -0
  86. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/src/sphinxnotes_render.egg-info/top_level.txt +0 -0
  87. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/tests/__init__.py +0 -0
  88. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/tests/roots/test-strictdir-card/conf.py +0 -0
  89. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/tests/roots/test-strictdir-card/index.rst +0 -0
  90. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/tests/test_always_pass.py +0 -0
  91. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b5}/tests/test_data.py +0 -0
@@ -8,8 +8,8 @@
8
8
  "name": "render",
9
9
  "full_name": "sphinxnotes-render",
10
10
  "author": "Shengyu Zhang",
11
- "description": "A framework to define, constrain, and render data in Sphinx documentation",
12
- "version": "1.0a0",
11
+ "description": "Define, constrain, and render data in Sphinx documentation",
12
+ "version": "1.0b4",
13
13
  "github_owner": "sphinx-notes",
14
14
  "github_repo": "data",
15
15
  "pypi_name": "sphinxnotes-render",
@@ -135,3 +135,4 @@ poetry.lock
135
135
  docs/_build/
136
136
  # sphinxnotes-any >= 2.5
137
137
  docs/.any*
138
+ .worktrees/
@@ -1,15 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sphinxnotes-render
3
- Version: 1.0b3
4
- Summary: A framework to define, constrain, and render data in Sphinx documentation
3
+ Version: 1.0b5
4
+ Summary: Define, constrain, and render data in Sphinx documentation
5
5
  Author: Shengyu Zhang
6
6
  Maintainer: Shengyu Zhang
7
7
  License-Expression: BSD-3-Clause
8
8
  Project-URL: homepage, https://sphinx.silverrainz.me/render
9
9
  Project-URL: documentation, https://sphinx.silverrainz.me/render
10
- Project-URL: repository, https://github.com/sphinx-notes/data
10
+ Project-URL: repository, https://github.com/sphinx-notes/render
11
11
  Project-URL: changelog, https://sphinx.silverrainz.me/render/changelog.html
12
- Project-URL: tracker, https://github.com/sphinx-notes/data/issues
12
+ Project-URL: tracker, https://github.com/sphinx-notes/render/issues
13
13
  Keywords: sphinx,extension,documentation,sphinxnotes
14
14
  Classifier: Development Status :: 3 - Alpha
15
15
  Classifier: Environment :: Plugins
@@ -24,6 +24,7 @@ Requires-Python: >=3.12
24
24
  Description-Content-Type: text/x-rst
25
25
  License-File: LICENSE
26
26
  Requires-Dist: Sphinx>=7.0
27
+ Requires-Dist: Jinja2
27
28
  Provides-Extra: dev
28
29
  Requires-Dist: build; extra == "dev"
29
30
  Requires-Dist: twine; extra == "dev"
@@ -32,6 +33,7 @@ Requires-Dist: ruff>=0.11.10; extra == "dev"
32
33
  Requires-Dist: pre-commit; extra == "dev"
33
34
  Provides-Extra: test
34
35
  Requires-Dist: pytest; extra == "test"
36
+ Requires-Dist: schema; extra == "test"
35
37
  Provides-Extra: docs
36
38
  Requires-Dist: furo; extra == "docs"
37
39
  Requires-Dist: sphinx_design; extra == "docs"
@@ -42,7 +44,9 @@ Requires-Dist: sphinxext-opengraph; extra == "docs"
42
44
  Requires-Dist: sphinx-last-updated-by-git; extra == "docs"
43
45
  Requires-Dist: sphinxnotes-project; extra == "docs"
44
46
  Requires-Dist: sphinxnotes-comboroles; extra == "docs"
45
- Requires-Dist: sphinxnotes-data; extra == "docs"
47
+ Requires-Dist: schema; extra == "docs"
48
+ Provides-Extra: ext
49
+ Requires-Dist: schema; extra == "ext"
46
50
  Dynamic: license-file
47
51
 
48
52
  .. This file is generated from sphinx-notes/cookiecutter.
@@ -67,7 +71,7 @@ sphinxnotes-render
67
71
 
68
72
  |docs| |license| |pypi| |download|
69
73
 
70
- A framework to define, constrain, and render data in Sphinx documentation.
74
+ Define, constrain, and render data in Sphinx documentation.
71
75
 
72
76
  .. INTRODUCTION START
73
77
  (MUST written in standard reStructuredText, without Sphinx stuff)
@@ -20,7 +20,7 @@ sphinxnotes-render
20
20
 
21
21
  |docs| |license| |pypi| |download|
22
22
 
23
- A framework to define, constrain, and render data in Sphinx documentation.
23
+ Define, constrain, and render data in Sphinx documentation.
24
24
 
25
25
  .. INTRODUCTION START
26
26
  (MUST written in standard reStructuredText, without Sphinx stuff)
@@ -2,39 +2,52 @@
2
2
  API References
3
3
  ==============
4
4
 
5
- The Render Pipeline
6
- ===================
5
+ .. _api-directives:
6
+ .. _api-roles:
7
7
 
8
- The pipeline defines how nodes carrying data are generated and when they are
9
- rendered as part of the document.
8
+ Roles and Directives
9
+ ====================
10
10
 
11
- 1. Generation: :py:class:`~sphinxnotes.render.BaseContextRole`,
12
- :py:class:`~sphinxnotes.render.BaseContextDirective` and their subclasses
13
- create :py:class:`~sphinxnotes.render.pending_node` on document parsing,
14
- and the node will be inserted to the document tree. The node contains:
11
+ .. seealso::
15
12
 
16
- - :ref:`context`, the dynamic content of a Jinja template
13
+ For a minimal end-to-end example of creating your own directive, start with
14
+ :ref:`ext-directives`.
17
15
 
18
- - :py:class:`~sphinxnotes.render.Template`,
19
- the Jinja template for rendering context to markup text
20
- (reStructuredText or Markdown)
16
+ Base Role Classes
17
+ -----------------
18
+
19
+ .. autoclass:: sphinxnotes.render.BaseContextRole
20
+ :show-inheritance:
21
+ :members: process_pending_node, queue_pending_node, queue_context, current_context, current_template
22
+
23
+ .. autoclass:: sphinxnotes.render.BaseDataDefineRole
24
+ :show-inheritance:
25
+ :members: process_pending_node, queue_pending_node, queue_context, current_schema, current_template
26
+
27
+ Base Directive Classes
28
+ ----------------------
29
+
30
+ .. autoclass:: sphinxnotes.render.BaseContextDirective
31
+ :show-inheritance:
32
+ :members: process_pending_node, queue_pending_node, queue_context, current_raw_data, current_context, current_template
21
33
 
22
- 2. Render: the ``pending_node`` node will be rendered at the appropriate
23
- :py:class:`~sphinxnotes.render.Phase`, depending on
24
- :py:attr:`~sphinxnotes.render.pending_node.template.phase`.
34
+ .. autoclass:: sphinxnotes.render.BaseDataDefineDirective
35
+ :show-inheritance:
36
+ :members: process_pending_node, queue_pending_node, queue_context, current_raw_data, current_schema, current_template
25
37
 
26
- For a task-oriented explanation of template variables, extra context, and phase
27
- selection, see :doc:`tmpl`.
38
+ .. autoclass:: sphinxnotes.render.StrictDataDefineDirective
39
+ :show-inheritance:
40
+ :members: derive
28
41
 
29
42
  Node
30
- -----
43
+ =====
31
44
 
32
45
  .. autoclass:: sphinxnotes.render.pending_node
33
46
 
34
- .. _context:
47
+ .. _api-context:
35
48
 
36
49
  Context
37
- -------
50
+ =======
38
51
 
39
52
  Context refers to the dynamic content of a Jinja template. It can be:
40
53
 
@@ -42,22 +55,22 @@ Context refers to the dynamic content of a Jinja template. It can be:
42
55
  Our dedicated data type (:py:class:`sphinxnotes.render.ParsedData`), or any
43
56
  Python ``dict``.
44
57
 
45
- :py:class:`~sphinxnotes.render.PendingContext`:
58
+ :py:class:`~sphinxnotes.render.UnresolvedContext`:
46
59
  Context that is not yet available. For example, it may contain
47
60
  :py:class:`unparsed data <sphinxnotes.render.RawData>`,
48
61
  remote data, and more.
49
62
 
50
- :py:class:`PendingContext` can be resolved to
63
+ :py:class:`UnresolvedContext` can be resolved to
51
64
  :py:class:`~sphinxnotes.render.ResolvedContext` by calling
52
- :py:meth:`~sphinxnotes.render.PendingContext.resolve`.
65
+ :py:meth:`~sphinxnotes.render.UnresolvedContext.resolve`.
53
66
 
54
67
  .. autotype:: sphinxnotes.render.ResolvedContext
55
68
 
56
- .. autoclass:: sphinxnotes.render.PendingContext
69
+ .. autoclass:: sphinxnotes.render.UnresolvedContext
57
70
  :members: resolve
58
71
 
59
- ``PendingContext`` Implementations
60
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72
+ ``UnresolvedContext`` Implementations
73
+ -------------------------------------
61
74
 
62
75
  .. autoclass:: sphinxnotes.render.UnparsedData
63
76
  :show-inheritance:
@@ -65,7 +78,7 @@ Context refers to the dynamic content of a Jinja template. It can be:
65
78
  .. _extractx:
66
79
 
67
80
  Template
68
- --------
81
+ ========
69
82
 
70
83
  See :doc:`tmpl` for the higher-level guide.
71
84
 
@@ -76,51 +89,25 @@ See :doc:`tmpl` for the higher-level guide.
76
89
  :members:
77
90
 
78
91
  Extra Context
79
- -------------
80
-
81
- See :doc:`tmpl` for built-in extra-context names such as ``_doc`` and
82
- ``_sphinx``, plus usage examples.
92
+ =============
83
93
 
84
- .. autoclass:: sphinxnotes.render.GlobalExtraContxt
94
+ See :doc:`tmpl` for built-in extra-context names such as ``doc`` and
95
+ ``env``, plus usage examples.
85
96
 
86
- .. autoclass:: sphinxnotes.render.ParsePhaseExtraContext
97
+ .. autodecorator:: sphinxnotes.render.extra_context
87
98
 
88
- .. autoclass:: sphinxnotes.render.ResolvePhaseExtraContext
99
+ .. autoclass:: sphinxnotes.render.ExtraContext
100
+ :members: generate
101
+ :undoc-members:
89
102
 
90
- .. autoclass:: sphinxnotes.render.ExtraContextRegistry
103
+ .. autoclass:: sphinxnotes.render.ExtraContextRequest
91
104
  :members:
105
+ :undoc-members:
92
106
 
107
+ Filters
108
+ =======
93
109
 
94
- Base Roles and Directives
95
- -------------------------
96
-
97
- For a minimal end-to-end example of a custom directive, start with :doc:`usage`.
98
-
99
- Base Role Classes
100
- ~~~~~~~~~~~~~~~~~
101
-
102
- .. autoclass:: sphinxnotes.render.BaseContextRole
103
- :show-inheritance:
104
- :members: process_pending_node, queue_pending_node, queue_context, current_context, current_template
105
-
106
- .. autoclass:: sphinxnotes.render.BaseDataDefineRole
107
- :show-inheritance:
108
- :members: process_pending_node, queue_pending_node, queue_context, current_schema, current_template
109
-
110
- Base Directive Classes
111
- ~~~~~~~~~~~~~~~~~~~~~~
112
-
113
- .. autoclass:: sphinxnotes.render.BaseContextDirective
114
- :show-inheritance:
115
- :members: process_pending_node, queue_pending_node, queue_context, current_context, current_template
116
-
117
- .. autoclass:: sphinxnotes.render.BaseDataDefineDirective
118
- :show-inheritance:
119
- :members: process_pending_node, queue_pending_node, queue_context, current_schema, current_template
120
-
121
- .. autoclass:: sphinxnotes.render.StrictDataDefineDirective
122
- :show-inheritance:
123
- :members: derive
110
+ .. autodecorator:: sphinxnotes.render.filter
124
111
 
125
112
  Data, Field and Schema
126
113
  ======================
@@ -161,4 +148,3 @@ or add new extra context) by adding new items to
161
148
  .. autoclass:: sphinxnotes.render.Registry
162
149
 
163
150
  .. autoproperty:: data
164
- .. autoproperty:: extra_context
@@ -14,7 +14,7 @@ author = 'Shengyu Zhang'
14
14
  copyright = "2025, " + author
15
15
 
16
16
  # The full version, including alpha/beta/rc tags
17
- version = release = '1.0a0'
17
+ version = release = '1.0b4'
18
18
 
19
19
  # -- General configuration ---------------------------------------------------
20
20
 
@@ -122,23 +122,46 @@ import sys
122
122
  sys.path.insert(0, os.path.abspath('../src/'))
123
123
  extensions.append('sphinxnotes.render')
124
124
 
125
- extensions.append('sphinxnotes.data')
126
-
127
125
  # CUSTOM CONFIGURATION
128
126
 
127
+ extensions.append('sphinxnotes.render.ext')
128
+
129
+ # [example config start]
130
+ render_ext_data_define_directives = {
131
+ 'cat': {
132
+ 'schema': {
133
+ 'name': 'str, required',
134
+ 'attrs': {
135
+ 'color': 'str',
136
+ },
137
+ 'content': 'str, required'
138
+ },
139
+ 'template': {
140
+ 'text': '\n'.join([
141
+ 'Hi human! I am a cat named {{ name }}, I have {{ color }} fur.',
142
+ '',
143
+ '{{ content }}.',
144
+ ]),
145
+ },
146
+ },
147
+ }
148
+ # [example config end]
149
+
129
150
  autodoc_default_options = {
130
151
  'member-order': 'bysource',
131
152
  }
132
153
 
133
154
  intersphinx_mapping['python'] = ('https://docs.python.org/3', None)
134
155
  intersphinx_mapping['sphinx'] = ('https://www.sphinx-doc.org/en/master', None)
135
- intersphinx_mapping['data'] = ('https://sphinx.silverrainz.me/data', None)
136
156
 
137
- ctxdir_usage_example_path = os.path.abspath('../tests/roots/test-ctxdir-usage')
157
+ test_roots = os.path.abspath('../tests/roots')
138
158
 
139
159
  def setup(app):
140
160
  app.add_object_type('event', 'event') # for intersphinx
141
161
 
142
- sys.path.insert(0, ctxdir_usage_example_path)
143
- from conf import setup as setup_ctxdir_usage_example
144
- setup_ctxdir_usage_example(app)
162
+ sys.path.insert(0, test_roots)
163
+ __import__('test-extra-context.conf').conf.setup(app)
164
+ __import__('test-base-context-directive-example.conf').conf.setup(app)
165
+ __import__('test-base-data-define-directive-example.conf').conf.setup(app)
166
+ __import__('test-strict-data-define-directive-example.conf').conf.setup(app)
167
+ __import__('test-filter-example.conf').conf.setup(app)
@@ -0,0 +1,29 @@
1
+ =============
2
+ Configuration
3
+ =============
4
+
5
+ The extension provides the following configuration:
6
+
7
+ .. autoconfval:: render_ext_data_define_directives
8
+
9
+ A dictionary ``dict[str, directive_def]`` for creating custom directives for
10
+ data definition.
11
+
12
+ The ``str`` key is the name of the directive to be created;
13
+ The ``directive_def`` value is a ``dict`` with the following keys:
14
+
15
+ - ``schema`` (dict): Schema definition, works same as the
16
+ :rst:dir:`data.schema` directive, which has the following keys:
17
+
18
+ - ``name`` (str, optional): same as the directive argument
19
+ - ``attr`` (dict, can be empty): same as the directive options
20
+ - ``content`` (str, optional): same as the directive content
21
+
22
+ - ``template`` (dict): Template definition, works same as the
23
+ :rst:dir:`data.template` directive, which has the following keys:
24
+
25
+ - ``text`` (str): the Jinja2 template text.
26
+ - ``on`` (str, optional): same as :rst:dir:`data.template:on`
27
+ - ``debug`` (bool, optional): same as :rst:dir:`data.template:debug`
28
+
29
+ See :ref:`usage-custom-directive` for example.
@@ -180,61 +180,3 @@ DSL Input Result
180
180
  ``int, sep by ':'`` ``1:2:3`` :py:`[1, 2, 3]`
181
181
  =================== ========= ================
182
182
 
183
- Extending the FDL
184
- =================
185
-
186
- You can extend the FDL by registering custom types, flags, and by-options
187
- through the :attr:`~sphinxnotes.render.Registry.data` attribute of
188
- :data:`sphinxnotes.render.REGISTRY`.
189
-
190
- .. _add-custom-types:
191
-
192
- Adding Custom Types
193
- -------------------
194
-
195
- Use :meth:`~sphinxnotes.render.data.REGISTRY.add_type` method of
196
- :data:`sphinxnotes.render.REGISTRY` to add a new type:
197
-
198
- >>> from sphinxnotes.render import REGISTRY
199
- >>>
200
- >>> def parse_color(v: str):
201
- ... return tuple(int(x) for x in v.split(';'))
202
- ...
203
- >>> def color_to_str(v):
204
- ... return ';'.join(str(x) for x in v)
205
- ...
206
- >>> REGISTRY.data.add_type('color', tuple, parse_color, color_to_str)
207
- >>> Field.from_dsl('color').parse('255;0;0')
208
- (255, 0, 0)
209
-
210
- .. _add-custom-flags:
211
-
212
- Adding Custom Flags
213
- -------------------
214
-
215
- Use :meth:`~sphinxnotes.render.data.Registry.add_flag` method of
216
- :data:`sphinxnotes.render.REGISTRY` to add a new flag:
217
-
218
- >>> from sphinxnotes.render import REGISTRY
219
- >>> REGISTRY.data.add_flag('unique', default=False)
220
- >>> field = Field.from_dsl('int, unique')
221
- >>> field.unique
222
- True
223
-
224
- .. _add-custom-by-options:
225
-
226
- Adding Custom By-Options
227
- ------------------------
228
-
229
- Use :meth:`~sphinxnotes.render.data.Registry.add_by_option` method of
230
- :data:`sphinxnotes.render.REGISTRY` to add a new by-option:
231
-
232
- >>> from sphinxnotes.render import REGISTRY
233
- >>> REGISTRY.data.add_by_option('group', str)
234
- >>> field = Field.from_dsl('str, group by size')
235
- >>> field.group
236
- 'size'
237
- >>> REGISTRY.data.add_by_option('index', str, store='append')
238
- >>> field = Field.from_dsl('str, index by month, index by year')
239
- >>> field.index
240
- ['month', 'year']
@@ -0,0 +1,248 @@
1
+ =========
2
+ Extending
3
+ =========
4
+
5
+ Extending the FDL
6
+ =================
7
+
8
+ You can extend the :doc:`dsl` by registering custom types, flags, and by-options
9
+ through the :py:attr:`~sphinxnotes.render.Registry.data` attribute of
10
+ :py:data:`sphinxnotes.render.REGISTRY`.
11
+
12
+ .. _add-custom-types:
13
+
14
+ Adding Custom Types
15
+ -------------------
16
+
17
+ Use :py:meth:`~sphinxnotes.render.data.REGISTRY.add_type` method of
18
+ :py:data:`sphinxnotes.render.REGISTRY` to add a new type:
19
+
20
+ >>> from sphinxnotes.render import REGISTRY, Field
21
+ >>>
22
+ >>> def parse_color(v: str):
23
+ ... return tuple(int(x) for x in v.split(';'))
24
+ ...
25
+ >>> def color_to_str(v):
26
+ ... return ';'.join(str(x) for x in v)
27
+ ...
28
+ >>> REGISTRY.data.add_type('color', tuple, parse_color, color_to_str)
29
+ >>> Field.from_dsl('color').parse('255;0;0')
30
+ (255, 0, 0)
31
+
32
+ .. _add-custom-flags:
33
+
34
+ Adding Custom Flags
35
+ -------------------
36
+
37
+ Use :py:meth:`~sphinxnotes.render.data.Registry.add_flag` method of
38
+ :py:data:`sphinxnotes.render.REGISTRY` to add a new flag:
39
+
40
+ >>> from sphinxnotes.render import REGISTRY, Field
41
+ >>> REGISTRY.data.add_flag('unique', default=False)
42
+ >>> field = Field.from_dsl('int, unique')
43
+ >>> field.unique
44
+ True
45
+
46
+ .. _add-custom-by-options:
47
+
48
+ Adding Custom By-Options
49
+ ------------------------
50
+
51
+ Use :py:meth:`~sphinxnotes.render.data.Registry.add_by_option` method of
52
+ :py:data:`sphinxnotes.render.REGISTRY` to add a new by-option:
53
+
54
+ >>> from sphinxnotes.render import REGISTRY, Field
55
+ >>> REGISTRY.data.add_by_option('group', str)
56
+ >>> field = Field.from_dsl('str, group by size')
57
+ >>> field.group
58
+ 'size'
59
+ >>> REGISTRY.data.add_by_option('index', str, store='append')
60
+ >>> field = Field.from_dsl('str, index by month, index by year')
61
+ >>> field.index
62
+ ['month', 'year']
63
+
64
+ .. _ext-extra-context:
65
+
66
+ Extending Extra Contexts
67
+ ========================
68
+
69
+ Extra contexts are registered by a
70
+ :py:deco:`sphinxnotes.render.extra_context` class decorator.
71
+
72
+ The decorated class must be a subclass of
73
+ :py:class:`~sphinxnotes.render.ExtraContext`.
74
+
75
+ .. literalinclude:: ../tests/roots/test-extra-context/conf.py
76
+ :language: python
77
+ :start-after: [literalinclude start]
78
+ :end-before: [literalinclude end]
79
+
80
+ .. dropdown:: :file:`cat.json`
81
+
82
+ .. literalinclude:: ../tests/roots/test-extra-context/cat.json
83
+
84
+ .. example::
85
+ :style: grid
86
+
87
+ .. data.render::
88
+
89
+ {{ load_extra('cat').name }}
90
+
91
+ .. _ext-filters:
92
+
93
+ Extending ilters
94
+ =================
95
+
96
+ Template filters are registered by a
97
+ :py:deco:`sphinxnotes.render.filter` function decorator.
98
+
99
+ The decorated function takes a :py:class:`sphinx.environment.BuildEnvironment`
100
+ as argument and returns a filter function.
101
+
102
+ .. note::
103
+
104
+ The decorator is used to **decorate the filter function factory, NOT
105
+ the filter function itself**.
106
+
107
+ .. literalinclude:: ../tests/roots/test-filter-example/conf.py
108
+ :language: python
109
+ :start-after: [literalinclude start]
110
+ :end-before: [literalinclude end]
111
+
112
+ .. example::
113
+ :style: grid
114
+
115
+ .. data.render::
116
+
117
+ {{ "Hello world" | catify }}
118
+
119
+ .. _ext-directives:
120
+ .. _ext-roles:
121
+
122
+ Extending Directives/Roles
123
+ ==========================
124
+
125
+ .. tip::
126
+
127
+ Before reading this documentation, please refer to
128
+ :external+sphinx:doc:`development/tutorials/extending_syntax`.
129
+ See how to extend :py:class:`SphinxDirective` and :py:class:`SphinxRole`.
130
+
131
+ All of the classes listed in :ref:`api-directives` are subclassed from the
132
+ internal ``sphinxnotes.render.Pipeline`` class, which is responsible to generate
133
+ the dedicated :py:class:`node <sphinxnotes.render.pending_node>` that
134
+ carries a :ref:`context` and a :py:class:`~sphinxnotes.render.Template`.
135
+
136
+ At the appropriate :ref:`render-phases`, the node will be rendered into markup
137
+ text, usually reStructuredText. The rendered text is then parsed again by
138
+ Sphinx and inserted into the document.
139
+
140
+ .. seealso::
141
+
142
+ - :doc:`tmpl` for template variables, phases, and extra context
143
+ - :doc:`dsl` for the field description language used by
144
+ :py:class:`~sphinxnotes.render.Field` and
145
+ :py:class:`~sphinxnotes.render.Schema`
146
+ - Implementations of :parsed_literal:`sphinxnotes-render.ext__`
147
+ and :parsed_literal:`sphinxnotes-any__`.
148
+
149
+ __ https://github.com/sphinx-notes/render/tree/master/src/sphinxnotes/render/ext
150
+ __ https://github.com/sphinx-notes/any
151
+
152
+ Subclassing :py:class:`~sphinxnotes.render.BaseContextDirective`
153
+ ----------------------------------------------------------------
154
+
155
+ Now we have a quick example to help you get Started.
156
+ :external+sphinx:doc:`Create a Sphinx documentation <tutorial/getting-started>`
157
+ with the following ``conf.py``:
158
+
159
+ .. literalinclude:: ../tests/roots/test-base-context-directive-example/conf.py
160
+
161
+ This is the smallest useful extension built on top of ``sphinxnotes.render``:
162
+
163
+ - it defines a mimi-dedicated directive by subclassing
164
+ :py:class:`~sphinxnotes.render.BaseContextDirective`
165
+ - it returns a :py:class:`~sphinxnotes.render.ResolvedContext` object from
166
+ ``current_context()``
167
+ - it returns a :py:class:`~sphinxnotes.render.Template` from
168
+ ``current_template()``
169
+ - the template is rendered in the default
170
+ :py:data:`~sphinxnotes.render.Phase.Parsing` phase
171
+
172
+ Now use the directive in your document:
173
+
174
+ .. example::
175
+ :style: grid
176
+
177
+ .. mimi::
178
+
179
+ Subclassing :py:class:`~sphinxnotes.render.BaseDataDefineDirective`
180
+ -------------------------------------------------------------------
181
+
182
+ ``BaseDataDefineDirective`` is higher level of API than ``BaseContextDirective``.
183
+ You no longer need to implement the ``current_context`` methods; instead,
184
+ implement the :py:meth:`~sphinxnotes.render.BaseDataDefineDirective.current_schema`
185
+ method.
186
+
187
+ Here's an example:
188
+
189
+ .. literalinclude:: ../tests/roots/test-base-data-define-directive-example/conf.py
190
+
191
+ Key differences from ``BaseContextDirective``:
192
+
193
+ - The directive automatically generates :py:class:`~sphinxnotes.render.RawData`
194
+ (from directive's arguments, options, and content, by method
195
+ :py:meth:`~sphinxnotes.render.BaseDataDefineDirective.current_raw_data`).
196
+ - The generated RawData are parsed to :py:class:`~sphinxnotes.render.ParsedData`
197
+ according to the :py:class:`~sphinxnotes.render.Schema` returned from
198
+ :py:meth:`~sphinxnotes.render.BaseDataDefineDirective.current_schema` method.
199
+
200
+ .. tip::
201
+
202
+ Internally, the ``ParsedData`` is returned by ``current_context``, so
203
+ we do not need to implement it.
204
+
205
+ - The the fields of schema are generated from :doc:`dsl` which restricted the
206
+ ``color`` must be an space-separated list, and ``birth`` must be a integer.
207
+ - The ``current_template`` still returns a Jinja template, but it uses more fancy
208
+ syntax.
209
+
210
+ Use the directive in your document:
211
+
212
+ .. example::
213
+ :style: grid
214
+
215
+ .. cat2:: mimi
216
+ :color: black and brown
217
+ :birth: 2025
218
+
219
+ I like fish!
220
+
221
+ Subclassing :py:class:`~sphinxnotes.render.StrictDataDefineDirective`
222
+ ----------------------------------------------------------------------
223
+
224
+ ``StrictDataDefineDirective`` is an even higher-level API built on top of
225
+ ``BaseDataDefineDirective``. It automatically handles ``SphinxDirective``'s members
226
+ from your :py:class:`~sphinxnotes.render.Schema`, so you don't need to manually
227
+ set:
228
+
229
+ - ``required_arguments`` / ``optional_arguments`` - derived from ``Schema.name``
230
+ - ``option_spec`` - derived from ``Schema.attrs``
231
+ - ``has_content`` - derived from ``Schema.content``
232
+
233
+ You no longer need to manually create subclasses, simply pass ``schema`` and
234
+ ``template`` to :py:meth:`~sphinxnotes.render.StrictDataDefineDirective.derive`
235
+ method:
236
+
237
+ .. literalinclude:: ../tests/roots/test-strict-data-define-directive-example/conf.py
238
+
239
+ Use the directive in your document:
240
+
241
+ .. example::
242
+ :style: grid
243
+
244
+ .. cat3:: mimi
245
+ :color: black and brown
246
+ :birth: 2025
247
+
248
+ I like fish!