Skip to content

feat(reading-order): re-enable same-row left-to-right linking with additive r2l fix#163

Open
aImErYbArRaUlT wants to merge 3 commits into
docling-project:mainfrom
aImErYbArRaUlT:dev/reading-order-overwrite-fix
Open

feat(reading-order): re-enable same-row left-to-right linking with additive r2l fix#163
aImErYbArRaUlT wants to merge 3 commits into
docling-project:mainfrom
aImErYbArRaUlT:dev/reading-order-overwrite-fix

Conversation

@aImErYbArRaUlT

Copy link
Copy Markdown

Addresses #162.

_init_l2r_map (the same-row left-to-right linking) has been guarded by False since #44, with the note that it "leads to errors ... might be necessary in the future." This re-enables it and fixes the underlying issue the errors came from.

What was wrong

With same-row linking off, an element on the same row as a right-hand neighbour (a right-aligned date next to a job title, or the right column of a two-column figure) never gets an edge into the reading-order graph. It ends up as an orphan node, and an orphan sorts to the end of the traversal. So same-row right elements get emitted last, detached from where they belong.

Why it isn't just a one-line re-enable

Flipping the guard back on exposes a second issue in the r2l branch of _init_ud_maps: when an element is a same-row right partner, the code overwrites its up/down links with only the same-row link and continues, skipping the spatial search that finds its real vertical parents. So a caption sitting above the right column loses its link to the figure and orphans to the bottom. That's the regression the original "leads to errors" note was about.

The fix (two commits)

  1. Re-enable the link with the original follows_maintext_order (cid-adjacency) guard.
  2. Make the r2l edges additive: append the same-row edge instead of replacing, and drop the continue so the spatial search still runs and the element keeps its real vertical parents.

This preserves the model's count invariant (it returns exactly as many elements as it receives, none stranded). The symptom-level alternatives I tried either stranded elements or dropped edges, which violates that.

Evidence (dpbench, Spearman vs. ground truth)

Measured across three states to isolate each commit's effect:

  • baseline (main): mean 0.9820
  • re-enable only (commit 1): improves 5 docs (two previously-whitelisted hard cases, one 0.65 -> 1.0) but regresses one caption doc 0.96 -> 0.75 (the orphaning above)
  • re-enable + additive fix (commit 2): repairs that regression to 0.99, touches nothing else

Net: mean 0.9820 -> 0.9845, 6 docs improved, 0 regressions, 0 elements stranded, stable across 5 seeds, full suite passes.

Tests

Added a regression test for the caption-orphan case (test_caption_not_orphaned_in_two_column_figure). It is a minimal hand-built fixture that reproduces the orphaning. It fails on the pre-fix behaviour (caption emitted last) and passes with the fix. Verified it actually bites: confirmed failing on the re-enable-only branch and passing on the full fix.

Scope

This targets the same-row / right-aligned class only. It does not solve single-column heading inversion or general multi-column reading order. I tested SSG-42 directly and it's unchanged, since that page is single-column and the same-row branch never fires.

Checklist

  • Tests have been added
  • Documentation has been updated, if necessary
  • Examples have been added, if necessary

Signed-off-by: aImErYbArRaUlT <aimery@barratec.com>
Signed-off-by: aImErYbArRaUlT <aimery@barratec.com>
Signed-off-by: aImErYbArRaUlT <aimery@barratec.com>
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

DCO Check Passed

Thanks @aImErYbArRaUlT, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 1 of 2 protections blocking · waiting on 👀 reviews

Protection Waiting on
🔴 Require two reviewer for test updates 👀 reviews
🟢 Enforce conventional commit

🔴 Require two reviewer for test updates

Waiting for

  • #approved-reviews-by >= 2
This rule is failing.

When test data is updated, we require two reviewers

  • #approved-reviews-by >= 2

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

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.

1 participant