sphinxnotes-render 1.0b1__tar.gz → 1.0b3__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 (60) hide show
  1. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/.cruft.json +2 -2
  2. sphinxnotes_render-1.0b3/.github/workflows/test.yml +25 -0
  3. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/Makefile +5 -1
  4. {sphinxnotes_render-1.0b1/src/sphinxnotes_render.egg-info → sphinxnotes_render-1.0b3}/PKG-INFO +2 -1
  5. sphinxnotes_render-1.0b3/docs/api.rst +164 -0
  6. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/conf.py +22 -4
  7. sphinxnotes_render-1.0b3/docs/dsl.rst +240 -0
  8. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/index.rst +16 -7
  9. sphinxnotes_render-1.0b3/docs/tmpl.rst +319 -0
  10. sphinxnotes_render-1.0b3/docs/usage.rst +63 -0
  11. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/pyproject.toml +1 -0
  12. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/__init__.py +12 -3
  13. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/ctx.py +17 -24
  14. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/ctxnodes.py +11 -4
  15. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/data.py +48 -11
  16. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/extractx.py +21 -11
  17. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/pipeline.py +68 -79
  18. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/render.py +15 -6
  19. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/sources.py +21 -7
  20. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/utils/__init__.py +3 -3
  21. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/utils/ctxproxy.py +4 -0
  22. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/utils/freestyle.py +3 -0
  23. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3/src/sphinxnotes_render.egg-info}/PKG-INFO +2 -1
  24. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes_render.egg-info/SOURCES.txt +11 -1
  25. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes_render.egg-info/requires.txt +1 -0
  26. sphinxnotes_render-1.0b3/tests/conftest.py +9 -0
  27. sphinxnotes_render-1.0b3/tests/roots/test-ctxdir-usage/conf.py +15 -0
  28. sphinxnotes_render-1.0b3/tests/roots/test-ctxdir-usage/index.rst +4 -0
  29. sphinxnotes_render-1.0b3/tests/roots/test-strictdir-card/conf.py +36 -0
  30. sphinxnotes_render-1.0b3/tests/roots/test-strictdir-card/index.rst +8 -0
  31. sphinxnotes_render-1.0b3/tests/test_always_pass.py +9 -0
  32. sphinxnotes_render-1.0b3/tests/test_smoke.py +28 -0
  33. sphinxnotes_render-1.0b1/.github/workflows/test.yml +0 -16
  34. sphinxnotes_render-1.0b1/docs/api.rst +0 -7
  35. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/.github/workflows/lint.yml +0 -0
  36. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/.github/workflows/pages.yml +0 -0
  37. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/.github/workflows/pypi.yml +0 -0
  38. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/.github/workflows/release.yml +0 -0
  39. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/.gitignore +0 -0
  40. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/.pre-commit-config.yaml +0 -0
  41. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/LICENSE +0 -0
  42. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/MANIFEST.in +0 -0
  43. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/README.rst +0 -0
  44. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/Makefile +0 -0
  45. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/_images/.gitkeep +0 -0
  46. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/_static/.gitkeep +0 -0
  47. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/_static/custom.css +0 -0
  48. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/_static/sphinx-notes.png +0 -0
  49. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/changelog.rst +0 -0
  50. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/docs/make.bat +0 -0
  51. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/ruff.toml +0 -0
  52. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/setup.cfg +0 -0
  53. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/markup.py +0 -0
  54. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/meta.py +0 -0
  55. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/py.typed +0 -0
  56. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes/render/template.py +0 -0
  57. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes_render.egg-info/dependency_links.txt +0 -0
  58. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/src/sphinxnotes_render.egg-info/top_level.txt +0 -0
  59. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/tests/__init__.py +0 -0
  60. {sphinxnotes_render-1.0b1 → sphinxnotes_render-1.0b3}/tests/test_data.py +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "template": "https://github.com/sphinx-notes/cookiecutter",
3
- "commit": "634c4022e575bd086ea47f3b42feafe24e14a939",
3
+ "commit": "4c6b17aec1a4b8ddca95c4882c6bed2bc230d595",
4
4
  "checkout": null,
5
5
  "context": {
6
6
  "cookiecutter": {
@@ -20,7 +20,7 @@
20
20
  "sphinx_version": "7.0",
21
21
  "development_status": "3 - Alpha",
22
22
  "_template": "https://github.com/sphinx-notes/cookiecutter",
23
- "_commit": "634c4022e575bd086ea47f3b42feafe24e14a939"
23
+ "_commit": "4c6b17aec1a4b8ddca95c4882c6bed2bc230d595"
24
24
  }
25
25
  },
26
26
  "directory": null
@@ -0,0 +1,25 @@
1
+ name: Test
2
+ on:
3
+ push:
4
+ pull_request:
5
+ schedule:
6
+ - cron: '0 7 * * 6'
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v2
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version-file: 'pyproject.toml'
15
+ - run: python3 -m pip install .[test]
16
+ - run: make test
17
+ doctest:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version-file: 'pyproject.toml'
24
+ - run: python3 -m pip install .[docs]
25
+ - run: make doctest
@@ -27,7 +27,11 @@ fmt:
27
27
 
28
28
  .PHONY: test
29
29
  test:
30
- $(PY) -m unittest discover -s tests -v
30
+ $(PY) -m pytest tests/ -v
31
+
32
+ .PHONY: doctest
33
+ doctest:
34
+ $(MAKE) doctest -C docs/
31
35
 
32
36
  ################################################################################
33
37
  # Distribution Package
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sphinxnotes-render
3
- Version: 1.0b1
3
+ Version: 1.0b3
4
4
  Summary: A framework to define, constrain, and render data in Sphinx documentation
5
5
  Author: Shengyu Zhang
6
6
  Maintainer: Shengyu Zhang
@@ -42,6 +42,7 @@ Requires-Dist: sphinxext-opengraph; extra == "docs"
42
42
  Requires-Dist: sphinx-last-updated-by-git; extra == "docs"
43
43
  Requires-Dist: sphinxnotes-project; extra == "docs"
44
44
  Requires-Dist: sphinxnotes-comboroles; extra == "docs"
45
+ Requires-Dist: sphinxnotes-data; extra == "docs"
45
46
  Dynamic: license-file
46
47
 
47
48
  .. This file is generated from sphinx-notes/cookiecutter.
@@ -0,0 +1,164 @@
1
+ ==============
2
+ API References
3
+ ==============
4
+
5
+ The Render Pipeline
6
+ ===================
7
+
8
+ The pipeline defines how nodes carrying data are generated and when they are
9
+ rendered as part of the document.
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:
15
+
16
+ - :ref:`context`, the dynamic content of a Jinja template
17
+
18
+ - :py:class:`~sphinxnotes.render.Template`,
19
+ the Jinja template for rendering context to markup text
20
+ (reStructuredText or Markdown)
21
+
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`.
25
+
26
+ For a task-oriented explanation of template variables, extra context, and phase
27
+ selection, see :doc:`tmpl`.
28
+
29
+ Node
30
+ -----
31
+
32
+ .. autoclass:: sphinxnotes.render.pending_node
33
+
34
+ .. _context:
35
+
36
+ Context
37
+ -------
38
+
39
+ Context refers to the dynamic content of a Jinja template. It can be:
40
+
41
+ :py:class:`~sphinxnotes.render.ResolvedContext`:
42
+ Our dedicated data type (:py:class:`sphinxnotes.render.ParsedData`), or any
43
+ Python ``dict``.
44
+
45
+ :py:class:`~sphinxnotes.render.PendingContext`:
46
+ Context that is not yet available. For example, it may contain
47
+ :py:class:`unparsed data <sphinxnotes.render.RawData>`,
48
+ remote data, and more.
49
+
50
+ :py:class:`PendingContext` can be resolved to
51
+ :py:class:`~sphinxnotes.render.ResolvedContext` by calling
52
+ :py:meth:`~sphinxnotes.render.PendingContext.resolve`.
53
+
54
+ .. autotype:: sphinxnotes.render.ResolvedContext
55
+
56
+ .. autoclass:: sphinxnotes.render.PendingContext
57
+ :members: resolve
58
+
59
+ ``PendingContext`` Implementations
60
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61
+
62
+ .. autoclass:: sphinxnotes.render.UnparsedData
63
+ :show-inheritance:
64
+
65
+ .. _extractx:
66
+
67
+ Template
68
+ --------
69
+
70
+ See :doc:`tmpl` for the higher-level guide.
71
+
72
+ .. autoclass:: sphinxnotes.render.Template
73
+ :members:
74
+
75
+ .. autoclass:: sphinxnotes.render.Phase
76
+ :members:
77
+
78
+ 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
85
+
86
+ .. autoclass:: sphinxnotes.render.ParsePhaseExtraContext
87
+
88
+ .. autoclass:: sphinxnotes.render.ResolvePhaseExtraContext
89
+
90
+ .. autoclass:: sphinxnotes.render.ExtraContextRegistry
91
+ :members:
92
+
93
+
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
124
+
125
+ Data, Field and Schema
126
+ ======================
127
+
128
+ .. autotype:: sphinxnotes.render.PlainValue
129
+
130
+ .. autotype:: sphinxnotes.render.Value
131
+
132
+ .. autoclass:: sphinxnotes.render.RawData
133
+ :members: name, attrs, content
134
+ :undoc-members:
135
+
136
+ .. autoclass:: sphinxnotes.render.ParsedData
137
+ :members: name, attrs, content
138
+ :undoc-members:
139
+
140
+ .. autoclass:: sphinxnotes.render.Field
141
+ :members: parse
142
+
143
+ .. autoclass:: sphinxnotes.render.Schema
144
+ :members: name, attrs, content
145
+ :undoc-members:
146
+
147
+ .. autoclass:: sphinxnotes.render.data.Registry
148
+ :members:
149
+
150
+ .. autotype:: sphinxnotes.render.data.ByOptionStore
151
+
152
+ Registry
153
+ ========
154
+
155
+ Developers can extend this extension (for example, to support more data types
156
+ or add new extra context) by adding new items to
157
+ :py:class:`sphinxnotes.render.REGISTRY`.
158
+
159
+ .. autodata:: sphinxnotes.render.REGISTRY
160
+
161
+ .. autoclass:: sphinxnotes.render.Registry
162
+
163
+ .. autoproperty:: data
164
+ .. autoproperty:: extra_context
@@ -23,6 +23,8 @@ version = release = '1.0a0'
23
23
  # ones.
24
24
  extensions = [
25
25
  'sphinx.ext.githubpages',
26
+ 'sphinx.ext.doctest',
27
+ 'sphinx.ext.viewcode',
26
28
  'sphinx_design',
27
29
  'sphinx_copybutton',
28
30
  'sphinx_last_updated_by_git',
@@ -117,10 +119,26 @@ primary_domain = 'any'
117
119
  # documentation root, use os.path.abspath to make it absolute, like shown here.
118
120
  import os
119
121
  import sys
120
- sys.path.insert(0, os.path.abspath('../src/sphinxnotes'))
121
- extensions.append('render')
122
+ sys.path.insert(0, os.path.abspath('../src/'))
123
+ extensions.append('sphinxnotes.render')
124
+
125
+ extensions.append('sphinxnotes.data')
122
126
 
123
127
  # CUSTOM CONFIGURATION
124
128
 
125
- _ = extensions.pop() # no need to load extension
126
- primary_domain = 'py'
129
+ autodoc_default_options = {
130
+ 'member-order': 'bysource',
131
+ }
132
+
133
+ intersphinx_mapping['python'] = ('https://docs.python.org/3', None)
134
+ intersphinx_mapping['sphinx'] = ('https://www.sphinx-doc.org/en/master', None)
135
+ intersphinx_mapping['data'] = ('https://sphinx.silverrainz.me/data', None)
136
+
137
+ ctxdir_usage_example_path = os.path.abspath('../tests/roots/test-ctxdir-usage')
138
+
139
+ def setup(app):
140
+ app.add_object_type('event', 'event') # for intersphinx
141
+
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)
@@ -0,0 +1,240 @@
1
+ ==========================
2
+ Field Description Language
3
+ ==========================
4
+
5
+ .. default-domain:: py
6
+ .. highlight:: python
7
+ .. role:: py(code)
8
+ :language: Python
9
+
10
+
11
+ The Field Description Language is a Domain Specific Language (DSL) that is used to
12
+ define the type and structure of field values. An FDL declaration consists of
13
+ one or more :term:`modifier` entries separated by commas (``,``).
14
+
15
+ Syntax
16
+ ======
17
+
18
+ .. productionlist::
19
+ dsl : modifier ("," modifier)*
20
+ modifier : type_modifier | form_modifier | flag | by_option
21
+
22
+ .. glossary::
23
+
24
+ Modifier
25
+ There are four categories of modifiers:
26
+
27
+ Type modifier
28
+ Specifies the element type (scalar value)
29
+
30
+ Form modifier
31
+ Specifies a container type with element type
32
+
33
+ Flag
34
+ A boolean flag (either on or off)
35
+
36
+ By-Option
37
+ A key-value option
38
+
39
+ Python API
40
+ ==========
41
+
42
+ Users can create a :class:`sphinxnotes.render.Field` from FDL and use it to parse
43
+ strings into :type:`sphinxnotes.render.Value`:
44
+
45
+ >>> from sphinxnotes.render import Field
46
+ >>> Field.from_dsl('list of int').parse('1,2,3')
47
+ [1, 2, 3]
48
+
49
+
50
+ Type
51
+ ====
52
+
53
+ A type modifier specifies the data type of a single (scalar) value.
54
+
55
+ .. list-table::
56
+ :header-rows: 1
57
+
58
+ * - Modifier
59
+ - Type
60
+ - Aliases
61
+ - Description
62
+ * - ``bool``
63
+ - :py:class:`bool`
64
+ - ``flag``
65
+ - Boolean: ``true``/``yes``/``1``/``on``/``y`` → True, ``false``/``no``/``0``/``off``/``n`` → False
66
+ * - ``int``
67
+ - :py:class:`int`
68
+ - ``integer``
69
+ - Integer
70
+ * - ``float``
71
+ - :py:class:`float`
72
+ - ``number``, ``num``
73
+ - Floating-point number
74
+ * - ``str``
75
+ - :py:class:`str`
76
+ - ``string``
77
+ - String. If it looks like a Python literal (e.g., ``"hello"``), it is parsed accordingly.
78
+
79
+ Examples:
80
+
81
+ ======= ========= =============
82
+ DSL Input Result
83
+ ------- --------- -------------
84
+ ``int`` ``42`` :py:`42`
85
+ ``str`` ``hello`` :py:`"hello"`
86
+ ======= ========= =============
87
+
88
+ Form
89
+ ====
90
+
91
+ A form modifier specifies a container type with its element type, using
92
+ ``<form> of <type>`` syntax.
93
+
94
+ .. list-table::
95
+ :header-rows: 1
96
+
97
+ * - Modifier
98
+ - Container
99
+ - Separator
100
+ - Description
101
+ * - ``list of <type>``
102
+ - :py:class:`list`
103
+ - ``,``
104
+ - Comma-separated list
105
+ * - ``lines of <type>``
106
+ - :py:class:`list`
107
+ - ``\n``
108
+ - Newline-separated list
109
+ * - ``words of <type>``
110
+ - :py:class:`list`
111
+ - whitespace
112
+ - Whitespace-separated list
113
+ * - ``set of <type>``
114
+ - :py:class:`set`
115
+ - whitespace
116
+ - Whitespace-separated set (unique values)
117
+
118
+ Examples:
119
+
120
+ ================ =========== =====================
121
+ DSL Input Result
122
+ ---------------- ----------- ---------------------
123
+ ``list of int`` ``1, 2, 3`` :py:`[1, 2, 3]`
124
+ ``lines of str`` ``a\nb`` :py:`['a', 'b']`
125
+ ``words of str`` ``a b c`` :py:`['a', 'b', 'c']`
126
+ ================ =========== =====================
127
+
128
+ Flag
129
+ ====
130
+
131
+ A flag is a boolean modifier that can be either on or off.
132
+
133
+ Every flag is available as an attribute of the :class:`Field`.
134
+ For example, we have a "required" flag registered, and we can access ``Field.required``
135
+ attribute.
136
+
137
+ .. list-table::
138
+ :header-rows: 1
139
+
140
+ * - Modifier
141
+ - Aliases
142
+ - Default
143
+ - Description
144
+ * - ``required``
145
+ - ``require``, ``req``
146
+ - ``False``
147
+ - Field must have a value
148
+
149
+ Examples::
150
+
151
+ int, required
152
+
153
+ By-Option
154
+ =========
155
+
156
+ A by-option is a key-value modifier with the syntax ``<name> by <value>``.
157
+
158
+ Every by-option is available as an attribute of the :class:`Field`.
159
+ For example, we have a "sep" by-option registered, and we can get the separator
160
+ from ``Field.sep`` attribute.
161
+
162
+ Built-in by-options:
163
+
164
+ .. list-table::
165
+ :header-rows: 1
166
+
167
+ * - Modifier
168
+ - Type
169
+ - Description
170
+ * - ``sep by '<sep>'``
171
+ - :py:class:`str`
172
+ - Custom separator for value form. Implies ``list`` if no form specified.
173
+
174
+ Examples:
175
+
176
+ =================== ========= ================
177
+ DSL Input Result
178
+ ------------------- --------- ----------------
179
+ ``str, sep by '|'`` ``a|b`` :py:`['a', 'b']`
180
+ ``int, sep by ':'`` ``1:2:3`` :py:`[1, 2, 3]`
181
+ =================== ========= ================
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']
@@ -30,11 +30,6 @@ Introduction
30
30
 
31
31
  A framework to define, constrain, and render data in Sphinx documentation.
32
32
 
33
- .. seealso:: `sphinxnotes-any`__ and `sphinxnotes-data`__
34
-
35
- __ https://sphinx.silverrainz.me/any/
36
- __ https://sphinx.silverrainz.me/data/
37
-
38
33
  .. INTRODUCTION END
39
34
 
40
35
  Getting Started
@@ -42,8 +37,18 @@ Getting Started
42
37
 
43
38
  .. ADDITIONAL CONTENT START
44
39
 
45
- This extension is not intended to be used directly by Sphinx user.
46
- It is for Sphinx extension developer, please refer to :doc:`api`.
40
+ .. note::
41
+
42
+ This extension is **aimed at advanced Sphinx users or extension developers**.
43
+
44
+ If you are new to Sphinx, you may instersting with
45
+ :parsed_literal:`sphinxnotes.data__` or :parsed_literal:`sphinxnotes.any__`.
46
+
47
+ __ https://sphinx.silverrainz.me/data
48
+ __ https://sphinx.silverrainz.me/any
49
+
50
+ We cannot get you started with this short section; please refer to the
51
+ :doc:`usage` for more detailed information.
47
52
 
48
53
  .. ADDITIONAL CONTENT END
49
54
 
@@ -52,7 +57,11 @@ Contents
52
57
 
53
58
  .. toctree::
54
59
  :caption: Contents
60
+ :maxdepth: 2
55
61
 
62
+ usage
63
+ tmpl
64
+ dsl
56
65
  api
57
66
  changelog
58
67