Repository navigation
fix(asciidoc): skip empty tables after incomplete rows - #4300
Conversation
Signed-off-by: Ai-Eastern <[email protected]>
|
✅ DCO Check Passed Thanks @Ai-Eastern, all your commits are properly signed off. 🎉 |
Merge Protections🟢 Merge protection satisfied — ready to merge. Show 1 satisfied protection🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
|
dolfim-ibm
left a comment
There was a problem hiding this comment.
Good — the guard is in the right place and the helper is a nice extraction.
Two small things: the end-of-document flush at asciidoc_backend.py:364 still inlines the same logic (and silently drops the caption), so it would be worth routing it through _add_table_if_nonempty too; and the new helper should use type annotations to match the rest of the module.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Signed-off-by: Ai-Eastern <[email protected]>
|
Thanks for the review. I've updated the end-of-document table flush to use |
* fix(asciidoc): keep one-cell-per-line (vertical) tables intact _is_table_line required a second | on the line, so in a table written in the common vertical style (one cell per line) each single-| line was read as the end of the table: the first such line was silently dropped, the remaining ones leaked into the document body as literal text, and the closing |=== reopened an empty table that disappeared at EOF. Relax _is_table_line to accept a line whose first cell starts right after the (optional) cell specifier, and handle |=== as an explicit open/close marker checked before that match. Rows with fewer cells than the widest row keep flowing into the grid the way they did before (the incomplete trailing row from #4300 is now kept and rendered next to an empty cell instead of being dropped), so no cell content is lost. Update the two tests that asserted the accidental drop, and add a regression test for the vertical table layout. Signed-off-by: simpleqt <[email protected]> * fix(asciidoc): do not emit block attributes and anchors as body text Lines like [cols="2,1"], [NOTE] or [[some-id]] are block attributes and anchors that apply to the block following them; the backend treated them as plain text and leaked them into the document body as literal text items (also visible in the asciidoc_03/asciidoc_04 groundtruth exports). Skip standalone bracket lines in the block loop. Regenerate the two affected groundtruth files and add a regression test covering anchors, table attributes, and admonition markers. Signed-off-by: simpleqt <[email protected]> * fix(asciidoc): also skip entry attribute lines Entry attributes (":_mod-docs-content-type: PROCEDURE", ":experimental:") are global metadata, not body content; consume them like block attributes. Signed-off-by: simpleqt <[email protected]> * fix(asciidoc): keep content that follows an unmatched block title A block title (.Title) whose target is not a floating element added its text to caption_data, and every following non-blank line was then absorbed as a 'multiline caption'. caption_data was never flushed when no floating element arrived, so a document containing any line starting with '.' lost that line and everything after it: '.Title\ncontent' produced an empty document, and even an ordinary paragraph starting with a period silently swallowed the rest of the file. A blank line now ends the title association (emitting it as the bold paragraph the parsing contract promises), and a pending title at EOF is emitted instead of discarded; an unclosed table still consumes its caption. Wrapped captions that directly precede their picture/table are unchanged. Red/green verified: the two new tests fail against the old implementation (empty output) and pass with the fix. Signed-off-by: simpleqt <[email protected]> * fix(asciidoc): consume content block delimiters instead of leaking them Example (====), sidebar (****), quote (____), open (--), passthrough (+++) and listing (----) blocks carry regular content, but their delimiter lines were emitted as body text, so paragraphs like '==== example content ====' appeared in the conversion output. When a content block delimiter line has a matching closer further down, _iter_blocks now re-emits only the inner lines; the closer look-ahead keeps stray separator lines without a pair (e.g. '--' inside a changelog) from swallowing the rest of the document. Literal (....) blocks are unaffected. Red/green verified: the new tests fail against the old implementation (delimiter text in output) and pass with the fix. Signed-off-by: simpleqt <[email protected]> * fix(asciidoc): do not emit comments as body text Lines starting with // are comments and never body content: they used to render as paragraphs or merge into the following paragraph. Skip // lines and hide //// delimited comment blocks, keeping both as content inside literal/listing blocks. Also covers nested bullet list markers (** and ***) which used to fall through to paragraph text. Originally opened as #4426 (whose only commit mistakenly carried the message and author of an unrelated cherry-pick, failing DCO); recreated here with the proper author and sign-off. Signed-off-by: simpleqt <[email protected]> * refactor(asciidoc): extract literal-block and picture handling from _parse The consolidated parser changes push _parse past the mccabe limit (32 > 30); moving the literal-block and picture branches into _add_literal_block/_add_picture_item keeps it under the threshold without behavior changes. Signed-off-by: simpleqt <[email protected]> * style: apply ruff format to the consolidated asciidoc changes Signed-off-by: simpleqt <[email protected]> * test(asciidoc): remove duplicate test_nested_bullet_list_keeps_items_nested_and_in_order Signed-off-by: Cesar Berrospi Ramis <[email protected]> * docs(asciidoc): fix stale +++ → ++++ in _iter_blocks comment Signed-off-by: Cesar Berrospi Ramis <[email protected]> * perf(asciidoc): call _has_matching_closer once per content-block delimiter line Signed-off-by: Cesar Berrospi Ramis <[email protected]> * fix(asciidoc): flush text_data before caption_data in _flush_blank_line Signed-off-by: Cesar Berrospi Ramis <[email protected]> * fix(asciidoc): do not skip empty brackets [] as a block attribute Signed-off-by: Cesar Berrospi Ramis <[email protected]> * test(asciidoc): remove redundant stray-dash test and listing block from delimiter variants Signed-off-by: Cesar Berrospi Ramis <[email protected]> * docs(asciidoc): fix docstring style and trim historical inline comment Signed-off-by: Cesar Berrospi Ramis <[email protected]> * chore(asciidoc): remove stale commented-out lines Signed-off-by: Cesar Berrospi Ramis <[email protected]> --------- Signed-off-by: simpleqt <[email protected]> Signed-off-by: Cesar Berrospi Ramis <[email protected]> Co-authored-by: Cesar Berrospi Ramis <[email protected]>
Closes #4299.
What changed
When a table has already been closed by a single-cell line that the backend does not parse as a table row, the later
|===is treated as a new opening delimiter. The following blank line used to add its emptytable_dataas a second, 0x0 table. The close path now adds a table only when it has rows.This fixes the extra empty table noted as out of scope in #4290. It does not change how single-cell lines or cell spans are parsed; that separate limitation remains.
Reproduction
For both
|3and2+|wideafter a two-cell header:The new regression test fails on the unmodified branch and passes with this change. The existing rowspan-only test from #4290 remains green.
Verification
uv run --no-default-groups --group dev --frozen pytest tests/test_backend_asciidoc.py -q: 16 passeduv run --no-default-groups --group dev --frozen tach check: passeduv run --no-default-groups --group dev --frozen ty check docling/backend/asciidoc_backend.py: exit 0 with three pre-existing warnings on unchanged linesprek run --files ...: could not initialize external hooks on this Windows host because Git fetch failed withImproper link; direct project checks above were run instead