Skip to content

Add right-to-left reading order support to xy-cut sorting - #4420

Open
Nimra3261 wants to merge 1 commit into
Unstructured-IO:mainfrom
Nimra3261:rtl-xy-cut-sort
Open

Add right-to-left reading order support to xy-cut sorting#4420
Nimra3261 wants to merge 1 commit into
Unstructured-IO:mainfrom
Nimra3261:rtl-xy-cut-sort

Conversation

@Nimra3261

@Nimra3261 Nimra3261 commented Jul 26, 2026

Copy link
Copy Markdown

What

The xy-cut layout sorting (recursive_xy_cut / recursive_xy_cut_swapped in unstructured/partition/utils/xycut.py) always visits column/block groups left-to-right. For right-to-left scripts (Arabic, Hebrew, etc.) this is the wrong reading order - the rightmost block on a line should come first, not last.

Adds an rtl parameter (default False, fully backward compatible) that reverses the horizontal traversal order at each split, while leaving vertical (top-to-bottom) order untouched - that part of reading order is the same for LTR and RTL documents. Threaded through sort_page_elements, sort_bboxes_by_xy_cut, and sort_text_regions, plus a new UNSTRUCTURED_XY_CUT_RTL env var matching the existing UNSTRUCTURED_XY_CUT_PRIMARY_DIRECTION pattern.

Scope

This fixes block/column reading order in the layout sorting step only. It does not touch OCR text recognition itself - Tesseract already produces correctly-ordered text within a single recognized line/paragraph when given the right language, so glyph-level bidi shaping is out of scope here. Happy to help with that side separately if it's still an open problem once this lands.

Testing

Added unit tests for both the low-level xycut.py functions and the sort_page_elements wrapper, verifying: (1) default (rtl=False) behavior is byte-identical to before - the existing test_recursive_xy_cut fixture still passes unchanged, and (2) rtl=True correctly mirrors reading order.

Ran locally: test_sorting.py and test_xycut.py both pass in full (17/17 and 13/13). I couldn't install unstructured-inference itself locally (pulls in torch and isn't needed for this change), so the TextRegions-dependent tests in test_sorting.py were verified against a minimal local stub matching its documented interface rather than the real package - flagging that honestly in case CI surfaces something my stub didn't catch.

Addresses #3927

Review in cubic

The xy-cut layout sorting (recursive_xy_cut / recursive_xy_cut_swapped)
always visits column/block groups left-to-right, which is the wrong
reading order for right-to-left scripts (Arabic, Hebrew, etc.) - the
rightmost block on a line should come first, not last.

Adds an rtl parameter (default False, fully backward compatible) that
reverses the horizontal traversal order at each split while leaving
vertical (top-to-bottom) order untouched, since that's the same for
LTR and RTL documents. Threaded through sort_page_elements,
sort_bboxes_by_xy_cut, and sort_text_regions, plus a new
UNSTRUCTURED_XY_CUT_RTL env var matching the existing
UNSTRUCTURED_XY_CUT_PRIMARY_DIRECTION pattern.

Scope note: this fixes block/column reading order in the layout
sorting step only. It does not touch OCR text recognition itself -
Tesseract already produces correctly-ordered text within a single
recognized line/paragraph when given the right language, so glyph-level
bidi shaping is out of scope here.

Addresses Unstructured-IO#3927

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 4 files

Shadow auto-approve: would auto-approve. Adds an opt-in RTL reading order parameter to xy-cut sorting, with tests confirming backward compatibility and correct reversal of horizontal order.

Re-trigger cubic

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