Scaffold table token

This commit is contained in:
Juno Takano 2026-02-16 01:06:24 -03:00
commit b890eb93f1
6 changed files with 217 additions and 4 deletions

View file

@ -9,7 +9,7 @@ use crate::{
Block, Lexeme, State, Token,
token::{
Header, List, LineBreak, Literal, Paragraph, PreFormat, Quote,
Verse,
Table, Verse,
},
},
},
@ -59,6 +59,11 @@ pub fn parse(
iterator.next();
iterator.next();
return true;
} else if Table::probe(lexeme) {
log!(VERBOSE, "Block Context: None -> Table on {lexeme}");
state.context.block = Block::Table;
iterator.next();
return true;
} else if Paragraph::probe(lexeme) {
log!(VERBOSE, "Block Context: None -> Paragraph on {lexeme}");
state.context.block = Block::Paragraph;
@ -95,6 +100,9 @@ pub fn parse(
Block::Quote => {
return super::quote::parse(lexeme, state, tokens, iterator, graph);
},
Block::Table => {
return super::table::parse(lexeme, state, tokens, iterator, graph);
},
Block::Verse => {
if Verse::probe_end(lexeme) {
tokens.push(Token::Verse(Verse::new(false)));

View file

@ -0,0 +1,114 @@
use std::{iter::Peekable, slice::Iter};
use crate::{
graph::Graph,
prelude::*,
syntax::content::parser::{
Lexeme, State, Token, context::Block, format, state, token::Table,
},
};
/// Handles open table contexts until a table is fully parsed.
///
/// A return of `true` will trigger a continue in the outer parser,
/// skipping any further parsing of the current lexeme.
///
/// # Panics
/// This parser can handle only the Table context, and will panic if passed an
/// unrelated context since it has no knowledge on how to handle them.
pub fn parse(
lexeme: &Lexeme,
state: &mut State,
tokens: &mut Vec<Token>,
iterator: &mut Peekable<Iter<'_, Lexeme>>,
graph: &Graph,
) -> bool {
let buffer = &mut state.buffers.table;
let candidate = &mut buffer.candidate;
let mut parse_text = |text: &str| {
let (parsed_text, text_tokens) = format(text, graph);
state.format_tokens.extend_from_slice(&text_tokens);
parsed_text
};
#[allow(clippy::wildcard_enum_match_arm)]
match state.context.block {
Block::Table => {
if Table::probe_end(lexeme) {
log!(VERBOSE, "Probed end of table on {lexeme}");
if buffer.in_header {
log!(VERBOSE, "Adding unterminated header: {lexeme}");
candidate.add_header(&parse_text(&buffer.cell));
buffer.cell.clear();
iterator.next();
iterator.next();
} else if buffer.in_cell {
log!(VERBOSE, "Adding unterminated cell: {lexeme}");
candidate.add_cell(&parse_text(&buffer.cell));
buffer.cell.clear();
iterator.next();
iterator.next();
} else {
log!(VERBOSE, "Adding undelimited cell: {lexeme}");
candidate.add_cell(&parse_text(&buffer.cell));
buffer.cell.clear();
iterator.next();
iterator.next();
}
tokens.push(Token::Table(candidate.clone()));
log!(VERBOSE, "Block Context: Table -> None on {lexeme}");
state.context.block = Block::None;
*buffer = state::TableBuffer::default();
iterator.next();
} else if lexeme.match_char('\n') {
log!(VERBOSE, "Adding row: found newline on {lexeme}");
if !buffer.cell.is_empty() {
if buffer.in_header {
log!(VERBOSE, "Adding unterminated header: {lexeme}");
candidate.add_header(&parse_text(&buffer.cell));
buffer.cell.clear();
iterator.next();
iterator.next();
} else if buffer.in_cell {
log!(VERBOSE, "Adding unterminated cell: {lexeme}");
candidate.add_cell(&parse_text(&buffer.cell));
buffer.cell.clear();
iterator.next();
iterator.next();
} else {
log!(VERBOSE, "Adding undelimited cell: {lexeme}");
candidate.add_cell(&parse_text(&buffer.cell));
buffer.cell.clear();
iterator.next();
iterator.next();
}
}
candidate.add_row(vec![]);
} else if lexeme.match_char_triple(' ', '!', ' ') {
log!(VERBOSE, "Adding header: found spaced ! on {lexeme}");
candidate.add_header(&parse_text(&buffer.cell));
buffer.cell.clear();
iterator.next();
iterator.next();
} else if lexeme.match_char_triple(' ', '|', ' ') {
log!(VERBOSE, "Adding cell: found spaced | on {lexeme}");
candidate.add_cell(&parse_text(&buffer.cell));
buffer.cell.clear();
iterator.next();
iterator.next();
} else {
log!(VERBOSE, "Extending cell text on {lexeme}");
buffer.cell.push_str(lexeme.text().as_str());
}
},
_ => {
panic!("Table context parser called to handle non-table context")
},
}
true
}