Skip to content

Nest inline markers instead of crossing them - #98

Merged
Wavesonics merged 1 commit into
mainfrom
fix/crossing-inline-spans
Aug 7, 2026
Merged

Nest inline markers instead of crossing them#98
Wavesonics merged 1 commit into
mainfrom
fix/crossing-inline-spans

Conversation

@Wavesonics

Copy link
Copy Markdown
Collaborator

The bug

Markdown delimiters can only nest. AnnotatedString.toMarkdown sorted style boundaries by run length and emitted them blind, so a style applied across part of an existing emphasis run came out as crossing delimiters:

text  = He said hello there.     (italic "hello there", strikethrough "there")
export= He said *hello ~~there*~~.

No parser reads that back as emphasis. On the next import the markers landed in the document as literal characters and the styling was gone:

reloaded = He said hello there~~.

It reproduced for a style inside an emphasis run, over the head or tail of one, and crossing a link. Strikethrough is where it shows up in practice, because striking part of a line of italic dialogue is a natural edit, but nothing about it is strikethrough-specific.

The fix

toMarkdown now:

  1. builds typed MarkerRuns rather than loose boundaries,
  2. splits any partially overlapping pair at the crossing point, so every pair ends up disjoint or nested. Links are never split, since that would emit the destination twice,
  3. emits through a stack, so every close is the exact LIFO mirror of its open.

Where markdown genuinely cannot express a crossing, the run is split and both styles survive over exactly the text they covered:

He said *hello ~~there~~* now.          nested
He ~~said~~ *~~hello~~ there* now.      crossing, split, both styles kept
See [the ~~docs~~](http://x.com) ~~now.~~

Testing

New CrossingSpanSerializationTest covers the six shapes, asserting the reloaded text is byte-identical and the markers balance.

Full :ComposeTextEditor:desktopTest suite: 1052 tests, 0 failures.

A style applied across part of an existing emphasis run serialized as
crossing delimiters, `*hello ~~there*~~`, which no markdown parser reads
back. The markers landed in the reloaded document as literal characters
and the styling was lost.

toMarkdown now builds typed runs, splits any partially overlapping pair
at the crossing point, and emits through a stack so every close mirrors
its open. Links are never split, since that would emit the destination
twice.
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 27 complexity · 0 duplication

Metric Results
Complexity 27
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@Wavesonics
Wavesonics merged commit 10864a3 into main Aug 7, 2026
2 checks passed
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.

1 participant