|
| 1 | +--- |
| 2 | +jupyter: |
| 3 | + jupytext: |
| 4 | + formats: ipynb,md |
| 5 | + text_representation: |
| 6 | + extension: .md |
| 7 | + format_name: markdown |
| 8 | + format_version: '1.2' |
| 9 | + jupytext_version: 1.4.1 |
| 10 | + kernelspec: |
| 11 | + display_name: Python 3 |
| 12 | + language: python |
| 13 | + name: python3 |
| 14 | +--- |
| 15 | + |
| 16 | +# Using `markdown_it` |
| 17 | + |
| 18 | +> This document can be opened to execute with [Jupytext](https://jupytext.readthedocs.io)! |
| 19 | +
|
| 20 | +markdown-it-py may be used as an API *via* the `markdown_it` package. |
| 21 | + |
| 22 | +The raw text is first parsed to syntax 'tokens', |
| 23 | +then these are converted to other formats using 'renderers'. |
| 24 | + |
| 25 | + |
| 26 | +## Quick-Start |
| 27 | + |
| 28 | +The simplest way to understand how text will be parsed is using: |
| 29 | + |
| 30 | +```python |
| 31 | +from markdown_it import MarkdownIt |
| 32 | +``` |
| 33 | + |
| 34 | +```python |
| 35 | +md = MarkdownIt() |
| 36 | +md.render("some *text*") |
| 37 | +``` |
| 38 | + |
| 39 | +```python |
| 40 | +for token in md.parse("some *text*"): |
| 41 | + print(token) |
| 42 | + print() |
| 43 | +``` |
| 44 | + |
| 45 | +## The Parser |
| 46 | + |
| 47 | + |
| 48 | +The `MarkdownIt` class is instantiated with parsing configuration options, |
| 49 | +dictating the syntax rules and additional options for the parser and renderer. |
| 50 | +You can define this configuration *via* a preset name (`'zero'`, `'commonmark'` or `'default'`), |
| 51 | +or by directly supplying a dictionary. |
| 52 | + |
| 53 | +```python |
| 54 | +from markdown_it.presets import zero |
| 55 | +zero.make() |
| 56 | +``` |
| 57 | + |
| 58 | +```python |
| 59 | +md = MarkdownIt("zero") |
| 60 | +md.options |
| 61 | +``` |
| 62 | + |
| 63 | +```python |
| 64 | +print(md.get_active_rules()) |
| 65 | +``` |
| 66 | + |
| 67 | +```python |
| 68 | +print(md.get_all_rules()) |
| 69 | +``` |
| 70 | + |
| 71 | +You can find all the parsing rules in the source code: |
| 72 | +`parser_core.py`, `parser_block.py`, |
| 73 | +`parser_inline.py`. |
| 74 | +Any of the parsing rules can be enabled/disabled, and these methods are chainable: |
| 75 | + |
| 76 | +```python |
| 77 | +md.render("- __*emphasise this*__") |
| 78 | +``` |
| 79 | + |
| 80 | +```python |
| 81 | +md.enable(["list", "emphasis"]).render("- __*emphasise this*__") |
| 82 | +``` |
| 83 | + |
| 84 | +You can temporarily modify rules with the `reset_rules` context manager. |
| 85 | + |
| 86 | +```python |
| 87 | +with md.reset_rules(): |
| 88 | + md.disable("emphasis") |
| 89 | + print(md.render("__*emphasise this*__")) |
| 90 | +md.render("__*emphasise this*__") |
| 91 | +``` |
| 92 | + |
| 93 | +Additionally `renderInline` runs the parser with all block syntax rules disabled. |
| 94 | + |
| 95 | +```python |
| 96 | +md.renderInline("__*emphasise this*__") |
| 97 | +``` |
| 98 | + |
| 99 | + |
| 100 | +### Plugins load |
| 101 | + |
| 102 | +Plugins load collections of additional syntax rules and render methods into the parser |
| 103 | + |
| 104 | +```python |
| 105 | +from markdown_it import MarkdownIt |
| 106 | +from markdown_it.extensions.front_matter import front_matter_plugin |
| 107 | +from markdown_it.extensions.footnote import footnote_plugin |
| 108 | + |
| 109 | +md = ( |
| 110 | + MarkdownIt() |
| 111 | + .use(front_matter_plugin) |
| 112 | + .use(footnote_plugin) |
| 113 | + .enable('table') |
| 114 | +) |
| 115 | +text = (""" |
| 116 | +--- |
| 117 | +a: 1 |
| 118 | +--- |
| 119 | +
|
| 120 | +a | b |
| 121 | +- | - |
| 122 | +1 | 2 |
| 123 | +
|
| 124 | +A footnote [^1] |
| 125 | +
|
| 126 | +[^1]: some details |
| 127 | +""") |
| 128 | +md.render(text) |
| 129 | +``` |
| 130 | + |
| 131 | + |
| 132 | +## The Token Stream |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | +Before rendering, the text is parsed to a flat token stream of block level syntax elements, with nesting defined by opening (1) and closing (-1) attributes: |
| 138 | + |
| 139 | +```python |
| 140 | +md = MarkdownIt("commonmark") |
| 141 | +tokens = md.parse(""" |
| 142 | +Here's some *text* |
| 143 | +
|
| 144 | +1. a list |
| 145 | +
|
| 146 | +> a *quote*""") |
| 147 | +[(t.type, t.nesting) for t in tokens] |
| 148 | +``` |
| 149 | + |
| 150 | +Naturally all openings should eventually be closed, |
| 151 | +such that: |
| 152 | + |
| 153 | +```python |
| 154 | +sum([t.nesting for t in tokens]) == 0 |
| 155 | +``` |
| 156 | + |
| 157 | +All tokens are the same class, which can also be created outside the parser: |
| 158 | + |
| 159 | +```python |
| 160 | +tokens[0] |
| 161 | +``` |
| 162 | + |
| 163 | +```python |
| 164 | +from markdown_it.token import Token |
| 165 | +token = Token("paragraph_open", "p", 1, block=True, map=[1, 2]) |
| 166 | +token == tokens[0] |
| 167 | +``` |
| 168 | + |
| 169 | +The `'inline'` type token contain the inline tokens as children: |
| 170 | + |
| 171 | +```python |
| 172 | +tokens[1] |
| 173 | +``` |
| 174 | + |
| 175 | +You can serialize a token (and its children) to a JSONable dictionary using: |
| 176 | + |
| 177 | +```python |
| 178 | +print(tokens[1].as_dict()) |
| 179 | +``` |
| 180 | + |
| 181 | +This dictionary can also be deserialized: |
| 182 | + |
| 183 | +```python |
| 184 | +Token.from_dict(tokens[1].as_dict()) |
| 185 | +``` |
| 186 | + |
| 187 | +In some use cases `nest_tokens` may be useful, to collapse the opening/closing tokens into single tokens: |
| 188 | + |
| 189 | +```python |
| 190 | +from markdown_it.token import nest_tokens |
| 191 | +nested_tokens = nest_tokens(tokens) |
| 192 | +[t.type for t in nested_tokens] |
| 193 | +``` |
| 194 | + |
| 195 | +This introduces a single additional class `NestedTokens`, |
| 196 | +containing an `opening`, `closing` and `children`, which can be a list of mixed |
| 197 | +`Token` and `NestedTokens`. |
| 198 | + |
| 199 | +```python |
| 200 | +nested_tokens[0] |
| 201 | +``` |
| 202 | + |
| 203 | +## Renderers |
| 204 | + |
| 205 | + |
| 206 | +Todo ... |
0 commit comments