quarto-dev / quarto-dev/q2

Inline parser: apostrophe after a code span trips Q-2-7 (Unclosed Single Quote)

Open
#221 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug readers-writers
Dominant language
Rust
Stars
255
Forks
17
Avg merge
6h 20m
Merged PRs (30d)
109

Description

Claude kept hitting Q-2-7 when writing items in the hub-client changelog. Apostrophe seems to be a special case that works in Pandoc.

Summary

The inline grammar's smart-quote rule treats ' immediately after a closing backtick (code-span boundary) as an opening single quote, even when followed by letters as in a possessive. Pandoc treats the same construct as a possessive and emits no error. As a result, common technical-writing patterns like `setAst`'s callback trip Q-2-7 (Unclosed Single Quote).

Reproducer

printf "x \`code\`'s gate\n" | cargo run --bin pampa -- -t json -i -

Output:

Error: [Q-2-7] Unclosed Single Quote
 1 │ x `code`'s gate
   │         ┬
   │         ╰── This is the opening quote. If you need an apostrophe, escape it with a backslash.

Pandoc reads the same input as a possessive without complaint.

Scope

Pattern Result Why
`code`'s gate FAIL post-codespan ' promoted to opening
`code`'foo bar FAIL same
`code` 's gate FAIL whitespace between doesn't help
`code`\'s gate PASS escaped apostrophe
word's gate PASS letter-letter → possessive
`code`'s and `other`'s pair PASS two opens form a balanced pair
`code`'s and word's pair FAIL only one promoted-to-opening

The angle brackets in patterns like `<AssetManifestContext>`'s are a red herring — backticks alone are the trigger.

Real-world incidents

This has tripped the hub-client changelog at least twice:

  • 0c78b1a4 (2026-05-08) — diagnosis blamed <Tag> HTML-like content; the angle brackets were coincidental.
  • d7d7e063 (2026-05-10) — same pattern in plan changelog entries; rewritten in plain prose to clear the parse.

Proposed fix

In tree-sitter-markdown-inline's grammar, extend the rule for opening single quote so a ' immediately after a closing backtick — more generally, after any inline-end token — is treated as a possessive when the next character is a letter. This is the same heuristic that already handles word's. Pandoc's smart-quote algorithm is "an apostrophe between letters, or after a markup boundary that resolves to letters, is a possessive."

After regenerate + build, add a test case to the inline grammar's corpus and a passing case to resources/error-corpus showing that `code`'s no longer fires Q-2-7.

Workarounds available today

  1. Pair them deliberately in the same block (two close-backtick apostrophes form a smart-quote pair).
  2. Backslash-escape: `code`\'s.
  3. Rephrase so the apostrophe is inside a word (e.g. "the setAst callback's behavior").

Related

  • Internal: bd-1qk5 (this issue's origin), bd-kk0a (writer-side escape for unbalanced apostrophes — a parser fix here would obviate part of bd-kk0a's scope).
  • crates/pampa/snapshots/error-corpus/text/006.snap, 009.snap — current Q-2-7 examples.
  • resources/error-corpus/_autogen-table.json:18686 — parser-state mapping table.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the opening-single-quote rule in tree-sitter-markdown-inline and reproduce the code's case from the issue. Regenerate and build the grammar, then add the inline grammar corpus case and a passing case to resources/error-corpus. Done means the possessive no longer emits Q-2-7 while the existing quote behavior remains covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
markdown, rust
Domain
testing-qa, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.