use serde::{Deserialize, Serialize};
use super::bbox::BoundingBox;
use super::chunks::TextChunk;
use super::content::ContentElement;
use super::enums::SemanticType;
pub const TABLE_BORDER_EPSILON: f64 = 0.5;
pub const MIN_CELL_CONTENT_INTERSECTION_PERCENT: f64 = 0.01;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableBorder {
pub bbox: BoundingBox,
pub index: Option<u32>,
pub level: Option<String>,
pub x_coordinates: Vec<f64>,
pub x_widths: Vec<f64>,
pub y_coordinates: Vec<f64>,
pub y_widths: Vec<f64>,
pub rows: Vec<TableBorderRow>,
pub num_rows: usize,
pub num_columns: usize,
pub is_bad_table: bool,
pub is_table_transformer: bool,
pub previous_table: Option<Box<TableBorder>>,
pub next_table: Option<Box<TableBorder>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableBorderRow {
pub bbox: BoundingBox,
pub index: Option<u32>,
pub level: Option<String>,
pub row_number: usize,
pub cells: Vec<TableBorderCell>,
pub semantic_type: Option<SemanticType>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableBorderCell {
pub bbox: BoundingBox,
pub index: Option<u32>,
pub level: Option<String>,
pub row_number: usize,
pub col_number: usize,
pub row_span: usize,
pub col_span: usize,
pub content: Vec<TableToken>,
pub contents: Vec<ContentElement>,
pub semantic_type: Option<SemanticType>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableToken {
pub base: TextChunk,
pub token_type: TableTokenType,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum TableTokenType {
Text,
Image,
Table,
}
pub type TableTokenRow = Vec<TableToken>;
#[derive(Debug, Clone, Default)]
pub struct TableBordersCollection {
pub table_borders: Vec<Vec<TableBorder>>,
}
impl TableBordersCollection {
pub fn new(num_pages: usize) -> Self {
Self {
table_borders: vec![Vec::new(); num_pages],
}
}
pub fn add(&mut self, page: usize, border: TableBorder) {
if page < self.table_borders.len() {
self.table_borders[page].push(border);
}
}
pub fn get_page(&self, page: usize) -> &[TableBorder] {
if page < self.table_borders.len() {
&self.table_borders[page]
} else {
&[]
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_table_borders_collection() {
let mut collection = TableBordersCollection::new(5);
let border = TableBorder {
bbox: BoundingBox::new(Some(1), 10.0, 10.0, 200.0, 300.0),
index: None,
level: None,
x_coordinates: vec![10.0, 100.0, 200.0],
x_widths: vec![1.0, 1.0, 1.0],
y_coordinates: vec![10.0, 150.0, 300.0],
y_widths: vec![1.0, 1.0, 1.0],
rows: vec![],
num_rows: 2,
num_columns: 2,
is_bad_table: false,
is_table_transformer: false,
previous_table: None,
next_table: None,
};
collection.add(0, border);
assert_eq!(collection.get_page(0).len(), 1);
assert_eq!(collection.get_page(1).len(), 0);
assert_eq!(collection.get_page(10).len(), 0);
}
}