From 339ff5cd2612f4f806e6a489f647c0d7bb9be831 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Thu, 20 Jul 2023 01:13:49 -0400 Subject: [PATCH] Implement key parser and begin key_suffix parser. --- src/parser/citation_reference.rs | 51 ++++++++++++++++++++++++++++++++ src/parser/parser_context.rs | 23 +++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/parser/citation_reference.rs b/src/parser/citation_reference.rs index 6e2a1c0..cc47254 100644 --- a/src/parser/citation_reference.rs +++ b/src/parser/citation_reference.rs @@ -1,7 +1,22 @@ +use nom::character::complete::anychar; +use nom::combinator::not; +use nom::combinator::recognize; +use nom::combinator::verify; +use nom::multi::many1; +use nom::multi::many_till; +use nom::sequence::preceded; + use super::Context; use crate::error::Res; use crate::parser::object::CitationReference; +use crate::parser::object_parser::minimal_set_object; +use crate::parser::parser_context::CitationBracket; +use crate::parser::parser_context::ContextElement; +use crate::parser::parser_with_context::parser_with_context; +use crate::parser::util::exit_matcher_parser; use crate::parser::util::not_yet_implemented; +use crate::parser::util::WORD_CONSTITUENT_CHARACTERS; +use crate::parser::Object; #[tracing::instrument(ret, level = "debug")] pub fn citation_reference<'r, 's>( @@ -11,3 +26,39 @@ pub fn citation_reference<'r, 's>( not_yet_implemented()?; todo!() } + +#[tracing::instrument(ret, level = "debug")] +fn key<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { + let (remaining, source) = recognize(many1(verify( + preceded( + not(parser_with_context!(exit_matcher_parser)(context)), + anychar, + ), + |c| WORD_CONSTITUENT_CHARACTERS.contains(*c) || "-.:?~`'/*@+|(){}<>&_^$#%~".contains(*c), + )))(input)?; + Ok((remaining, source)) +} + +#[tracing::instrument(ret, level = "debug")] +fn key_suffix<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Vec>> { + // TODO: Add to context with the depth object and an exit matcher + let (remaining, (children, _exit_contents)) = verify( + many_till( + parser_with_context!(minimal_set_object)(context), + parser_with_context!(exit_matcher_parser)(context), + ), + |(children, _exit_contents)| !children.is_empty(), + )(input)?; + todo!() +} + +#[tracing::instrument(ret, level = "debug")] +fn get_bracket_depth<'r, 's>(context: Context<'r, 's>) -> Option<&'r CitationBracket<'s>> { + for node in context.iter() { + match node.get_data() { + ContextElement::CitationBracket(depth) => return Some(depth), + _ => {} + } + } + None +} diff --git a/src/parser/parser_context.rs b/src/parser/parser_context.rs index d2c105e..d50377c 100644 --- a/src/parser/parser_context.rs +++ b/src/parser/parser_context.rs @@ -147,12 +147,27 @@ pub enum ContextElement<'r, 's> { /// The definition inside a footnote reference must have balanced /// brackets [] inside the definition, so this stores the amount /// of opening brackets subtracted by the amount of closing - /// brackets within the definition. + /// brackets within the definition must equal zero. /// /// A reference to the position in the string is also included so /// unbalanced brackets can be detected in the middle of an /// object. FootnoteReferenceDefinition(FootnoteReferenceDefinition<'s>), + + /// Stores the current bracket depth inside a citation. + /// + /// The global prefix, global suffix, key prefix, and key suffix + /// inside a footnote reference must have balanced brackets [] + /// inside the definition, so this stores the amount of opening + /// brackets subtracted by the amount of closing brackets within + /// the definition must equal zero. None of the prefixes or + /// suffixes can be nested inside each other so we can use a + /// single type for this without conflict. + /// + /// A reference to the position in the string is also included so + /// unbalanced brackets can be detected in the middle of an + /// object. + CitationBracket(CitationBracket<'s>), } pub struct ExitMatcherNode<'r> { @@ -166,6 +181,12 @@ pub struct FootnoteReferenceDefinition<'s> { pub depth: usize, } +#[derive(Debug)] +pub struct CitationBracket<'s> { + pub position: &'s str, + pub depth: usize, +} + impl<'r> std::fmt::Debug for ExitMatcherNode<'r> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut formatter = f.debug_struct("ExitMatcherNode");