Conversation
Add a new .monospace CaptureOutputPreset that uses OCR block boundingBox positions to produce monospace-aligned text: - y-clustering groups blocks into lines - x-sorting orders blocks within each line - x-differences convert to spaces to preserve horizontal position - y-differences convert to blank lines using median line height Interface changes: - CaptureOutputFormatter.format() / clipboardPayload() accept optional OCRResult parameter - CaptureOutputWriter.copyCapturedText accepts optional OCRResult - CaptureCoordinator protocol and implementations pass OCRResult through - Main capture flow and watch mode pass the actual OCRResult - History repaste / menu bar / table review pass nil (no block data) UI: - Monospace appears automatically in output preset menus (allCases) - Menu bar icon: textformat - Localized titles in Turkish and English Tests: - OCRResultTests: 8 new tests covering horizontal alignment, multi-line, blank line insertion, empty/single block, x-sorting, explicit columns - CaptureOutputFormatterTests: 2 new tests for monospace preset with and without OCRResult
Replace the standalone .monospace output preset with a toggle-based feature. When enabled, the capture pipeline uses OCR block boundingBox positions to produce monospace-aligned text that preserves horizontal and vertical layout. Algorithm (ported from ocr-layout.swift): - Fixed-column horizontal alignment: col = Int(x * columns), pad to col - y-clustering into rows (threshold 0.02) - Median row height for blank line estimation - Vertical gaps convert to blank lines (capped at 6) Changes: - AppModels: MonospaceLayoutSettings struct + UserDefaults store (isEnabled Bool, columns Int default 120, clamped 20-300) - AppState: @published monospaceLayoutSettings, setters, persist - OCRResult: monospaceAlignedText(columns:) using fixed-column algorithm - CaptureCoordinator: resolvedRawText(for:) applies monospace when toggle ON; works for both normal capture and watch mode - Settings UI: Toggle + column slider (40-200) in General tab, under Output Format section - Tests: 9 new OCRResultTests covering horizontal position, multi-line, blank lines, empty/single block, x-sorting, explicit columns, clamping No changes to CaptureOutputFormatter/CaptureOutputWriter interfaces — the toggle is applied at the coordinator level before text reaches the formatter, so it composes with any existing output preset.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Monospace Layout toggle that preserves the exact horizontal and vertical positions of OCR text blocks using space padding. When enabled, captured text is rendered as monospace-aligned output — ideal for terminal screenshots, table layouts, and any UI where spatial alignment matters.
This is implemented as a toggle (Settings → General → Monospace Layout), not a separate output preset, so it composes with any existing output format.
How it works
The algorithm uses each OCR block's normalized boundingBox:
col = Int(x * columns)), with space padding to reach that columnDefault column count is 120, adjustable via a slider (40–200).
Changes
Models/AppModels.swiftMonospaceLayoutSettingsstruct + UserDefaults storeAppState.swift@Published monospaceLayoutSettings, setters, persistModels/OCRResult.swiftmonospaceAlignedText(columns:)methodServices/CaptureCoordinator.swiftresolvedRawText(for:)applies monospace when enabled; works for normal capture and watch modeViews/Settings/SettingsTabViews.swiftViews/SettingsView.swiftScreenTextGrabTests/OCRResultTests.swiftDesign decisions
col = Int(x * columns)) produces more predictable alignment than estimating per-character width from block sizes. The column count is user-adjustable.Testing
swiftc -typecheckpasses with zero errors on the full project.Notes for reviewer
(x0, y0, x1, y1)per block.