Going to try to make the functions in the context more generic.
This commit is contained in:
parent
c958136949
commit
262bd3c061
@ -3,56 +3,23 @@ use nom::error::VerboseError;
|
||||
use nom::IResult;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NomContext<F>
|
||||
where
|
||||
F: for<'a> FnMut(&'a str) -> IResult<&'a str, &'a str, VerboseError<&'a str>>,
|
||||
F: Clone,
|
||||
pub struct NomContext
|
||||
// where
|
||||
// F: for<'a> FnMut(&'a str) -> IResult<&'a str, &'a str, VerboseError<&'a str>>,
|
||||
// F: Clone,
|
||||
{
|
||||
pub fail_matcher: F,
|
||||
|
||||
// pub fail_matcher: F,
|
||||
/// You can't have nested bolds in org-mode
|
||||
pub can_match_bold: bool,
|
||||
pub can_match_link: bool,
|
||||
}
|
||||
|
||||
impl<F> NomContext<F>
|
||||
where
|
||||
F: for<'a> FnMut(&'a str) -> IResult<&'a str, &'a str, VerboseError<&'a str>>,
|
||||
F: Clone,
|
||||
{
|
||||
impl NomContext {
|
||||
pub fn new(fail_matcher: F) -> Self {
|
||||
NomContext {
|
||||
fail_matcher,
|
||||
// fail_matcher,
|
||||
can_match_bold: true,
|
||||
can_match_link: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn without_bold(&self) -> Self {
|
||||
NomContext {
|
||||
fail_matcher: self.fail_matcher.clone(),
|
||||
can_match_bold: true,
|
||||
can_match_link: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_additional_fail_matcher<G>(
|
||||
&self,
|
||||
mut additional_fail_matcher: G,
|
||||
) -> NomContext<
|
||||
impl Clone + for<'o> FnMut(&'o str) -> IResult<&'o str, &'o str, VerboseError<&'o str>>,
|
||||
>
|
||||
where
|
||||
G: for<'g> FnMut(&'g str) -> IResult<&'g str, &'g str, VerboseError<&'g str>>,
|
||||
G: Clone,
|
||||
{
|
||||
let mut old_fail_matcher_clone = self.fail_matcher.clone();
|
||||
NomContext {
|
||||
fail_matcher: move |i| {
|
||||
alt((&mut additional_fail_matcher, &mut old_fail_matcher_clone))(i)
|
||||
},
|
||||
can_match_bold: self.can_match_bold,
|
||||
can_match_link: self.can_match_link,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ use nom::IResult;
|
||||
|
||||
use super::nom_context::NomContext;
|
||||
use super::parser_with_context::parser_with_context;
|
||||
use super::text_element_parser::paragraph;
|
||||
|
||||
pub type Res<T, U> = IResult<T, U, VerboseError<T>>;
|
||||
|
||||
@ -129,17 +128,12 @@ pub fn link_end(input: &str) -> Res<&str, TextElement> {
|
||||
map(symbol("]"), TextElement::Symbol)(input)
|
||||
}
|
||||
|
||||
// pub fn paragraph(input: &str) -> Res<&str, (Vec<TextElement>, &str)> {
|
||||
// // let initial_context = NomContext::new(¶graph_end);
|
||||
// // many_till(text_element(initial_context), paragraph_end)(input)
|
||||
// todo!()
|
||||
// }
|
||||
|
||||
pub fn paragraph_end(input: &str) -> Res<&str, &str> {
|
||||
recognize(tuple((map(line_break, TextElement::LineBreak), blank_line)))(input)
|
||||
}
|
||||
|
||||
pub fn document(input: &str) -> Res<&str, Vec<(Vec<TextElement>, &str)>> {
|
||||
let initial_context = NomContext::new(¶graph_end);
|
||||
many1(parser_with_context!(paragraph)(initial_context))(input)
|
||||
todo!()
|
||||
// many1(parser_with_context!(paragraph)(initial_context))(input)
|
||||
}
|
||||
|
@ -20,62 +20,3 @@ use nom::error::VerboseError;
|
||||
use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
|
||||
pub fn flat_text_element<'a, F>(
|
||||
i: &'a str,
|
||||
context: &mut NomContext<F>,
|
||||
) -> Res<&'a str, TextElement<'a>>
|
||||
where
|
||||
F: for<'b> FnMut(&'b str) -> IResult<&'b str, &'b str, VerboseError<&'b str>>
|
||||
+ std::clone::Clone,
|
||||
{
|
||||
not(&mut context.fail_matcher)(i)?;
|
||||
// if context.can_match_bold {
|
||||
// if let Ok(v) = parser_with_context!(flat_bold)(context.clone())(i) {
|
||||
// return Ok(v);
|
||||
// }
|
||||
// }
|
||||
// if context.can_match_link {
|
||||
// // todo
|
||||
// }
|
||||
alt((
|
||||
map(span, TextElement::Span),
|
||||
map(symbol("*"), TextElement::Symbol),
|
||||
map(symbol("["), TextElement::Symbol),
|
||||
map(symbol("]"), TextElement::Symbol),
|
||||
map(space, TextElement::Space),
|
||||
map(line_break, TextElement::LineBreak),
|
||||
))(i)
|
||||
}
|
||||
|
||||
// pub fn flat_bold<'a, F>(i: &'a str, context: &mut NomContext<F>) -> Res<&'a str, TextElement<'a>>
|
||||
// where
|
||||
// F: for<'b> FnMut(&'b str) -> IResult<&'b str, &'b str, VerboseError<&'b str>>,
|
||||
// F: Clone,
|
||||
// {
|
||||
// not(&mut context.fail_matcher)(i)?;
|
||||
// let new_context = context
|
||||
// .without_bold()
|
||||
// .with_additional_fail_matcher(|i| recognize(bold_end)(i));
|
||||
// let text_element_parser = parser_with_context!(flat_text_element)(new_context);
|
||||
// map(
|
||||
// recognize(tuple((
|
||||
// bold_start,
|
||||
// many_till(text_element_parser, bold_end),
|
||||
// bold_end,
|
||||
// ))),
|
||||
// |body| TextElement::Bold(Bold { contents: body }),
|
||||
// )(i)
|
||||
// }
|
||||
|
||||
pub fn paragraph<'a, F>(
|
||||
i: &'a str,
|
||||
context: &mut NomContext<F>,
|
||||
) -> Res<&'a str, (Vec<TextElement<'a>>, &'a str)>
|
||||
where
|
||||
F: for<'b> FnMut(&'b str) -> IResult<&'b str, &'b str, VerboseError<&'b str>>,
|
||||
F: Clone,
|
||||
{
|
||||
let text_element_parser = parser_with_context!(flat_text_element)(context.clone());
|
||||
many_till(text_element_parser, paragraph_end)(i)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user