Skip to content

Fix qmd writer escape for apostrophes in non-word contexts (#201)#204

Merged
cscheid merged 2 commits into
mainfrom
bugfix/issue-201
May 15, 2026
Merged

Fix qmd writer escape for apostrophes in non-word contexts (#201)#204
cscheid merged 2 commits into
mainfrom
bugfix/issue-201

Conversation

@cscheid
Copy link
Copy Markdown
Member

@cscheid cscheid commented May 15, 2026

Summary

  • Fixes Writer does not emit \' for apostrophes that the reader would otherwise reject as quote opens #201. The qmd writer dropped the \' escape on apostrophes whose source form required it (reveal.js\' jump-to-slide.), so qmd → AST → qmd → AST was not a fixed point: the regenerated output failed to re-parse with Q-2-7 or Q-2-10.
  • Sharpens escape_markdown with a single '\'' arm: escape when the previous char in the Str body is Unicode alphanumeric AND the next char is either absent or non-alphanumeric. Otherwise leave bare (preserves don't, it's, ab'9).
  • Adds two regression fixtures under crates/pampa/tests/roundtrip_tests/qmd-json-qmd/ exercising the two distinct trigger shapes (apostrophe before whitespace, apostrophe before punctuation within the same Str).

The fix is purely local to escape_markdown — no QmdWriterContext field, no cross-inline lookahead, no signature changes. The reader's apostrophe rule turned out to be local to the two characters around ', so the writer's rule mirrors that.

Triage record: claude-notes/issue-reports/201/triage.md (commit f9a45a7).
Plan + end-to-end record: claude-notes/plans/2026-05-15-issue-201-apostrophe-escape.md.
Beads: bd-8lcm (closed in the sync commit on main).

Test plan

  • cargo nextest run -p pampa test_qmd_roundtrip_consistency — passes (the suite now includes the two new fixtures, which fail at HEAD before the fix).
  • cargo nextest run -p pampa --no-fail-fast — 3686 / 3686 passed.
  • cargo nextest run --workspace --no-fail-fast — 8863 / 8863 passed.
  • cargo xtask verify --skip-hub-build --skip-hub-tests — all 9 steps green (lint, fmt, build with -D warnings, tree-sitter, Rust tests, trace-viewer build + tests).
  • End-to-end CLI round-trip on the issue's literal repro and six adjacent patterns:
    • reveal.js\' jump-to-slide. (issue's case) → \' emitted, re-parse identical.
    • ab\'.cd (within-Str punctuation) → \' emitted, re-parse identical.
    • *hi\'* (apostrophe before Emph close *) → \' emitted.
    • "hi\'" (apostrophe before Quoted close ") → \' emitted.
    • don't, it's (letter-apostrophe-letter) → bare ' preserved.
    • ab'9 (letter-apostrophe-digit) → bare ' preserved.

🤖 Generated with Claude Code

cscheid and others added 2 commits May 15, 2026 09:17
…ophe (bd-8lcm)

Round-trip qmd → AST → qmd produces output the reader re-rejects with
Q-2-10. Triage doc records the trigger boundary (letter on left AND
whitespace on right — confirmed by probes), code localization in
crates/pampa/src/writers/qmd.rs, and a TDD-first fix scope handed off
to bd-8lcm. Includes the minimal repro fixture from the issue.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…issue #201)

The reader accepts a bare `'` between alphanumeric characters as an
apostrophe (`don't`, `it's`, `ab'9`), but rejects it at any non-alnum
boundary: `reveal.js' jump-to-slide.`, `ab'.cd`, `*hi'*`, `"hi'"`, and
even `ab'` at end-of-block all fail with Q-2-7 / Q-2-10. The writer
previously emitted bare `'` everywhere, so `qmd → AST → qmd → AST` was
not a fixed point for inputs that originally required `\'`.

`escape_markdown` now tracks `prev_char` and peeks at `next_char` so a
single `'` arm can decide locally — no cross-inline lookahead is needed
because the reader's rule itself is local to two characters around the
apostrophe.

Adds two roundtrip fixtures (`apostrophe_before_space.qmd`,
`apostrophe_before_punct.qmd`) that exercised the bug and now lock in
the fix.

Triage: claude-notes/issue-reports/201/triage.md
Plan:   claude-notes/plans/2026-05-15-issue-201-apostrophe-escape.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cscheid cscheid merged commit b7e780f into main May 15, 2026
4 checks passed
@cscheid cscheid deleted the bugfix/issue-201 branch May 15, 2026 15:44
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.

Writer does not emit \' for apostrophes that the reader would otherwise reject as quote opens

1 participant