Skip to main content

Module balanced

Module balanced 

Source
Expand description

The balanced tier’s page assembly: detector boxes plus our own text (#641). Off by default, beside layout. The balanced tier’s page assembly: detector boxes plus our own text, page in, markdown out (#641).

Behind the ort-layout cargo feature (off by default), beside crate::layout. This is the Rust port of the balanced adapter – scripts/extraction/adapters/teacher_page.py with detector A (Heron-ft ep03) only, no union, and the chosen thresholds – rule for rule:

  • regions from the detector’s boxes, kept per class at [THRESHOLDS] (section_header/title 0.25, list_item 0.10, page_header/footer 0.10, table 0.75, everything else 0.50);
  • lines from the engine’s own words before the learned pass (the same [crate::learned::features::page_features] the feature_dump record carries), grouped exactly as align_labels.lines_of groups them;
  • each line to the TIGHTEST kept region holding at least half its ink, placed where its first line falls in the engine’s reading order;
  • R1: a table region takes TATR’s cells where the stage fires (only when BalancedOptions::with_tatr opts in), else the grid of the engine’s own table in the same place (position filters, text ranks), else the grid the engine builds inside the region, else its lines as paragraphs;
  • R2: a page with no words is the engine’s own markdown for the page, verbatim;
  • R3/R8/R9: bold/italic runs with the engine’s markers, the engine’s sup/sub/underline tags on aligned words, one style run across a line break;
  • R4: a taken grid’s leftover lines as paragraphs around it;
  • R5: a short line (at most [SHORT_HEADING_WORDS] words) claimed by a below-threshold section_header/title box at or above [SHORT_THRESHOLD] is a heading;
  • R7: an engine table no region took is written at the reading position of the lines it covers;
  • R10: ligatures folded, hyphen wraps joined, a list item’s own bullet dropped;
  • furniture (page_header/page_footer) dropped, unless BalancedOptions::keep_furniture keeps it as paragraphs.

balanced_page_markdown assembles one page from caller-held boxes – crate::layout::layout_boxes output or cached boxes injected for parity – and balanced_markdown runs the detector per page. The table-structure stage hooks in per kept table region through BalancedOptions::with_tatr: TATR first, and only on a fire are its cells the region’s table. There is no coarser switch here: a whole-page override would bypass the stage’s own per-region invariants (no word lost, the coverage bar, the gap fill).

Byte parity with the Python adapter (same boxes, same engine) is the contract: every helper below ports its Python original exactly, including difflib.SequenceMatcher (autojunk off, no junk) for the R8 alignment and the bench’s blocks_of/text_similarity for the R1 match. Where the engine already computes the identical value in this crate (ligatures, is_hyphen_wrap_candidate, BULLET_CHARS), the port calls it rather than copying it.

Model failures come back as EngineError::Io carrying the typed pdf_ocr::runtime::ModelError – no new EngineError variants.

Structs§

BalancedOptions
Options for balanced_page_markdown and balanced_markdown.

Functions§

balanced_markdown
The document as markdown through the balanced tier: layout_boxes per page, each page through balanced_page_markdown.
balanced_page_markdown
One page plus its layout boxes as markdown, the balanced tier’s assembly.