Skip to content

Commit 17962a7

Browse files
committed
Update documentation
1 parent c1148b8 commit 17962a7

File tree

15 files changed

+498
-488
lines changed

15 files changed

+498
-488
lines changed

README.md

Lines changed: 91 additions & 282 deletions
Large diffs are not rendered by default.

docs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.ipynb

docs/4.0_migration.md

Lines changed: 0 additions & 35 deletions
This file was deleted.

docs/5.0_migration.md

Lines changed: 0 additions & 23 deletions
This file was deleted.

docs/README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
This folder contains useful info for plugin developers.
22

3-
If you just use `markdown-it` in your app, see
4-
[README](https://github.com/markdown-it/markdown-it#markdown-it) and
5-
[API docs](https://markdown-it.github.io/markdown-it/).
6-
73
__Content__:
84

95
- [Parser architecture & design principles](architecture.md)

docs/Using_the_api.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
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 ...

docs/architecture.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# markdown-it design principles
22

3+
34
## Data flow
45

56
Input data is parsed via nested chains of rules. There are 3 nested chains -

markdown_it/main.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,46 +12,37 @@
1212
from .utils import AttrDict
1313

1414

15-
config = AttrDict(
15+
_PRESETS = AttrDict(
1616
{
17-
"default": presets.default.presets,
18-
"zero": presets.zero.presets,
19-
"commonmark": presets.commonmark.presets,
17+
"default": presets.default.make(),
18+
"zero": presets.zero.make(),
19+
"commonmark": presets.commonmark.make(),
2020
}
2121
)
2222

2323

2424
class MarkdownIt:
2525
def __init__(
26-
self,
27-
presetName: Union[str, AttrDict] = "commonmark",
28-
options=None,
29-
renderer_cls=RendererHTML,
26+
self, config: Union[str, AttrDict] = "commonmark", renderer_cls=RendererHTML
3027
):
3128
"""Main parser class
3229
33-
:param presetName: name of configuration to load or a pre-defined one
34-
:param options: specific options to load
30+
:param config: name of configuration to load or a pre-defined dictionary
31+
:param renderer_cls: the class to load as the renderer:
32+
``self.renderer = renderer_cls(self)
3533
"""
36-
options = options or {}
37-
if not options:
38-
if not isinstance(presetName, str):
39-
options = presetName or {}
40-
presetName = "default"
41-
4234
self.inline = ParserInline()
4335
self.block = ParserBlock()
4436
self.core = ParserCore()
4537
self.renderer = renderer_cls(self)
46-
# var LinkifyIt = require('linkify-it')
47-
# self.linkify = LinkifyIt() # TODO maybe see https://github.com/Suor/autolink
4838

4939
self.utils = utils
5040
self.helpers = helpers
5141
self.options = {}
52-
self.configure(presetName)
53-
if options:
54-
self.set(options)
42+
self.configure(config)
43+
44+
# var LinkifyIt = require('linkify-it')
45+
# self.linkify = LinkifyIt() # TODO maybe see https://github.com/Suor/autolink
5546

5647
def __repr__(self):
5748
return f"{self.__class__.__module__}.{self.__class__.__name__}()"
@@ -86,7 +77,7 @@ def configure(self, presets: Union[str, AttrDict]):
8677
"""
8778
if isinstance(presets, str):
8879
presetName = presets
89-
presets = config.get(presetName, None)
80+
presets = _PRESETS.get(presetName, None)
9081
if not presets:
9182
raise KeyError(
9283
'Wrong `markdown-it` preset "' + presetName + '", check name'
@@ -109,6 +100,15 @@ def configure(self, presets: Union[str, AttrDict]):
109100

110101
return self
111102

103+
def get_all_rules(self) -> Dict[str, List[str]]:
104+
"""Return the names of all active rules."""
105+
rules = {
106+
chain: self[chain].ruler.get_all_rules()
107+
for chain in ["core", "block", "inline"]
108+
}
109+
rules["inline2"] = self.inline.ruler2.get_all_rules()
110+
return rules
111+
112112
def get_active_rules(self) -> Dict[str, List[str]]:
113113
"""Return the names of all active rules."""
114114
rules = {

0 commit comments

Comments
 (0)