System Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
Writer is a distraction-free Markdown editor for macOS built with SwiftUI. Its architecture is centered around a live-rendering pipeline that converts Markdown text into multiple output formats (HTML, PDF, RTF) while maintaining a clean, sidebar-driven file management system. The application leverages the modern Swift Observation framework for reactive state management.
Sources: CLAUDE.md:1-10, Writer/WriterApp.swift:1-15
Core Application Components
The system is organized into several key architectural layers: state management, user interface, rendering/formatting, and export utilities.
State Management & Data Flow
The application uses a centralized state pattern where @Observable stores are injected into the SwiftUI environment. EditorStore acts as the primary orchestrator, managing the file tree, security-scoped bookmarks for folder access, and document persistence.
The EditorStore uses URL.startAccessingSecurityScopedResource() to maintain persistent access to user-selected directories across sessions.
Sources: Writer/EditorStore.swift:15-50, CLAUDE.md:20-25, Writer/WriterApp.swift:10-15
UI Hierarchy
The interface is built on a NavigationSplitView consisting of a sidebar for file navigation and a detail view for editing and previewing.
| Component | Responsibility | Derived From |
|---|---|---|
| Sidebar | Hierarchical file tree navigation, context menus for file operations (rename, delete, duplicate). | Writer/ContentView.swift |
| MarkdownTextView | A custom NSViewRepresentable wrapping NSTextView for syntax-highlighted editing. | Writer/MarkdownTextView.swift |
| WebView | Renders the HTML output of the Markdown content for live preview. | CLAUDE.md:31-35 |
| Toolbar | Provides controls for preview toggling, manual saving, and refreshing the file tree. | Writer/ContentView.swift |
Sources: Writer/ContentView.swift:20-80, Writer/MarkdownTextView.swift:15-30
Markdown Processing Pipeline
The conversion of raw text to a visual preview or exportable file follows a structured pipeline using a custom MarkupVisitor.
Rendering Logic
- Parsing: Uses Apple's
Markdownframework to parse text into aDocumentAST. - Visitation: The
HTMLVisitortraverses the AST to generate HTML tags. - Custom Extensions: The
MarkdownRendererprocesses non-standard syntax like==highlight==using regular expressions. - Styling: The
PreviewThemeprovides acssStylesproperty that is injected into the HTML<head>.
Table Formatting
The TableFormatter provides specialized logic to detect and align Markdown tables. It calculates visual widths (accounting for CJK characters) and applies padding to ensure columns are vertically aligned in the plain text editor.
func formatTable(_ lines: [String]) -> String {
let rows = lines.map { parseTableRow($0) }
let columns = calculateColumnWidths(rows: rows)
// ... logic to build padded strings ...
}
Sources: Writer/TableFormatter.swift:20-100, Writer/TableFormatter.swift:184-210
Export System
The application supports three primary export formats, each utilizing a different technical approach to convert the internal Markdown state into a final file.
| Format | Implementation Strategy | File Path |
|---|---|---|
| HTML | Direct string writing of the rendered HTML and inline CSS. | Writer/HTMLExporter.swift |
Uses a hidden WKWebView to render the content and calls webView.pdf() to generate data. | Writer/PDFExporter.swift | |
| RTF | Converts HTML to NSAttributedString using the .html document type, then generates RTF data. | Writer/RTFExporter.swift |
Sequence: PDF Export Flow
State Persistence
Persistence is handled via two mechanisms:
- File Content: Managed by
EditorStore.scheduleAutosave(), which debounces changes by 350ms before writing to the selectedURL. - App Configuration:
UserDefaultsstores thefolderBookmarkdata, allowing the app to re-establish security-scoped access to the user's workspace upon relaunch.
Sources: Writer/EditorStore.swift:185-215, Writer/EditorStore.swift:230-250
Conclusion
The architecture of Writer effectively separates the concerns of file system management (EditorStore), content styling (PreviewTheme), and multi-format rendering (MarkdownRenderer). By bridging SwiftUI with AppKit's NSTextView and WebKit's WKWebView, the system provides a performant editing experience with high-fidelity previews and exports.