Motivated by the desire to have a better representation of Markdown documents in Julia for Documenter, I am happy to announce a package for working with Markdown abstract syntax trees (ASTs).
Its goal is to provide an API for working with Markdown ASTs and also to function as a relatively lightweight interface package for sharing Markdown trees between different packages (like parsers and document generators).
To give a sense of what the package does, the following small Markdown document
# Markdown document
Hello [world](https://example.com/)!
can be constructed as the following tree using the MarkdownAST @ast
macro DSL
using MarkdownAST: @ast, Document, Heading, Paragraph, Link
@ast Document() do
Heading(1) do
"Markdown document"
end
Paragraph() do
"Hello "
Link("https://example.com/", "") do
"world"
end
"!"
end
end
Each node of the tree is a Node
object that wraps an element (giving each node its semantic meaning; like Link
or Paragraph
) and references other Node
s (parent, sibling, and child nodes). Unlike the Markdown
standard library AST, this provides a type-stable way of traversing ASTs, and it also implements the AbstractTrees.jl interface.
- A lot of the core design is derived from @mike’s CommonMark.jl (in large parts, I just documented the design and added additional APIs for working with the trees). Currently, MarkdownAST is staying pretty close to CommonMark, and once MarkdownAST is stable, I hope we can switch CommonMark over to it internally.
- The package can also convert to and from the
Markdown
standard library AST. - The current API is preliminary, and there will likely be a few breaking iterations to it. With that in mind, I would be very keen to get feedback on the design from anyone who might want to use MarkdownAST — please do open an issue (or a PR), or chime in on some of the existing ones.
- In the long run, I hope this package is a step towards replacing the current
Markdown
standard library (see also JuliaLang/julia#37337).
Finally, I would like to acknowledge the funding from the Julia project (via NumFOCUS) that enabled this work!