Skip to main content
ParseResult is returned by the parse() and parseIncremental() methods of MarkdownParser. It contains the structured AST representation of the markdown document along with any extracted mathematical expressions.

Structure

public struct ParseResult {
    public let document: [MarkdownBlockNode]
    public let mathContext: [Int: String]
}

Fields

document
[MarkdownBlockNode]
required
Array of root-level block nodes representing the parsed document structure. Each element is a MarkdownBlockNode enum case such as .paragraph, .heading, .codeBlock, etc.The document array contains only top-level blocks. Nested blocks (like paragraphs inside a blockquote) are contained within their parent’s structure.
mathContext
[Int: String]
required
Dictionary mapping math replacement identifiers to their original LaTeX content.When the parser encounters inline or block math expressions (like $E = mc^2$ or $$...$$), it:
  1. Extracts the LaTeX content
  2. Assigns it a unique integer identifier
  3. Replaces it with a placeholder in the AST
  4. Stores the mapping in mathContext
The keys are integer identifiers, and the values are the original LaTeX strings.

Usage

Basic Parsing

let parser = MarkdownParser()
let result = parser.parse("""
# Mathematics Example

The formula $E = mc^2$ represents energy-mass equivalence.

$$
\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}
$$
""")

// Access document structure
for block in result.document {
    switch block {
    case .heading(let level, let content):
        print("Heading level \(level)")
    case .paragraph(let content):
        print("Paragraph with \(content.count) inline nodes")
    default:
        break
    }
}

// Access extracted math expressions
for (id, latex) in result.mathContext {
    print("Math [\(id)]: \(latex)")
}

Working with Math Context

let result = parser.parse("Inline math: $x^2 + y^2 = z^2$")

// Find math nodes in the document
if case .paragraph(let inlines) = result.document.first {
    for inline in inlines {
        if case .math(let content, let replacementId) = inline {
            // Look up original LaTeX in mathContext
            if let originalLatex = result.mathContext[Int(replacementId) ?? 0] {
                print("Math expression: \(originalLatex)")
            }
        }
    }
}

Incremental Parsing

let parser = MarkdownParser()
let initialResult = parser.parse("# Title\n\nInitial content")

let newText = "# Title\n\nInitial content\n\nNew paragraph"
if let incremental = parser.parseIncremental(
    previousMarkdown: "# Title\n\nInitial content",
    newMarkdown: newText,
    previousBlocks: initialResult.document
) {
    // Merge math contexts
    var mergedMath = Dictionary(
        uniqueKeysWithValues: initialResult.mathContext
            .prefix(incremental.stablePrefixBlockCount)
    )
    mergedMath.merge(incremental.tailResult.mathContext) { $1 }
    
    // Combine blocks
    let finalBlocks = Array(initialResult.document.prefix(incremental.stablePrefixBlockCount))
        + incremental.tailResult.document
    
    let finalResult = MarkdownParser.ParseResult(
        document: finalBlocks,
        mathContext: mergedMath
    )
}

Build docs developers (and LLMs) love