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
Paragraph) and references other
Nodes (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
Markdownstandard 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
Markdownstandard library (see also JuliaLang/julia#37337).
Finally, I would like to acknowledge the funding from the Julia project (via NumFOCUS) that enabled this work!