Make the item tag exit matcher a lower class than all all others.

This is to allow for " :: " inside a description list item's tag if it is nested inside another object.
This commit is contained in:
Tom Alexander 2023-09-08 14:02:15 -04:00
parent ab612f293f
commit 40f22034da
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 30 additions and 24 deletions

View File

@ -108,7 +108,7 @@ impl<'g, 'r, 's> Context<'g, 'r, 's> {
&'r self, &'r self,
i: OrgSource<'s>, i: OrgSource<'s>,
) -> IResult<OrgSource<'s>, OrgSource<'s>, CustomError<OrgSource<'s>>> { ) -> IResult<OrgSource<'s>, OrgSource<'s>, CustomError<OrgSource<'s>>> {
let mut current_class_filter = ExitClass::Gamma; let mut current_class_filter = ExitClass::Delta;
for current_node in self.iter_context() { for current_node in self.iter_context() {
let context_element = current_node.get_data(); let context_element = current_node.get_data();
match context_element { match context_element {

View File

@ -1,16 +1,10 @@
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum ExitClass { pub enum ExitClass {
/// Headlines and sections.
Document = 1, Document = 1,
Alpha = 2,
/// Elements who take priority over beta elements when matching. Beta = 3,
Alpha = 20, Gamma = 4,
Delta = 5,
/// Elements who cede priority to alpha elements when matching.
Beta = 300,
/// Elements who cede priority to alpha and beta elements when matching.
Gamma = 4000,
} }
impl std::fmt::Display for ExitClass { impl std::fmt::Display for ExitClass {

View File

@ -152,11 +152,8 @@ pub fn plain_list_item<'b, 'g, 'r, 's>(
// TODO: parse checkbox // TODO: parse checkbox
let (remaining, maybe_tag) = opt(tuple(( let (remaining, maybe_tag) =
space1, opt(tuple((space1, parser_with_context!(item_tag)(context))))(remaining)?;
parser_with_context!(item_tag)(context),
tag(" ::"),
)))(remaining)?;
let maybe_contentless_item: Res<OrgSource<'_>, OrgSource<'_>> = let maybe_contentless_item: Res<OrgSource<'_>, OrgSource<'_>> =
peek(recognize(tuple((many0(blank_line), eof))))(remaining); peek(recognize(tuple((many0(blank_line), eof))))(remaining);
match maybe_contentless_item { match maybe_contentless_item {
@ -170,7 +167,7 @@ pub fn plain_list_item<'b, 'g, 'r, 's>(
indentation: indent_level, indentation: indent_level,
bullet: bull.into(), bullet: bull.into(),
tag: maybe_tag tag: maybe_tag
.map(|(_ws, item_tag, _divider)| item_tag) .map(|(_ws, item_tag)| item_tag)
.unwrap_or(Vec::new()), .unwrap_or(Vec::new()),
children: Vec::new(), children: Vec::new(),
}, },
@ -219,7 +216,7 @@ pub fn plain_list_item<'b, 'g, 'r, 's>(
indentation: indent_level, indentation: indent_level,
bullet: bull.into(), bullet: bull.into(),
tag: maybe_tag tag: maybe_tag
.map(|(_ws, item_tag, _divider)| item_tag) .map(|(_ws, item_tag)| item_tag)
.unwrap_or(Vec::new()), .unwrap_or(Vec::new()),
children: children.into_iter().map(|(_start, item)| item).collect(), children: children.into_iter().map(|(_start, item)| item).collect(),
}, },
@ -313,11 +310,18 @@ fn item_tag<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>, context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
) -> Res<OrgSource<'s>, Vec<Object<'s>>> { ) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode { let contexts = [
class: ExitClass::Gamma, ContextElement::ExitMatcherNode(ExitMatcherNode {
exit_matcher: &item_tag_end, class: ExitClass::Gamma,
}); exit_matcher: &item_tag_line_ending_end,
let parser_context = context.with_additional_node(&parser_context); }),
ContextElement::ExitMatcherNode(ExitMatcherNode {
class: ExitClass::Delta,
exit_matcher: &item_tag_end,
}),
];
let parser_context = context.with_additional_node(&contexts[0]);
let parser_context = parser_context.with_additional_node(&contexts[1]);
let (remaining, (children, _exit_contents)) = verify( let (remaining, (children, _exit_contents)) = verify(
many_till( many_till(
// TODO: Should this be using a different set like the minimal set? // TODO: Should this be using a different set like the minimal set?
@ -326,6 +330,7 @@ fn item_tag<'b, 'g, 'r, 's>(
), ),
|(children, _exit_contents)| !children.is_empty(), |(children, _exit_contents)| !children.is_empty(),
)(input)?; )(input)?;
let (remaining, _) = tag(" ::")(remaining)?;
Ok((remaining, children)) Ok((remaining, children))
} }
@ -335,12 +340,19 @@ fn item_tag_end<'b, 'g, 'r, 's>(
input: OrgSource<'s>, input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> { ) -> Res<OrgSource<'s>, OrgSource<'s>> {
recognize(alt(( recognize(alt((
line_ending,
tag(" :: "), tag(" :: "),
recognize(tuple((tag(" ::"), alt((line_ending, eof))))), recognize(tuple((tag(" ::"), alt((line_ending, eof))))),
)))(input) )))(input)
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn item_tag_line_ending_end<'b, 'g, 'r, 's>(
_context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> {
line_ending(input)
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn item_tag_post_gap<'b, 'g, 'r, 's>( fn item_tag_post_gap<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>, context: RefContext<'b, 'g, 'r, 's>,