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>( context: Context<'r, 's>, input: &'s str, ) -> Res<&'s str, CitationReference<'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 }