Detect grid tables and emit error on parse#159
Open
rundel wants to merge 1 commit intoquarto-dev:mainfrom
Open
Detect grid tables and emit error on parse#159rundel wants to merge 1 commit intoquarto-dev:mainfrom
rundel wants to merge 1 commit intoquarto-dev:mainfrom
Conversation
Quarto Markdown intentionally doesn't support Pandoc-style grid
tables. Today they fall through as paragraphs (silently mis-parsed)
or generic ERROR nodes — no diagnostic that names the construct or
captures its text.
tree-sitter-qmd
- Add a GRID_TABLE external token to scanner.c. parse_plus is
refactored to disambiguate after the leading `+`: `+-`, `+=`, or
`++` enters parse_grid_table_after_first_plus(); space/tab/EOL
keeps the existing list-marker path.
- parse_grid_table_after_first_plus greedily consumes a `+...+`
border followed by one or more `|...|` body / border lines,
walking nested block-quote prefixes via the open_blocks stack
so grids inside `>` / `> >` are captured correctly.
- grammar.js wires `grid_table` into _block_not_section.
- 5 new corpus tests in test/corpus/grid_table.txt cover plain,
single-quoted, double-nested-with-intermediate-paragraph,
lone-border (negative), and `+====+` separator forms.
pampa
- native_visitor in pandoc/treesitter.rs handles `grid_table`:
builds a Q-2-36 DiagnosticMessage and falls back to a
`Block::RawBlock { format: "qmd-grid-table" }` so the AST stays
well-formed.
- The diagnostic uses a layered Ariadne rendering:
1. multi-line main label spans the whole table (provides
`╭─▶ … ╰─` corners and the red highlight on table content);
2. empty-content `add_detail_at` labels on interior body lines
force Ariadne to display them instead of eliding to `┆`;
3. `add_faded_at` labels on `>` block-quote prefixes after the
opening border render those columns in Ariadne's grey
(matching the prefix on line 1, which falls outside every
label).
- 5 new integration tests in tests/test_grid_table_error.rs.
quarto-error-reporting
- New `DetailKind::Faded` variant + `add_faded_at` builder method.
Maps to Ariadne's `unimportant_color` via a named constant
ARIADNE_UNIMPORTANT_COLOR (mirror of ariadne 0.6.0's private
`Config::unimportant_color`, currently `Color::Fixed(249)`).
- Two generic improvements that this feature needed:
- Skip `Label::with_message` when detail content is empty so
empty labels don't draw a \`╰── \` arrow row in the snippet.
- Set `Label::with_order(end_offset)` on every label so labels
sort by line and stay in one Ariadne group instead of
producing duplicated snippet blocks.
- error_catalog.json registers Q-2-36 ("Grid tables are not
supported"). quarto-lsp-core::DetailKind folds Faded into Note.
Side effect — regenerating parser.c shifts LR state numbers, so
crates/pampa/resources/error-corpus/_autogen-table.json was
regenerated via crates/pampa/scripts/build_error_table.ts (the
documented Merr workflow in crates/pampa/CLAUDE.md). Skipping this
step silently breaks every autogen-table-driven diagnostic
including Q-2-10.
Verification
- tree-sitter test: 475/475 corpus
- cargo nextest run --workspace: 8390/8390
- cargo xtask verify --skip-hub-build --skip-hub-tests: clean
- cargo xtask lint: 677 files clean
Co-Authored-By: Claude Opus 4.7 (1M context) <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.
Based on the discussion in #156
Very much a proof of concept / vibe coded state at the moment but was able to handle the basic test cases I threw at it.
Sample output:
Fixture 1: bare grid tables (no block quote)
gt_block_quote1.qmd:Run:
Output:
(Note: the trailing fenced code block in the source — lines ~17–21 — is not flagged. Content inside
```fences is treated as a code block, so+----+/| oh |lines there don't trigger the grid-table detector. This is the correct behavior.)Fixture 2: grid table inside a single block quote
gt_block_quote2.qmd:Run:
Output:
Fixture 3: nested block quotes with intermediate non-grid lines
gt_block_quote3.qmd:Run:
Output: