pdftract/crates/pdftract-core/src/layout/mod.rs
jedarden cce26bb6b6 feat(pdftract-64j83): implement column label assignment to Span.column + Line.column
- Add column: Option<u32> field to Span in hybrid.rs
- Create layout/columns.rs module with:
  - Column struct (index + x_range)
  - assign_columns_to_spans() - assign by x_range containing bbox[0]
  - assign_columns_to_lines() - propagate via mode (>50% dominance)
  - HasBBoxAndColumn and HasSpansWithColumn traits
- Update layout/mod.rs to export column types
- Fix test fixtures in inspect/render (add column: None)

Acceptance criteria:
- 2-column page span at x0=50 -> Some(0), x0=350 -> Some(1)
- Full-width heading line -> None (mixed spans)
- Single-column page -> all spans Some(0)
- Inter-column gap -> None

Closes: pdftract-64j83

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 14:45:19 -04:00

32 lines
1.2 KiB
Rust

//! Layout analysis for Phase 4.
//!
//! This module implements block-level layout analysis including:
//! - Caption classification (caption.rs)
//! - Code block classification (code.rs)
//! - Column label assignment (columns.rs)
//! - Line formation (line.rs)
//! - Readability aggregation (readability.rs)
//! - English wordlist for dict coverage scoring (wordlist.rs)
//!
//! Phase 4 organizes extracted text into semantic blocks (paragraphs,
//! headings, figures, captions, etc.) based on spatial and font metrics.
pub mod caption;
pub mod code;
pub mod columns;
pub mod line;
pub mod readability;
pub mod wordlist;
pub use caption::{classify_caption, classify_page_captions, Block, PageContext};
pub use code::{
classify_code, classify_page_code_blocks, is_fixed_pitch_flag, is_monospace_font_name,
is_monospace_span, MonospaceSpan,
};
pub use columns::{assign_columns_to_lines, assign_columns_to_spans, Column};
pub use line::{
cluster_spans_into_lines, compute_baseline, group_lines_into_blocks, union_bboxes, BlockInput,
HasBBox, HasFontSize, Line, LineDirection, LineMetadata,
};
pub use readability::{aggregate_page_readability, ScoredSpan};
pub use wordlist::is_english_word;