Skip to content

fix(html): don't spread one run's formatting or link to a whole heading - #4670

Merged
dolfim-ibm merged 1 commit into
docling-project:mainfrom
er-s-an:fix/html-heading-partial-formatting
Oct 12, 2026
Merged

dolfim-ibm merged 1 commit into
docling-project:mainfrom
er-s-an:fix/html-heading-partial-formatting

Conversation

@er-s-an

@er-s-an er-s-an commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Issue resolved by this Pull Request:
Resolves #4668

Headings and figure captions in the HTML backend are flattened to one text element by
AnnotatedTextList.to_single_text_element(). It took the first formatting and the first hyperlink
it found and applied them to the whole element. A heading like <h2>To the <i>Hibernia</i></h2>
became an italic heading, and a caption with one link became a link as a whole.

The element now keeps a formatting or a hyperlink only when every text run has it (whitespace-only
runs are ignored). A heading that is bold or linked as a whole is unchanged. Keeping the partial
formatting itself (e.g. an inline group like list items use) would be a bigger change, so this PR
only stops reporting formatting that is not there.

Checklist:

  • Documentation has been updated, if necessary. (not needed)
  • Examples have been added, if necessary. (not needed)
  • Tests have been added, if necessary.

Review evidence:

Before / after:

input before after
<h2>Section <strong>bold</strong> heading</h2> ## **Section bold heading** ## Section bold heading
<h2><a href=...>Docs</a> and more</h2> heading linked as a whole no link
<h2><strong>All</strong> <strong>bold</strong></h2> bold bold (unchanged)
<h2><a href=...>Docs</a></h2> linked linked (unchanged)

Reference data changes (only formatting/hyperlink fields change; I checked that every other
field is identical):

  • tests/data/epub/groundtruth/epub_purvis_poetry.epub.{json,md}: "To the Hibernia" heading is
    no longer italic (only "Hibernia" is italic in the source).
  • tests/data/html/groundtruth/wiki_duck.html.{json,md}: 12 captions lose a link that covered
    only part of the caption (one also loses superscript from its [49] reference). "Ringed teal",
    where the whole caption is the link, keeps its link.
  • tests/data/html/groundtruth/hyperlink_05.html.json: the caption
    This is an example <a href="#caption">caption</a> for the image. is no longer linked as a whole.

I edited only these fields by hand. Regenerating with DOCLING_GEN_TEST_DATA=1 also rewrites
unrelated values that are already stale on main (orig quote characters in the EPUB JSON,
row_span in example_08.html.json), so I left those out.

Tests added in tests/test_backend_html.py:

  • test_heading_keeps_only_formatting_of_all_its_text (4 cases: partial bold, partial link, full
    bold, full link)
  • test_caption_with_partial_link_has_no_hyperlink

The partial cases and both e2e tests fail on main and pass with the change.

Commands:

  • uv run pytest tests/test_backend_html.py tests/test_backend_epub.py tests/test_backend_markdown.py tests/test_backend_mhtml.py: 160 passed, 1 skipped
  • uv run pytest tests -k "not pdf and not ocr and not vlm and not asr": 2233 passed; the 23
    failures and 19 collection errors are the same on main in my environment (no docling-parse,
    torchvision or LibreOffice installed)
  • make validate (ruff, ruff-format, ty, tach, license header, max lines): all passed

Note: #3891 changes the text joining in the same function (current_text += ...). It does not
change the formatting/hyperlink logic, but the two may need a small rebase.

Headings and figure captions are flattened to one text element. The first
run that had a formatting or a hyperlink gave it to the whole element, so
<h2>To the <i>Hibernia</i></h2> became an italic heading and a caption
with one link became a link as a whole.

Keep a formatting or a hyperlink only when every text run has it.

Reference data: the italic heading in epub_purvis_poetry and the caption
links in wiki_duck and hyperlink_05 that only covered part of the text.

Signed-off-by: er-s-an <92594860+er-s-an@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

✅ DCO Check Passed

Thanks @er-s-an, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 All 2 merge protections satisfied — ready to merge.

Show 2 satisfied protections

🟢 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)(?:\(.+\))?(!)?:

🟢 Require two reviewer for test updates

When test data is updated, we require two reviewers

  • #approved-reviews-by >= 2

@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) bug Something isn't working html issue related to html backend labels Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

AI triage (advisory)

Checked commit 204f927f19. The analysis read the diff only. It did not run code from this pull request.

Fixes AnnotatedTextList.to_single_text_element() in the HTML backend so that it only propagates a formatting style or hyperlink to the whole element when all non-whitespace runs share it, stopping partial formatting from spreading across headings and captions.

Topic labels added: bug, html.

CI safety: no concern found. A maintainer must still approve CI.

1 related pull request(s) in the same code
PR State Signal Assessment
#3891 open referenced as #3891 related: PR #3891 also edits html_backend.py and to_single_text_element(), but it fixes whitespace boundary handling with a new normalize_whitespace() method; it does not fix the 'first formatting wins' bug that this PR addresses.

Reference data changes

Change Files
text 5
  • text tests/data/epub/groundtruth/epub_purvis_poetry.epub.json: item attributes changed
  • text tests/data/epub/groundtruth/epub_purvis_poetry.epub.md: +1 / -1 lines
  • text tests/data/html/groundtruth/hyperlink_05.html.json: item attributes changed
  • text tests/data/html/groundtruth/wiki_duck.html.json: item attributes changed
  • text tests/data/html/groundtruth/wiki_duck.html.md: +1 / -1 lines

Assessment: expected. The reference data changes match exactly what the PR description predicts: the 'Hibernia' heading loses its italic, 12 wiki_duck captions lose partial hyperlinks, and only formatting/hyperlink fields change.

The ai:* labels are advisory. They do not approve CI and they do not add tests:full. A new push runs this check again.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI first review (advisory): no blocking issue found

This review covers the full diff at 204f927f19. It read the code only. It did not run tests or code from this pull request.

This PR updates AnnotatedTextList.to_single_text_element in the HTML backend to only apply formatting or hyperlink metadata when it matches across all non-whitespace text runs. The fix resolves heading and caption metadata bleeding with targeted tests and minimal regression scope.

A maintainer makes the merge decision. This review never approves the pull request.

@github-actions github-actions Bot added the ai:review-lgtm AI first review found no blocker or major issue (advisory) label Oct 8, 2026
@codecov

codecov Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@PeterStaar-IBM PeterStaar-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.

lgtm!

@dolfim-ibm
dolfim-ibm merged commit 930bf20 into docling-project:main Oct 12, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:ci-safe AI triage found no CI-safety concern (advisory) ai:review-lgtm AI first review found no blocker or major issue (advisory) bug Something isn't working html issue related to html backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTML backend: formatting or link of one word is applied to the whole heading or caption

4 participants