Quickstart¶
This page follows one small document through a parse, two changes and two renders. Every output shown was produced by running the code against the current source.
Prerequisite: marktripy is installed (Installation).
1. Create a parser¶
Parsers are registered by name when their module is imported. Import the module, then ask the registry for an instance:
from marktripy.core.parser import ParserRegistry
from marktripy.parsers import markdown_it # registers "markdown-it"
parser = ParserRegistry.create("markdown-it")
You can also construct the class directly: markdown_it.MarkdownItParser().
2. Parse Markdown¶
doc is a Document node. Its tree looks like this:
Inline formatting is a node with children: **bold** became a strong node that contains a text node.
3. Change the tree¶
Every node has walk() (all nodes, depth first) and find_all(type) (all nodes of one type). Headings carry their level in the level attribute:
The Heading constructor rejects levels outside 1–6, but assigning level afterwards is not checked. The transformers in Transformers clamp levels for you.
4. Render Markdown¶
Output:
5. Render HTML¶
Output:
6. Add heading IDs and a table of contents¶
The transformer modules provide one-call helper functions.
from marktripy.transformers.id_generator import add_heading_ids
from marktripy.transformers.toc import generate_toc
doc = parser.parse("# Intro\n\n## Setup\n\n## Setup\n\n### Café & Crème\n")
add_heading_ids(doc) # changes doc in place
doc = generate_toc(doc) # returns a new Document with the TOC inserted
print(MarkdownRenderer().render(doc))
Output:
# Intro
## Table of Contents
- [Intro](#intro)
- [Setup](#setup)
- [Setup](#setup-1)
- [Café & Crème](#cafe-creme)
## Setup
## Setup
### Café & Crème
What happened:
add_heading_idsslugified each heading's text. The secondSetupgot the suffix-1so IDs stay unique, and the accents were stripped (Café & Crème→cafe-creme).generate_toccollected headings of levels 1–3, built a nested list of links, and inserted it after the first level-1 heading. It returned a copy of the document, so keep the return value.
The IDs are stored in each heading's attrs and appear in HTML output (<h2 id="setup">Setup</h2>). Markdown has no heading-ID syntax, so MarkdownRenderer does not write them.
7. Enable GFM features¶
Strikethrough and task lists need two things: a parser preset that recognises the syntax, and the extension that turns the parsed result into proper nodes and renders them.
from marktripy.extensions.base import ExtensionManager
from marktripy.extensions.gfm import GFMExtension
parser = ParserRegistry.create("markdown-it", {"preset": "default"})
html = HTMLRenderer()
manager = ExtensionManager()
manager.register(GFMExtension())
manager.apply_renderer_extensions(html, "html")
doc = parser.parse("~~old~~ new\n\n- [ ] todo\n- [x] done\n")
doc = manager.apply_ast_transformations(doc)
print(html.render(doc))
Output (line breaks as produced):
<p><del>old</del> new</p>
<ul>
<li><input type="checkbox" disabled> todo</li><li><input type="checkbox" disabled checked> done</li></ul>
See Extensions for the order of these calls and for the ++key++ extension.
Next steps¶
- The AST lists every node class and tree method.
- Parsers explains presets, plugins and the
mistletoeadapter. - Known limitations lists the cases that do not round-trip yet.