Skip to content

Commit 3374383

Browse files
authored
✨ NEW: Create custom directives (#194)
You can use the `sd_custom_directives` configuration option in your `conf.py` to add custom directives, with default option values: ```python sd_custom_directives = { "dropdown-syntax": { "inherit": "dropdown", "argument": "Syntax", "options": { "color": "primary", "icon": "code", }, } } ``` The key is the new directive name to add, and the value is a dictionary with the following keys: - `inherit`: The directive to inherit from (e.g. `dropdown`) - `argument`: The default argument (optional, only for directives that take a single argument) - `options`: A dictionary of default options for the directive (optional)
1 parent af64472 commit 3374383

20 files changed

+267
-120
lines changed

docs/additional.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ normally positioned just below the title of the article (shown below with non-st
1919
:class-container: sd-p-2 sd-outline-muted sd-rounded-1
2020
```
2121

22-
`````{dropdown} Syntax
23-
:icon: code
24-
:color: primary
22+
`````{dropdown-syntax}
2523
2624
````{tab-set-code}
2725
```{literalinclude} ./snippets/myst/article-info.txt

docs/badges_buttons.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ Badges are available in each semantic color, with filled and outline variants:
1717
- {bdg-light}`light`, {bdg-light-line}`light-line`
1818
- {bdg-dark}`dark`, {bdg-dark-line}`dark-line`
1919

20-
`````{dropdown} Syntax
21-
:icon: code
22-
:color: primary
20+
`````{dropdown-syntax}
2321
2422
````{tab-set-code}
2523
```{literalinclude} ./snippets/myst/badge-basic.txt
@@ -40,9 +38,7 @@ The syntax is the same as for the `ref` role.
4038

4139
{bdg-ref-primary}`badges`
4240

43-
`````{dropdown} Syntax
44-
:icon: code
45-
:color: primary
41+
`````{dropdown-syntax}
4642
4743
````{tab-set-code}
4844
```{literalinclude} ./snippets/myst/badge-link.txt
@@ -94,9 +90,7 @@ Button text
9490
Reference Button text
9591
```
9692

97-
`````{dropdown} Syntax
98-
:icon: code
99-
:color: primary
93+
`````{dropdown-syntax}
10094
10195
````{tab-set-code}
10296
```{literalinclude} ./snippets/myst/button-link.txt

docs/cards.md

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ Card content
1313

1414
See the [Material Design](https://material.io/components/cards) and [Bootstrap card](https://getbootstrap.com/docs/5.0/layout/grid/) descriptions for further details.
1515

16-
`````{dropdown} Syntax
17-
:icon: code
18-
:color: primary
16+
`````{dropdown-syntax}
1917
2018
````{tab-set-code}
2119
```{literalinclude} ./snippets/myst/card-basic.txt
@@ -38,9 +36,7 @@ Card content
3836
Footer
3937
:::
4038

41-
`````{dropdown} Syntax
42-
:icon: code
43-
:color: primary
39+
`````{dropdown-syntax}
4440
4541
````{tab-set-code}
4642
```{literalinclude} ./snippets/myst/card-head-foot.txt
@@ -115,9 +111,7 @@ Footer
115111

116112
:::::
117113

118-
`````{dropdown} Syntax
119-
:icon: code
120-
:color: primary
114+
`````{dropdown-syntax}
121115
122116
````{tab-set-code}
123117
```{literalinclude} ./snippets/myst/card-images.txt
@@ -151,9 +145,7 @@ The entire card can be clicked to navigate to <https://example.com>.
151145
The entire card can be clicked to navigate to the `cards-clickable` reference target.
152146
:::
153147

154-
`````{dropdown} Syntax
155-
:icon: code
156-
:color: primary
148+
`````{dropdown-syntax}
157149
158150
````{tab-set-code}
159151
```{literalinclude} ./snippets/myst/card-link.txt
@@ -223,9 +215,7 @@ content
223215
:::
224216
::::
225217

226-
`````{dropdown} Syntax
227-
:icon: code
228-
:color: primary
218+
`````{dropdown-syntax}
229219
230220
````{tab-set-code}
231221
```{literalinclude} ./snippets/myst/card-carousel.txt

docs/conf.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010

1111
suppress_warnings = ["design.fa-build"]
1212
sd_fontawesome_latex = True
13+
sd_custom_directives = {
14+
"dropdown-syntax": {
15+
"inherit": "dropdown",
16+
"argument": "Syntax",
17+
"options": {
18+
"color": "primary",
19+
"icon": "code",
20+
},
21+
}
22+
}
1323

1424
html_theme = os.environ.get("SPHINX_THEME", "alabaster")
1525
html_title = f"Sphinx Design ({html_theme.replace('_', '-')})"

docs/css_classes.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ All CSS classes that are part of sphinx-design are prefixed with `sd-`.
99
Some CSS styled text
1010
:::
1111

12-
`````{dropdown} Syntax
13-
:icon: code
14-
:color: primary
12+
`````{dropdown-syntax}
1513
1614
````{tab-set-code}
1715
```{literalinclude} ./snippets/myst/div-basic.txt

docs/dropdowns.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ Dropdown content
2020
Dropdown content
2121
:::
2222

23-
`````{dropdown} Syntax
24-
:icon: code
25-
:color: primary
23+
`````{dropdown-syntax}
2624
2725
````{tab-set-code}
2826
```{literalinclude} ./snippets/myst/dropdown-basic.txt

docs/get_started.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,29 @@ sd_hide_title: true
4343
:::
4444
::::
4545

46+
### Creating custom directives
47+
48+
You can use the `sd_custom_directives` configuration option in your `conf.py` to add custom directives, with default option values:
49+
50+
```python
51+
sd_custom_directives = {
52+
"dropdown-syntax": {
53+
"inherit": "dropdown",
54+
"argument": "Syntax",
55+
"options": {
56+
"color": "primary",
57+
"icon": "code",
58+
},
59+
}
60+
}
61+
```
62+
63+
The key is the new directive name to add, and the value is a dictionary with the following keys:
64+
65+
- `inherit`: The directive to inherit from (e.g. `dropdown`)
66+
- `argument`: The default argument (optional, only for directives that take a single argument)
67+
- `options`: A dictionary of default options for the directive (optional)
68+
4669
## Supported browsers
4770

4871
- Chrome >= 60

docs/grids.md

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ D
2929
:::
3030
::::
3131

32-
`````{dropdown} Syntax
33-
:icon: code
34-
:color: primary
32+
`````{dropdown-syntax}
3533
3634
````{tab-set-code}
3735
```{literalinclude} ./snippets/myst/grid-basic.txt
@@ -80,9 +78,7 @@ B
8078
:::
8179
::::
8280

83-
`````{dropdown} Syntax
84-
:icon: code
85-
:color: primary
81+
`````{dropdown-syntax}
8682
8783
````{tab-set-code}
8884
```{literalinclude} ./snippets/myst/grid-card.txt
@@ -121,9 +117,7 @@ B
121117
:::
122118
::::
123119

124-
`````{dropdown} Syntax
125-
:icon: code
126-
:color: primary
120+
`````{dropdown-syntax}
127121
128122
````{tab-set-code}
129123
```{literalinclude} ./snippets/myst/grid-gutter.txt
@@ -160,9 +154,7 @@ C
160154
:::
161155
::::
162156

163-
`````{dropdown} Syntax
164-
:icon: code
165-
:color: primary
157+
`````{dropdown-syntax}
166158
167159
````{tab-set-code}
168160
```{literalinclude} ./snippets/myst/grid-card-columns.txt
@@ -254,9 +246,7 @@ Content
254246

255247
::::::
256248

257-
`````{dropdown} Syntax
258-
:icon: code
259-
:color: primary
249+
`````{dropdown-syntax}
260250
261251
````{tab-set-code}
262252
```{literalinclude} ./snippets/myst/grid-nested.txt

docs/tabs.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ Content 2
1717

1818
::::
1919

20-
`````{dropdown} Syntax
21-
:icon: code
22-
:color: primary
20+
`````{dropdown-syntax}
2321
2422
````{tab-set-code}
2523
```{literalinclude} ./snippets/myst/tab-basic.txt
@@ -70,9 +68,7 @@ Content 2
7068

7169
::::
7270

73-
`````{dropdown} Syntax
74-
:icon: code
75-
:color: primary
71+
`````{dropdown-syntax}
7672
7773
````{tab-set-code}
7874
```{literalinclude} ./snippets/myst/tab-sync.txt

sphinx_design/article_info.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
from docutils import nodes
44
from docutils.parsers.rst import directives
55
from sphinx.application import Sphinx
6-
from sphinx.util.docutils import SphinxDirective
76

87
from .icons import get_octicon
9-
from .shared import SEMANTIC_COLORS, create_component, make_choice
8+
from .shared import SEMANTIC_COLORS, SdDirective, create_component, make_choice
109

1110

1211
def setup_article_info(app: Sphinx):
1312
"""Setup the article information components."""
1413
app.add_directive("article-info", ArticleInfoDirective)
1514

1615

17-
class ArticleInfoDirective(SphinxDirective):
16+
class ArticleInfoDirective(SdDirective):
1817
""" """
1918

2019
has_content = False
@@ -48,8 +47,7 @@ def _parse_text(
4847
output = [para]
4948
return output
5049

51-
def run(self) -> list[nodes.Node]: # noqa: PLR0915
52-
"""Run the directive."""
50+
def run_with_defaults(self) -> list[nodes.Node]: # noqa: PLR0915
5351
parse_fields = True # parse field text
5452

5553
top_grid = create_component(

sphinx_design/badges_buttons.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
from docutils.parsers.rst import directives
55
from sphinx import addnodes
66
from sphinx.application import Sphinx
7-
from sphinx.util.docutils import ReferenceRole, SphinxDirective, SphinxRole
7+
from sphinx.util.docutils import ReferenceRole, SphinxRole
88

9-
from sphinx_design.shared import SEMANTIC_COLORS, make_choice, text_align
9+
from sphinx_design.shared import SEMANTIC_COLORS, SdDirective, make_choice, text_align
1010

1111
ROLE_NAME_BADGE_PREFIX = "bdg"
1212
ROLE_NAME_LINK_PREFIX = "bdg-link"
@@ -127,7 +127,7 @@ def run(self) -> tuple[list[nodes.Node], list[nodes.system_message]]:
127127
return [node], []
128128

129129

130-
class _ButtonDirective(SphinxDirective):
130+
class _ButtonDirective(SdDirective):
131131
"""A base button directive."""
132132

133133
required_arguments = 1
@@ -155,8 +155,7 @@ def create_ref_node(
155155
"""Create the reference node."""
156156
raise NotImplementedError
157157

158-
def run(self) -> list[nodes.Node]:
159-
"""Run the directive."""
158+
def run_with_defaults(self) -> list[nodes.Node]:
160159
rawtext = self.arguments[0]
161160
target = directives.uri(rawtext)
162161
classes = ["sd-sphinx-override", "sd-btn", "sd-text-wrap"]

sphinx_design/cards.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from .shared import (
1414
WARNING_TYPE,
1515
PassthroughTextElement,
16+
SdDirective,
1617
create_component,
1718
is_component,
1819
make_choice,
@@ -45,7 +46,7 @@ class CardContent(NamedTuple):
4546
footer: Optional[tuple[int, StringList]] = None
4647

4748

48-
class CardDirective(SphinxDirective):
49+
class CardDirective(SdDirective):
4950
"""A card component."""
5051

5152
has_content = True
@@ -73,7 +74,7 @@ class CardDirective(SphinxDirective):
7374
"class-img-bottom": directives.class_option,
7475
}
7576

76-
def run(self) -> list[nodes.Node]:
77+
def run_with_defaults(self) -> list[nodes.Node]:
7778
return [self.create_card(self, self.arguments, self.options)]
7879

7980
@classmethod
@@ -256,7 +257,7 @@ def add_card_child_classes(node):
256257
# ]
257258

258259

259-
class CardCarouselDirective(SphinxDirective):
260+
class CardCarouselDirective(SdDirective):
260261
"""A component, which is a container for cards in a single scrollable row."""
261262

262263
has_content = True
@@ -266,8 +267,7 @@ class CardCarouselDirective(SphinxDirective):
266267
"class": directives.class_option,
267268
}
268269

269-
def run(self) -> list[nodes.Node]:
270-
"""Run the directive."""
270+
def run_with_defaults(self) -> list[nodes.Node]:
271271
self.assert_has_content()
272272
try:
273273
cols = make_choice([str(i) for i in range(1, 13)])(

sphinx_design/dropdown.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
from docutils.parsers.rst import directives
55
from sphinx.application import Sphinx
66
from sphinx.transforms.post_transforms import SphinxPostTransform
7-
from sphinx.util.docutils import SphinxDirective
87

98
from sphinx_design.shared import (
109
SEMANTIC_COLORS,
10+
SdDirective,
1111
create_component,
1212
is_component,
1313
make_choice,
@@ -52,7 +52,7 @@ def depart_dropdown_title(self, node):
5252
self.body.append("</summary>")
5353

5454

55-
class DropdownDirective(SphinxDirective):
55+
class DropdownDirective(SdDirective):
5656
"""A directive to generate a collapsible container.
5757
5858
Note: This directive generates a single container,
@@ -87,8 +87,7 @@ class DropdownDirective(SphinxDirective):
8787
"class-body": directives.class_option,
8888
}
8989

90-
def run(self):
91-
"""Run the directive"""
90+
def run_with_defaults(self) -> list[nodes.Node]:
9291
# default classes
9392
classes = {
9493
"container_classes": self.options.get("margin", ["sd-mb-3"])
@@ -149,7 +148,7 @@ class DropdownHtmlTransform(SphinxPostTransform):
149148
default_priority = 199
150149
formats = ("html",)
151150

152-
def run(self):
151+
def run(self) -> None:
153152
"""Run the transform"""
154153
document: nodes.document = self.document
155154
for node in findall(document)(lambda node: is_component(node, "dropdown")):

0 commit comments

Comments
 (0)