Support interchangeable whitespace in re-matching plain text.

This commit is contained in:
Tom Alexander 2023-09-14 04:00:34 -04:00
parent ee5e0698b1
commit 66d16d89ed
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -1,17 +1,24 @@
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::is_not;
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
use nom::character::complete::anychar; use nom::character::complete::anychar;
use nom::combinator::map; use nom::character::complete::line_ending;
use nom::character::complete::one_of;
use nom::combinator::peek; use nom::combinator::peek;
use nom::combinator::recognize; use nom::combinator::recognize;
use nom::combinator::verify; use nom::combinator::verify;
use nom::multi::many1;
use nom::multi::many_till; use nom::multi::many_till;
use super::org_source::OrgSource; use super::org_source::OrgSource;
use super::radio_link::RematchObject; use super::radio_link::RematchObject;
use super::util::exit_matcher_parser; use super::util::exit_matcher_parser;
use super::util::get_consumed;
use super::util::org_space_or_line_ending;
use crate::context::parser_with_context; use crate::context::parser_with_context;
use crate::context::RefContext; use crate::context::RefContext;
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res; use crate::error::Res;
use crate::types::Object; use crate::types::Object;
use crate::types::PlainText; use crate::types::PlainText;
@ -72,11 +79,52 @@ impl<'x> RematchObject<'x> for PlainText<'x> {
_context: RefContext<'b, 'g, 'r, 's>, _context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
) -> Res<OrgSource<'s>, Object<'s>> { ) -> Res<OrgSource<'s>, Object<'s>> {
map(tag(self.source), |s| { let mut remaining = input;
let mut goal = self.source;
loop {
if goal.is_empty() {
break;
}
// let is_whitespace = recognize(many1(org_space_or_line_ending))(input);
let is_not_whitespace = is_not::<&str, &str, CustomError<_>>(" \t\r\n")(goal);
match is_not_whitespace {
Ok((new_goal, payload)) => {
let (new_remaining, _) = tag(payload)(remaining)?;
remaining = new_remaining;
goal = new_goal;
continue;
}
Err(_) => {}
};
let is_whitespace = recognize(many1(alt((
recognize(one_of::<&str, &str, CustomError<_>>(" \t")),
line_ending,
))))(goal);
match is_whitespace {
Ok((new_goal, _)) => {
let (new_remaining, _) = many1(org_space_or_line_ending)(remaining)?;
remaining = new_remaining;
goal = new_goal;
continue;
}
Err(_) => {}
};
return Err(nom::Err::Error(CustomError::MyError(MyError(
"Target does not match.".into(),
))));
}
let source = get_consumed(input, remaining);
Ok((
remaining,
Object::PlainText(PlainText { Object::PlainText(PlainText {
source: Into::<&str>::into(s), source: Into::<&str>::into(source),
}) }),
})(input) ))
} }
} }