CST-based incremental Markdown parser for MoonBit
moon add mizchi/markdown// Parse markdown
let doc = @markdown.parse("# Hello\n\nWorld")
// Serialize back (lossless)
let output = @markdown.serialize(doc)
// Incremental update
let edit = @markdown.EditInfo::new(start, end, new_length)
let new_doc = @markdown.parse_incremental(doc, new_text, edit)// Direct conversion
let html = @markdown.md_to_html("# Hello\n\nWorld")
// Or with handle for incremental updates
let handle = @markdown.md_parse(source)
let html = @markdown.md_render_to_html(handle)
@markdown.md_free(handle)pnpm install
moon build --target js
pnpm exec vitepub(all) type AgentId Intpub(all) enum Block {
ThematicBreak(Char, Int, Span, Trivia, Trivia)
Heading(Int, HeadingStyle, Array[Inline], Int, Span, Trivia, Trivia)
Paragraph(Array[Inline], Span, Trivia, Trivia)
FencedCode(FenceMarker, Int, String, String, Int, Span, Trivia, Trivia)
IndentedCode(String, Span, Trivia, Trivia)
Blockquote(Array[Block], Span, Trivia, Trivia)
BulletList(BulletMarker, Bool, Array[ListItem], Span, Trivia, Trivia)
OrderedList(Int, OrderedDelimiter, Bool, Array[ListItem], Span, Trivia, Trivia)
HtmlBlock(String, Span, Trivia, Trivia)
Table(Array[TableCell], Array[TableAlign], Array[Array[TableCell]], Span, Trivia, Trivia)
BlankLines(Int, Span)
FootnoteDefinition(String, Array[Block], Span, Trivia, Trivia)
}pub(all) enum BulletMarker {
Dash
Asterisk
Plus
}impl Eq for BulletMarkerimpl Show for BulletMarkerpub struct CodeBlockInfo {
lang : String
filename : String
meta : String
}pub(all) struct EditInfo {
offset : Int
old_len : Int
new_len : Int
}pub(all) enum EmphasisMarker {
Asterisk
Underscore
}impl Eq for EmphasisMarkerimpl Show for EmphasisMarkerpub(all) enum FenceMarker {
Backtick
Tilde
}impl Eq for FenceMarkerimpl Show for FenceMarkerpub(all) enum HardBreakStyle {
TwoSpaces
Backslash
}impl Eq for HardBreakStyleimpl Show for HardBreakStylepub(all) enum HeadingStyle {
Atx
Setext
}impl Eq for HeadingStyleimpl Show for HeadingStylepub(all) struct IncrementalResult {
document : Document
reused_before : Int
reparsed : Int
reused_after : Int
}pub(all) enum Inline {
Text(String, Span)
SoftBreak(Span)
HardBreak(HardBreakStyle, Span)
Emphasis(EmphasisMarker, Array[Inline], Span)
Strong(EmphasisMarker, Array[Inline], Span)
Strikethrough(Array[Inline], Span)
Code(String, Int, Span)
Link(Array[Inline], String, String, Span)
RefLink(Array[Inline], String, Span)
Autolink(String, Bool, Span)
Image(String, String, String, Span)
RefImage(String, String, Span)
HtmlInline(String, Span)
FootnoteReference(String, Span)
}pub(all) enum OrderedDelimiter {
Dot
Paren
}impl Eq for OrderedDelimiterimpl Show for OrderedDelimiterfn RenderOptions::with_highlighter(highlighter : (CodeBlockInfo, String) -> String) -> RenderOptionsfn RenderOptions::with_simple_highlighter(highlighter : (String, String) -> String) -> RenderOptionspub(all) struct Span {
from : Int
to : Int
}pub(all) enum TableAlign {
Left
Center
Right
None
}impl Eq for TableAlignimpl Show for TableAlignpub(all) struct Trivia {
content : String
}fn md_parse_and_render(source : String, strict? : Bool) -> Stringfn md_parse_incremental(handle : Int, new_source : String, change_start : Int, old_end : Int, new_end : Int) -> Intfn md_render_to_html(handle : Int) -> Stringfn md_render_to_string(handle : Int) -> Stringfn md_to_html_strict(source : String) -> Stringfn parse_incremental(old_doc : Document, old_source : String, new_source : String, edit : EditInfo) -> IncrementalResult