101 lines
3.5 KiB
Rust
Raw Normal View History

2023-10-31 20:26:34 -04:00
use super::macros::intermediate;
use super::table_row::ITableRow;
use crate::error::CustomError;
use crate::intermediate::table_group::ITableGroup;
2023-12-21 14:56:58 -05:00
use organic::types::StandardProperties;
2023-10-27 17:08:58 -04:00
2023-10-31 20:26:34 -04:00
#[derive(Debug, Clone)]
pub(crate) struct ITable {
pub(crate) children: Vec<ITableGroup>,
2023-12-21 14:56:58 -05:00
pub(crate) post_blank: organic::types::PostBlank,
2023-10-31 20:26:34 -04:00
}
intermediate!(
ITable,
&'orig organic::types::Table<'parse>,
original,
intermediate_context,
{
2023-12-22 00:08:06 -05:00
// Separate groups by lines, multiple contiguous lines are the same as one.
// If there is only one group, it is a tbody.
// If there are more than one group, the first is thead and the rest are tbody.
let sections = group_into_sections(&original.children);
let children = if sections.len() == 1 {
// If there is only one section, then it is a body.
let mut ret = Vec::new();
for group in sections.into_iter() {
let mut rows = Vec::new();
for obj in group.into_iter() {
rows.push(ITableRow::new(intermediate_context.clone(), obj).await?)
}
ret.push(ITableGroup::Body(rows));
}
ret
} else {
// If there are more than one section, the first is a head and the rest are body.
let mut ret = Vec::new();
let mut sections = sections.into_iter();
if let Some(group) = sections.next() {
let mut rows = Vec::new();
for obj in group.into_iter() {
rows.push(ITableRow::new(intermediate_context.clone(), obj).await?)
}
ret.push(ITableGroup::Head(rows));
}
for group in sections {
let mut rows = Vec::new();
for obj in group.into_iter() {
rows.push(ITableRow::new(intermediate_context.clone(), obj).await?)
}
ret.push(ITableGroup::Body(rows));
}
ret
};
2023-10-31 20:26:34 -04:00
2023-12-21 14:56:58 -05:00
Ok(ITable {
children,
post_blank: original.get_post_blank(),
})
}
);
2023-12-22 00:08:06 -05:00
enum GroupIntoSectionsState<'orig, 'parse> {
NonSection,
Section(Vec<&'orig organic::types::TableRow<'parse>>),
}
fn group_into_sections<'orig, 'parse>(
2023-12-23 06:38:23 -05:00
rows: &'orig [organic::types::TableRow<'parse>],
2023-12-22 00:08:06 -05:00
) -> Vec<Vec<&'orig organic::types::TableRow<'parse>>> {
let mut sections = Vec::new();
2023-12-23 06:38:23 -05:00
let mut rows = rows.iter();
2023-12-22 00:08:06 -05:00
let mut state = GroupIntoSectionsState::NonSection;
loop {
state = match (state, rows.next()) {
(GroupIntoSectionsState::NonSection, None) => break,
(GroupIntoSectionsState::NonSection, Some(row)) if row.children.is_empty() => {
GroupIntoSectionsState::NonSection
}
(GroupIntoSectionsState::NonSection, Some(row)) => {
GroupIntoSectionsState::Section(vec![row])
}
(GroupIntoSectionsState::Section(section), None) => {
sections.push(section);
break;
}
(GroupIntoSectionsState::Section(section), Some(row)) if row.children.is_empty() => {
sections.push(section);
GroupIntoSectionsState::NonSection
}
(GroupIntoSectionsState::Section(mut section), Some(row)) => {
section.push(row);
GroupIntoSectionsState::Section(section)
}
}
}
sections
}