Skip to content

fix(asciidoc): skip empty tables after incomplete rows - #4300

Merged
ceberam merged 2 commits into
docling-project:mainfrom
Ai-Eastern:fix/asciidoc-empty-table
Sep 24, 2026
Merged

ceberam merged 2 commits into
docling-project:mainfrom
Ai-Eastern:fix/asciidoc-empty-table

Conversation

@Ai-Eastern

Copy link
Copy Markdown
Contributor

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 empty table_data as 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 |3 and 2+|wide after a two-cell header:

before: [(1, 2), (0, 0)]
after:  [(1, 2)]

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 passed
  • Ruff check and format check on the two changed files: passed
  • uv run --no-default-groups --group dev --frozen tach check: passed
  • uv run --no-default-groups --group dev --frozen ty check docling/backend/asciidoc_backend.py: exit 0 with three pre-existing warnings on unchanged lines
  • prek run --files ...: could not initialize external hooks on this Windows host because Git fetch failed with Improper link; direct project checks above were run instead

@github-actions

Copy link
Copy Markdown
Contributor

✅ DCO Check Passed

Thanks @Ai-Eastern, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 Merge protection satisfied — ready to merge.

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@dolfim-ibm dolfim-ibm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

codecov Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Ai-Eastern

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I've updated the end-of-document table flush to use _add_table_if_nonempty, added type annotations to the helper, and added a regression test covering caption preservation for an unclosed table at EOF. The current checks are green.

@ceberam ceberam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ceberam
ceberam merged commit 7e361ab into docling-project:main Sep 24, 2026
26 checks passed
PeterStaar-IBM pushed a commit that referenced this pull request Oct 6, 2026
* 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]>
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.

AsciiDoc table with a single-cell line emits a spurious empty table

3 participants