Support leading whitespace for list items.

This commit is contained in:
Tom Alexander 2023-03-17 16:37:47 -04:00
parent 37070689c6
commit 32897270a5
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
5 changed files with 26 additions and 9 deletions

View File

@ -1,4 +1,6 @@
use crate::parser::document;
use crate::parser::item;
use crate::parser::ContextTree;
use tracing::Level;
use tracing_subscriber::fmt::format::FmtSpan;
@ -18,8 +20,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.with_span_events(FmtSpan::ENTER | FmtSpan::EXIT)
.finish();
tracing::subscriber::set_global_default(subscriber)?;
let parsed = document(TEST_DOC);
println!("{}\n\n\n", TEST_DOC);
// let parsed = document(TEST_DOC);
// println!("{}\n\n\n", TEST_DOC);
let initial_context: ContextTree<'_, '_> = ContextTree::new();
let parsed = item(&initial_context, " 1. foo\n");
println!("{:#?}", parsed);
Ok(())
}

View File

@ -13,3 +13,5 @@ mod token;
mod util;
pub use document::document;
type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>;
pub use parser_context::ContextTree;
pub use plain_list::item;

View File

@ -56,7 +56,7 @@ fn context_paragraph_end<'r, 's>(
paragraph_end(input)
}
fn paragraph_end(input: &str) -> Res<&str, &str> {
pub fn paragraph_end(input: &str) -> Res<&str, &str> {
alt((
recognize(tuple((
map(line_break, TextElement::LineBreak),

View File

@ -4,15 +4,18 @@ use nom::character::complete::anychar;
use nom::character::complete::digit1;
use nom::character::complete::line_ending;
use nom::character::complete::one_of;
use nom::character::complete::space0;
use nom::combinator::consumed;
use nom::combinator::not;
use nom::combinator::opt;
use nom::combinator::recognize;
use nom::multi::many0_count;
use nom::multi::many1;
use nom::sequence::tuple;
use super::combinator::context_many_till;
use super::error::Res;
use super::paragraph::paragraph_end;
use super::text::space;
use super::text::text_element;
use super::token::ListItem;
@ -25,8 +28,10 @@ pub fn plain_list<'r, 's>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str,
todo!()
}
fn item<'r, 's>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, ListItem<'s>> {
let (remaining, (source, (bul, count, check, tg, sp, (contents, end)))) = consumed(tuple((
pub fn item<'r, 's>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, ListItem<'s>> {
let (remaining, leading_whitespace) = space0(i)?;
let indent_level = leading_whitespace.len();
let (remaining, (bul, countset, check, tg, sp, (contents, end))) = tuple((
bullet,
opt(tuple((space, counter_set))),
opt(tuple((space, check_box))),
@ -34,7 +39,7 @@ fn item<'r, 's>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, ListItem<'
space,
// TODO: This context should probably be something involving the item
context_many_till(context, text_element, item_end),
)))(i)?;
))(remaining)?;
let elements = contents
.into_iter()
@ -44,10 +49,16 @@ fn item<'r, 's>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, ListItem<'
})
.collect();
let source = {
let offset = remaining.as_ptr() as usize - i.as_ptr() as usize;
&i[..offset]
};
let ret = ListItem {
source,
leading_whitespace,
bullet: bul,
counter_set: count.map(|(_spc, count)| count),
counter_set: countset.map(|(_spc, count)| count),
check_box: check.map(|(_spc, check)| check),
item_tag: tg.map(|(_spc, tg)| tg),
contents: elements,
@ -94,6 +105,5 @@ fn tag_separator<'s>(i: &'s str) -> Res<&'s str, &'s str> {
}
pub fn item_end<'r, 's>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, &'s str> {
// todo
todo!()
paragraph_end(i)
}

View File

@ -110,6 +110,7 @@ impl<'a> Source<'a> for PlainList<'a> {
#[derive(Debug)]
pub struct ListItem<'a> {
pub source: &'a str,
pub leading_whitespace: &'a str,
pub bullet: &'a str,
pub counter_set: Option<&'a str>,
pub check_box: Option<&'a str>,