Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sphinx_design/cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
SdDirective,
create_component,
is_component,
is_ignorable_child,
make_choice,
margin_option,
text_align,
Expand Down Expand Up @@ -284,6 +285,8 @@ def run_with_defaults(self) -> list[nodes.Node]:
self.set_source_info(container)
self.state.nested_parse(self.content, self.content_offset, container)
for item in container.children:
if is_ignorable_child(item):
continue
if not is_component(item, "card"):
LOGGER.warning(
"All children of a 'card-carousel' "
Expand Down
3 changes: 3 additions & 0 deletions sphinx_design/grids.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
SdDirective,
create_component,
is_component,
is_ignorable_child,
make_choice,
margin_option,
padding_option,
Expand Down Expand Up @@ -142,6 +143,8 @@ def run_with_defaults(self) -> list[nodes.Node]:
self.state.nested_parse(self.content, self.content_offset, row)
# each item in a row should be a column
for item in row.children:
if is_ignorable_child(item):
continue
if not is_component(item, "grid-item"):
LOGGER.warning(
f"All children of a 'grid-row' "
Expand Down
9 changes: 9 additions & 0 deletions sphinx_design/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@ def is_component(node: nodes.Node, name: str):
return False


#: Node types that are structurally inert inside component containers.
SKIP_CHILD_TYPES = (nodes.comment, nodes.target, nodes.system_message)


def is_ignorable_child(node: nodes.Node) -> bool:
"""Check if a node can be silently ignored when validating component children."""
return isinstance(node, SKIP_CHILD_TYPES)


def make_choice(choices: Sequence[str]):
"""Create a choice validator."""
return lambda argument: directives.choice(argument, choices)
Expand Down
35 changes: 29 additions & 6 deletions sphinx_design/tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
from sphinx.util.logging import getLogger

from ._compat import findall
from .shared import WARNING_TYPE, SdDirective, create_component, is_component
from .shared import (
WARNING_TYPE,
SdDirective,
create_component,
is_component,
is_ignorable_child,
)

LOGGER = getLogger(__name__)

Expand Down Expand Up @@ -39,6 +45,13 @@ def run_with_defaults(self) -> list[nodes.Node]:
self.state.nested_parse(self.content, self.content_offset, tab_set)
valid_children = []
for item in tab_set.children:
if is_ignorable_child(item):
# comments and system messages can be safely dropped,
# but hyperlink targets must be kept,
# so that references to them still resolve
if isinstance(item, nodes.target):
valid_children.append(item)
continue
if not is_component(item, "tab-item"):
LOGGER.warning(
f"All children of a 'tab-set' "
Expand Down Expand Up @@ -145,6 +158,8 @@ def run_with_defaults(self) -> list[nodes.Node]:
self.state.nested_parse(self.content, self.content_offset, tab_set)
new_children = []
for item in tab_set.children:
if is_ignorable_child(item):
continue
if not isinstance(item, nodes.literal_block):
LOGGER.warning(
f"All children of a 'tab-code-set' "
Expand Down Expand Up @@ -230,9 +245,19 @@ def run(self, **kwargs: Any) -> None:
):
tab_set_identity = tab_set_id_base + str(tab_set_id_num)
children = []
# keep non tab-item children (e.g. hyperlink targets),
# placing them at the front of the rebuilt tab-set
preserved = [
child
for child in tab_set.children
if not is_component(child, "tab-item")
]
tab_items = [
child for child in tab_set.children if is_component(child, "tab-item")
]
# get the first selected node
selected_idx = None
for idx, tab_item in enumerate(tab_set.children):
for idx, tab_item in enumerate(tab_items):
if tab_item.get("selected", False):
if selected_idx is None:
selected_idx = idx
Expand All @@ -245,9 +270,7 @@ def run(self, **kwargs: Any) -> None:
)
selected_idx = 0 if selected_idx is None else selected_idx

for idx, tab_item in enumerate(tab_set.children):
if not is_component(tab_item, "tab-item"):
continue # Skip non tab-item children
for idx, tab_item in enumerate(tab_items):
if len(tab_item.children) != 2:
LOGGER.warning(
f"Malformed 'tab-item' directive [{WARNING_TYPE}.tab]",
Expand Down Expand Up @@ -290,4 +313,4 @@ def run(self, **kwargs: Any) -> None:
# add content
children.append(tab_content)

tab_set.children = children
tab_set.children = preserved + children
Loading
Loading