sphinxnotes-render 1.0b3__tar.gz → 1.0b4__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 (85) hide show
  1. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/.cruft.json +1 -1
  2. {sphinxnotes_render-1.0b3/src/sphinxnotes_render.egg-info → sphinxnotes_render-1.0b4}/PKG-INFO +10 -6
  3. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/README.rst +1 -1
  4. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/api.rst +54 -60
  5. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/conf.py +30 -7
  6. sphinxnotes_render-1.0b4/docs/conf.rst +31 -0
  7. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/dsl.rst +0 -58
  8. sphinxnotes_render-1.0b4/docs/ext.rst +252 -0
  9. sphinxnotes_render-1.0b4/docs/index.rst +181 -0
  10. sphinxnotes_render-1.0b4/docs/tmpl.rst +425 -0
  11. sphinxnotes_render-1.0b4/docs/usage.rst +165 -0
  12. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/pyproject.toml +9 -4
  13. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/__init__.py +16 -22
  14. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/ctxnodes.py +2 -2
  15. sphinxnotes_render-1.0b4/src/sphinxnotes/render/ext/__init__.py +32 -0
  16. sphinxnotes_render-1.0b4/src/sphinxnotes/render/ext/adhoc.py +220 -0
  17. sphinxnotes_render-1.0b4/src/sphinxnotes/render/ext/derive.py +74 -0
  18. sphinxnotes_render-1.0b4/src/sphinxnotes/render/ext/extractx.py +81 -0
  19. sphinxnotes_render-1.0b4/src/sphinxnotes/render/ext/filters.py +53 -0
  20. sphinxnotes_render-1.0b4/src/sphinxnotes/render/extractx.py +208 -0
  21. sphinxnotes_render-1.0b3/src/sphinxnotes/render/template.py → sphinxnotes_render-1.0b4/src/sphinxnotes/render/jinja.py +43 -47
  22. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/markup.py +1 -1
  23. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/meta.py +1 -1
  24. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/pipeline.py +18 -15
  25. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/sources.py +29 -4
  26. sphinxnotes_render-1.0b3/src/sphinxnotes/render/render.py → sphinxnotes_render-1.0b4/src/sphinxnotes/render/template.py +7 -10
  27. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/utils/freestyle.py +1 -1
  28. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4/src/sphinxnotes_render.egg-info}/PKG-INFO +10 -6
  29. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes_render.egg-info/SOURCES.txt +24 -4
  30. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes_render.egg-info/requires.txt +6 -1
  31. sphinxnotes_render-1.0b4/tests/roots/test-base-context-directive-example/conf.py +23 -0
  32. sphinxnotes_render-1.0b4/tests/roots/test-base-context-directive-example/index.rst +4 -0
  33. sphinxnotes_render-1.0b4/tests/roots/test-base-data-define-directive-example/conf.py +42 -0
  34. sphinxnotes_render-1.0b4/tests/roots/test-base-data-define-directive-example/index.rst +14 -0
  35. sphinxnotes_render-1.0b4/tests/roots/test-data-define/conf.py +1 -0
  36. sphinxnotes_render-1.0b4/tests/roots/test-data-define/index.rst +18 -0
  37. sphinxnotes_render-1.0b4/tests/roots/test-derive/conf.py +16 -0
  38. sphinxnotes_render-1.0b4/tests/roots/test-derive/index.rst +8 -0
  39. sphinxnotes_render-1.0b4/tests/roots/test-extra-context/cat.json +7 -0
  40. sphinxnotes_render-1.0b4/tests/roots/test-extra-context/conf.py +25 -0
  41. sphinxnotes_render-1.0b4/tests/roots/test-extra-context/index.rst +7 -0
  42. sphinxnotes_render-1.0b4/tests/roots/test-filter-example/conf.py +22 -0
  43. sphinxnotes_render-1.0b4/tests/roots/test-filter-example/index.rst +6 -0
  44. sphinxnotes_render-1.0b4/tests/roots/test-strict-data-define-directive-example/conf.py +31 -0
  45. sphinxnotes_render-1.0b4/tests/roots/test-strict-data-define-directive-example/index.rst +14 -0
  46. sphinxnotes_render-1.0b4/tests/test_e2e.py +98 -0
  47. sphinxnotes_render-1.0b3/docs/index.rst +0 -82
  48. sphinxnotes_render-1.0b3/docs/tmpl.rst +0 -319
  49. sphinxnotes_render-1.0b3/docs/usage.rst +0 -63
  50. sphinxnotes_render-1.0b3/src/sphinxnotes/render/extractx.py +0 -194
  51. sphinxnotes_render-1.0b3/tests/roots/test-ctxdir-usage/conf.py +0 -15
  52. sphinxnotes_render-1.0b3/tests/roots/test-ctxdir-usage/index.rst +0 -4
  53. sphinxnotes_render-1.0b3/tests/test_smoke.py +0 -28
  54. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/.github/workflows/lint.yml +0 -0
  55. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/.github/workflows/pages.yml +0 -0
  56. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/.github/workflows/pypi.yml +0 -0
  57. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/.github/workflows/release.yml +0 -0
  58. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/.github/workflows/test.yml +0 -0
  59. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/.gitignore +0 -0
  60. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/.pre-commit-config.yaml +0 -0
  61. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/LICENSE +0 -0
  62. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/MANIFEST.in +0 -0
  63. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/Makefile +0 -0
  64. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/Makefile +0 -0
  65. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/_images/.gitkeep +0 -0
  66. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/_static/.gitkeep +0 -0
  67. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/_static/custom.css +0 -0
  68. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/_static/sphinx-notes.png +0 -0
  69. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/changelog.rst +0 -0
  70. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/docs/make.bat +0 -0
  71. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/ruff.toml +0 -0
  72. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/setup.cfg +0 -0
  73. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/ctx.py +0 -0
  74. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/data.py +0 -0
  75. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/py.typed +0 -0
  76. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/utils/__init__.py +0 -0
  77. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes/render/utils/ctxproxy.py +0 -0
  78. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes_render.egg-info/dependency_links.txt +0 -0
  79. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/src/sphinxnotes_render.egg-info/top_level.txt +0 -0
  80. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/tests/__init__.py +0 -0
  81. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/tests/conftest.py +0 -0
  82. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/tests/roots/test-strictdir-card/conf.py +0 -0
  83. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/tests/roots/test-strictdir-card/index.rst +0 -0
  84. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/tests/test_always_pass.py +0 -0
  85. {sphinxnotes_render-1.0b3 → sphinxnotes_render-1.0b4}/tests/test_data.py +0 -0
@@ -8,7 +8,7 @@
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",
11
+ "description": "Define, constrain, and render data in Sphinx documentation",
12
12
  "version": "1.0a0",
13
13
  "github_owner": "sphinx-notes",
14
14
  "github_repo": "data",
@@ -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.0b4
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
+ -----------------
21
18
 
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`.
19
+ .. autoclass:: sphinxnotes.render.BaseContextRole
20
+ :show-inheritance:
21
+ :members: process_pending_node, queue_pending_node, queue_context, current_context, current_template
25
22
 
26
- For a task-oriented explanation of template variables, extra context, and phase
27
- selection, see :doc:`tmpl`.
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
33
+
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
37
+
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
 
@@ -57,7 +70,7 @@ Context refers to the dynamic content of a Jinja template. It can be:
57
70
  :members: resolve
58
71
 
59
72
  ``PendingContext`` Implementations
60
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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,33 @@ 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.
83
-
84
- .. autoclass:: sphinxnotes.render.GlobalExtraContxt
92
+ =============
85
93
 
86
- .. autoclass:: sphinxnotes.render.ParsePhaseExtraContext
87
-
88
- .. autoclass:: sphinxnotes.render.ResolvePhaseExtraContext
89
-
90
- .. autoclass:: sphinxnotes.render.ExtraContextRegistry
91
- :members:
94
+ See :doc:`tmpl` for built-in extra-context names such as ``doc`` and
95
+ ``sphinx``, plus usage examples.
92
96
 
97
+ .. autodecorator:: sphinxnotes.render.extra_context
93
98
 
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
99
+ .. autoclass:: sphinxnotes.render.ParsingPhaseExtraContext
100
+ :members: phase, generate
101
+ :undoc-members:
105
102
 
106
- .. autoclass:: sphinxnotes.render.BaseDataDefineRole
107
- :show-inheritance:
108
- :members: process_pending_node, queue_pending_node, queue_context, current_schema, current_template
103
+ .. autoclass:: sphinxnotes.render.ParsedPhaseExtraContext
104
+ :members: phase, generate
105
+ :undoc-members:
109
106
 
110
- Base Directive Classes
111
- ~~~~~~~~~~~~~~~~~~~~~~
107
+ .. autoclass:: sphinxnotes.render.ResolvingPhaseExtraContext
108
+ :members: phase, generate
109
+ :undoc-members:
112
110
 
113
- .. autoclass:: sphinxnotes.render.BaseContextDirective
114
- :show-inheritance:
115
- :members: process_pending_node, queue_pending_node, queue_context, current_context, current_template
111
+ .. autoclass:: sphinxnotes.render.GlobalExtraContext
112
+ :members: phase, generate
113
+ :undoc-members:
116
114
 
117
- .. autoclass:: sphinxnotes.render.BaseDataDefineDirective
118
- :show-inheritance:
119
- :members: process_pending_node, queue_pending_node, queue_context, current_schema, current_template
115
+ Filters
116
+ =======
120
117
 
121
- .. autoclass:: sphinxnotes.render.StrictDataDefineDirective
122
- :show-inheritance:
123
- :members: derive
118
+ .. autodecorator:: sphinxnotes.render.filter
124
119
 
125
120
  Data, Field and Schema
126
121
  ======================
@@ -161,4 +156,3 @@ or add new extra context) by adding new items to
161
156
  .. autoclass:: sphinxnotes.render.Registry
162
157
 
163
158
  .. autoproperty:: data
164
- .. autoproperty:: extra_context
@@ -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,31 @@
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
+ - ``extra`` (list[str], optional): same as :rst:dir:`data.template:extra`
29
+
30
+ See :ref:`usage-custom-directive` for example.
31
+
@@ -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,252 @@
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 one of the following classes:
73
+ :py:class:`~sphinxnotes.render.ParsingPhaseExtraContext`,
74
+ :py:class:`~sphinxnotes.render.ParsedPhaseExtraContext`,
75
+ :py:class:`~sphinxnotes.render.ResolvingPhaseExtraContext`,
76
+ :py:class:`~sphinxnotes.render.GlobalExtraContext`.
77
+
78
+ .. literalinclude:: ../tests/roots/test-extra-context/conf.py
79
+ :language: python
80
+ :start-after: [literalinclude start]
81
+ :end-before: [literalinclude end]
82
+
83
+ .. dropdown:: :file:`cat.json`
84
+
85
+ .. literalinclude:: ../tests/roots/test-extra-context/cat.json
86
+
87
+ .. example::
88
+ :style: grid
89
+
90
+ .. data.render::
91
+ :extra: cat
92
+
93
+ {{ load_extra('cat').name }}
94
+
95
+ .. _ext-filters:
96
+
97
+ Extending ilters
98
+ =================
99
+
100
+ Template filters are registered by a
101
+ :py:deco:`sphinxnotes.render.filter` function decorator.
102
+
103
+ The decorated function takes a :py:class:`sphinx.environment.BuildEnvironment`
104
+ as argument and returns a filter function.
105
+
106
+ .. note::
107
+
108
+ The decorator is used to **decorate the filter function factory, NOT
109
+ the filter function itself**.
110
+
111
+ .. literalinclude:: ../tests/roots/test-filter-example/conf.py
112
+ :language: python
113
+ :start-after: [literalinclude start]
114
+ :end-before: [literalinclude end]
115
+
116
+ .. example::
117
+ :style: grid
118
+
119
+ .. data.render::
120
+
121
+ {{ "Hello world" | catify }}
122
+
123
+ .. _ext-directives:
124
+ .. _ext-roles:
125
+
126
+ Extending Directives/Roles
127
+ ==========================
128
+
129
+ .. tip::
130
+
131
+ Before reading this documentation, please refer to
132
+ :external+sphinx:doc:`development/tutorials/extending_syntax`.
133
+ See how to extend :py:class:`SphinxDirective` and :py:class:`SphinxRole`.
134
+
135
+ All of the classes listed in :ref:`api-directives` are subclassed from the
136
+ internal ``sphinxnotes.render.Pipeline`` class, which is responsible to generate
137
+ the dedicated :py:class:`node <sphinxnotes.render.pending_node>` that
138
+ carries a :ref:`context` and a :py:class:`~sphinxnotes.render.Template`.
139
+
140
+ At the appropriate :ref:`render-phases`, the node will be rendered into markup
141
+ text, usually reStructuredText. The rendered text is then parsed again by
142
+ Sphinx and inserted into the document.
143
+
144
+ .. seealso::
145
+
146
+ - :doc:`tmpl` for template variables, phases, and extra context
147
+ - :doc:`dsl` for the field description language used by
148
+ :py:class:`~sphinxnotes.render.Field` and
149
+ :py:class:`~sphinxnotes.render.Schema`
150
+ - Implementations of :parsed_literal:`sphinxnotes-render.ext__`
151
+ and :parsed_literal:`sphinxnotes-any__`.
152
+
153
+ __ https://github.com/sphinx-notes/render/tree/master/src/sphinxnotes/render/ext
154
+ __ https://github.com/sphinx-notes/any
155
+
156
+ Subclassing :py:class:`~sphinxnotes.render.BaseContextDirective`
157
+ ----------------------------------------------------------------
158
+
159
+ Now we have a quick example to help you get Started.
160
+ :external+sphinx:doc:`Create a Sphinx documentation <tutorial/getting-started>`
161
+ with the following ``conf.py``:
162
+
163
+ .. literalinclude:: ../tests/roots/test-base-context-directive-example/conf.py
164
+
165
+ This is the smallest useful extension built on top of ``sphinxnotes.render``:
166
+
167
+ - it defines a mimi-dedicated directive by subclassing
168
+ :py:class:`~sphinxnotes.render.BaseContextDirective`
169
+ - it returns a :py:class:`~sphinxnotes.render.ResolvedContext` object from
170
+ ``current_context()``
171
+ - it returns a :py:class:`~sphinxnotes.render.Template` from
172
+ ``current_template()``
173
+ - the template is rendered in the default
174
+ :py:data:`~sphinxnotes.render.Phase.Parsing` phase
175
+
176
+ Now use the directive in your document:
177
+
178
+ .. example::
179
+ :style: grid
180
+
181
+ .. mimi::
182
+
183
+ Subclassing :py:class:`~sphinxnotes.render.BaseDataDefineDirective`
184
+ -------------------------------------------------------------------
185
+
186
+ ``BaseDataDefineDirective`` is higher level of API than ``BaseContextDirective``.
187
+ You no longer need to implement the ``current_context`` methods; instead,
188
+ implement the :py:meth:`~sphinxnotes.render.BaseDataDefineDirective.current_schema`
189
+ method.
190
+
191
+ Here's an example:
192
+
193
+ .. literalinclude:: ../tests/roots/test-base-data-define-directive-example/conf.py
194
+
195
+ Key differences from ``BaseContextDirective``:
196
+
197
+ - The directive automatically generates :py:class:`~sphinxnotes.render.RawData`
198
+ (from directive's arguments, options, and content, by method
199
+ :py:meth:`~sphinxnotes.render.BaseDataDefineDirective.current_raw_data`).
200
+ - The generated RawData are parsed to :py:class:`~sphinxnotes.render.ParsedData`
201
+ according to the :py:class:`~sphinxnotes.render.Schema` returned from
202
+ :py:meth:`~sphinxnotes.render.BaseDataDefineDirective.current_schema` method.
203
+
204
+ .. tip::
205
+
206
+ Internally, the ``ParsedData`` is returned by ``current_context``, so
207
+ we do not need to implement it.
208
+
209
+ - The the fields of schema are generated from :doc:`dsl` which restricted the
210
+ ``color`` must be an space-separated list, and ``birth`` must be a integer.
211
+ - The ``current_template`` still returns a Jinja template, but it uses more fancy
212
+ syntax.
213
+
214
+ Use the directive in your document:
215
+
216
+ .. example::
217
+ :style: grid
218
+
219
+ .. cat2:: mimi
220
+ :color: black and brown
221
+ :birth: 2025
222
+
223
+ I like fish!
224
+
225
+ Subclassing :py:class:`~sphinxnotes.render.StrictDataDefineDirective`
226
+ ----------------------------------------------------------------------
227
+
228
+ ``StrictDataDefineDirective`` is an even higher-level API built on top of
229
+ ``BaseDataDefineDirective``. It automatically handles ``SphinxDirective``'s members
230
+ from your :py:class:`~sphinxnotes.render.Schema`, so you don't need to manually
231
+ set:
232
+
233
+ - ``required_arguments`` / ``optional_arguments`` - derived from ``Schema.name``
234
+ - ``option_spec`` - derived from ``Schema.attrs``
235
+ - ``has_content`` - derived from ``Schema.content``
236
+
237
+ You no longer need to manually create subclasses, simply pass ``schema`` and
238
+ ``template`` to :py:meth:`~sphinxnotes.render.StrictDataDefineDirective.derive`
239
+ method:
240
+
241
+ .. literalinclude:: ../tests/roots/test-strict-data-define-directive-example/conf.py
242
+
243
+ Use the directive in your document:
244
+
245
+ .. example::
246
+ :style: grid
247
+
248
+ .. cat3:: mimi
249
+ :color: black and brown
250
+ :birth: 2025
251
+
252
+ I like fish!