- Pods
- Markdown Parser 0.0.2
- API
- MarkdownParser
- Src
sourceafMarkdownParser::MarkdownParser.fan
using afPegger
using fandoc
** (Service) -
** Parses Markdown strings into fandoc documents.
@Js
const class MarkdownParser {
** Parses the given Markdown string into a fandoc document.
Doc parse(Str markdown) {
toFandoc(parseTree(markdown))
}
internal TreeCtx parseTree(Str markdown) {
parser := Parser(MarkdownRules().rootRule)
return ((TreeCtx) parser.parseAll(markdown.in, TreeCtx()))
}
internal Doc toFandoc(TreeCtx tree) {
elems := DocElem[Doc()]
push := |DocElem elem| {
elems.last.add(elem)
elems.push(elem)
}
add := |DocNode elem| {
elems.last.add(elem)
}
pop := |->| {
elems.pop
}
tree.root.walk(
|TreeItem item| {
switch (item.type) {
case "paragraph" : push(Para())
case "heading" : push(Heading(item.data))
case "blockquote" : push(BlockQuote())
case "pre" : push(Pre())
case "ul" : push(UnorderedList())
case "ol" : push(OrderedList(OrderedListStyle.number))
case "li" : push(ListItem())
case "italic" : push(Emphasis())
case "bold" : push(Strong())
case "code" : push(Code())
case "text" : add(DocText(item.matched))
}
},
|TreeItem item| {
switch (item.type) {
case "heading":
case "paragraph":
case "blockquote":
case "pre":
case "ul":
case "ol":
case "li":
case "italic":
case "bold":
case "code":
pop()
case "link":
text := item.items.find { it.type == "linkText" }.matched
href := item.items.find { it.type == "linkHref" }.matched
push(Link(href))
add(DocText(text))
pop()
case "link":
text := item.items.find { it.type == "linkText" }.matched
href := item.items.find { it.type == "linkHref" }.matched
push(Link(href))
add(DocText(text))
pop()
case "image":
alt := item.items.find { it.type == "imageAlt" }.matched
src := item.items.find { it.type == "imageSrc" }.matched
push(Image(src, alt))
pop()
}
}
)
return elems.first
}
}