|
| 1 | +Column-Aware Reading Order (XY-Cut) |
| 2 | +=================================== |
| 3 | + |
| 4 | +``element_parse.reading_order`` is a flat top-to-bottom / left-to-right sort — it interleaves |
| 5 | +columns on any multi-column page (the well-documented naive-sort failure: it reads row 1 of |
| 6 | +column A, then row 1 of column B, then row 2 of A …). ``reading_flow`` recovers the correct |
| 7 | +order with recursive **XY-cut**: it repeatedly splits the boxes at the widest whitespace valley |
| 8 | +(a vertical gutter → columns, a horizontal gutter → rows / blocks), so a two-column layout is |
| 9 | +read *down* column A fully, then column B. |
| 10 | + |
| 11 | +The public flattener is named ``flow_order`` to sit *beside* — not shadow — |
| 12 | +``element_parse.reading_order``; it returns the same ``index``-tagged element contract, so it is |
| 13 | +a drop-in column-aware upgrade. Pure-stdlib geometry over plain box dicts (no image, no OCR |
| 14 | +engine); reuses ``table_grid_fill``'s box-bounds reader. Imports no ``PySide6``. |
| 15 | + |
| 16 | +Headless API |
| 17 | +------------ |
| 18 | + |
| 19 | +.. code-block:: python |
| 20 | +
|
| 21 | + from je_auto_control import flow_order, xy_cut, to_blocks |
| 22 | +
|
| 23 | + # two columns, two rows each: reads A1, A2, B1, B2 — not A1, B1, A2, B2 |
| 24 | + for element in flow_order(ocr_boxes, min_gap=12): |
| 25 | + print(element["index"], element["text"]) |
| 26 | +
|
| 27 | + tree = xy_cut(ocr_boxes, min_gap=12) # {type, axis, children|boxes} |
| 28 | + blocks = to_blocks(tree) # leaf blocks in reading order |
| 29 | +
|
| 30 | +``flow_order`` returns the boxes in column-aware reading order, each tagged with an ``index``. |
| 31 | +``xy_cut`` returns the recursive region tree (each node is a ``split`` on ``axis`` ``"x"`` / |
| 32 | +``"y"`` or a ``leaf`` of boxes). ``to_blocks`` flattens the tree to its leaf blocks in order. |
| 33 | +``min_gap`` is the smallest whitespace valley treated as a column / row break. |
| 34 | + |
| 35 | +Executor commands |
| 36 | +----------------- |
| 37 | + |
| 38 | +``AC_flow_order`` (``boxes`` / ``min_gap`` → ``{count, elements}``) and ``AC_xy_cut`` |
| 39 | +(``boxes`` / ``min_gap`` → ``{tree}``). They are exposed as the MCP tools ``ac_flow_order`` / |
| 40 | +``ac_xy_cut`` (read-only) and as the Script Builder commands **Reading Order (column-aware)** / |
| 41 | +**XY-Cut Region Tree** under **OCR**. |
0 commit comments