Switch citations to using bracket depth from OrgSource instead of from the context.
This is for the same reasons as footnote references.
This commit is contained in:
parent
ec813e3b3f
commit
a46b358549
22
org_mode_samples/object/citation/balanced_brackets.org
Normal file
22
org_mode_samples/object/citation/balanced_brackets.org
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Extra open
|
||||||
|
[cite/a/b-_/foo:unbalancedglobal[prefix;keyprefix @foo keysuffix;globalsuffix]
|
||||||
|
|
||||||
|
[cite/a/b-_/foo:globalprefix;unbalancedkey[prefix @foo keysuffix;globalsuffix]
|
||||||
|
|
||||||
|
[cite/a/b-_/foo:globalprefix;keyprefix @foo unbalancedkey[suffix;globalsuffix]
|
||||||
|
|
||||||
|
[cite/a/b-_/foo:globalprefix;keyprefix @foo keysuffix;unbalancedglobal[suffix]
|
||||||
|
|
||||||
|
|
||||||
|
# Extra close
|
||||||
|
[cite/a/b-_/foo:unbalancedglobal]prefix;keyprefix @foo keysuffix;globalsuffix]
|
||||||
|
|
||||||
|
[cite/a/b-_/foo:globalprefix;unbalancedkey]prefix @foo keysuffix;globalsuffix]
|
||||||
|
|
||||||
|
[cite/a/b-_/foo:globalprefix;keyprefix @foo unbalancedkey]suffix;globalsuffix]
|
||||||
|
|
||||||
|
[cite/a/b-_/foo:globalprefix;keyprefix @foo keysuffix;unbalancedglobal]suffix]
|
||||||
|
|
||||||
|
|
||||||
|
# balanced:
|
||||||
|
[cite/a/b-_/foo:gl[obalpref]ix;ke[ypref]ix @foo ke[ysuff]ix;gl[obalsuff]ix]
|
@ -11,17 +11,16 @@ use nom::multi::many_till;
|
|||||||
use nom::multi::separated_list1;
|
use nom::multi::separated_list1;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
|
||||||
|
use super::citation_reference::must_balance_bracket;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
use super::Context;
|
use super::Context;
|
||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use crate::parser::citation_reference::citation_reference;
|
use crate::parser::citation_reference::citation_reference;
|
||||||
use crate::parser::citation_reference::citation_reference_key;
|
use crate::parser::citation_reference::citation_reference_key;
|
||||||
use crate::parser::citation_reference::get_bracket_depth;
|
|
||||||
use crate::parser::exiting::ExitClass;
|
use crate::parser::exiting::ExitClass;
|
||||||
use crate::parser::object::Citation;
|
use crate::parser::object::Citation;
|
||||||
use crate::parser::object_parser::standard_set_object;
|
use crate::parser::object_parser::standard_set_object;
|
||||||
use crate::parser::parser_context::CitationBracket;
|
|
||||||
use crate::parser::parser_context::ContextElement;
|
use crate::parser::parser_context::ContextElement;
|
||||||
use crate::parser::parser_context::ExitMatcherNode;
|
use crate::parser::parser_context::ExitMatcherNode;
|
||||||
use crate::parser::parser_with_context::parser_with_context;
|
use crate::parser::parser_with_context::parser_with_context;
|
||||||
@ -38,13 +37,15 @@ pub fn citation<'r, 's>(
|
|||||||
let (remaining, _) = tag_no_case("[cite")(input)?;
|
let (remaining, _) = tag_no_case("[cite")(input)?;
|
||||||
let (remaining, _) = opt(citestyle)(remaining)?;
|
let (remaining, _) = opt(citestyle)(remaining)?;
|
||||||
let (remaining, _) = tag(":")(remaining)?;
|
let (remaining, _) = tag(":")(remaining)?;
|
||||||
let (remaining, _prefix) = opt(parser_with_context!(global_prefix)(context))(remaining)?;
|
let (remaining, _prefix) =
|
||||||
|
must_balance_bracket(opt(parser_with_context!(global_prefix)(context)))(remaining)?;
|
||||||
|
|
||||||
let (remaining, _references) =
|
let (remaining, _references) =
|
||||||
separated_list1(tag(";"), parser_with_context!(citation_reference)(context))(remaining)?;
|
separated_list1(tag(";"), parser_with_context!(citation_reference)(context))(remaining)?;
|
||||||
let (remaining, _suffix) = opt(tuple((
|
let (remaining, _suffix) = must_balance_bracket(opt(tuple((
|
||||||
tag(";"),
|
tag(";"),
|
||||||
parser_with_context!(global_suffix)(context),
|
parser_with_context!(global_suffix)(context),
|
||||||
)))(remaining)?;
|
))))(remaining)?;
|
||||||
let (remaining, _) = tag("]")(remaining)?;
|
let (remaining, _) = tag("]")(remaining)?;
|
||||||
let (remaining, _) = space0(remaining)?;
|
let (remaining, _) = space0(remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
@ -83,15 +84,11 @@ fn global_prefix<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||||
// TODO: I could insert CitationBracket entries in the context after each matched object to reduce the scanning done for counting brackets which should be more efficient.
|
let exit_with_depth = global_prefix_end(input.get_bracket_depth());
|
||||||
let parser_context = context
|
let parser_context =
|
||||||
.with_additional_node(ContextElement::CitationBracket(CitationBracket {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
position: input,
|
|
||||||
depth: 0,
|
|
||||||
}))
|
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
|
||||||
class: ExitClass::Gamma,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &global_prefix_end,
|
exit_matcher: &exit_with_depth,
|
||||||
}));
|
}));
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
many_till(
|
many_till(
|
||||||
@ -104,28 +101,24 @@ fn global_prefix<'r, 's>(
|
|||||||
Ok((remaining, children))
|
Ok((remaining, children))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn global_prefix_end(
|
||||||
|
starting_bracket_depth: isize,
|
||||||
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
|
move |context: Context, input: OrgSource<'_>| {
|
||||||
|
_global_prefix_end(context, input, starting_bracket_depth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn global_prefix_end<'r, 's>(
|
fn _global_prefix_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
|
starting_bracket_depth: isize,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let context_depth = get_bracket_depth(context)
|
let current_depth = input.get_bracket_depth() - starting_bracket_depth;
|
||||||
.expect("This function should only be called from inside a citation.");
|
if current_depth < 0 {
|
||||||
let text_since_context_entry = get_consumed(context_depth.position, input);
|
// This shouldn't be possible because if depth is 0 then a closing bracket should end the citation.
|
||||||
let mut current_depth = context_depth.depth;
|
unreachable!("Exceeded citation global prefix bracket depth.")
|
||||||
for c in Into::<&str>::into(text_since_context_entry).chars() {
|
|
||||||
match c {
|
|
||||||
'[' => {
|
|
||||||
current_depth += 1;
|
|
||||||
}
|
|
||||||
']' if current_depth == 0 => {
|
|
||||||
panic!("Exceeded citation global prefix bracket depth.")
|
|
||||||
}
|
|
||||||
']' if current_depth > 0 => {
|
|
||||||
current_depth -= 1;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if current_depth == 0 {
|
if current_depth == 0 {
|
||||||
let close_bracket = tag::<&str, OrgSource<'_>, CustomError<OrgSource<'_>>>("]")(input);
|
let close_bracket = tag::<&str, OrgSource<'_>, CustomError<OrgSource<'_>>>("]")(input);
|
||||||
@ -144,15 +137,11 @@ fn global_suffix<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||||
// TODO: I could insert CitationBracket entries in the context after each matched object to reduce the scanning done for counting brackets which should be more efficient.
|
let exit_with_depth = global_suffix_end(input.get_bracket_depth());
|
||||||
let parser_context = context
|
let parser_context =
|
||||||
.with_additional_node(ContextElement::CitationBracket(CitationBracket {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
position: input,
|
|
||||||
depth: 0,
|
|
||||||
}))
|
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
|
||||||
class: ExitClass::Gamma,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &global_suffix_end,
|
exit_matcher: &exit_with_depth,
|
||||||
}));
|
}));
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
many_till(
|
many_till(
|
||||||
@ -164,28 +153,24 @@ fn global_suffix<'r, 's>(
|
|||||||
Ok((remaining, children))
|
Ok((remaining, children))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn global_suffix_end(
|
||||||
|
starting_bracket_depth: isize,
|
||||||
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
|
move |context: Context, input: OrgSource<'_>| {
|
||||||
|
_global_suffix_end(context, input, starting_bracket_depth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn global_suffix_end<'r, 's>(
|
fn _global_suffix_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
|
starting_bracket_depth: isize,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let context_depth = get_bracket_depth(context)
|
let current_depth = input.get_bracket_depth() - starting_bracket_depth;
|
||||||
.expect("This function should only be called from inside a citation.");
|
if current_depth < 0 {
|
||||||
let text_since_context_entry = get_consumed(context_depth.position, input);
|
// This shouldn't be possible because if depth is 0 then a closing bracket should end the citation.
|
||||||
let mut current_depth = context_depth.depth;
|
unreachable!("Exceeded citation global suffix bracket depth.")
|
||||||
for c in Into::<&str>::into(text_since_context_entry).chars() {
|
|
||||||
match c {
|
|
||||||
'[' => {
|
|
||||||
current_depth += 1;
|
|
||||||
}
|
|
||||||
']' if current_depth == 0 => {
|
|
||||||
panic!("Exceeded citation global suffix bracket depth.")
|
|
||||||
}
|
|
||||||
']' if current_depth > 0 => {
|
|
||||||
current_depth -= 1;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if current_depth == 0 {
|
if current_depth == 0 {
|
||||||
let close_bracket = tag::<&str, OrgSource<'_>, CustomError<OrgSource<'_>>>("]")(input);
|
let close_bracket = tag::<&str, OrgSource<'_>, CustomError<OrgSource<'_>>>("]")(input);
|
||||||
|
@ -13,11 +13,11 @@ use nom::sequence::tuple;
|
|||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
use super::Context;
|
use super::Context;
|
||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
|
use crate::error::MyError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use crate::parser::exiting::ExitClass;
|
use crate::parser::exiting::ExitClass;
|
||||||
use crate::parser::object::CitationReference;
|
use crate::parser::object::CitationReference;
|
||||||
use crate::parser::object_parser::minimal_set_object;
|
use crate::parser::object_parser::minimal_set_object;
|
||||||
use crate::parser::parser_context::CitationBracket;
|
|
||||||
use crate::parser::parser_context::ContextElement;
|
use crate::parser::parser_context::ContextElement;
|
||||||
use crate::parser::parser_context::ExitMatcherNode;
|
use crate::parser::parser_context::ExitMatcherNode;
|
||||||
use crate::parser::parser_with_context::parser_with_context;
|
use crate::parser::parser_with_context::parser_with_context;
|
||||||
@ -31,9 +31,11 @@ pub fn citation_reference<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, CitationReference<'s>> {
|
) -> Res<OrgSource<'s>, CitationReference<'s>> {
|
||||||
let (remaining, _prefix) = opt(parser_with_context!(key_prefix)(context))(input)?;
|
let (remaining, _prefix) =
|
||||||
|
must_balance_bracket(opt(parser_with_context!(key_prefix)(context)))(input)?;
|
||||||
let (remaining, _key) = parser_with_context!(citation_reference_key)(context)(remaining)?;
|
let (remaining, _key) = parser_with_context!(citation_reference_key)(context)(remaining)?;
|
||||||
let (remaining, _suffix) = opt(parser_with_context!(key_suffix)(context))(remaining)?;
|
let (remaining, _suffix) =
|
||||||
|
must_balance_bracket(opt(parser_with_context!(key_suffix)(context)))(remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
@ -69,15 +71,11 @@ fn key_prefix<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||||
// TODO: I could insert CitationBracket entries in the context after each matched object to reduce the scanning done for counting brackets which should be more efficient.
|
let exit_with_depth = key_prefix_end(input.get_bracket_depth());
|
||||||
let parser_context = context
|
let parser_context =
|
||||||
.with_additional_node(ContextElement::CitationBracket(CitationBracket {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
position: input,
|
|
||||||
depth: 0,
|
|
||||||
}))
|
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
|
||||||
class: ExitClass::Gamma,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &key_prefix_end,
|
exit_matcher: &exit_with_depth,
|
||||||
}));
|
}));
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
many_till(
|
many_till(
|
||||||
@ -94,15 +92,11 @@ fn key_suffix<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||||
// TODO: I could insert CitationBracket entries in the context after each matched object to reduce the scanning done for counting brackets which should be more efficient.
|
let exit_with_depth = key_suffix_end(input.get_bracket_depth());
|
||||||
let parser_context = context
|
let parser_context =
|
||||||
.with_additional_node(ContextElement::CitationBracket(CitationBracket {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
position: input,
|
|
||||||
depth: 0,
|
|
||||||
}))
|
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
|
||||||
class: ExitClass::Gamma,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &key_suffix_end,
|
exit_matcher: &exit_with_depth,
|
||||||
}));
|
}));
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
many_till(
|
many_till(
|
||||||
@ -114,39 +108,24 @@ fn key_suffix<'r, 's>(
|
|||||||
Ok((remaining, children))
|
Ok((remaining, children))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
fn key_prefix_end(
|
||||||
pub fn get_bracket_depth<'r, 's>(context: Context<'r, 's>) -> Option<&'r CitationBracket<'s>> {
|
starting_bracket_depth: isize,
|
||||||
for node in context.iter() {
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
match node.get_data() {
|
move |context: Context, input: OrgSource<'_>| {
|
||||||
ContextElement::CitationBracket(depth) => return Some(depth),
|
_key_prefix_end(context, input, starting_bracket_depth)
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn key_prefix_end<'r, 's>(
|
fn _key_prefix_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
|
starting_bracket_depth: isize,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let context_depth = get_bracket_depth(context)
|
let current_depth = input.get_bracket_depth() - starting_bracket_depth;
|
||||||
.expect("This function should only be called from inside a citation reference.");
|
if current_depth < 0 {
|
||||||
let text_since_context_entry = get_consumed(context_depth.position, input);
|
// This shouldn't be possible because if depth is 0 then a closing bracket should end the citation.
|
||||||
let mut current_depth = context_depth.depth;
|
unreachable!("Exceeded citation key prefix bracket depth.")
|
||||||
for c in Into::<&str>::into(text_since_context_entry).chars() {
|
|
||||||
match c {
|
|
||||||
'[' => {
|
|
||||||
current_depth += 1;
|
|
||||||
}
|
|
||||||
']' if current_depth == 0 => {
|
|
||||||
panic!("Exceeded citation reference key prefix bracket depth.")
|
|
||||||
}
|
|
||||||
']' if current_depth > 0 => {
|
|
||||||
current_depth -= 1;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if current_depth == 0 {
|
if current_depth == 0 {
|
||||||
let close_bracket = tag::<&str, OrgSource<'_>, CustomError<OrgSource<'_>>>("]")(input);
|
let close_bracket = tag::<&str, OrgSource<'_>, CustomError<OrgSource<'_>>>("]")(input);
|
||||||
@ -160,28 +139,24 @@ fn key_prefix_end<'r, 's>(
|
|||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn key_suffix_end(
|
||||||
|
starting_bracket_depth: isize,
|
||||||
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
|
move |context: Context, input: OrgSource<'_>| {
|
||||||
|
_key_suffix_end(context, input, starting_bracket_depth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn key_suffix_end<'r, 's>(
|
fn _key_suffix_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
|
starting_bracket_depth: isize,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let context_depth = get_bracket_depth(context)
|
let current_depth = input.get_bracket_depth() - starting_bracket_depth;
|
||||||
.expect("This function should only be called from inside a citation reference.");
|
if current_depth < 0 {
|
||||||
let text_since_context_entry = get_consumed(context_depth.position, input);
|
// This shouldn't be possible because if depth is 0 then a closing bracket should end the citation.
|
||||||
let mut current_depth = context_depth.depth;
|
unreachable!("Exceeded citation key suffix bracket depth.")
|
||||||
for c in Into::<&str>::into(text_since_context_entry).chars() {
|
|
||||||
match c {
|
|
||||||
'[' => {
|
|
||||||
current_depth += 1;
|
|
||||||
}
|
|
||||||
']' if current_depth == 0 => {
|
|
||||||
panic!("Exceeded citation reference key prefix bracket depth.")
|
|
||||||
}
|
|
||||||
']' if current_depth > 0 => {
|
|
||||||
current_depth -= 1;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if current_depth == 0 {
|
if current_depth == 0 {
|
||||||
let close_bracket = tag::<&str, OrgSource<'_>, CustomError<OrgSource<'_>>>("]")(input);
|
let close_bracket = tag::<&str, OrgSource<'_>, CustomError<OrgSource<'_>>>("]")(input);
|
||||||
@ -191,3 +166,21 @@ fn key_suffix_end<'r, 's>(
|
|||||||
}
|
}
|
||||||
tag(";")(input)
|
tag(";")(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn must_balance_bracket<'s, F, O>(
|
||||||
|
mut inner: F,
|
||||||
|
) -> impl FnMut(OrgSource<'s>) -> Res<OrgSource<'s>, O>
|
||||||
|
where
|
||||||
|
F: FnMut(OrgSource<'s>) -> Res<OrgSource<'s>, O>,
|
||||||
|
{
|
||||||
|
move |input: OrgSource<'_>| {
|
||||||
|
let pre_bracket_depth = input.get_bracket_depth();
|
||||||
|
let (remaining, output) = inner(input)?;
|
||||||
|
if remaining.get_bracket_depth() - pre_bracket_depth != 0 {
|
||||||
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
|
"UnbalancedBrackets".into(),
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
Ok((remaining, output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -124,21 +124,6 @@ pub enum ContextElement<'r, 's> {
|
|||||||
/// radio links matching the contents of radio targets.
|
/// radio links matching the contents of radio targets.
|
||||||
RadioTarget(Vec<&'r Vec<Object<'s>>>),
|
RadioTarget(Vec<&'r Vec<Object<'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>),
|
|
||||||
|
|
||||||
/// Stores the current bracket or parenthesis depth inside an inline babel call.
|
/// Stores the current bracket or parenthesis depth inside an inline babel call.
|
||||||
///
|
///
|
||||||
/// Inside an inline babel call the headers must have balanced
|
/// Inside an inline babel call the headers must have balanced
|
||||||
@ -183,12 +168,6 @@ pub struct ExitMatcherNode<'r> {
|
|||||||
pub class: ExitClass,
|
pub class: ExitClass,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct CitationBracket<'s> {
|
|
||||||
pub position: OrgSource<'s>,
|
|
||||||
pub depth: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BabelHeaderBracket<'s> {
|
pub struct BabelHeaderBracket<'s> {
|
||||||
pub position: OrgSource<'s>,
|
pub position: OrgSource<'s>,
|
||||||
|
Loading…
Reference in New Issue
Block a user