fix: prevent table rows from being broken by line wrapping (#36)#37
Open
fix: prevent table rows from being broken by line wrapping (#36)#37
Conversation
Table rows (lines starting with |) are structural markdown elements that must remain on a single line. When Marko's GFM parser doesn't recognize a table (e.g. when it directly follows paragraph text without a blank line), the rows were parsed as paragraph content and broken by the line wrapper at the wrap width. Fix: always treat table rows as segment boundaries in the tag handling layer, and pass table-row segments through without wrapping. List items retain the existing behavior (only segment boundaries when tags present). https://claude.ai/code/session_01JESDwDj2UYgf9v5yttYyxr
Fixes ruff E741 (ambiguous variable name) and basedpyright reportUnknownMemberType warning. https://claude.ai/code/session_01JESDwDj2UYgf9v5yttYyxr
jlevy
commented
Feb 17, 2026
| table rows as paragraph content rather than a table element. | ||
| The line wrapper must still preserve each table row on its own line. | ||
| | Quarter | Revenue ($M) | YoY % | QoQ % | Segment A % | Segment B % | Geo: US % | Geo: Intl % | | ||
| |---------|-------------|-------|-------|-------------|-------------|-----------|-------------| |
Owner
Author
There was a problem hiding this comment.
Why is this removing the dashes? Shouldn't it be a minimum of 3 dashes ?
…zing to 3 Previously render_table() normalized all separator dashes to exactly 3 (e.g. `| --- | --- |`), discarding the original column alignment. Now preserves the original dash widths from the source while ensuring a minimum of 3 dashes per column. https://claude.ai/code/session_01JESDwDj2UYgf9v5yttYyxr
Reverts the dash-preserving change. Normalizing separators to `| --- |` is the cleaner approach. Updated expected test docs accordingly. https://claude.ai/code/session_01JESDwDj2UYgf9v5yttYyxr
Tables adjacent to paragraph text bypass the Marko parser and pass through the line wrapper verbatim. Added normalize_table_separator() to block_heuristics.py so the line wrapper also normalizes separator rows to `| --- |`, consistent with the Marko-parsed table rendering. https://claude.ai/code/session_01JESDwDj2UYgf9v5yttYyxr
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.
Summary
Fixes #36. When a table directly follows paragraph text without a blank line, Marko's GFM parser doesn't recognize it as a
Tableelement—the table rows are parsed as inline content within aParagraph. The line wrapper then breaks wide rows at the wrap width (88 chars), producing invalid markdown likeGeo:\nIntl % |. This PR makes the line wrapper always preserve table rows on single lines.Additionally fixes table separator rendering to preserve original dash widths instead of normalizing everything to
| --- |.Changes
src/flowmark/linewrapping/tag_handling.py: Modifiedadd_tag_newline_handling()to:|-prefixed lines) as segment boundaries, regardless of whether template tags are present (previously only activated when tags were detected)src/flowmark/formats/flowmark_markdown.py: Modifiedrender_table()to preserve original table separator dash widths (ensuring a minimum of 3 dashes) instead of normalizing all separators to exactly---tests/test_wrapping.py: Added 4 new unit tests + updated 1 existing test:test_table_rows_preserved_without_tags— table rows in paragraphs stay on own linestest_wide_table_rows_not_wrapped— exact reproduction of issue Wide table header rows broken mid-cell by line wrapping #36test_table_rows_with_semantic_wrapping— semantic mode also preserves rowstest_table_rows_only_no_surrounding_text— standalone table rows preservedtest_block_heuristics_only_with_tags_for_lists— updated regression guard (renamed fromtest_block_heuristics_only_with_tags)tests/test_filling.py: Added 2 integration tests viafill_markdown():test_wide_table_adjacent_to_paragraph— end-to-end reproduction of Wide table header rows broken mid-cell by line wrapping #36test_standalone_wide_table— regression guard for properly-parsed tablestests/testdocs/: Added "Wide Table Adjacent to Paragraph" section totestdoc.orig.mdand updated all 4 expected output files (plain, semantic, cleaned, auto) — now with preserved separator dash widthsTest Plan
python -m pytest tests/ -v)python -m pytest src/flowmark/linewrapping/block_heuristics.py)flowmark --autoon a file containing a wide table directly after paragraph text (no blank line) — verify table rows are preserved on single linesflowmark --autoon a file with a standalone wide table (blank line before it) — verify separator dashes are preserved{% field %}) — verify existing behavior preserved:---:,:---,---:) — verify alignment preservedRelated Beads
fm-1422(epic): Fix table rows broken by line wrapping when parsed as paragraph content (issue Wide table header rows broken mid-cell by line wrapping #36)fm-625c: Core fix — remove has_tags guard for table row detectionfm-y6np: Unit tests in test_wrapping.pyfm-gt51: Integration tests in test_filling.pyfm-vzb9: Reference doc test updatesfm-ngl0: Regression guard verificationfm-3ahm: Full test suite runhttps://claude.ai/code/session_01JESDwDj2UYgf9v5yttYyxr