diff --git a/src/parser/line_break.rs b/src/parser/line_break.rs index f3407e2..d681edf 100644 --- a/src/parser/line_break.rs +++ b/src/parser/line_break.rs @@ -1,13 +1,42 @@ +use nom::bytes::complete::tag; +use nom::character::complete::line_ending; +use nom::character::complete::one_of; +use nom::combinator::recognize; +use nom::multi::many0; + use super::Context; +use crate::error::CustomError; +use crate::error::MyError; use crate::error::Res; -use crate::parser::util::not_yet_implemented; -use crate::parser::CitationReference; +use crate::parser::util::get_consumed; +use crate::parser::util::get_one_before; +use crate::parser::LineBreak; #[tracing::instrument(ret, level = "debug")] -pub fn citation_reference<'r, 's>( - context: Context<'r, 's>, - input: &'s str, -) -> Res<&'s str, CitationReference<'s>> { - not_yet_implemented()?; - todo!() +pub fn line_break<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, LineBreak<'s>> { + let (remaining, _) = pre(context, input)?; + let (remaining, _) = tag(r#"\\"#)(remaining)?; + let (remaining, _) = recognize(many0(one_of(" \t")))(remaining)?; + let (remaining, _) = line_ending(remaining)?; + let source = get_consumed(input, remaining); + Ok((remaining, LineBreak { source })) +} + +#[tracing::instrument(ret, level = "debug")] +fn pre<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, ()> { + let document_root = context.get_document_root().unwrap(); + let preceding_character = get_one_before(document_root, input) + .map(|slice| slice.chars().next()) + .flatten(); + // TODO: Must be at the end of a non-empty line so instead of getting one character before, we need to grab the entire line. + match preceding_character { + // If None, we are at the start of the file + None | Some('\\') => { + return Err(nom::Err::Error(CustomError::MyError(MyError( + "Not a valid pre character for line break.", + )))); + } + _ => {} + }; + Ok((input, ())) } diff --git a/src/parser/object_parser.rs b/src/parser/object_parser.rs index c27b644..d0c7031 100644 --- a/src/parser/object_parser.rs +++ b/src/parser/object_parser.rs @@ -15,6 +15,7 @@ use crate::parser::footnote_reference::footnote_reference; use crate::parser::inline_babel_call::inline_babel_call; use crate::parser::inline_source_block::inline_source_block; use crate::parser::latex_fragment::latex_fragment; +use crate::parser::line_break::line_break; use crate::parser::object::Object; use crate::parser::org_macro::org_macro; use crate::parser::plain_link::plain_link; @@ -31,6 +32,7 @@ pub fn standard_set_object<'r, 's>( not(|i| context.check_exit_matcher(i))(input)?; alt(( + map(parser_with_context!(line_break)(context), Object::LineBreak), map( parser_with_context!(inline_source_block)(context), Object::InlineSourceBlock, @@ -96,6 +98,7 @@ pub fn any_object_except_plain_text<'r, 's>( ) -> Res<&'s str, Object<'s>> { // Used for exit matchers so this does not check exit matcher condition. alt(( + map(parser_with_context!(line_break)(context), Object::LineBreak), map( parser_with_context!(inline_source_block)(context), Object::InlineSourceBlock,