Table Formatting
Relevant source files
The following files were used as context for generating this wiki page:
The table formatting system in Writer is a specialized utility designed to detect, parse, and visually align Markdown tables within the editor. It ensures that tables are not only structurally valid for Markdown rendering but also human-readable in their raw text form by normalizing column widths and adhering to alignment markers. This feature is accessible through the application's command menu and keyboard shortcuts, providing a seamless way to maintain clean document structures.
Sources: Writer/TableFormatter.swift:4-10, Writer/EditorStore.swift:349-352, Writer/WriterApp.swift:151-157
Core Architecture and Logic
The system is centered around the TableFormatter struct, which contains the logic for document scanning and string manipulation. It operates independently of the UI, allowing it to process raw strings and return formatted results that are then persisted by the application's state management.
Detection and Parsing
The formatting process begins with detectTableRanges(in:), which scans the document line-by-line. A valid table is identified by a row containing at least two pipe (|) characters followed immediately by a delimiter row. A delimiter row must contain at least three dashes (-) per cell, potentially with colons (:) to indicate alignment.
The logic distinguishes between standard rows and delimiter rows to ensure that the structural "spine" of the table is used as the basis for alignment calculations.
Sources: Writer/TableFormatter.swift:39-88, Writer/TableFormatter.swift:91-118
Alignment and Width Calculation
Writer employs a sophisticated width calculation logic that accounts for visual discrepancies in character sets. The visualWidth(of:) function calculates the space a string occupies, treating CJK (Chinese, Japanese, Korean) characters and emojis as taking two positions, while standard alphanumeric characters take one.
The ColumnAlignment enumeration defines how content is positioned within these calculated widths:
- Left: Content followed by padding.
- Center: Padding distributed on both sides.
- Right: Padding preceding the content.
- None: Default left-aligned behavior.
Sources: Writer/TableFormatter.swift:15-28, Writer/TableFormatter.swift:131-154, Writer/TableFormatter.swift:165-189
Application Integration
The table formatting feature is integrated into the EditorStore and triggered via the WriterApp command menu.
User Interaction Flow
Users can trigger the "Format Tables" command (Shortcut: ⌘⇧F). This invokes editorStore.formatAllTables(), which utilizes a TableFormatter instance to process the current documentText.
Data Structures and Configuration
The system uses internal structures to manage table metadata during the formatting pass.
| Component | Type | Description |
|---|---|---|
TableColumn | Struct | Stores the calculated width and parsed ColumnAlignment for a specific column. |
ColumnAlignment | Enum | Defines .left, .center, .right, or .none alignment based on delimiter syntax. |
visualWidth | Function | Calculates width accounting for wide Unicode scalars (CJK/Emoji). |
Sources: Writer/TableFormatter.swift:15-33, Writer/TableFormatter.swift:165-176
Rendering and Styles
While the TableFormatter handles raw text alignment, the MarkdownRenderer and PreviewTheme manage how these tables appear in the live preview and exported files.
HTML Rendering
The HTMLVisitor handles the conversion of Markdown table nodes into HTML elements (<table>, <thead>, <tbody>, <tr>, <td>).
Sources: Writer/MarkdownRenderer.swift:110-135
CSS Styling
The PreviewTheme provides the visual styling for tables in the preview pane and HTML exports, defining borders, padding, and background colors for header cells.
table {
border-collapse: collapse;
width: 100%;
margin-bottom: 16px;
}
th, td {
padding: 8px 12px;
border: 1px solid #e1e4e8;
}
th {
background-color: #f6f8fa;
font-weight: 600;
}
Sources: Writer/PreviewTheme.swift:98-111
Summary
The Table Formatting module provides a robust mechanism for maintaining clean Markdown data. By separating the concerns of raw text alignment (TableFormatter), application state (EditorStore), and visual rendering (MarkdownRenderer), the project ensures that tables remain legible across all views—whether in the plain-text editor, the rich preview, or exported formats like PDF and HTML.
Sources: Writer/TableFormatter.swift:234-247, Writer/EditorStore.swift:349-352, Writer/MarkdownRenderer.swift:158-175