Guide

Selection, copy, and export

Selecting across blocks, what goes on the pasteboard, Find, and PDF export.

SDK on GitHub ↗

Selection

Selection works across blocks by default. On macOS, you can click and drag across paragraphs, tables, code, and math, and use the keyboard to extend the selection. Double-clicking selects a whole word, even when the word has been broken across lines. Option-arrow moves by word in the direction you press, and in bidirectional text the caret moves in visual order.

On iPhone and iPad, a long press or double tap selects a word. Two handles with 44-point touch targets adjust the selection, and the system edit menu appears next to the selected text.

MarkdownSelectionController publishes the current selection, and MarkdownCopyProvider(markdownSource:) lets copy return the exact source text.

swift
let controller = MarkdownSelectionController()
StreamingMarkdownView(preparedSnapshot: prepared, configuration: configuration)
    .markdownSelectionController(controller)

If you split a long document into several prepared sections, share one controller and one MarkdownSelectionDocument across them so Select All and Copy cover the whole document.

Copy

Copying puts plain text and the exact Markdown on the pasteboard. Complete selections also provide HTML, and macOS adds RTF. Selections crossing unloaded windowed content may omit rich formats rather than provide incomplete HTML or RTF. Links in the copied HTML follow the same link policy as the document. Copying an equation gives you its original LaTeX.

Partial semantic Copy and native RTF retain selected styled words and spaces without adding unselected list markers or a paragraph terminator. Selected authored line breaks and joins between disjoint ranges remain intact.

Formatting the selection

If your app owns the Markdown source, you can let readers apply formatting to what they've selected. Set MarkdownRendererConfiguration.selectionFormatting with a MarkdownFormattingHandler. The automatic presentation uses a floating bar for pointer interaction and a Format section in the touch edit menu. Hosts can choose a presentation explicitly. Each button sends a MarkdownFormattingRequest with the exact source range, the selected Markdown and plain text, and the snapshot generation. Your app applies the change to its own source and publishes a new snapshot. Without this setting, the renderer is read-only.

Find and navigation

MarkdownDocumentFindController searches the rendered text, with options to ignore case and diacritics. Moving between matches wraps around at the ends, and the current match is kept as new text streams in. MarkdownDocumentFindBar is a native search field. If your app owns the scroll view, you can pin the bar above it and hide the inline controls. Headings get predictable, unique IDs you can link to, and so do id attributes in HTML.

Find matches literal visible text across inline formatting, with separate block and table-cell boundaries. Hidden HTML and rasterized equation source are excluded. Next or Previous reveals the current occurrence even when it is the only match. Table and code results also reveal horizontally hidden text.

Navigation retains the destination while document content settles, prepared content changes or the viewport is resized. Reader scrolling or selection, closing Find, replacing the document, removing the view or issuing another command supersedes the earlier reveal. Use independent Find controllers for independent documents. On macOS, document content mounts around the viewport, retaining selection and offscreen scroll destinations. Code collapse, diagram source and camera choices, and explicitly started video sessions survive scrolling away from their source. Empty HTML anchors reveal their actual block or neighbor without adding text.

Readable chart export does not interrupt subsequent Find navigation. The rendered match stays visible as the reader settles after resizing, including code and table matches inside horizontal scrollers.

Text beside semicolon-terminated HTML character references keeps its exact source range; a decoded reference selects its complete authored span. Unreconciled HTML normalization conservatively selects the containing source node, which can include neighboring text.

On macOS, create the export from a prepared snapshot:

swift
let output = try MarkdownDocumentPrintExporter.prepare(prepared)
try output.writePDF(to: destination)
let operation = try output.makePrintOperation()

The PDF keeps text selectable, including in tables. Tables repeat their headers on each new page, links stay clickable, and images and math are included. Prepared Mermaid diagrams draw as vectors on macOS and iPadOS, including formula outlines. Figures fit the printable page and retain their captions and nested quote/list indentation. The export also tells you about anything it couldn't include as rendered, such as mathAsSourceText when your app uses the plain math renderer.

Native diagram labels retain shaped Unicode and composed emoji when embedded in a text-flow PDF. Neutral PDF labels carry a direction mark beside right-to-left text; that mark can appear in copied text. Readers can infer different word order or line breaks. Use Copy Source for exact authored text. Try the native diagram PDF and its Markdown source, or open the Unicode example in the playground.

On macOS and iPadOS, reader-page export captures the rendered appearance as raster pages. Choose text-flow export when selectable PDF text matters. Use .readable pagination to prefer breaks between blocks; oversized blocks may still span pages.

Accessibility

Links in rendered text are native accessibility actions. On macOS, native table accessibility exposes row, column, header, and merged-cell relationships. Verify touch-platform navigation in your host app. Equations expose their structure, figures keep their caption and image description separate, and diagrams come with a spoken summary. Lists and block quotes read item by item.

Document interactions

Native captureOpen original ↗
Native document capture