Repository navigation
Treat ' directly after a word as an apostrophe (GH #943) - #969
Merged
Merged
Conversation
Plural possessives (`Dogs' toys`, `the cats'.`) and `d'` before a code span were reported as Q-2-10 and failed the render, because the grammar read every non-word-internal `'` as a quote mark. The external scanner now applies pandoc's `notAfterString` rule for ASCII words: at the start of a word it looks ahead, and when the word is followed by `'` plus a non-alphanumeric it emits `word'` as one `_pandoc_literal_str`, outside an open single quote. A serialized `single_quote_depth` counter tracks whether a single quote is open; it is maintained in the scan wrapper and reset at line endings and block closes. At a block start the scanner must also decide whether the line is a pipe-table header, and the two candidate tokens end at different places. A hidden zero-width `_paragraph_start` token, optional at the front of `pandoc_paragraph`, lets the scanner commit to a paragraph when the first word ends in an apostrophe and the line is not a table header. No `conflicts:` were added; the generated table stays deterministic. Regenerating the parser renumbers LR states, so the pampa error table was rebuilt. The Q-2-10 corpus case and the fixtures that used `groups'`-style apostrophes as a parse-error trigger now use a `'` with whitespace around it, which still errors. The Q-2-10 and Q-2-7 error pages and the markdown migration guide are updated. Known limits, pinned in tests: words starting with a digit or a non-ASCII letter (`1990s'`, `Agnès'`), a `'` after a closing delimiter (`` `a.rs`'s ``), and a possessive inside an emphasis inside a quote. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
…de-notes CI's rustfmt check caught the unformatted test file. The strict claude-notes render then failed on four plan files: on main, a plural possessive such as `packages'` was mis-read as an opening quote that a later `` `code`'s `` happened to close. With `packages'` now an apostrophe, the `'` after the code span is an unclosed opener (Q-2-7), the documented limit for a `'` after a closing delimiter. Those apostrophes are now escaped as `` `code`\'s ``, which is the migration guide's fix. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #943.
What changes
A straight
'directly after a word, outside an open single quote, is now an apostrophe instead of a quote mark.Dogs' toys and cats' toys.renders as<p>Dogs’ toys and cats’ toys.</p>, matching pandoc. Also fixed:the cats'.,Cats'at end of block,It's the cats' toys., andd'before a code span (one half of #221). It works at paragraph start, in list items, headings, block quotes, the first cell of a pipe table, and inside double quotes.'Dogs' toys'still closes at the first', and'Hello world'still pairs.How
The external scanner applies pandoc's
notAfterStringrule for ASCII words. The tree-sitter lexer cannot look behind, so the decision is made at the start of each word: the scanner reads ahead, and if the word is followed by'plus a non-alphanumeric, it emitsword'as one_pandoc_literal_str. Otherwise it returns false and the internal lexer proceeds as before."Outside a single quote" is a serialized
single_quote_depthcounter maintained in the scan wrapper (+1 on open, -1 on close, reset at line endings and block closes).valid_symbols[SINGLE_QUOTE_CLOSE]cannot serve that purpose because a closer is not accepted right after whitespace inside a quote.One grammar change: a hidden zero-width
_paragraph_starttoken, optional at the front ofpandoc_paragraph. At a block start the scanner must also decide whether the line is a pipe-table header, and the two candidate tokens need different ends. When the first word ends in an apostrophe and the line is not a table header, the scanner emits the hint and the next call emits the word. Noconflicts:were added;tree-sitter generateproduced a deterministic table.Fallout
_autogen-table.jsonand the Q-2-10 case files were rebuilt withscripts/build_error_table.ts.groups'-style apostrophes as their parse-error trigger now use a'with whitespace around it, which still errors. Two LMD snapshots shifted by one column.docs/errors/markdown/Q-2-10.qmd,Q-2-7.qmdand the markdown migration guide are updated.claude-notes/plans/*.mdfiles relied on an accidental pairing: a plural possessive such aspackages'was read as an opening quote that a later`code`'sclosed. With the possessive now an apostrophe, the'after the code span became an unclosed opener and the strict claude-notes render failed in CI. Those apostrophes are escaped as`code`\'s, per the migration guide.Known limits (pinned in tests)
Words starting with a digit or a non-ASCII letter (
1990s',Agnès'), a'after a closing delimiter (`a.rs`'s, still Q-2-7), and a possessive inside an emphasis inside a quote. Each keeps its previous error.Verification
tree-sitter test: 840/840 (10 new corpus cases ininline-quotes.txt)cargo xtask test: 17518 passed, 200 skipped-D warnings) andcargo xtask lintcleantree-sitter parse --timeon a 300 KB document: unchanged within noise--target x86_64-pc-windows-msvc) could not run: the tree-sitter C build needs Windows headers. The Rust changes are tests and fixtures only.🤖 Generated with Claude Code