Add an exit matcher to plain text.
This commit is contained in:
parent
9a3bde0d80
commit
a4cce121c0
@ -1,4 +1,5 @@
|
|||||||
imports_granularity = "Item"
|
imports_granularity = "Item"
|
||||||
|
group_imports = "StdExternalCrate"
|
||||||
|
|
||||||
# In rustfmt 2.0 I will want to adjust these settings.
|
# In rustfmt 2.0 I will want to adjust these settings.
|
||||||
#
|
#
|
||||||
|
@ -43,3 +43,17 @@ pub fn minimal_set_object<'r, 's>(
|
|||||||
map(parser_with_context!(plain_text)(context), Object::PlainText),
|
map(parser_with_context!(plain_text)(context), Object::PlainText),
|
||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(ret, level = "debug")]
|
||||||
|
pub fn any_object_except_plain_text<'r, 's>(
|
||||||
|
context: Context<'r, 's>,
|
||||||
|
input: &'s str,
|
||||||
|
) -> Res<&'s str, Object<'s>> {
|
||||||
|
// TODO: add entities, LaTeX fragments, export snippets, footnote references, citations (NOT citation references), inline babel calls, inline source blocks, line breaks, links, macros, targets and radio targets, statistics cookies, subscript and superscript, timestamps, and text markup.
|
||||||
|
not(|i| context.check_exit_matcher(i))(input)?;
|
||||||
|
|
||||||
|
alt((map(
|
||||||
|
parser_with_context!(text_markup)(context),
|
||||||
|
Object::TextMarkup,
|
||||||
|
),))(input)
|
||||||
|
}
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
|
use nom::combinator::not;
|
||||||
|
use nom::combinator::recognize;
|
||||||
|
|
||||||
use super::object::PlainText;
|
use super::object::PlainText;
|
||||||
use super::Context;
|
use super::Context;
|
||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
use crate::error::MyError;
|
use crate::error::MyError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use nom::combinator::not;
|
use crate::parser::exiting::ExitClass;
|
||||||
|
use crate::parser::object_parser::any_object_except_plain_text;
|
||||||
|
use crate::parser::parser_context::ContextElement;
|
||||||
|
use crate::parser::parser_context::ExitMatcherNode;
|
||||||
|
use crate::parser::parser_with_context::parser_with_context;
|
||||||
|
|
||||||
#[tracing::instrument(ret, level = "debug")]
|
#[tracing::instrument(ret, level = "debug")]
|
||||||
pub fn plain_text<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, PlainText<'s>> {
|
pub fn plain_text<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, PlainText<'s>> {
|
||||||
@ -12,12 +19,17 @@ pub fn plain_text<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s s
|
|||||||
"Zero input length to plain_text.",
|
"Zero input length to plain_text.",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
let parser_context =
|
||||||
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
|
class: ExitClass::Beta,
|
||||||
|
exit_matcher: &plain_text_end,
|
||||||
|
}));
|
||||||
let mut current_input = input.char_indices();
|
let mut current_input = input.char_indices();
|
||||||
loop {
|
loop {
|
||||||
match current_input.next() {
|
match current_input.next() {
|
||||||
Some((offset, _char)) => {
|
Some((offset, _char)) => {
|
||||||
let remaining = &input[offset..];
|
let remaining = &input[offset..];
|
||||||
let exit_matcher_status = not(|i| context.check_exit_matcher(i))(remaining);
|
let exit_matcher_status = not(|i| parser_context.check_exit_matcher(i))(remaining);
|
||||||
if exit_matcher_status.is_err() {
|
if exit_matcher_status.is_err() {
|
||||||
if offset == 0 {
|
if offset == 0 {
|
||||||
// If we're at the start of the input, then nothing is plain text, so fire an error for zero-length match.
|
// If we're at the start of the input, then nothing is plain text, so fire an error for zero-length match.
|
||||||
@ -40,18 +52,22 @@ pub fn plain_text<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(ret, level = "debug")]
|
||||||
|
fn plain_text_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> {
|
||||||
|
recognize(parser_with_context!(any_object_except_plain_text)(context))(input)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
use crate::parser::object::Object;
|
use crate::parser::object::Object;
|
||||||
use crate::parser::parser_context::ContextElement;
|
use crate::parser::parser_context::ContextElement;
|
||||||
use crate::parser::parser_context::ContextTree;
|
use crate::parser::parser_context::ContextTree;
|
||||||
use crate::parser::parser_with_context::parser_with_context;
|
use crate::parser::parser_with_context::parser_with_context;
|
||||||
use crate::parser::source::Source;
|
use crate::parser::source::Source;
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn plain_text_simple() {
|
fn plain_text_simple() {
|
||||||
let input = "foobarbaz";
|
let input = "foobarbaz";
|
||||||
|
Loading…
Reference in New Issue
Block a user