Skip to content

Tableaux : exiger une ligne séparatrice et gérer les pipes échappés - #45

Merged
jmcollin merged 1 commit into
mainfrom
fix/table-detection
Oct 8, 2026
Merged

jmcollin merged 1 commit into
mainfrom
fix/table-detection

Conversation

@jmcollin

@jmcollin jmcollin commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Problème

  • Faux tableaux : toute ligne avec deux cellules séparées par | devenait un tableau. I like cats | dogs | birds produisait un <table> avec seulement un en-tête.
  • Pipes échappés : \| coupait quand même la cellule (explode('|')).
  • Les lignes avec trop de cellules en affichaient trop. Les tableaux à une seule colonne n'étaient pas reconnus.

Correctif (GFM §4.10)

  • Une ligne d'en-tête ne devient un tableau que si la ligne suivante est une ligne séparatrice valide (:?-+:? par cellule) avec le même nombre de cellules. Les lignes du corps continuent jusqu'à une ligne vide ou au début d'un autre bloc.
  • Les tableaux à une colonne (| a | / | :-: |) sont supportés.
  • Les cellules sont découpées sur les | non échappés. \| devient un | littéral avant le parsing inline, y compris dans un code span.
  • Chaque ligne est complétée ou tronquée au nombre de cellules de l'en-tête.
  • Le découpage est centralisé dans Lexer\TableCells, partagé par le Lexer (détection) et le Parser (cellules, alignements). PATTERN_TABLE_ROW et PATTERN_TABLE_SEPARATOR sont supprimés.

Précision par rapport à la review : selon GFM, un | non échappé dans un code span sépare quand même les cellules. Pour l'inclure dans une cellule, il faut écrire `x\|y`, ce qui est maintenant géré.

Tests

  • Nouveau tests/Integration/TableTest.php (7 cas), plus deux tests négatifs dans LexerTest.
  • Les tests du lexer qui attendaient un TABLE_ROW pour une ligne seule (sans ligne séparatrice) ont été adaptés : c'était le bug. ||| hors bloc colonnes est maintenant un paragraphe.
  • Spec CommonMark : aucune régression (389/652). Les tableaux n'en font pas partie.
  • PHPUnit OK, PHPStan et Psalm sans erreur.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CPcuaaxrCottkeL1ykoSWe


Generated by Claude Code

Any line with two pipe-separated cells used to become a table, so prose
like "cats | dogs | birds" rendered as a header-only <table>.

Tables now follow GFM §4.10:
- a header row is a table only when the next line is a delimiter row
  with the same number of cells; body rows continue until a blank line
  or the start of another block
- single-column tables ("| a |" / "| - |") are supported
- cells split on unescaped pipes only; \| becomes a literal pipe before
  inline parsing, including inside code spans
- rows are padded or truncated to the header's cell count

Row splitting and delimiter parsing live in Lexer\TableCells, shared by
Lexer (detection) and Parser (cells, alignment).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPcuaaxrCottkeL1ykoSWe
@jmcollin
jmcollin merged commit b52b4f9 into main Oct 8, 2026
6 checks passed
jmcollin pushed a commit that referenced this pull request Oct 8, 2026
Conflicts in src/Lexer/Lexer.php with the blockquote laziness change
(#44) and table detection (#45), all side-by-side additions:
- quote pattern from main, list patterns from this branch
- both state blocks (quote laziness, open list columns)
- quote lazy continuation first, then list item continuation
- list item placement before table detection (it may turn an item into
  a paragraph line)

Also drops the PATTERN_TABLE_SEPARATOR reference left by #44 (same
change as #50), without which every blockquote throws on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPcuaaxrCottkeL1ykoSWe
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.

2 participants