use oxidize_pdf::graphics::extraction::{ExtractedGraphics, VectorLine};
use oxidize_pdf::pipeline::{Element, PartitionConfig, Partitioner};
use oxidize_pdf::text::extraction::TextFragment;
fn hline(x1: f64, x2: f64, y: f64) -> VectorLine {
VectorLine::new(x1, y, x2, y, 1.0, true, None)
}
fn vline(x: f64, y1: f64, y2: f64) -> VectorLine {
VectorLine::new(x, y1, x, y2, 1.0, true, None)
}
fn frag(t: &str, x: f64, y: f64) -> TextFragment {
TextFragment {
text: t.into(),
x,
y,
width: 30.0,
height: 10.0,
font_size: 10.0,
font_name: None,
is_bold: false,
is_italic: false,
color: None,
space_decisions: Vec::new(),
mcid: None,
struct_tag: None,
}
}
fn build_graphics(h: Vec<VectorLine>, v: Vec<VectorLine>) -> ExtractedGraphics {
let mut g = ExtractedGraphics::new();
for line in h.into_iter().chain(v.into_iter()) {
g.add_line(line);
}
g
}
#[test]
fn ruling_partition_emits_rich_structure_with_merged_header() {
let h = vec![
hline(100.0, 300.0, 100.0),
hline(100.0, 300.0, 150.0),
hline(100.0, 300.0, 200.0),
];
let v = vec![
vline(100.0, 100.0, 200.0), vline(300.0, 100.0, 200.0), vline(200.0, 100.0, 150.0), ];
let graphics = build_graphics(h, v);
let mut header_frag = frag("Header", 150.0, 170.0);
header_frag.struct_tag = Some("TH".to_string());
let frags = vec![
header_frag,
frag("A", 130.0, 120.0),
frag("B", 230.0, 120.0),
];
let elements = Partitioner::new(PartitionConfig::default()).partition_fragments_with_graphics(
&frags,
Some(&graphics),
0,
842.0,
);
let table = elements
.iter()
.find_map(|e| match e {
Element::Table(t) => Some(t),
_ => None,
})
.expect("a table element");
let st = table.structure.as_ref().expect("rich structure present");
assert!(
st.cells
.iter()
.any(|c| c.row == 0 && c.col == 0 && c.col_span == 2 && c.is_header),
"expected a spanning header cell at row 0, col 0 with col_span == 2"
);
assert_eq!(st.header_rows, 1, "single header row expected");
assert_eq!(table.rows[0].len(), 2);
}