mirror of
https://github.com/docling-project/docling.git
synced 2026-05-17 13:10:38 +00:00
* fix(html): fix broken document tree and quadratic PictureItems in rich table cells
Three related bugs in the HTML backend when processing table cells that
contain rich content (RichTableCell), as found on Wikipedia pages with
large reference, taxobox, or classification tables:
Bug 1 — orphaned InlineGroups causing broken parent/child relationships
------------------------------------------------------------------------
When _use_inline_group() created an InlineGroup node (for paragraphs
containing multiple hyperlinks, e.g. "text <a> and <a>"), it was added
as a child of the current parent via doc.add_group(), but its RefItem was
never appended to added_refs / provs_in_cell. This meant:
- group_cell_elements() reparented the text items inside the InlineGroup
(because their individual refs WERE in added_refs), moving them from
body → outer_group_element.
- The InlineGroup itself remained in body.children still pointing to
those same text items as its .children.
- Result: two nodes (InlineGroup and outer_group_element) claimed the
same child items, with contradictory .parent pointers. This broken
tree caused double-serialization of text items in export_to_markdown().
Fix: make _use_inline_group() yield the RefItem of the created group.
Callers (_flush_buffer, _handle_block, _handle_list) now track the
InlineGroup ref instead of individual leaf refs when a group was created.
group_cell_elements() then reparents the whole InlineGroup (with its
children intact) rather than orphaning it.
Bug 2 — quadratic PictureItem creation from stray outer image loop
-------------------------------------------------------------------
In _handle_block() for <table> tags, after parse_table_data() had already
walked the entire table subtree (including nested tables) and emitted
PictureItems for every <img>, there was an additional outer loop:
for img_tag in tag("img"):
im_ref2 = self._emit_image(tag, doc)
Because BeautifulSoup's .find_all("img") on a tag finds ALL descendant
<img> elements (including those in nested tables), this loop processed
every image in the entire subtree again. A table nested N levels deep
caused N*(N+1)/2 duplicate PictureItems per image (quadratic growth).
Fix: remove the outer loop. Images are already handled by parse_table_data()
-> _use_table_cell_context() -> _walk() -> _emit_image().
Bug 3 — missing space separator between nested table cell text
--------------------------------------------------------------
HTMLDocumentBackend.get_text() uses _extract_text_recursively(), which
only appended a trailing space for <p> and <li> tags. When a table cell
contained a nested <table>, adjacent <th> or <td> elements without
whitespace NavigableString nodes between them were concatenated directly
(e.g. "TypeSound" instead of "Type Sound").
Fix: add "th" and "td" to the trailing-space tag set so that the text
content of each cell is separated by a space.
Bug 1 and Bug 2 were introduced in docling v2.55.0 (commit c803abe) with
rich table cell support.
Signed-off-by: Ivan Traus <ivan@liminary.io>
* test(html): align markdown fixtures with current docling-core behavior
Signed-off-by: Ivan Traus <ivan@liminary.io>
* test(xbrl): update XBRL fixture after get_text() cell spacing fix
The Bug 3 fix (adding th/td to trailing-space tags in get_text())
affects the XBRL backend which internally uses HTMLDocumentBackend.
Regenerate the mlac-20251231 fixture to match the corrected text
extraction.
Signed-off-by: Ivan Traus <ivan@liminary.io>
* chore(deps): bump docling-core to 2.67.1, regenerate fixtures and trim tests
Update uv.lock to pull in the merged nested-table flattening fix
(docling-core#525). Regenerate markdown fixtures that now show flattened
text instead of invalid embedded table syntax. Trim verbose test
docstrings and remove narrating comments.
Signed-off-by: Ivan Traus <ivan@liminary.io>
* fix: annotate _use_inline_group return type and regenerate docx fixtures
Add Generator[RefItem | None, None, None] return type and Google-style
Yields section to _use_inline_group. Regenerate docx ground truth
fixtures affected by docling-core 2.67.1 nested-table flattening.
Signed-off-by: Ivan Traus <ivan@liminary.io>
* refactor: use Iterator type hint and remove redundant test
Apply feedback: use Iterator instead of Generator, drop type from Yields docstring, and remove
test_e2e_rich_table_cells_markdown (already covered by test_e2e_html_conversions).
Signed-off-by: Ivan Traus <ivan@liminary.io>
* style(html): apply indent to docstrings
Signed-off-by: Cesar Berrospi Ramis <ceb@zurich.ibm.com>
---------
Signed-off-by: Ivan Traus <ivan@liminary.io>
Signed-off-by: Cesar Berrospi Ramis <75900930+ceberam@users.noreply.github.com>
Signed-off-by: Cesar Berrospi Ramis <ceb@zurich.ibm.com>
Co-authored-by: Cesar Berrospi Ramis <75900930+ceberam@users.noreply.github.com>
Co-authored-by: Cesar Berrospi Ramis <ceb@zurich.ibm.com>
47 lines
1.5 KiB
HTML
Vendored
47 lines
1.5 KiB
HTML
Vendored
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head><meta charset="UTF-8"><title>InlineGroup in table cell</title></head>
|
|
<body>
|
|
<p>Intro paragraph.</p>
|
|
<table>
|
|
<thead>
|
|
<tr><th>Name</th><th>Links</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Cell with a paragraph containing multiple hyperlinks → forces _use_inline_group -->
|
|
<tr>
|
|
<td>Multi-link cell</td>
|
|
<td><p>See <a href="https://example.com/a">Page A</a> and <a href="https://example.com/b">Page B</a> for details.</p></td>
|
|
</tr>
|
|
<!-- Plain text cell -->
|
|
<tr>
|
|
<td>Plain cell</td>
|
|
<td>Just text</td>
|
|
</tr>
|
|
<!-- Cell with bold+italic text -->
|
|
<tr>
|
|
<td>Formatted cell</td>
|
|
<td><strong>Bold</strong> and <em>italic</em> text</td>
|
|
</tr>
|
|
<!-- Inline <code> element → exercises annotated_text.code in _flush_buffer (lines 673-674) -->
|
|
<tr>
|
|
<td>Inline code cell</td>
|
|
<td><code>inline_fn()</code></td>
|
|
</tr>
|
|
<!-- <p> with only a <code> element → single item, so inline_ref=None
|
|
→ exercises annotated_text.code in _handle_block p-handler (lines 1227-1228) -->
|
|
<tr>
|
|
<td>Block code cell</td>
|
|
<td><p><code>do_thing()</code></p></td>
|
|
</tr>
|
|
<!-- <pre> with hyperlink → makes inline_ref non-None in _handle_block pre-handler (line 1279) -->
|
|
<tr>
|
|
<td>Pre with link</td>
|
|
<td><pre>See <a href="https://example.com/docs">the docs</a> first</pre></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Outro paragraph.</p>
|
|
</body>
|
|
</html>
|