Move paragraph to its own module.

This commit is contained in:
Tom Alexander 2022-12-18 02:53:26 -05:00
parent 7fc19cc9a6
commit eaf8721ae9
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 66 additions and 51 deletions

View File

@ -3,6 +3,7 @@ mod combinator;
mod error;
mod link;
mod list;
mod paragraph;
mod parser_context;
mod parser_with_context;
mod text;

62
src/parser/paragraph.rs Normal file
View File

@ -0,0 +1,62 @@
use super::combinator::context_many_till;
use super::parser_context::ChainBehavior;
use super::parser_context::ContextElement;
use super::parser_context::ExitMatcherNode;
use super::text::blank_line;
use super::text::line_break;
use super::text::Paragraph;
use super::text::Res;
use super::text::TextElement;
use super::text_element_parser::flat_text_element;
use super::token::Token;
use super::Context;
use nom::branch::alt;
use nom::combinator::eof;
use nom::combinator::map;
use nom::combinator::not;
use nom::combinator::recognize;
use nom::multi::many1;
use nom::sequence::tuple;
pub fn paragraph<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, Paragraph<'s>> {
// Add a not(eof) check because many_till cannot match a zero-length string
not(eof)(i)?;
let paragraph_context = context
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
exit_matcher: ChainBehavior::AndParent(Some(&context_paragraph_end)),
}))
.with_additional_node(ContextElement::StartOfParagraph);
let (remaining, (many, till)) =
context_many_till(&paragraph_context, flat_text_element, context_paragraph_end)(i)?;
let many = many
.into_iter()
.filter_map(|token| match token {
Token::TextElement(text_element) => Some(text_element),
Token::Paragraph(_) => panic!("There should only be text elements in paragraphs."),
})
.collect();
Ok((
remaining,
Paragraph {
contents: many,
paragraph_end: till,
},
))
}
fn context_paragraph_end<'s, 'r>(
context: Context<'r, 's>,
input: &'s str,
) -> Res<&'s str, &'s str> {
paragraph_end(input)
}
fn paragraph_end(input: &str) -> Res<&str, &str> {
alt((
recognize(tuple((
map(line_break, TextElement::LineBreak),
many1(blank_line),
))),
eof,
))(input)
}

View File

@ -90,7 +90,7 @@ pub fn symbol(symbol_tag: &'static str) -> impl for<'a> Fn(&'a str) -> Res<&'a s
/// A line containing only whitespace and then a line break
///
/// It is up to the caller to ensure this is called at the start of a line.
fn blank_line(input: &str) -> Res<&str, BlankLine> {
pub fn blank_line(input: &str) -> Res<&str, BlankLine> {
map(
recognize(many_till(
map(space, TextElement::Space),
@ -99,13 +99,3 @@ fn blank_line(input: &str) -> Res<&str, BlankLine> {
|contents| BlankLine { contents },
)(input)
}
pub fn paragraph_end(input: &str) -> Res<&str, &str> {
alt((
recognize(tuple((
map(line_break, TextElement::LineBreak),
many1(blank_line),
))),
eof,
))(input)
}

View File

@ -1,15 +1,10 @@
//! A single element of text.
use crate::parser::parser_with_context::parser_with_context;
use crate::parser::text::paragraph_end;
use super::bold::bold;
use super::combinator::context_many1;
use super::combinator::context_many_till;
use super::link::link;
use super::parser_context::ChainBehavior;
use super::paragraph::paragraph;
use super::parser_context::ContextElement;
use super::parser_context::ContextTree;
use super::parser_context::ExitMatcherNode;
use super::text::line_break;
use super::text::space;
use super::text::span;
@ -19,8 +14,8 @@ use super::text::Res;
use super::text::TextElement;
use super::token::Token;
use super::Context;
use crate::parser::parser_with_context::parser_with_context;
use nom::branch::alt;
use nom::combinator::eof;
use nom::combinator::map;
use nom::combinator::not;
use nom::IResult;
@ -40,13 +35,6 @@ pub fn document(input: &str) -> Res<&str, Vec<Paragraph>> {
Ok((remaining, paragraphs))
}
pub fn context_paragraph_end<'s, 'r>(
context: Context<'r, 's>,
input: &'s str,
) -> Res<&'s str, &'s str> {
paragraph_end(input)
}
pub fn in_section<'s, 'r, 'x>(context: Context<'r, 's>, section_name: &'x str) -> bool {
for thing in context.iter() {
match thing.get_data() {
@ -93,32 +81,6 @@ pub fn _preceded_by_whitespace<'s, 'r>(context: Context<'r, 's>) -> bool {
false
}
pub fn paragraph<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, Paragraph<'s>> {
// Add a not(eof) check because many_till cannot match a zero-length string
not(eof)(i)?;
let paragraph_context = context
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
exit_matcher: ChainBehavior::AndParent(Some(&context_paragraph_end)),
}))
.with_additional_node(ContextElement::StartOfParagraph);
let (remaining, (many, till)) =
context_many_till(&paragraph_context, flat_text_element, context_paragraph_end)(i)?;
let many = many
.into_iter()
.filter_map(|token| match token {
Token::TextElement(text_element) => Some(text_element),
Token::Paragraph(_) => panic!("There should only be text elements in paragraphs."),
})
.collect();
Ok((
remaining,
Paragraph {
contents: many,
paragraph_end: till,
},
))
}
pub fn flat_text_element<'s, 'r>(
context: Context<'r, 's>,
i: &'s str,