Skip to main content
MarkdownParser is the main class for converting markdown text into a structured abstract syntax tree (AST). It uses cmark-gfm under the hood and supports GitHub Flavored Markdown extensions including tables, task lists, and strikethrough.

Initialization

public init()
Creates a new markdown parser instance.
let parser = MarkdownParser()

Methods

parse()

Parses markdown text into a complete document AST.
public func parse(_ markdown: String) -> ParseResult
markdown
String
required
The markdown text to parse
ParseResult
ParseResult
Contains the parsed document nodes and math context mapping
document
[MarkdownBlockNode]
Array of root-level block nodes representing the document structure
mathContext
[Int: String]
Dictionary mapping math replacement identifiers to their original LaTeX content

Example

let parser = MarkdownParser()
let result = parser.parse("# Hello World\n\nThis is **bold** text.")
print(result.document) // [.heading(level: 1, ...), .paragraph(...)]

parseIncremental()

Performs incremental parsing by reusing previously parsed blocks when possible. This is optimized for real-time editing scenarios where only the end of the document changes.
public func parseIncremental(
    previousMarkdown: String,
    newMarkdown: String,
    previousBlocks: [MarkdownBlockNode],
    previousRanges: [RootBlockRange]? = nil
) -> IncrementalParseResult?
previousMarkdown
String
required
The previous version of the markdown text
newMarkdown
String
required
The new version of the markdown text (must be longer than previous)
previousBlocks
[MarkdownBlockNode]
required
The previously parsed block nodes from the previous markdown
previousRanges
[RootBlockRange]?
default:"nil"
Optional cached ranges from previous parsing. If nil, they will be computed.
IncrementalParseResult
IncrementalParseResult?
Returns nil if incremental parsing is not applicable, otherwise returns the incremental result
stablePrefixBlockCount
Int
Number of blocks from the previous parse that remain unchanged
tailResult
ParseResult
Parse result for the changed portion of the document
blockRanges
[RootBlockRange]
Updated block ranges for all blocks in the new document

Example

let parser = MarkdownParser()
let initialText = "# Title\n\nParagraph 1"
let initialResult = parser.parse(initialText)

let newText = "# Title\n\nParagraph 1\n\nParagraph 2"
if let incrementalResult = parser.parseIncremental(
    previousMarkdown: initialText,
    newMarkdown: newText,
    previousBlocks: initialResult.document
) {
    // Reuse first N blocks, append tail
    let updatedBlocks = Array(initialResult.document.prefix(incrementalResult.stablePrefixBlockCount)) 
        + incrementalResult.tailResult.document
}

parseBlockRange()

Computes the source range of each root-level block in the markdown document without performing full parsing.
public func parseBlockRange(_ markdown: String) -> [RootBlockRange]
markdown
String
required
The markdown text to analyze
[RootBlockRange]
[RootBlockRange]
Array of range information for each root block
type
MarkdownNodeType
The type of the block node
startIndex
String.Index
Starting position in the source text
endIndex
String.Index
Ending position in the source text
outputBlockCount
Int
Number of blocks this root node will produce after transformation

Example

let parser = MarkdownParser()
let ranges = parser.parseBlockRange("# Heading\n\nParagraph")
for range in ranges {
    print("Block type: \(range.type), outputs \(range.outputBlockCount) blocks")
}

Types

ParseResult

public struct ParseResult {
    public let document: [MarkdownBlockNode]
    public let mathContext: [Int: String]
}
The result of parsing markdown text.

IncrementalParseResult

public struct IncrementalParseResult {
    public let stablePrefixBlockCount: Int
    public let tailResult: ParseResult
    public let blockRanges: [RootBlockRange]
}
The result of incremental parsing.

RootBlockRange

public struct RootBlockRange {
    public let type: MarkdownNodeType
    public let startIndex: String.Index
    public let endIndex: String.Index
    public let outputBlockCount: Int
}
Describes the source location and output characteristics of a root block.

Build docs developers (and LLMs) love