SwiftMarkdownParser Usage Guide
September 16, 2025 ยท View on GitHub
Complete reference for parsing Markdown and working with the AST.
Basic Usage
import SwiftMarkdownParser
// Create parser
let parser = SwiftMarkdownParser()
// Parse to AST
let ast = try await parser.parseToAST("# Hello **World**!")
// Parse directly to HTML
let html = try await parser.parseToHTML("# Hello **World**!")
Configuration
let config = SwiftMarkdownParser.Configuration(
enableGFMExtensions: true, // Tables, task lists, strikethrough
strictMode: false, // Relaxed parsing
maxNestingDepth: 100, // Recursion limit
trackSourceLocations: false, // Debug info
maxParsingTime: 30.0 // Timeout in seconds
)
let parser = SwiftMarkdownParser(configuration: config)
AST Structure
The parser generates a hierarchical AST with these main node types:
Common Nodes
AST.DocumentNode- Root document nodeAST.HeadingNode- Headings (# ## ###)AST.ParagraphNode- Text paragraphsAST.TextNode- Plain text contentAST.EmphasisNode- italic textAST.StrongEmphasisNode- bold textAST.LinkNode- text linksAST.ImageNode-images
AST.CodeBlockNode-codeblocksAST.InlineCodeNode-codespansAST.ListNode- Ordered/unordered listsAST.ListItemNode- List itemsAST.BlockQuoteNode- > blockquotes
GFM Extension Nodes
AST.GFMTableNode- Pipe-separated tablesAST.GFMTableRowNode- Table rowsAST.GFMTableCellNode- Table cellsAST.GFMTaskListItemNode- [x] task listsAST.GFMStrikethroughNode-strikethrough
Working with AST
let parser = SwiftMarkdownParser()
let ast = try await parser.parseToAST(markdown)
func analyzeDocument(_ node: ASTNode) {
switch node {
case let heading as AST.HeadingNode:
print("Heading level \(heading.level)")
case let link as AST.LinkNode:
print("Link: \(link.url)")
case let codeBlock as AST.CodeBlockNode:
print("Code: \(codeBlock.language ?? "plain")")
case let table as AST.GFMTableNode:
print("Table: \(table.rows.count) rows")
default:
break
}
// Process children recursively
for child in node.children {
analyzeDocument(child)
}
}
analyzeDocument(ast)
Error Handling
do {
let ast = try await parser.parseToAST(markdown)
} catch MarkdownParsingError.invalidInput(let message) {
print("Invalid input: \(message)")
} catch MarkdownParsingError.tokenizationFailed(let message) {
print("Tokenization failed: \(message)")
} catch {
print("Parsing failed: \(error)")
}
Performance Tips
- Use default configuration for most cases
- Increase
maxParsingTimeonly for very large documents - Set
trackSourceLocations: falsefor better performance - Consider parsing to AST once and rendering multiple times