Sign in

    markdown

    Event-driven Markdown parser with CommonMark, GFM, HTML, and AST support.

    markdown
    commonmark
    gfm
    html
    mdast
    Download zip
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    4 months ago
    Downloads
    35

    No dependencies

    #shiguri-01/markdown

    An event-driven Markdown parser for MoonBit.

    The core idea is simple: Markdown parsing produces Event values, and every output format is a Sink. Processor owns the syntax rules, parse pushes events into a sink, and renderers, AST builders, collectors, and transforms all compose downstream.

    Use the CommonMark rule with the sink for the output you want:

    ///|
    test {
    let html = @markdown.Html(@commonmark.html_renderers())
    @markdown.Processor(@commonmark.rule()).parse(
    "# Hello *MoonBit*",
    html.sink(),
    )
    assert_eq(html.to_string(), "<h1>Hello <em>MoonBit</em></h1>\n")
    }

    ///|
    test {
    let ast = @markdown.Ast()
    @markdown.Processor(@commonmark.rule()).parse("hello", ast.sink())
    let root = ast.result()
    assert_eq(
    root.to_json().stringify(),
    (
    #|{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"hello"}]}]}
    ),
    )
    }

    You can also keep a processor and reuse it:

    ///|
    test {
    let html = @markdown.Html(@commonmark.html_renderers())
    @markdown.Processor(@commonmark.rule()).parse("# Hello", html.sink())
    assert_eq(html.to_string(), "<h1>Hello</h1>\n")
    }

    ///|
    test {
    let events = @markdown.Events()
    @markdown.Processor(@commonmark.rule()).parse("hello", events.sink())
    match events.collect().get(1) {
    Some(Text(text)) => assert_eq(text, "hello")
    _ => abort("expected text")
    }
    }

    #Extensions

    Rules are composable syntax definitions. A rule can register parser entries or apply controls such as disable, enable, and replace. Processors and rules are immutable builders: each method returns a new value.

    Syntax extensions and HTML renderers are configured separately. For example, GFM tables and strikethrough emit GFM event tags, and @gfm.html_renderers() provides CommonMark plus GFM renderers.

    ///|
    test {
    let rule = @gfm.rule()
    let html = @markdown.Html(@gfm.html_renderers())
    @markdown.Processor(rule).parse("~~done~~", html.sink())
    assert_eq(html.to_string(), "<p><del>done</del></p>\n")
    }

    ///|
    test {
    let math = @markdown.Rule::inline(
    @markdown.RuleName::raw("x:inline:math"),
    priority=100,
    triggers="$",
    fn(ctx, sink) {
    let scanner = ctx.scanner()
    if !scanner.has_prefix("$") {
    NoMatch
    } else {
    let mut end = 1
    while scanner.char_at_offset(end) != Some(36) &&
    ctx.offset() + end < ctx.source().length() {
    end = end + 1
    }
    if ctx.offset() + end >= ctx.source().length() {
    NoMatch
    } else {
    match scanner.slice(1, end) {
    Some(text) => {
    @markdown.EventFragment::element(
    Element(@markdown.Tag::raw("x:math")),
    children=[@markdown.EventFragment::text(text)],
    ).emit_to(sink)
    Match(ConsumedChars(end + 1))
    }
    None => NoMatch
    }
    }
    }
    },
    )

    let html = @markdown.Html(@commonmark.html_renderers())
    let rule = @commonmark.rule().extend(math)
    @markdown.Processor(rule).parse("Euler: $x + y$", html.sink())
    assert_eq(html.to_string(), "<p>Euler: <x:math>x + y</x:math></p>\n")
    }

    ///|
    test {
    let no_raw_html = @markdown.Rule("no-raw-html")
    .disable(@markdown.RuleName::commonmark("block:html"))
    .disable(@markdown.RuleName::commonmark("inline:raw_html"))

    let html = @markdown.Html(@commonmark.html_renderers())
    let rule = @commonmark.rule().extend(no_raw_html)
    @markdown.Processor(rule).parse("<span>raw</span>", html.sink())
    assert_eq(html.to_string(), "<p>&lt;span&gt;raw&lt;/span&gt;</p>\n")
    }

    #Sinks

    Sink is the only downstream contract. You can create one directly, use the built-in sinks, or transform an existing sink.

    ///|
    test {
    let ast = @markdown.Ast()
    let sink = ast.sink().text_merge()
    sink.emit(Enter(Element(@markdown.Tag::raw("x:note"))))
    sink.emit(Text("a"))
    sink.emit(Text("b"))
    sink.emit(Exit(@markdown.Tag::raw("x:note")))
    sink.finish()

    let root = ast.result()
    assert_eq(
    root.to_json().stringify(),
    (
    #|{"type":"root","children":[{"type":"mdastExtension","name":"x:note","attributes":{},"children":[{"type":"text","value":"ab"}]}]}
    ),
    )
    }

    Event streams are tree-shaped. Enter(element) opens an element, Exit(tag) closes the most recent open element with the same tag, and text, breaks, and raw HTML events are leaves. Ast validates that contract. Html renders the stream as it arrives.

    #Development

    Use just from the Nix development shell:

    nix develop just

    just check # all MoonBit modules just fmt # all MoonBit modules just test # library tests just verify just conformance just bench

    BlockRuleFn

    type BlockRuleFn = (BlockContext) -> BlockRuleResult

    A block rule consumes source lines and returns events for accepted matches.

    CoreRuleFn

    type CoreRuleFn = (Sink) -> Sink

    A core rule wraps a downstream sink with stream transformation behavior.

    HtmlRendererFn

    type HtmlRendererFn = (HtmlWriter, Element) -> String

    A function that renders an opening HTML element and returns its close text.

    InlineRuleFn

    type InlineRuleFn = (InlineContext, Sink) -> InlineRuleResult

    An inline rule consumes characters from inline source and emits events for accepted matches.

    AstError

    pub(all) suberror AstError {
    UnexpectedExit(Tag)
    MismatchedExit(Tag, Tag)
    UnclosedTag(Tag)
    }

    An error raised when an event stream cannot form a balanced AST.

    Ast

    pub struct Ast {
    // private fields
    }
    fn Ast::Ast() -> Ast

    A streaming AST builder sink.

    Ast::result

    fn Ast::result(self : Ast) -> AstNode raise AstError

    Returns the AST root after the stream has finished.

    Ast::sink

    fn Ast::sink(self : Ast) -> Sink

    Returns a sink that builds the AST as events arrive.

    AstNode

    pub(all) enum AstNode {
    AstRoot(Array[AstNode])
    AstParagraph(Array[AstNode])
    AstHeading(Int, Array[AstNode])
    AstThematicBreak
    AstBlockquote(Array[AstNode])
    AstList(Bool, Int?, Bool, Array[AstNode])
    AstListItem(Bool, Bool?, Array[AstNode])
    AstCode(String, String?, String?)
    AstHtml(String)
    AstText(String)
    AstEmphasis(Array[AstNode])
    AstStrong(Array[AstNode])
    AstInlineCode(String)
    AstBreak
    AstLink(String, String?, Array[AstNode])
    AstImage(String, String?, String)
    AstDelete(Array[AstNode])
    AstTable(Array[String?], Array[AstNode])
    AstTableRow(Array[AstNode])
    AstTableCell(String?, Array[AstNode])
    AstTableSection(Array[AstNode])
    AstExtension(String, Array[Attr], Array[AstNode])
    }

    A Markdown AST node shaped to serialize as mdast-compatible JSON.
    impl ToJson for AstNode

    Attr

    pub struct Attr {
    // private fields
    }
    fn Attr::Attr(name : AttrName, value : String) -> Attr

    An attribute attached to an Element.

    Attr::name

    fn Attr::name(self : Attr) -> AttrName

    Returns the attribute name.

    Attr::value

    fn Attr::value(self : Attr) -> String

    Returns the attribute value.

    AttrName

    pub struct AttrName {
    // private fields
    } derive(Eq)

    An element attribute name.

    CommonMark attributes such as level, destination, and title are unqualified. Extension attributes can use a custom namespace.

    AttrName::commonmark

    fn AttrName::commonmark(name : String) -> AttrName

    Creates a CommonMark attribute name.

    Attribute names are not prefixed with cm: because they are interpreted in the context of their element tag.

    AttrName::custom

    fn AttrName::custom(ns : String, name : String) -> AttrName

    Creates an extension attribute name from ns and name as ns:name.

    AttrName::raw

    fn AttrName::raw(value : String) -> AttrName

    Creates an attribute name from an already-qualified value.

    AttrName::to_string

    fn AttrName::to_string(self : AttrName) -> String

    Returns the attribute name value used by renderers.

    BlockContext

    pub struct BlockContext {
    // private fields
    }

    Context passed to block rules.

    BlockContext::current_line

    fn BlockContext::current_line(self : BlockContext) -> String

    Returns the line currently being considered by a block rule.

    BlockContext::current_line_start

    fn BlockContext::current_line_start(self : BlockContext) -> Int

    Returns the parser offset where the current source line starts.

    BlockContext::is_collecting

    fn BlockContext::is_collecting(self : BlockContext) -> Bool

    Returns whether the parser is currently collecting definitions.

    BlockContext::line

    fn BlockContext::line(self : BlockContext, offset : Int) -> String?

    Returns the source line at offset relative to the current block line.

    BlockContext::line_at

    fn BlockContext::line_at(self : BlockContext, index : Int) -> String?

    Returns the source line at index, if it exists.

    BlockContext::line_count

    fn BlockContext::line_count(self : BlockContext) -> Int

    Returns the total number of source lines in this block parse.

    BlockContext::line_index

    fn BlockContext::line_index(self : BlockContext) -> Int

    Returns the current zero-based source line index.

    BlockContext::services

    fn BlockContext::services(self : BlockContext) -> ParserServices

    Returns parser services for nested parsing from a block rule.

    BlockContext::source_line_starts

    fn BlockContext::source_line_starts(self : BlockContext) -> Array[Int]

    Returns parser offsets for all source lines visible to this block parse.

    BlockContext::source_lines

    fn BlockContext::source_lines(self : BlockContext) -> Array[String]

    Returns all source lines visible to this block parse.

    BlockContext::source_offset

    fn BlockContext::source_offset(self : BlockContext, offset : Int) -> Int

    Returns the parser offset where the source line at offset starts.

    BlockRuleResult

    pub(all) enum BlockRuleResult {
    NoMatch
    Match(ConsumedLines, EventFragment)
    }

    ConsumedChars

    pub struct ConsumedChars {
    // private fields
    }
    fn ConsumedChars::ConsumedChars(value : Int) -> ConsumedChars

    A positive count of inline source characters consumed by a matched rule.

    ConsumedChars::to_int

    fn ConsumedChars::to_int(self : ConsumedChars) -> Int

    Returns the consumed-character count.

    ConsumedLines

    pub struct ConsumedLines {
    // private fields
    }
    fn ConsumedLines::ConsumedLines(value : Int) -> ConsumedLines

    A positive count of block source lines consumed by a matched rule.

    ConsumedLines::to_int

    fn ConsumedLines::to_int(self : ConsumedLines) -> Int

    Returns the consumed-line count.

    Element

    pub struct Element {
    // private fields
    }
    fn Element::Element(tag : Tag) -> Element

    A Markdown event element.

    Elements carry a tag, attributes, and an optional source range. Extension authors can construct elements with custom tags and attributes.

    Element::attr

    fn Element::attr(self : Element, name : AttrName) -> String?

    Returns the first attribute value for name, if present.

    Element::attrs

    fn Element::attrs(self : Element) -> Array[Attr]

    Returns the element attributes.

    Element::range

    fn Element::range(self : Element) -> SourceRange?

    Returns the source range attached to the element, if any.

    Element::tag

    fn Element::tag(self : Element) -> Tag

    Returns the element tag.

    Element::with_attrs

    fn Element::with_attrs(tag : Tag, attrs : Array[Attr], range? : SourceRange?) -> Element

    Creates an element with attributes and an optional source range.

    Event

    pub(all) enum Event {
    Enter(Element)
    Exit(Tag)
    Text(String)
    SoftBreak
    HardBreak
    RawHtml(String)
    }

    A parser event stream.

    Enter and Exit delimit elements by tag. Text, breaks, and raw HTML are leaf events. Extension tags are preserved by the parser, renderer, AST builder, and transforms.

    EventFragment

    pub struct EventFragment {
    // private fields
    }

    A balanced event sequence produced by a parser rule.

    EventFragment::concat

    fn EventFragment::concat(fragments : Array[EventFragment]) -> EventFragment

    Concatenates event fragments.

    EventFragment::element

    fn EventFragment::element(element : Element, children? : Array[EventFragment]) -> EventFragment

    Creates a balanced element event fragment.

    EventFragment::emit_to

    fn EventFragment::emit_to(self : EventFragment, sink : Sink) -> Unit

    Emits this fragment into sink.

    EventFragment::empty

    Creates an empty event fragment.

    EventFragment::events

    fn EventFragment::events(self : EventFragment) -> Array[Event]

    Returns a copy of the events in this fragment.

    EventFragment::from_events

    fn EventFragment::from_events(events : Array[Event]) -> EventFragment?

    Creates a fragment from events if all element enter/exit pairs are balanced.

    EventFragment::hard_break

    fn EventFragment::hard_break() -> EventFragment

    Creates a hard-break event fragment.

    EventFragment::html

    fn EventFragment::html(raw : String) -> EventFragment

    Creates a raw HTML event fragment.

    EventFragment::soft_break

    fn EventFragment::soft_break() -> EventFragment

    Creates a soft-break event fragment.

    EventFragment::text

    fn EventFragment::text(text : String) -> EventFragment

    Creates a text event fragment.

    Events

    pub struct Events {
    // private fields
    }
    fn Events::Events() -> Events

    A downstream sink that collects events into an array.

    Events::collect

    fn Events::collect(self : Events) -> Array[Event]

    Returns a copy of collected events.

    Events::into_fragment

    fn Events::into_fragment(self : Events) -> EventFragment

    Events::owned_events

    fn Events::owned_events(self : Events) -> Array[Event]

    Events::owned_sink

    fn Events::owned_sink(self : Events) -> Sink

    Events::sink

    fn Events::sink(self : Events) -> Sink

    Returns a sink that appends emitted events to this collector.

    Html

    pub struct Html {
    // private fields
    }
    fn Html::Html(renderers : HtmlRenderers, size_hint? : Int) -> Html

    A streaming HTML sink.

    Known tags are mapped by the configured renderers. Unknown extension tags are rendered with their tag value, with tag and attribute text escaped. Raw HTML events are passed through unchanged.

    Html::sink

    fn Html::sink(self : Html) -> Sink

    Returns a sink that renders events as they arrive.

    Html::to_string

    fn Html::to_string(self : Html) -> String

    Returns the rendered HTML.

    HtmlRenderers

    pub struct HtmlRenderers {
    // private fields
    }
    fn HtmlRenderers::HtmlRenderers() -> HtmlRenderers

    A composable set of HTML renderers keyed by Markdown event tags.

    HtmlRenderers does not parse Markdown. It only teaches Html how to render extension event tags emitted by syntax rules.

    HtmlRenderers::disable

    fn HtmlRenderers::disable(self : HtmlRenderers, tag : Tag) -> HtmlRenderers

    Disables the renderer for tag, causing Html to use unknown-tag fallback.

    HtmlRenderers::enable

    fn HtmlRenderers::enable(self : HtmlRenderers, tag : Tag) -> HtmlRenderers

    Re-enables the renderer for tag.

    HtmlRenderers::extend

    Appends all renderer operations from other.

    HtmlRenderers::register

    fn HtmlRenderers::register(self : HtmlRenderers, tag : Tag, f : (HtmlWriter, Element) -> String) -> HtmlRenderers

    Registers a renderer for tag.

    HtmlRenderers::replace

    fn HtmlRenderers::replace(self : HtmlRenderers, tag : Tag, f : (HtmlWriter, Element) -> String) -> HtmlRenderers

    Replaces the renderer for tag.

    HtmlWriter

    pub struct HtmlWriter {
    // private fields
    }

    A writer passed to custom HTML renderers.

    Renderer authors should use write_escaped and write_attrs for text and attribute output that comes from Markdown input.

    HtmlWriter::starts_with_block_child

    fn HtmlWriter::starts_with_block_child(self : HtmlWriter) -> Bool

    Returns whether the current element starts with a block child.

    HtmlWriter::write

    fn HtmlWriter::write(self : HtmlWriter, value : String) -> Unit

    Writes raw HTML.

    HtmlWriter::write_attrs

    fn HtmlWriter::write_attrs(self : HtmlWriter, attrs : Array[Attr]) -> Unit

    Writes escaped HTML attributes.

    HtmlWriter::write_attrs_except1

    fn HtmlWriter::write_attrs_except1(self : HtmlWriter, attrs : Array[Attr], excluded : String) -> Unit

    Writes escaped HTML attributes except one named attribute.

    HtmlWriter::write_attrs_except2

    fn HtmlWriter::write_attrs_except2(self : HtmlWriter, attrs : Array[Attr], first : String, second : String) -> Unit

    Writes escaped HTML attributes except two named attributes.

    HtmlWriter::write_attrs_except3

    fn HtmlWriter::write_attrs_except3(self : HtmlWriter, attrs : Array[Attr], first : String, second : String, third : String) -> Unit

    Writes escaped HTML attributes except three named attributes.

    HtmlWriter::write_escaped

    fn HtmlWriter::write_escaped(self : HtmlWriter, value : String) -> Unit

    Writes escaped HTML text.

    InlineContext

    pub struct InlineContext {
    // private fields
    }

    Context passed to inline and delimiter rules.

    InlineContext::has_inline_trigger_at

    fn InlineContext::has_inline_trigger_at(self : InlineContext, index : Int) -> Bool

    Returns whether any inline rule declares the character at index as a trigger. Text rules can use this to leave extension starts visible to the extension rule instead of consuming them as ordinary text.

    InlineContext::has_inline_triggers_other_than

    fn InlineContext::has_inline_triggers_other_than(self : InlineContext, ignored : String) -> Bool

    Returns whether any inline rule declares a trigger outside ignored.

    Text rules can use this to keep their own syntax characters on the fast path while still yielding to extension rules with new trigger characters.

    InlineContext::offset

    fn InlineContext::offset(self : InlineContext) -> Int

    Returns the current parser offset in the inline source.

    InlineContext::scanner

    Returns a scanner positioned at the current inline offset.

    InlineContext::services

    Returns parser services for nested parsing from an inline rule.

    InlineContext::source

    fn InlineContext::source(self : InlineContext) -> String

    Returns the full inline source being scanned.

    InlineRuleResult

    pub(all) enum InlineRuleResult {
    NoMatch
    Match(ConsumedChars)
    }

    InlineScanner

    pub struct InlineScanner {
    // private fields
    }

    A small scanner for inline rule implementations.

    InlineScanner::char

    fn InlineScanner::char(self : InlineScanner) -> Int?

    Returns the character code at the scanner position.

    InlineScanner::char_at_offset

    fn InlineScanner::char_at_offset(self : InlineScanner, offset : Int) -> Int?

    Returns the character code at an offset from the scanner position.

    InlineScanner::find_char

    fn InlineScanner::find_char(self : InlineScanner, needle : Int) -> Int?

    Finds needle from the scanner position and returns a relative offset.

    InlineScanner::has_prefix

    fn InlineScanner::has_prefix(self : InlineScanner, prefix : String) -> Bool

    Returns whether the scanner position starts with prefix.

    InlineScanner::new

    fn InlineScanner::new(text : String, index : Int) -> InlineScanner?

    Creates an inline scanner positioned at index.

    InlineScanner::slice

    fn InlineScanner::slice(self : InlineScanner, start_offset : Int, end_offset : Int) -> String?

    Returns a slice relative to the scanner position.

    ParserServices

    pub struct ParserServices {
    // private fields
    }

    Parser services exposed to rule implementations.

    ParserServices::collect_block_lines

    fn ParserServices::collect_block_lines(self : ParserServices, lines : Array[String], line_starts : Array[Int]) -> Unit

    Runs block rules in definition-collection mode over lines.

    ParserServices::parse_block_lines

    fn ParserServices::parse_block_lines(self : ParserServices, lines : Array[String], line_starts : Array[Int], sink : Sink) -> Unit

    Parses block lines with the current rule set into sink.

    ParserServices::parse_inline

    fn ParserServices::parse_inline(self : ParserServices, text : String, sink : Sink) -> Unit

    Parses inline text with the current inline rule set into sink.

    ParserServices::parse_inline_fragment

    fn ParserServices::parse_inline_fragment(self : ParserServices, text : String) -> EventFragment

    Parses inline text with the current inline rule set and returns a fragment.

    ParserServices::set_state_string

    fn ParserServices::set_state_string(self : ParserServices, key : StateKey, item : String, value : String) -> Unit

    Stores a string value in parser state.

    ParserServices::state_string

    fn ParserServices::state_string(self : ParserServices, key : StateKey, item : String) -> String?

    Returns a string value from parser state.

    Processor

    pub struct Processor {
    // private fields
    }
    fn Processor::Processor(rule : Rule) -> Processor

    A configured Markdown processor.

    A processor owns the rule registry used to turn Markdown input into events. Build it from a rule before calling parse.

    Processor::parse

    fn Processor::parse(self : Processor, input : String, sink : Sink) -> Unit

    Parses Markdown input and pushes events into sink.

    Core event rules wrap the downstream sink, so transforms can participate in the parse pipeline.

    Rule

    pub struct Rule {
    // private fields
    }
    fn Rule::Rule(name : String) -> Rule

    A composable Markdown syntax rule.

    A rule can be a single block, inline, delimiter, or core parser entry, or a larger rule made by composing smaller rules. Rules preserve operation order when composed, so a rule can model one extension or a whole rule.

    Rule::block

    fn Rule::block(name : RuleName, priority? : Int, before? : Array[RuleName], after? : Array[RuleName], triggers? : String, f : (BlockContext) -> BlockRuleResult) -> Rule

    Creates a block-start rule.

    Rule::block_continue

    fn Rule::block_continue(name : RuleName, priority? : Int, before? : Array[RuleName], after? : Array[RuleName], triggers? : String, f : (BlockContext) -> BlockRuleResult) -> Rule

    Creates a block-continuation rule.

    Continuation rules run before block-start rules at each source line.

    Rule::core

    fn Rule::core(name : RuleName, priority? : Int, before? : Array[RuleName], after? : Array[RuleName], f : (Sink) -> Sink) -> Rule

    Creates a core event rule.

    Rule::delimiter

    fn Rule::delimiter(name : RuleName, priority? : Int, before? : Array[RuleName], after? : Array[RuleName], triggers? : String, f : (InlineContext, Sink) -> InlineRuleResult) -> Rule

    Creates a delimiter rule.

    Delimiter rules run in the inline phase before ordinary inline rules.

    Rule::disable

    fn Rule::disable(self : Rule, name : RuleName) -> Rule

    Disables a named parser entry when this rule is installed.

    Rule::enable

    fn Rule::enable(self : Rule, name : RuleName) -> Rule

    Re-enables a named parser entry when this rule is installed.

    Rule::extend

    fn Rule::extend(self : Rule, rule : Rule) -> Rule

    Appends all operations from rule to this rule.

    Rule::inline

    fn Rule::inline(name : RuleName, priority? : Int, before? : Array[RuleName], after? : Array[RuleName], triggers? : String, f : (InlineContext, Sink) -> InlineRuleResult) -> Rule

    Creates an inline rule.

    Rule::name

    fn Rule::name(self : Rule) -> String

    Returns the rule name.

    Rule::replace

    fn Rule::replace(self : Rule, rule : Rule) -> Rule

    Replaces parser entries with the same names as entries in rule.

    Replacements are remembered by the registry, so they apply to both current and later matching entries from composed rules. If no base entry is ever registered, the replacement rule still participates as an ordinary rule.

    RuleName

    pub struct RuleName {
    // private fields
    } derive(Eq)

    A rule identifier used for ordering, override, enable, and disable.

    Built-in CommonMark rules use the cm: namespace.

    RuleName::commonmark

    fn RuleName::commonmark(name : String) -> RuleName

    Creates a CommonMark rule name by prefixing name with cm:.

    RuleName::custom

    fn RuleName::custom(ns : String, name : String) -> RuleName

    Creates an extension rule name from ns and name as ns:name.

    RuleName::raw

    fn RuleName::raw(value : String) -> RuleName

    Creates a rule name from an already-qualified value.

    RuleName::to_string

    fn RuleName::to_string(self : RuleName) -> String

    Returns the rule name value used by Processor rule controls.

    Sink

    pub struct Sink {
    // private fields
    }
    fn Sink::Sink(emit : (Event) -> Unit, finish? : () -> Unit) -> Sink

    A downstream event consumer used by parsers, rules, renderers, and transforms.

    Sink::emit

    fn Sink::emit(self : Sink, event : Event) -> Unit

    Emits an event downstream.

    Sink::finish

    fn Sink::finish(self : Sink) -> Unit

    Finishes the stream and lets downstream consumers flush buffered state.

    Sink::inject_attr

    fn Sink::inject_attr(self : Sink, tag : Tag, attr : Attr) -> Sink

    Creates a sink that appends an attribute to matching Enter elements.

    Sink::map

    fn Sink::map(self : Sink, f : (Event) -> Event) -> Sink

    Creates a sink that maps every event before forwarding it downstream.

    Sink::on_finish

    fn Sink::on_finish(self : Sink, f : (Sink) -> Unit) -> Sink

    Creates a sink that runs f before finishing downstream.

    Sink::rename_tag

    fn Sink::rename_tag(self : Sink, from : Tag, to : Tag) -> Sink

    Creates a sink that renames matching Enter and Exit tags.

    Sink::softbreak_to_hardbreak

    fn Sink::softbreak_to_hardbreak(self : Sink) -> Sink

    Creates a sink that rewrites every SoftBreak event to HardBreak.

    Sink::text_merge

    fn Sink::text_merge(self : Sink) -> Sink

    Creates a sink that merges adjacent Text events before forwarding.

    SourceRange

    pub struct SourceRange {
    // private fields
    }

    A parser source range measured in MoonBit string offsets.

    start is inclusive and end is exclusive. These offsets are compatible with the parser's String indexing and line normalization; they are not UTF-8 byte offsets.

    SourceRange::end

    fn SourceRange::end(self : SourceRange) -> Int

    Returns the exclusive end parser offset.

    SourceRange::new

    fn SourceRange::new(start : Int, end : Int) -> SourceRange?

    Creates a source range from inclusive start and exclusive end parser offsets.

    SourceRange::start

    fn SourceRange::start(self : SourceRange) -> Int

    Returns the inclusive start parser offset.

    StateKey

    pub struct StateKey {
    // private fields
    }
    fn StateKey::StateKey(scope : String, name : String) -> StateKey

    Tag

    pub struct Tag {
    // private fields
    } derive(Eq)

    A Markdown element tag used by events, renderers, and transforms.

    CommonMark tags use the cm: namespace. Extension authors should use a custom namespace or an agreed raw value to avoid collisions.

    Tag::commonmark

    fn Tag::commonmark(name : String) -> Tag

    Creates a CommonMark tag by prefixing name with cm:.

    Tag::custom

    fn Tag::custom(ns : String, name : String) -> Tag

    Creates an extension tag from ns and name as ns:name.

    Tag::raw

    fn Tag::raw(value : String) -> Tag

    Creates a tag from an already-qualified value.

    Tag::to_string

    fn Tag::to_string(self : Tag) -> String

    Returns the tag value used in events and rendered extension HTML.