Switch to putting radio targets in the global settings instead of the context tree.
This commit is contained in:
parent
71180d19fb
commit
0ef141d65e
@ -1,16 +1,19 @@
|
|||||||
#[derive(Debug)]
|
use crate::types::Object;
|
||||||
pub struct GlobalSettings<'s> {
|
|
||||||
#[allow(dead_code)]
|
#[derive(Debug, Clone)]
|
||||||
placeholder: Option<&'s str>,
|
pub struct GlobalSettings<'g, 's> {
|
||||||
|
pub radio_targets: Vec<&'g Vec<Object<'s>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> GlobalSettings<'s> {
|
impl<'g, 's> GlobalSettings<'g, 's> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
GlobalSettings { placeholder: None }
|
GlobalSettings {
|
||||||
|
radio_targets: Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> Default for GlobalSettings<'s> {
|
impl<'g, 's> Default for GlobalSettings<'g, 's> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
GlobalSettings::new()
|
GlobalSettings::new()
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
|
|
||||||
@ -10,7 +12,6 @@ use crate::error::CustomError;
|
|||||||
use crate::error::MyError;
|
use crate::error::MyError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use crate::parser::OrgSource;
|
use crate::parser::OrgSource;
|
||||||
use crate::types::Object;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ContextElement<'r, 's> {
|
pub enum ContextElement<'r, 's> {
|
||||||
@ -23,12 +24,8 @@ pub enum ContextElement<'r, 's> {
|
|||||||
/// Indicates if elements should consume the whitespace after them.
|
/// Indicates if elements should consume the whitespace after them.
|
||||||
ConsumeTrailingWhitespace(bool),
|
ConsumeTrailingWhitespace(bool),
|
||||||
|
|
||||||
/// The contents of a radio target.
|
/// This is just here to use the 's lifetime until I'm sure we can eliminate it from ContextElement.
|
||||||
///
|
Placeholder(PhantomData<&'s str>),
|
||||||
/// If any are found, this will force a 2nd parse through the
|
|
||||||
/// org-mode document since text needs to be re-parsed to look for
|
|
||||||
/// radio links matching the contents of radio targets.
|
|
||||||
RadioTarget(Vec<&'r Vec<Object<'s>>>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExitMatcherNode<'r> {
|
pub struct ExitMatcherNode<'r> {
|
||||||
@ -47,13 +44,13 @@ impl<'r> std::fmt::Debug for ExitMatcherNode<'r> {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Context<'g, 'r, 's> {
|
pub struct Context<'g, 'r, 's> {
|
||||||
global_settings: &'g GlobalSettings<'g>,
|
global_settings: &'g GlobalSettings<'g, 's>,
|
||||||
tree: List<'r, &'r ContextElement<'r, 's>>,
|
tree: List<'r, &'r ContextElement<'r, 's>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'g, 'r, 's> Context<'g, 'r, 's> {
|
impl<'g, 'r, 's> Context<'g, 'r, 's> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
global_settings: &'g GlobalSettings<'g>,
|
global_settings: &'g GlobalSettings<'g, 's>,
|
||||||
tree: List<'r, &'r ContextElement<'r, 's>>,
|
tree: List<'r, &'r ContextElement<'r, 's>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -89,6 +86,17 @@ impl<'g, 'r, 's> Context<'g, 'r, 's> {
|
|||||||
self.tree.get_data()
|
self.tree.get_data()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_global_settings(&self) -> &'g GlobalSettings<'g, 's> {
|
||||||
|
self.global_settings
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_global_settings<'gg>(&self, new_settings: &'gg GlobalSettings<'gg, 's>) -> Context<'gg, 'r, 's> {
|
||||||
|
Context {
|
||||||
|
global_settings: new_settings,
|
||||||
|
tree: self.tree.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn check_exit_matcher(
|
pub fn check_exit_matcher(
|
||||||
&'r self,
|
&'r self,
|
||||||
@ -145,7 +153,7 @@ fn document_end<'b, 'g, 'r, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Iter<'g, 'r, 's> {
|
pub struct Iter<'g, 'r, 's> {
|
||||||
global_settings: &'g GlobalSettings<'g>,
|
global_settings: &'g GlobalSettings<'g, 's>,
|
||||||
next: super::list::IterList<'r, &'r ContextElement<'r, 's>>,
|
next: super::list::IterList<'r, &'r ContextElement<'r, 's>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +95,9 @@ fn document_org_source<'b, 'g, 'r, 's>(
|
|||||||
.map(|rt| &rt.children)
|
.map(|rt| &rt.children)
|
||||||
.collect();
|
.collect();
|
||||||
if !all_radio_targets.is_empty() {
|
if !all_radio_targets.is_empty() {
|
||||||
let parser_context = ContextElement::RadioTarget(all_radio_targets);
|
let mut new_global_settings = context.get_global_settings().clone();
|
||||||
let parser_context = context.with_additional_node(&parser_context);
|
new_global_settings.radio_targets = all_radio_targets;
|
||||||
|
let parser_context = context.with_global_settings(&new_global_settings);
|
||||||
let (remaining, document) = _document(&parser_context, input)
|
let (remaining, document) = _document(&parser_context, input)
|
||||||
.map(|(rem, out)| (Into::<&str>::into(rem), out))?;
|
.map(|(rem, out)| (Into::<&str>::into(rem), out))?;
|
||||||
return Ok((remaining.into(), document));
|
return Ok((remaining.into(), document));
|
||||||
|
@ -27,14 +27,7 @@ pub fn radio_link<'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>, RadioLink<'s>> {
|
) -> Res<OrgSource<'s>, RadioLink<'s>> {
|
||||||
let radio_targets = context
|
for radio_target in &context.get_global_settings().radio_targets {
|
||||||
.iter()
|
|
||||||
.filter_map(|context_element| match context_element {
|
|
||||||
ContextElement::RadioTarget(targets) => Some(targets),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.flatten();
|
|
||||||
for radio_target in radio_targets {
|
|
||||||
let rematched_target = rematch_target(context, radio_target, input);
|
let rematched_target = rematch_target(context, radio_target, input);
|
||||||
if let Ok((remaining, rematched_target)) = rematched_target {
|
if let Ok((remaining, rematched_target)) = rematched_target {
|
||||||
let (remaining, _) = space0(remaining)?;
|
let (remaining, _) = space0(remaining)?;
|
||||||
@ -149,12 +142,14 @@ mod tests {
|
|||||||
fn plain_text_radio_target() {
|
fn plain_text_radio_target() {
|
||||||
let input = OrgSource::new("foo bar baz");
|
let input = OrgSource::new("foo bar baz");
|
||||||
let radio_target_match = vec![Object::PlainText(PlainText { source: "bar" })];
|
let radio_target_match = vec![Object::PlainText(PlainText { source: "bar" })];
|
||||||
let global_settings = GlobalSettings::default();
|
let global_settings = {
|
||||||
|
let mut global_settings = GlobalSettings::default();
|
||||||
|
global_settings.radio_targets = vec![&radio_target_match];
|
||||||
|
global_settings
|
||||||
|
};
|
||||||
let initial_context = ContextElement::document_context();
|
let initial_context = ContextElement::document_context();
|
||||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||||
let document_context = ContextElement::RadioTarget(vec![&radio_target_match]);
|
let paragraph_matcher = parser_with_context!(element(true))(&initial_context);
|
||||||
let document_context = initial_context.with_additional_node(&document_context);
|
|
||||||
let paragraph_matcher = parser_with_context!(element(true))(&document_context);
|
|
||||||
let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph");
|
let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph");
|
||||||
let first_paragraph = match first_paragraph {
|
let first_paragraph = match first_paragraph {
|
||||||
Element::Paragraph(paragraph) => paragraph,
|
Element::Paragraph(paragraph) => paragraph,
|
||||||
@ -182,12 +177,14 @@ mod tests {
|
|||||||
source: "*bar*",
|
source: "*bar*",
|
||||||
children: vec![Object::PlainText(PlainText { source: "bar" })],
|
children: vec![Object::PlainText(PlainText { source: "bar" })],
|
||||||
})];
|
})];
|
||||||
let global_settings = GlobalSettings::default();
|
let global_settings = {
|
||||||
|
let mut global_settings = GlobalSettings::default();
|
||||||
|
global_settings.radio_targets = vec![&radio_target_match];
|
||||||
|
global_settings
|
||||||
|
};
|
||||||
let initial_context = ContextElement::document_context();
|
let initial_context = ContextElement::document_context();
|
||||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||||
let document_context = ContextElement::RadioTarget(vec![&radio_target_match]);
|
let paragraph_matcher = parser_with_context!(element(true))(&initial_context);
|
||||||
let document_context = initial_context.with_additional_node(&document_context);
|
|
||||||
let paragraph_matcher = parser_with_context!(element(true))(&document_context);
|
|
||||||
let (remaining, first_paragraph) =
|
let (remaining, first_paragraph) =
|
||||||
paragraph_matcher(input.into()).expect("Parse first paragraph");
|
paragraph_matcher(input.into()).expect("Parse first paragraph");
|
||||||
let first_paragraph = match first_paragraph {
|
let first_paragraph = match first_paragraph {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user