Skip to content

Commit e3b1268

Browse files
authored
Stepper support rubric directive (#694)
1 parent f0945f0 commit e3b1268

2 files changed

Lines changed: 48 additions & 33 deletions

File tree

docs/myst/stepper.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ Steps can contain lists and admonitions:
3232
Example admonition.
3333
:::
3434

35+
You can also use ":::{rubric}":
36+
37+
:::{rubric} Rubric text
38+
:::
39+
3540
### Step three (a h3 header)
3641

3742
Steps can contain nested headings. You just have to make them one level smaller.

src/crate/theme/rtd/crate/directives/stepper.py

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -83,49 +83,59 @@ def run(self):
8383
for child in container.children:
8484
# MyST parser uses rubric nodes for headings when they appear inside
8585
# a directive/container.
86+
is_markdown_heading = False
87+
8688
if isinstance(child, nodes.rubric):
8789
# Get heading info
8890
heading_id = child.get('ids', [''])[0] if child.get('ids') else ''
8991
heading_text = child.astext()
90-
heading_level = heading_levels.get(heading_id, 3)
91-
92-
# Only treat as new step if at the step level
93-
if heading_level == step_level:
94-
# Close previous step if any
95-
if current_step is not None:
96-
stepper += current_step
97-
98-
# Add intro content before first step
99-
if intro_content:
100-
for item in intro_content:
101-
stepper += item
102-
intro_content = []
103-
104-
# Create new step
105-
current_step = step_node()
106-
current_step['step-number'] = step_number
107-
current_step['classes'] = ['stepper-step']
108-
109-
# Create step title node
110-
title_node = step_title_node()
111-
title_node['ids'] = child.get('ids', [])
112-
title_node['level'] = heading_level
113-
title_node['text'] = heading_text
114-
current_step += title_node
115-
116-
step_number += 1
117-
else:
118-
# Nested heading - add as content within current step
119-
if current_step is not None:
120-
# Convert rubric to a proper heading node for nested headings
92+
93+
# Only process as a heading if this rubric corresponds to a
94+
# markdown heading (found in pre-scan). Explicit rubric directives
95+
# won't be in heading_levels and should be treated as regular content.
96+
if heading_id in heading_levels:
97+
is_markdown_heading = True
98+
heading_level = heading_levels[heading_id]
99+
100+
# Only treat as new step if at the step level
101+
if heading_level == step_level:
102+
# Close previous step if any
103+
if current_step is not None:
104+
stepper += current_step
105+
106+
# Add intro content before first step
107+
if intro_content:
108+
for item in intro_content:
109+
stepper += item
110+
intro_content = []
111+
112+
# Create new step
113+
current_step = step_node()
114+
current_step['step-number'] = step_number
115+
current_step['classes'] = ['stepper-step']
116+
117+
# Create step title node
121118
title_node = step_title_node()
122119
title_node['ids'] = child.get('ids', [])
123120
title_node['level'] = heading_level
124121
title_node['text'] = heading_text
125122
current_step += title_node
123+
124+
step_number += 1
126125
else:
127-
intro_content.append(child)
128-
else:
126+
# Nested heading - add as content within current step
127+
if current_step is not None:
128+
# Convert rubric to a proper heading node for nested headings
129+
title_node = step_title_node()
130+
title_node['ids'] = child.get('ids', [])
131+
title_node['level'] = heading_level
132+
title_node['text'] = heading_text
133+
current_step += title_node
134+
else:
135+
intro_content.append(child)
136+
137+
# Handle regular content (non-heading rubrics and all other nodes)
138+
if not is_markdown_heading:
129139
if current_step is not None:
130140
current_step += child
131141
else:

0 commit comments

Comments
 (0)