How the AST is rendered into native views with syntax highlighting
The MarkdownView module transforms the parsed AST into rich, interactive native views. This involves converting block and inline nodes into NSAttributedString, embedding custom views for complex elements, and handling user interactions.
public class LTXLabel: LTXPlatformView { public var attributedText: NSAttributedString = .init() { didSet { textLayout = LTXTextLayout(attributedString: attributedText) } } public var preferredMaxLayoutWidth: CGFloat = 0 { didSet { if preferredMaxLayoutWidth != oldValue { invalidateTextLayout() } } } public var isSelectable: Bool = false public var selectionBackgroundColor: PlatformColor? public weak var delegate: LTXLabelDelegate?}
LTXLabel handles all text layout, rendering, and interaction. It’s used by MarkdownTextView to display the final rendered content.
LTXLabel is a generic text rendering component, not specific to markdown. It can display any NSAttributedString with custom attachments and drawing callbacks.
case let .math(content, replacementIdentifier): let latexContent = context.rendered[replacementIdentifier]?.text ?? content if let item = context.rendered[replacementIdentifier], let image = item.image { var imageSize = image.size let drawingCallback = LTXLineDrawingAction { context, line, lineOrigin in // Calculate position within the line let rect = CGRect(x: lineOrigin.x + runOffsetX, y: lineOrigin.y, width: imageSize.width, height: imageSize.height) // Draw the math image image.draw(in: rect) } let attachment = LTXAttachment.hold(attrString: .init(string: latexContent)) attachment.size = imageSize return NSAttributedString( string: LTXReplacementText, attributes: [ LTXAttachmentAttributeName: attachment, LTXLineDrawingCallbackName: drawingCallback, kCTRunDelegateAttributeName: attachment.runDelegate, ] ) }
The LTXLineDrawingAction callback is invoked during Core Text rendering to draw the math image at the correct position.
Math images are rendered as template images on UIKit and use dynamic color resolution on AppKit, ensuring they adapt to dark mode automatically.
import MarkdownParserimport MarkdownViewlet markdown = """# Code ExampleHere's a Swift function:```swiftfunc greet(_ name: String) -> String { return "Hello, \(name)!"}
Bold and italic text.
"""// Parse
let parser = MarkdownParser()
let result = parser.parse(markdown)// Preprocess (on main thread for math rendering)
let content = MarkdownTextView.PreprocessedContent(
parserResult: result,
theme: .default
)// Render
let markdownView = MarkdownTextView()
markdownView.setMarkdown(content)
The view now displays the markdown with:- Heading in large bold font- Syntax-highlighted Swift code in a CodeView- Inline formatting (bold and italic)See the [architecture overview](/core-concepts/architecture) for how parsing and rendering connect.