Skip to content

Commit 7f4ba9a

Browse files
SilverRainZMiniMax-M2.5opencode
committed
docs: Add DSL documentation
Co-authored-by: MiniMax-M2.5 <minimax-cn-coding-plan@minimax.io> Co-authored-by: opencode <opencode@anomaly.co>
1 parent 04ae980 commit 7f4ba9a

3 files changed

Lines changed: 212 additions & 0 deletions

File tree

docs/api.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,15 @@ API Reference
55
.. note:: WIP
66

77
.. automodule:: sphinxnotes.render.pipeline
8+
9+
.. autoclass:: sphinxnotes.render.Registry
10+
11+
.. autoproperty:: data
12+
.. autoproperty:: extra_context
13+
14+
.. autoclass:: sphinxnotes.render.data.Registry
15+
16+
.. automethod:: add_type
17+
.. automethod:: add_form
18+
.. automethod:: add_flag
19+
.. automethod:: add_by_option

docs/dsl.rst

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
=====================
2+
Field Declaration DSL
3+
=====================
4+
5+
.. default-domain:: py
6+
.. highlight:: python
7+
8+
The Field Declaration DSL is a Domain Specific Language (DSL) that used to
9+
define the type and structure of field values. A DSL declaration consists of
10+
one or more **modifiers** separated by commas (``,``).
11+
12+
Syntax
13+
======
14+
15+
.. productionlist::
16+
dsl : modifier ("," modifier)*
17+
modifier : type_modifier | container_modifier | flag | by_option
18+
19+
There are four categories of modifiers:
20+
21+
:Type: Specifies the element type (scalar value)
22+
:Form: Specifies a container type with element type
23+
:Flag: A boolean option (either on or off)
24+
:By-Option: A key-value option
25+
26+
Type
27+
====
28+
29+
A type modifier specifies the data type of a single (scalar) value.
30+
31+
.. list-table::
32+
:header-rows: 1
33+
34+
* - Modifier
35+
- Type
36+
- Aliases
37+
- Description
38+
* - ``bool``
39+
- :py:class:`bool`
40+
- ``flag``
41+
- Boolean: ``true``/``yes``/``1``/``on``/``y`` → True, ``false``/``no``/``0``/``off``/``n`` → False
42+
* - ``int``
43+
- :py:class:`int`
44+
- ``integer``
45+
- Integer
46+
* - ``float``
47+
- :py:class:`float`
48+
- ``number``, ``num``
49+
- Floating-point number
50+
* - ``str``
51+
- :py:class:`str`
52+
- ``string``
53+
- String. If looks like a Python literal (e.g., ``"hello"``), it's parsed accordingly.
54+
55+
Examples::
56+
57+
int -> "42" becomes 42
58+
str -> "hello" becomes "hello"
59+
60+
Form
61+
====
62+
63+
A form modifier specifies a container type with its element type, using
64+
``<form> of <type>`` syntax.
65+
66+
.. list-table::
67+
:header-rows: 1
68+
69+
* - Modifier
70+
- Container
71+
- Separator
72+
- Description
73+
* - ``list of <type>``
74+
- :py:class:`list`
75+
- ``,``
76+
- Comma-separated list
77+
* - ``lines of <type>``
78+
- :py:class:`list`
79+
- ``\n``
80+
- Newline-separated list
81+
* - ``words of <type>``
82+
- :py:class:`list`
83+
- whitespace
84+
- Whitespace-separated list
85+
* - ``set of <type>``
86+
- :py:class:`set`
87+
- whitespace
88+
- Whitespace-separated set (unique values)
89+
90+
Examples::
91+
92+
list of int -> "1, 2, 3" becomes [1, 2, 3]
93+
lines of str -> "a\nb" becomes ['a', 'b']
94+
words of str -> "a b c" becomes ['a', 'b', 'c']
95+
96+
Flag
97+
====
98+
99+
A flag is a boolean modifier that can be either on or off.
100+
101+
.. list-table::
102+
:header-rows: 1
103+
104+
* - Modifier
105+
- Aliases
106+
- Default
107+
- Description
108+
* - ``required``
109+
- ``require``, ``req``
110+
- ``False``
111+
- Field must have a value
112+
113+
Examples::
114+
115+
int, required
116+
117+
By-Option
118+
=========
119+
120+
A by-option is a key-value modifier with the syntax ``<name> by <value>``.
121+
122+
Built-in by-options:
123+
124+
.. list-table::
125+
:header-rows: 1
126+
127+
* - Modifier
128+
- Type
129+
- Description
130+
* - ``sep by '<sep>'``
131+
- :py:class:`str`
132+
- Custom separator for container values. Implies list if no container specified.
133+
134+
Examples::
135+
136+
list sep by '|'
137+
int sep by ':' -> "1:2:3" becomes [1, 2, 3]
138+
139+
Extending the DSL
140+
=================
141+
142+
You can extend the DSL by registering custom types, flags, and by-options
143+
through the :attr:`sphinxnotes.render.Registry.data` attribute of
144+
:class:`sphinxnotes.render.Registry`.
145+
146+
Adding Custom Types
147+
-------------------
148+
149+
Use :meth:`sphinxnotes.render.Registry.data.add_type` to add a new type:
150+
151+
.. code-block:: python
152+
153+
from sphinxnotes.render import Registry
154+
155+
def parse_color(v: str):
156+
return tuple(int(x) for x in v.split(','))
157+
158+
def color_to_str(v):
159+
return ','.join(str(x) for x in v)
160+
161+
Registry.data.add_type('color', tuple, parse_color, color_to_str)
162+
163+
Usage::
164+
165+
color -> "255,0,0" becomes (255, 0, 0)
166+
167+
Adding Custom Flags
168+
-------------------
169+
170+
Use :attr:`sphinxnotes.render.Registry.data` to add a new type:
171+
172+
.. code-block:: python
173+
174+
from sphinxnotes.render import Registry
175+
176+
Registry.data.add_flag('unique', default=False)
177+
178+
Usage::
179+
180+
int, unique
181+
182+
Adding Custom By-Options
183+
------------------------
184+
185+
Use :meth:`sphinxnotes.render.Registry.data`:
186+
187+
.. code-block:: python
188+
189+
from sphinxnotes.render import Registry
190+
191+
Registry.data.add_by_option('group', str)
192+
193+
# For options that can be specified multiple times:
194+
Registry.data.add_by_option('index', str, store='append')
195+
196+
Usage::
197+
198+
int, group by foo
199+
int, index by year, index by month

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Contents
5353
.. toctree::
5454
:caption: Contents
5555

56+
dsl
5657
api
5758
changelog
5859

0 commit comments

Comments
 (0)