Skip to content

Commit

Permalink
✨ NEW: Create custom directives (#194)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
chrisjsewell authored May 22, 2024
1 parent af64472 commit 3374383
Show file tree
Hide file tree
Showing 20 changed files with 267 additions and 120 deletions.
4 changes: 1 addition & 3 deletions docs/additional.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ normally positioned just below the title of the article (shown below with non-st
:class-container: sd-p-2 sd-outline-muted sd-rounded-1
```

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/article-info.txt
Expand Down
12 changes: 3 additions & 9 deletions docs/badges_buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ Badges are available in each semantic color, with filled and outline variants:
- {bdg-light}`light`, {bdg-light-line}`light-line`
- {bdg-dark}`dark`, {bdg-dark-line}`dark-line`

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

{bdg-ref-primary}`badges`

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/badge-link.txt
Expand Down Expand Up @@ -94,9 +90,7 @@ Button text
Reference Button text
```

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/button-link.txt
Expand Down
20 changes: 5 additions & 15 deletions docs/cards.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ Card content

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

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/card-basic.txt
Expand All @@ -38,9 +36,7 @@ Card content
Footer
:::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/card-head-foot.txt
Expand Down Expand Up @@ -115,9 +111,7 @@ Footer

:::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/card-images.txt
Expand Down Expand Up @@ -151,9 +145,7 @@ The entire card can be clicked to navigate to <https://example.com>.
The entire card can be clicked to navigate to the `cards-clickable` reference target.
:::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/card-link.txt
Expand Down Expand Up @@ -223,9 +215,7 @@ content
:::
::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/card-carousel.txt
Expand Down
10 changes: 10 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@

suppress_warnings = ["design.fa-build"]
sd_fontawesome_latex = True
sd_custom_directives = {
"dropdown-syntax": {
"inherit": "dropdown",
"argument": "Syntax",
"options": {
"color": "primary",
"icon": "code",
},
}
}

html_theme = os.environ.get("SPHINX_THEME", "alabaster")
html_title = f"Sphinx Design ({html_theme.replace('_', '-')})"
Expand Down
4 changes: 1 addition & 3 deletions docs/css_classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ All CSS classes that are part of sphinx-design are prefixed with `sd-`.
Some CSS styled text
:::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/div-basic.txt
Expand Down
4 changes: 1 addition & 3 deletions docs/dropdowns.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ Dropdown content
Dropdown content
:::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/dropdown-basic.txt
Expand Down
23 changes: 23 additions & 0 deletions docs/get_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,29 @@ sd_hide_title: true
:::
::::

### Creating custom directives

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)

## Supported browsers

- Chrome >= 60
Expand Down
20 changes: 5 additions & 15 deletions docs/grids.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ D
:::
::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/grid-basic.txt
Expand Down Expand Up @@ -80,9 +78,7 @@ B
:::
::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/grid-card.txt
Expand Down Expand Up @@ -121,9 +117,7 @@ B
:::
::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/grid-gutter.txt
Expand Down Expand Up @@ -160,9 +154,7 @@ C
:::
::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/grid-card-columns.txt
Expand Down Expand Up @@ -254,9 +246,7 @@ Content

::::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/grid-nested.txt
Expand Down
8 changes: 2 additions & 6 deletions docs/tabs.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ Content 2

::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/tab-basic.txt
Expand Down Expand Up @@ -70,9 +68,7 @@ Content 2

::::

`````{dropdown} Syntax
:icon: code
:color: primary
`````{dropdown-syntax}
````{tab-set-code}
```{literalinclude} ./snippets/myst/tab-sync.txt
Expand Down
8 changes: 3 additions & 5 deletions sphinx_design/article_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
from docutils import nodes
from docutils.parsers.rst import directives
from sphinx.application import Sphinx
from sphinx.util.docutils import SphinxDirective

from .icons import get_octicon
from .shared import SEMANTIC_COLORS, create_component, make_choice
from .shared import SEMANTIC_COLORS, SdDirective, create_component, make_choice


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


class ArticleInfoDirective(SphinxDirective):
class ArticleInfoDirective(SdDirective):
""" """

has_content = False
Expand Down Expand Up @@ -48,8 +47,7 @@ def _parse_text(
output = [para]
return output

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

top_grid = create_component(
Expand Down
9 changes: 4 additions & 5 deletions sphinx_design/badges_buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from docutils.parsers.rst import directives
from sphinx import addnodes
from sphinx.application import Sphinx
from sphinx.util.docutils import ReferenceRole, SphinxDirective, SphinxRole
from sphinx.util.docutils import ReferenceRole, SphinxRole

from sphinx_design.shared import SEMANTIC_COLORS, make_choice, text_align
from sphinx_design.shared import SEMANTIC_COLORS, SdDirective, make_choice, text_align

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


class _ButtonDirective(SphinxDirective):
class _ButtonDirective(SdDirective):
"""A base button directive."""

required_arguments = 1
Expand Down Expand Up @@ -155,8 +155,7 @@ def create_ref_node(
"""Create the reference node."""
raise NotImplementedError

def run(self) -> list[nodes.Node]:
"""Run the directive."""
def run_with_defaults(self) -> list[nodes.Node]:
rawtext = self.arguments[0]
target = directives.uri(rawtext)
classes = ["sd-sphinx-override", "sd-btn", "sd-text-wrap"]
Expand Down
10 changes: 5 additions & 5 deletions sphinx_design/cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from .shared import (
WARNING_TYPE,
PassthroughTextElement,
SdDirective,
create_component,
is_component,
make_choice,
Expand Down Expand Up @@ -45,7 +46,7 @@ class CardContent(NamedTuple):
footer: Optional[tuple[int, StringList]] = None


class CardDirective(SphinxDirective):
class CardDirective(SdDirective):
"""A card component."""

has_content = True
Expand Down Expand Up @@ -73,7 +74,7 @@ class CardDirective(SphinxDirective):
"class-img-bottom": directives.class_option,
}

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

@classmethod
Expand Down Expand Up @@ -256,7 +257,7 @@ def add_card_child_classes(node):
# ]


class CardCarouselDirective(SphinxDirective):
class CardCarouselDirective(SdDirective):
"""A component, which is a container for cards in a single scrollable row."""

has_content = True
Expand All @@ -266,8 +267,7 @@ class CardCarouselDirective(SphinxDirective):
"class": directives.class_option,
}

def run(self) -> list[nodes.Node]:
"""Run the directive."""
def run_with_defaults(self) -> list[nodes.Node]:
self.assert_has_content()
try:
cols = make_choice([str(i) for i in range(1, 13)])(
Expand Down
9 changes: 4 additions & 5 deletions sphinx_design/dropdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
from docutils.parsers.rst import directives
from sphinx.application import Sphinx
from sphinx.transforms.post_transforms import SphinxPostTransform
from sphinx.util.docutils import SphinxDirective

from sphinx_design.shared import (
SEMANTIC_COLORS,
SdDirective,
create_component,
is_component,
make_choice,
Expand Down Expand Up @@ -52,7 +52,7 @@ def depart_dropdown_title(self, node):
self.body.append("</summary>")


class DropdownDirective(SphinxDirective):
class DropdownDirective(SdDirective):
"""A directive to generate a collapsible container.
Note: This directive generates a single container,
Expand Down Expand Up @@ -87,8 +87,7 @@ class DropdownDirective(SphinxDirective):
"class-body": directives.class_option,
}

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

def run(self):
def run(self) -> None:
"""Run the transform"""
document: nodes.document = self.document
for node in findall(document)(lambda node: is_component(node, "dropdown")):
Expand Down
Loading

0 comments on commit 3374383

Please sign in to comment.