Skip to content

fix(ios): Copy as Markdown no longer splits bold after the first character - #1143

Open
juliusmarminge wants to merge 1 commit into
software-mansion:mainfrom
pingdotgg:fix/ios-copy-markdown-split-runs
Open

juliusmarminge wants to merge 1 commit into
software-mansion:mainfrom
pingdotgg:fix/ios-copy-markdown-split-runs

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

What/Why?

On iOS, selecting **What** in a rendered reply and choosing Copy as Markdown pastes **W****hat**. We hit this in T3 Code's iOS app; Dan Sanduleac wrote the fix in pingdotgg#12, and this PR carries his commit unchanged.

extractMarkdownFromAttributedString wraps each attribute run in its own delimiters, and runs also split on attributes with no inline meaning. ListItemRenderer anchors ListItemMarkerStartAttribute on a list item's first grapheme, so a bold lead-in such as - **What**: … arrives as W + hat. Bold around a recognized link and inline code around a link split the same way; for inline code the split changes what the pasted markdown means.

Now, when a run has the same inline delimiters as the span that still ends the output, its text goes inside that span: the closing delimiters move past it instead of a new span opening. Runs with different formatting are still wrapped separately (**a***b*), and adjacent links to different URLs stay separate.

Plain Copy uses the same extractor for the markdown flavor it puts on the pasteboard, so it gets the fix too. Selecting a whole message was never affected, only partial selections.

Testing

  • Adds __tests__/ios/ENRMMarkdownExtractorTests.mm: a bold run split by an unrelated attribute, bold at a list-item start, and adjacent bold/italic runs. Compiled with XCTest as a Mac Catalyst binary against MarkdownExtractor.m: 2 of 3 fail on main (**W****hat**, - **W****hat**: next), 3 of 3 pass with this change.
  • A 25-case harness against the old and new extractor: the old code got 18 wrong, the new code 1. That one is a synthetic case (a bold newline inside a run) that the renderer never produces, and the old code was wrong there too.
  • In T3 Code's iOS app (iOS 27 simulator, built with this change), selecting What in - **What**: … and choosing Copy as Markdown copies - **What**.
  • The commit cherry-picks cleanly onto current main. clang-format --dry-run --Werror passes.
  • Not run: the example-app XCTest lane (yarn turbo run test:ios).

PR Checklist

  • Code compiles and runs on iOS
  • Code compiles and runs on Android
  • Updated documentation/README if applicable
  • Ran example app to verify changes
  • E2E tests are passing

Opened by Claude Opus 5.5 in Claude Code.

🤖 Generated with Claude Code

…acter

Copying a selection like **What** from a list item gave **W****hat**:
the extractor wrapped each attribute run separately, and runs also split
on attributes with no inline meaning, such as the list-marker anchor on
an item's first grapheme. Runs with the same inline delimiters as the
segment that still ends the output now extend that span.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants