0
# Directives System
1
2
Advanced plugin system for structured content blocks that extends Markdown with reStructuredText-style and fenced code block-style directive syntax. Directives enable complex, parameterized content blocks with structured arguments and options, supporting both built-in directives and custom directive creation.
3
4
## Capabilities
5
6
### Base Directive System
7
8
Foundation classes for creating and managing directive plugins.
9
10
```python { .api }
11
class DirectivePlugin:
12
"""
13
Base class for directive plugins that add structured content blocks.
14
15
Directives are complex plugins that parse structured arguments and options
16
to generate rich content blocks beyond standard Markdown capabilities.
17
"""
18
19
def __init__(self, plugins: List[str]):
20
"""
21
Initialize directive plugin.
22
23
Parameters:
24
- plugins: List of plugin names this directive requires
25
"""
26
27
def __call__(self, md: Markdown) -> None:
28
"""
29
Apply directive plugin to Markdown instance.
30
31
Parameters:
32
- md: Markdown instance to modify
33
"""
34
35
class BaseDirective(metaclass=ABCMeta):
36
"""
37
Abstract base class for individual directive implementations.
38
39
Defines the interface for parsing directive blocks and integrating
40
with the block parser system.
41
"""
42
43
@abstractmethod
44
def parse(
45
self,
46
block: BlockParser,
47
m: Match[str],
48
state: BlockState
49
) -> int:
50
"""
51
Parse directive block and add tokens to state.
52
53
Parameters:
54
- block: Block parser instance
55
- m: Regex match object with directive content
56
- state: Current block parsing state
57
58
Returns:
59
Number of characters consumed
60
"""
61
```
62
63
### Directive Parser Types
64
65
Two main directive syntax patterns supported by mistune.
66
67
```python { .api }
68
class RSTParser(DirectiveParser):
69
"""
70
Parser for reStructuredText-style directive syntax.
71
72
Syntax pattern:
73
.. directive_name:: argument
74
:option1: value1
75
:option2: value2
76
77
Content block
78
"""
79
80
class FencedParser(DirectiveParser):
81
"""
82
Parser for fenced code block-style directive syntax.
83
84
Syntax pattern:
85
```{directive_name} argument
86
:option1: value1
87
:option2: value2
88
89
Content block
90
```
91
"""
92
93
class RSTDirective(BaseDirective):
94
"""Base directive using reStructuredText syntax."""
95
96
class FencedDirective(BaseDirective):
97
"""Base directive using fenced code block syntax."""
98
```
99
100
## Built-in Directives
101
102
### Admonition Directive
103
104
Creates styled callout boxes for notes, warnings, tips, and other advisory content.
105
106
```python
107
# reStructuredText syntax
108
"""
109
.. note::
110
This is a note admonition.
111
112
.. warning::
113
This is a warning admonition.
114
115
.. tip::
116
This is a tip admonition with **formatted** content.
117
"""
118
119
# Fenced syntax
120
"""
121
```{note}
122
This is a note admonition.
123
```
124
125
```{warning}
126
This is a warning admonition.
127
```
128
"""
129
```
130
131
Usage example:
132
133
```python
134
from mistune import create_markdown
135
from mistune.directives import Admonition
136
137
md = create_markdown()
138
admonition = Admonition(['rst', 'fenced']) # Support both syntaxes
139
md.use(admonition)
140
141
markdown_text = """
142
.. warning::
143
Make sure to backup your data before proceeding.
144
145
```{tip}
146
Use keyboard shortcuts to improve productivity.
147
```
148
"""
149
150
html = md(markdown_text)
151
# Outputs: <div class="admonition warning">...</div> and <div class="admonition tip">...</div>
152
```
153
154
### Include Directive
155
156
Includes content from external files, useful for documentation systems and content reuse.
157
158
```python
159
# Syntax
160
"""
161
.. include:: path/to/file.md
162
163
.. include:: code_example.py
164
:code: python
165
166
```{include} external_content.md
167
```
168
"""
169
```
170
171
Usage example:
172
173
```python
174
from mistune import create_markdown
175
from mistune.directives import Include
176
177
md = create_markdown()
178
include = Include(['rst', 'fenced'])
179
md.use(include)
180
181
# Create external file
182
with open('example.md', 'w') as f:
183
f.write('# External Content\n\nThis is included content.')
184
185
markdown_text = """
186
Main document content.
187
188
.. include:: example.md
189
190
More main content.
191
"""
192
193
html = md(markdown_text)
194
# Includes the external file content inline
195
```
196
197
### Image Directive
198
199
Enhanced image handling with advanced options for sizing, alignment, and captions.
200
201
```python
202
# Syntax
203
"""
204
.. image:: path/to/image.jpg
205
:alt: Alternative text
206
:width: 400px
207
:height: 300px
208
:align: center
209
210
```{image} path/to/image.jpg
211
:alt: Alternative text
212
:width: 400px
213
```
214
"""
215
```
216
217
Usage example:
218
219
```python
220
from mistune import create_markdown
221
from mistune.directives import Image
222
223
md = create_markdown()
224
image = Image(['rst', 'fenced'])
225
md.use(image)
226
227
markdown_text = """
228
.. image:: https://example.com/image.jpg
229
:alt: Example image
230
:width: 500px
231
:align: center
232
:class: featured-image
233
"""
234
235
html = md(markdown_text)
236
# Outputs: <img src="..." alt="..." width="500px" class="featured-image centered">
237
```
238
239
### Figure Directive
240
241
Creates figures with images, captions, and legends for richer content presentation.
242
243
```python
244
# Syntax
245
"""
246
.. figure:: image.jpg
247
:width: 400px
248
249
This is the figure caption.
250
251
This is the legend with additional details.
252
253
```{figure} image.jpg
254
:width: 400px
255
256
This is the figure caption.
257
258
This is the legend.
259
```
260
"""
261
```
262
263
Usage example:
264
265
```python
266
from mistune import create_markdown
267
from mistune.directives import Figure
268
269
md = create_markdown()
270
figure = Figure(['rst', 'fenced'])
271
md.use(figure)
272
273
markdown_text = """
274
.. figure:: chart.png
275
:width: 600px
276
:align: center
277
278
Sales Performance Chart
279
280
This chart shows quarterly sales data with trend analysis.
281
"""
282
283
html = md(markdown_text)
284
# Outputs: <figure><img...><figcaption>Sales Performance Chart</figcaption><div class="legend">...</div></figure>
285
```
286
287
### Table of Contents Directive
288
289
Generates automatic table of contents based on document headings.
290
291
```python
292
# Syntax
293
"""
294
.. toc::
295
:min-level: 1
296
:max-level: 3
297
:title: Contents
298
299
```{toc}
300
:min-level: 2
301
:max-level: 4
302
```
303
"""
304
```
305
306
Usage example:
307
308
```python
309
from mistune import create_markdown
310
from mistune.directives import TableOfContents
311
312
md = create_markdown()
313
toc = TableOfContents(['rst', 'fenced'])
314
md.use(toc)
315
316
markdown_text = """
317
```{toc}
318
:title: Table of Contents
319
:min-level: 1
320
:max-level: 3
321
```
322
323
# Chapter 1: Introduction
324
325
## Section 1.1: Overview
326
327
## Section 1.2: Getting Started
328
329
# Chapter 2: Advanced Topics
330
331
## Section 2.1: Configuration
332
"""
333
334
html = md(markdown_text)
335
# Generates TOC with links to headings
336
```
337
338
## Custom Directive Creation
339
340
Pattern for creating custom directives:
341
342
```python
343
from mistune.directives import DirectivePlugin, RSTDirective, FencedDirective
344
from mistune import BlockParser, BlockState
345
import re
346
347
class CustomAlert(DirectivePlugin):
348
"""Custom alert directive with color coding."""
349
350
def __init__(self):
351
super().__init__(['rst', 'fenced'])
352
353
def __call__(self, md):
354
# RST-style directive
355
class AlertRST(RSTDirective):
356
def parse(self, block, m, state):
357
info = self.parse_directive_info(m)
358
alert_type = info.get('arguments', ['info'])[0]
359
color = info.get('options', {}).get('color', 'blue')
360
content = info.get('content', '')
361
362
# Parse content as markdown
363
child = state.child_state(content)
364
block.parse(content, child)
365
366
token = {
367
'type': 'custom_alert',
368
'attrs': {
369
'alert_type': alert_type,
370
'color': color
371
},
372
'children': child.tokens
373
}
374
375
state.tokens.append(token)
376
return m.end()
377
378
# Fenced-style directive
379
class AlertFenced(FencedDirective):
380
def parse(self, block, m, state):
381
# Similar parsing logic for fenced syntax
382
pass
383
384
# Register parsers
385
rst_parser = RSTParser()
386
fenced_parser = FencedParser()
387
388
rst_parser.register('alert', AlertRST())
389
fenced_parser.register('alert', AlertFenced())
390
391
# Add to block parser
392
md.block.register_rule('alert_rst', rst_parser.pattern, rst_parser.parse)
393
md.block.register_rule('alert_fenced', fenced_parser.pattern, fenced_parser.parse)
394
395
# Add renderer
396
def render_custom_alert(text, alert_type, color):
397
return f'<div class="alert alert-{alert_type}" style="border-color: {color}">{text}</div>\n'
398
399
md.renderer.register('custom_alert', render_custom_alert)
400
401
# Use custom directive
402
md = create_markdown()
403
alert = CustomAlert()
404
md.use(alert)
405
406
result = md("""
407
.. alert:: success
408
:color: green
409
410
Operation completed successfully!
411
412
```{alert} warning
413
:color: orange
414
415
Please review the configuration before proceeding.
416
```
417
""")
418
```
419
420
## Directive Integration
421
422
Directives integrate with mistune through the plugin system:
423
424
```python
425
from mistune import create_markdown
426
from mistune.directives import Admonition, Include, Image, Figure, TableOfContents
427
428
# Load multiple directives
429
md = create_markdown()
430
431
# Add directives individually
432
md.use(Admonition(['rst', 'fenced']))
433
md.use(Include(['rst']))
434
md.use(Image(['rst', 'fenced']))
435
md.use(Figure(['rst']))
436
md.use(TableOfContents(['fenced']))
437
438
# Or create with directive plugins
439
directives = [
440
Admonition(['rst', 'fenced']),
441
Include(['rst']),
442
Image(['rst', 'fenced']),
443
TableOfContents(['fenced'])
444
]
445
446
md = create_markdown()
447
for directive in directives:
448
md.use(directive)
449
```
450
451
## Syntax Patterns
452
453
### reStructuredText Style
454
455
```
456
.. directive_name:: argument1 argument2
457
:option1: value1
458
:option2: value2
459
:flag_option:
460
461
Content block can contain
462
**formatted** Markdown text.
463
464
Multiple paragraphs are supported.
465
```
466
467
### Fenced Code Block Style
468
469
```
470
```{directive_name} argument1 argument2
471
:option1: value1
472
:option2: value2
473
:flag_option:
474
475
Content block can contain
476
**formatted** Markdown text.
477
478
Multiple paragraphs are supported.
479
```
480
```
481
482
Both syntax styles support:
483
- Positional arguments after directive name
484
- Named options with `:option: value` syntax
485
- Flag options with `:flag:` syntax
486
- Multi-line content blocks with Markdown formatting
487
- Nested directive processing
488
489
The directive system provides a powerful way to extend Markdown with structured, reusable content blocks while maintaining clean, readable syntax.