use crate::ast::TableAlign;
use crate::block::cursor::Cursor;
use crate::block::ir::IrRow;
use crate::block::probe::Start;
use crate::block::scan;
use crate::pos::{Segment, Span};
use super::Engine;
use super::state::Leaf;
impl<'s> Engine<'s> {
pub(super) fn continue_table(&mut self, cur: Cursor<'s>, content_end: u32) -> bool {
let row_at = match cur.flow_start().map(|c| (c, self.probe(c.tail(), false))) {
Some((c, None)) => Some(c),
Some((c, Some(Start::Liquid))) => {
if let Some(liquid) = self.liquid_scan(c, content_end) {
self.close_leaf();
self.open_liquid(liquid);
return true;
}
Some(c)
}
_ => None,
};
let Some(c) = row_at else { return false };
let span = Span::new(c.offset(), content_end);
let cells = row_cell_spans(self.source, span);
if let Some(Leaf::Table { rows, end, .. }) = &mut self.leaf {
rows.push(IrRow { span, cells });
*end = content_end;
}
true
}
pub(super) fn try_start_table(&mut self, align: Vec<TableAlign>, row: Segment) -> bool {
let Some(Leaf::Paragraph { segments, last_deep }) = &self.leaf else { return false };
let Some(last) = segments.last() else { return false };
if last.lazy || *last_deep {
return false;
}
let header = last.seg;
let cells = row_cell_spans(self.source, header.span);
if cells.len() != align.len() {
return false;
}
let tail = header.span.slice(self.source).trim_start_matches([' ', '\t']);
let html7 = matches!(self.probe(tail, false), Some(Start::Html { kind: 7 }));
if let Some(Leaf::Paragraph { segments, .. }) = &mut self.leaf {
segments.pop();
}
self.close_leaf_and_list();
self.leaf = Some(if html7 {
Leaf::Html {
kind: 7,
lines: vec![header, row],
trailing_newline: false,
start: header.span.start,
end: row.span.end,
}
} else {
Leaf::Table {
align,
rows: vec![IrRow { span: header.span, cells }],
start: header.span.start,
end: row.span.end,
}
});
true
}
}
fn row_cell_spans(source: &str, line_span: Span) -> Vec<Span> {
scan::table_row_cells(line_span.slice(source))
.into_iter()
.map(|r| Span::at(line_span.start, r))
.collect()
}