2022-12-18 08:11:56 +00:00
|
|
|
use nom::branch::alt;
|
2022-07-16 03:26:49 +00:00
|
|
|
use nom::bytes::complete::tag;
|
|
|
|
use nom::character::complete::alphanumeric1;
|
|
|
|
use nom::character::complete::line_ending;
|
|
|
|
use nom::character::complete::space1;
|
|
|
|
use nom::combinator::map;
|
2022-12-18 08:11:56 +00:00
|
|
|
use nom::combinator::not;
|
2022-07-16 03:26:49 +00:00
|
|
|
use nom::combinator::recognize;
|
|
|
|
use nom::multi::many_till;
|
2022-07-16 22:26:53 +00:00
|
|
|
|
2022-12-18 08:11:56 +00:00
|
|
|
use super::bold::bold;
|
2022-12-18 07:59:41 +00:00
|
|
|
use super::error::Res;
|
2022-12-18 08:11:56 +00:00
|
|
|
use super::link::link;
|
|
|
|
use super::parser_with_context::parser_with_context;
|
2022-12-18 08:24:35 +00:00
|
|
|
use super::token::BlankLine;
|
|
|
|
use super::token::LineBreak;
|
|
|
|
use super::token::Space;
|
|
|
|
use super::token::Span;
|
|
|
|
use super::token::Symbol;
|
|
|
|
use super::token::TextElement;
|
2022-12-18 08:11:56 +00:00
|
|
|
use super::Context;
|
2022-07-16 03:26:49 +00:00
|
|
|
|
|
|
|
pub fn line_break(input: &str) -> Res<&str, LineBreak> {
|
|
|
|
map(line_ending, |s: &str| LineBreak { contents: s })(input)
|
|
|
|
}
|
|
|
|
|
2022-12-18 08:14:56 +00:00
|
|
|
fn space(input: &str) -> Res<&str, Space> {
|
2022-07-16 03:26:49 +00:00
|
|
|
map(space1, |s: &str| Space { contents: s })(input)
|
|
|
|
}
|
|
|
|
|
2022-12-18 08:14:56 +00:00
|
|
|
fn span(input: &str) -> Res<&str, Span> {
|
2022-07-16 03:26:49 +00:00
|
|
|
map(alphanumeric1, |s: &str| Span { contents: s })(input)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn symbol(symbol_tag: &'static str) -> impl for<'a> Fn(&'a str) -> Res<&'a str, Symbol<'a>> {
|
|
|
|
move |i: &str| map(tag(symbol_tag), |s: &str| Symbol { contents: s })(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2022-12-18 07:53:26 +00:00
|
|
|
pub fn blank_line(input: &str) -> Res<&str, BlankLine> {
|
2022-07-16 03:26:49 +00:00
|
|
|
map(
|
2022-11-25 23:55:56 +00:00
|
|
|
recognize(many_till(
|
2022-07-16 03:26:49 +00:00
|
|
|
map(space, TextElement::Space),
|
|
|
|
map(line_break, TextElement::LineBreak),
|
2022-11-25 23:55:56 +00:00
|
|
|
)),
|
|
|
|
|contents| BlankLine { contents },
|
2022-07-16 03:26:49 +00:00
|
|
|
)(input)
|
|
|
|
}
|
2022-12-18 08:11:56 +00:00
|
|
|
|
|
|
|
pub fn text_element<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, TextElement<'s>> {
|
|
|
|
not(|i| context.check_exit_matcher(i))(i)?;
|
|
|
|
|
|
|
|
let bold_matcher = parser_with_context!(bold)(&context);
|
|
|
|
let link_matcher = parser_with_context!(link)(&context);
|
|
|
|
|
|
|
|
alt((
|
|
|
|
map(bold_matcher, TextElement::Bold),
|
|
|
|
map(link_matcher, TextElement::Link),
|
|
|
|
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)
|
|
|
|
}
|