0
# Plugin System
1
2
Extensible plugin architecture that enables mistune to support additional Markdown syntax and features beyond CommonMark. Includes a comprehensive set of built-in plugins and patterns for creating custom plugins to extend parsing capabilities.
3
4
## Capabilities
5
6
### Plugin Protocol
7
8
Interface definition for mistune plugins that modify parser behavior.
9
10
```python { .api }
11
class Plugin(Protocol):
12
"""
13
Protocol for mistune plugins.
14
"""
15
def __call__(self, md: Markdown) -> None:
16
"""
17
Apply plugin to a Markdown instance.
18
19
Parameters:
20
- md: Markdown instance to modify
21
"""
22
23
PluginRef = Union[str, Plugin] # Reference to register a plugin
24
```
25
26
### Plugin Import System
27
28
System for loading and caching plugins by name or instance.
29
30
```python { .api }
31
def import_plugin(name: PluginRef) -> Plugin:
32
"""
33
Import and return a plugin by name or return plugin instance.
34
35
Parameters:
36
- name: Plugin name string or Plugin instance
37
38
Returns:
39
Plugin instance ready for use
40
"""
41
```
42
43
Usage example:
44
45
```python
46
import mistune
47
48
# Load plugin by name
49
table_plugin = mistune.import_plugin('table')
50
51
# Use with parser
52
md = mistune.create_markdown(plugins=[table_plugin])
53
54
# Or load automatically by name
55
md = mistune.create_markdown(plugins=['table', 'footnotes'])
56
```
57
58
## Built-in Plugins
59
60
### Table Support
61
62
Enables GitHub Flavored Markdown table syntax with alignment options.
63
64
```python
65
# Plugin name: "table"
66
md = mistune.create_markdown(plugins=['table'])
67
68
markdown_text = """
69
| Name | Age | City |
70
|---------|-----|-----------|
71
| Alice | 25 | New York |
72
| Bob | 30 | London |
73
"""
74
75
html = md(markdown_text)
76
# Outputs: <table><thead><tr><th>Name</th>...</tr></thead><tbody>...</tbody></table>
77
```
78
79
### Footnotes
80
81
Adds support for footnote references and definitions.
82
83
```python
84
# Plugin name: "footnotes"
85
md = mistune.create_markdown(plugins=['footnotes'])
86
87
markdown_text = """
88
This is text with a footnote[^1].
89
90
[^1]: This is the footnote content.
91
"""
92
93
html = md(markdown_text)
94
# Outputs HTML with footnote links and footnote section
95
```
96
97
### Formatting Extensions
98
99
Additional text formatting options beyond standard bold and italic.
100
101
```python
102
# Plugin names: "strikethrough", "mark", "insert", "superscript", "subscript"
103
md = mistune.create_markdown(plugins=['strikethrough', 'mark', 'superscript', 'subscript'])
104
105
examples = {
106
'strikethrough': '~~deleted text~~', # <del>deleted text</del>
107
'mark': '==highlighted text==', # <mark>highlighted text</mark>
108
'insert': '++inserted text++', # <ins>inserted text</ins>
109
'superscript': 'E=mc^2^', # E=mc<sup>2</sup>
110
'subscript': 'H~2~O', # H<sub>2</sub>O
111
}
112
113
for name, text in examples.items():
114
print(f"{name}: {md(text)}")
115
```
116
117
### URL Auto-linking
118
119
Automatically converts URLs to clickable links.
120
121
```python
122
# Plugin name: "url"
123
md = mistune.create_markdown(plugins=['url'])
124
125
text = "Visit https://example.com for more info."
126
html = md(text)
127
# Output: Visit <a href="https://example.com">https://example.com</a> for more info.
128
```
129
130
### Abbreviations
131
132
Support for abbreviation definitions and expansions.
133
134
```python
135
# Plugin name: "abbr"
136
md = mistune.create_markdown(plugins=['abbr'])
137
138
markdown_text = """
139
The HTML specification is maintained by W3C.
140
141
*[HTML]: HyperText Markup Language
142
*[W3C]: World Wide Web Consortium
143
"""
144
145
html = md(markdown_text)
146
# Outputs: <abbr title="HyperText Markup Language">HTML</abbr> and <abbr title="World Wide Web Consortium">W3C</abbr>
147
```
148
149
### Definition Lists
150
151
Support for definition list syntax.
152
153
```python
154
# Plugin name: "def_list"
155
md = mistune.create_markdown(plugins=['def_list'])
156
157
markdown_text = """
158
Term 1
159
: Definition for term 1
160
161
Term 2
162
: Definition for term 2
163
With multiple lines
164
"""
165
166
html = md(markdown_text)
167
# Outputs: <dl><dt>Term 1</dt><dd>Definition for term 1</dd>...</dl>
168
```
169
170
### Mathematics
171
172
Support for mathematical expressions using LaTeX syntax.
173
174
```python
175
# Plugin name: "math"
176
md = mistune.create_markdown(plugins=['math'])
177
178
markdown_text = """
179
Inline math: $E = mc^2$
180
181
Block math:
182
$$
183
\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}
184
$$
185
"""
186
187
html = md(markdown_text)
188
# Outputs math expressions wrapped in appropriate tags for MathJax/KaTeX
189
```
190
191
### Ruby Annotations
192
193
Support for Ruby annotations (furigana) commonly used in East Asian typography.
194
195
```python
196
# Plugin name: "ruby"
197
md = mistune.create_markdown(plugins=['ruby'])
198
199
text = "This is {ruby text}(annotation) example."
200
html = md(text)
201
# Output: This is <ruby>ruby text<rt>annotation</rt></ruby> example.
202
```
203
204
### Task Lists
205
206
GitHub-style task list checkboxes.
207
208
```python
209
# Plugin name: "task_lists"
210
md = mistune.create_markdown(plugins=['task_lists'])
211
212
markdown_text = """
213
- [x] Completed task
214
- [ ] Incomplete task
215
- [x] Another completed task
216
"""
217
218
html = md(markdown_text)
219
# Outputs: <ul><li><input type="checkbox" checked disabled> Completed task</li>...</ul>
220
```
221
222
### Spoiler Text
223
224
Support for spoiler/hidden text that can be revealed.
225
226
```python
227
# Plugin name: "spoiler"
228
md = mistune.create_markdown(plugins=['spoiler'])
229
230
text = "This contains ||spoiler text|| that is hidden."
231
html = md(text)
232
# Output: This contains <span class="spoiler">spoiler text</span> that is hidden.
233
```
234
235
### Performance Speedup
236
237
C extension for improved parsing performance.
238
239
```python
240
# Plugin name: "speedup"
241
md = mistune.create_markdown(plugins=['speedup'])
242
# Automatically uses C extensions when available for better performance
243
```
244
245
## Plugin Usage Patterns
246
247
### Multiple Plugins
248
249
Combine multiple plugins for enhanced functionality:
250
251
```python
252
md = mistune.create_markdown(plugins=[
253
'table',
254
'footnotes',
255
'strikethrough',
256
'task_lists',
257
'url',
258
'speedup'
259
])
260
261
markdown_text = """
262
# Todo List
263
264
- [x] ~~Setup project~~
265
- [ ] Write documentation
266
- [ ] Add tests
267
268
Visit https://github.com/lepture/mistune for source code[^1].
269
270
| Feature | Status |
271
|---------|--------|
272
| Tables | ✅ |
273
| Lists | ✅ |
274
275
[^1]: Mistune GitHub repository
276
"""
277
278
html = md(markdown_text)
279
```
280
281
### Plugin Registration
282
283
Add plugins to existing Markdown instances:
284
285
```python
286
md = mistune.create_markdown()
287
288
# Add plugins after creation
289
md.use(mistune.import_plugin('table'))
290
md.use(mistune.import_plugin('footnotes'))
291
292
# Or register by name during creation
293
md = mistune.create_markdown(plugins=['table', 'footnotes'])
294
```
295
296
### Pre-configured Parser
297
298
The built-in `html` parser includes common plugins:
299
300
```python
301
import mistune
302
303
# Equivalent to create_markdown with these plugins:
304
# ["strikethrough", "footnotes", "table", "speedup"]
305
html = mistune.html("""
306
| Name | Status |
307
|------|--------|
308
| Task | ~~Done~~ |
309
310
This has footnotes[^1].
311
312
[^1]: Footnote content
313
""")
314
```
315
316
## Custom Plugin Creation
317
318
Pattern for creating custom plugins:
319
320
```python
321
from mistune import Markdown
322
import re
323
324
def custom_highlight_plugin(md: Markdown) -> None:
325
"""Plugin to add highlight syntax: ==text=="""
326
327
# Add inline rule for highlighting
328
def parse_highlight(inline, m, state):
329
text = m.group(1)
330
return 'highlight', text
331
332
# Add renderer method
333
def render_highlight(text):
334
return f'<mark class="highlight">{text}</mark>'
335
336
# Register with parser
337
md.inline.register_rule('highlight', r'==(.*?)==', parse_highlight)
338
md.renderer.register('highlight', render_highlight)
339
340
# Use custom plugin
341
md = mistune.create_markdown()
342
md.use(custom_highlight_plugin)
343
344
result = md('This is ==highlighted== text.')
345
# Output: This is <mark class="highlight">highlighted</mark> text.
346
```
347
348
## Plugin Integration
349
350
Plugins integrate with different parsing stages:
351
352
- **Block-level plugins**: Modify `md.block` parser for new block elements
353
- **Inline-level plugins**: Modify `md.inline` parser for new inline elements
354
- **Renderer plugins**: Add new rendering methods to `md.renderer`
355
- **Hook plugins**: Use `before_parse_hooks`, `before_render_hooks`, `after_render_hooks`
356
357
This architecture enables comprehensive customization while maintaining parsing performance and modularity.