Skip to content

fix: pair code regions by CommonMark rules in markdown preprocessing#228

Open
PathGao wants to merge 1 commit into
alecdotdev:masterfrom
PathGao:fix/code-region-protection
Open

fix: pair code regions by CommonMark rules in markdown preprocessing#228
PathGao wants to merge 1 commit into
alecdotdev:masterfrom
PathGao:fix/code-region-protection

Conversation

@PathGao

@PathGao PathGao commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Fixes #227.

The five source-level rewrites (![[embeds]], [[#wikilinks]], ^block-ids, ==highlight==, ^[inline footnotes]) protected code regions with the alternation (?s)```.*?```|`.*?`|…, which cannot express CommonMark pairing. One 4-backtick inline sample — or any ~~~ fence, which the pattern did not know at all — desynchronized protection for the entire rest of the document, rewriting later inline code containing ![[x]] into <img> tags with nonlocal collateral damage (details and minimal repro in #227).

Change: a small scanner code_region_ranges() computes protected byte ranges by the CommonMark rules —

  • a fence (``` or ~~~, up to 3 leading spaces) closes only on a line-leading run of the same character at least as long as the opener (unclosed fence protects to EOF; backtick-fence info strings may not contain backticks);
  • an inline span opened by N backticks closes only on a run of exactly N; unpaired runs are literal.

Each rewrite pass then skips matches that start inside a protected range. Ranges are recomputed per pass since replacements shift offsets. No new dependencies; rewrite behavior outside code regions is unchanged.

Tests: 8 new unit tests covering both rupture modes (4-backtick desync, ~~~ fences), pairing rules (longer-run close, exact-N spans, unclosed fence), and unchanged rewrites outside code. cargo test: 10/10.

🤖 Generated with Claude Code

The five source-level rewrites (![[embeds]], [[#wikilinks]], ^block-ids,
==highlight==, ^[inline footnotes]) protected code regions with the regex
alternation ```.*?```|`.*?`, which cannot express CommonMark pairing:
fences close only on a line-leading run of the same character at least as
long as the opener, and a span of N backticks closes only on a run of
exactly N. A single 4-backtick inline sample (or any ~~~ fence, which the
pattern did not know at all) desynchronized protection for the entire rest
of the document — later inline code containing ![[x]] was rewritten into
<img> tags, with nonlocal collateral damage in unrelated blocks.

Replace the alternation with a small scanner (code_region_ranges) that
walks fences and backtick runs by the CommonMark rules, and skip any match
that starts inside a protected range.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

Code-region protection in markdown preprocessing is desynchronized by longer backtick runs (nonlocal corruption)

1 participant