Add Clean Formatting and Markdown paste options - #93
Open
alvst wants to merge 3 commits into
Open
Conversation
Two new context-menu paste modes alongside Paste as Plain Text, enabled whenever a clip has rich content. Clean Formatting keeps bold, italic, underline, strikethrough, and links while normalizing fonts, sizes, and colors to the system default. Markdown converts the rich content to Markdown text, splitting style markers across line breaks so the output stays valid, and rendering links as [text](url). The clipboard monitor now also captures a copy's HTML flavor - browser copies often carry HTML with no RTF - without changing how clips are classified. Conversions prefer HTML, then RTF, then fall back to plain text. Paste plumbing moves from an asPlainText flag to a PasteFormat enum carrying all four modes.
The HTML importer behind the Clean Formatting and Markdown conversions is WebKit-backed: handed raw captured HTML, it fetches remote subresources - tracking pixels included - synchronously on the main thread at paste time, breaking the no-network-calls promise. Strip every element that can reference an external resource (img, picture, source, iframe, object, embed, link, script, style, svg, video, audio, and CSS url() values) before conversion; the converters only keep text plus bold/italic/underline/links, so nothing representable is lost. A 2-second importer timeout backs the stripping up, and sources over 1MB skip rich conversion entirely, falling back to plain text so a pathological clip can't hitch the paste. Capture-side, cap stored pasteboard HTML at the sync layer's inline payload bound (CKSchema.inlineLimit) so every routine text copy can't persist an unbounded HTML blob; oversized HTML is dropped and the conversions fall back to RTF/plain text as before.
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.
"Paste as Plain Text" is all-or-nothing: it's the only escape from a clip that arrives with a website's fonts and colors attached. This adds two middle options — keep the emphasis, drop the styling, or convert to Markdown.
What changed
[text](url).asPlainTextflag to aPasteFormatenum carrying all four modes.img,picture,source,iframe,object,embed,link,script,style,svg,video,audio, and CSSurl()) is stripped before conversion, backed by a 2-second importer timeout. Sources over 1 MB skip rich conversion and fall back to plain text.CKSchema.inlineLimit); oversized HTML is dropped and conversions fall back to RTF/plain text as before.Screenshots
Before:

After:

Notes for review
htmlDatais not carried by iCloud sync, so the same clip can produce different Markdown on a synced Mac — the one that captured it converts from HTML, the other falls back to RTF or plain text. It degrades gracefully rather than failing, and extending the sync schema for it felt like the wrong thing to bundle into this PR. Stating it rather than letting it be discovered.htmlDatainherits the store's 0600 permissions.This feature should be bundled into v2.
Part of #80.