org_rust_parser/object/
table_cell.rs

1use crate::constants::NEWLINE;
2use crate::node_pool::NodeID;
3use crate::parse::parse_object;
4use crate::types::{Cursor, Expr, MatchError, ParseOpts, Parseable, Parser, Result};
5
6#[derive(Debug, Clone)]
7pub struct TableCell(pub Vec<NodeID>);
8
9impl<'a> Parseable<'a> for TableCell {
10    fn parse(
11        parser: &mut Parser<'a>,
12        mut cursor: Cursor<'a>,
13        parent: Option<NodeID>,
14        parse_opts: ParseOpts,
15    ) -> Result<NodeID> {
16        let start = cursor.index;
17
18        let mut content_vec: Vec<NodeID> = Vec::new();
19        loop {
20            match parse_object(parser, cursor, parent, parse_opts) {
21                Ok(id) => {
22                    cursor.index = parser.pool[id].end;
23                    content_vec.push(id);
24                }
25                Err(MatchError::MarkupEnd(kind)) => {
26                    // table cells can end on both a vbar and a newline
27                    // a newline indicates the start of the next row
28                    // we can't skip past it so that tablerow
29                    // has a signal to know when it ends (a table cell ending in a newline)
30                    if cursor.curr() != NEWLINE {
31                        cursor.next();
32                    }
33                    break;
34                }
35                Err(_) => break,
36            }
37        }
38
39        // set parents of children
40        // TODO: abstract this? stolen from markup.rs
41        let new_id = parser.pool.reserve_id();
42        for id in &mut content_vec {
43            parser.pool[*id].parent = Some(new_id);
44        }
45
46        // get rid of alignment spaces, deleting the object if it becomes empty
47        if let Some(last_id) = content_vec.last() {
48            let last_item = &mut parser.pool[*last_id];
49            if let Expr::Plain(plains) = last_item.obj {
50                let repl_str = plains.trim_end();
51                if repl_str.trim_end().is_empty() {
52                    content_vec.pop();
53                } else {
54                    last_item.obj = Expr::Plain(repl_str);
55                }
56            }
57        }
58
59        Ok(parser
60            .pool
61            .alloc_with_id(Self(content_vec), start, cursor.index, parent, new_id))
62    }
63}