Merge branch 'stack_based_context'
This commit is contained in:
commit
5997567233
2
build.rs
2
build.rs
@ -72,7 +72,7 @@ fn write_header(test_file: &mut File) {
|
||||
r#"
|
||||
#[feature(exit_status_error)]
|
||||
use organic::compare_document;
|
||||
use organic::parser::document;
|
||||
use organic::parser::parse;
|
||||
use organic::emacs_parse_anonymous_org_document;
|
||||
use organic::parser::sexp::sexp_with_padding;
|
||||
|
||||
|
@ -5,64 +5,64 @@ use super::util::assert_name;
|
||||
use super::util::get_property;
|
||||
use crate::parser::sexp::unquote;
|
||||
use crate::parser::sexp::Token;
|
||||
use crate::parser::AngleLink;
|
||||
use crate::parser::Bold;
|
||||
use crate::parser::Citation;
|
||||
use crate::parser::CitationReference;
|
||||
use crate::parser::Clock;
|
||||
use crate::parser::Code;
|
||||
use crate::parser::Comment;
|
||||
use crate::parser::CommentBlock;
|
||||
use crate::parser::DiarySexp;
|
||||
use crate::parser::Document;
|
||||
use crate::parser::DocumentElement;
|
||||
use crate::parser::Drawer;
|
||||
use crate::parser::DynamicBlock;
|
||||
use crate::parser::Element;
|
||||
use crate::parser::Entity;
|
||||
use crate::parser::ExampleBlock;
|
||||
use crate::parser::ExportBlock;
|
||||
use crate::parser::ExportSnippet;
|
||||
use crate::parser::FixedWidthArea;
|
||||
use crate::parser::FootnoteDefinition;
|
||||
use crate::parser::FootnoteReference;
|
||||
use crate::parser::GreaterBlock;
|
||||
use crate::parser::Heading;
|
||||
use crate::parser::HorizontalRule;
|
||||
use crate::parser::InlineBabelCall;
|
||||
use crate::parser::InlineSourceBlock;
|
||||
use crate::parser::Italic;
|
||||
use crate::parser::Keyword;
|
||||
use crate::parser::LatexEnvironment;
|
||||
use crate::parser::LatexFragment;
|
||||
use crate::parser::LineBreak;
|
||||
use crate::parser::Object;
|
||||
use crate::parser::OrgMacro;
|
||||
use crate::parser::Paragraph;
|
||||
use crate::parser::PlainLink;
|
||||
use crate::parser::PlainList;
|
||||
use crate::parser::PlainListItem;
|
||||
use crate::parser::PlainText;
|
||||
use crate::parser::Planning;
|
||||
use crate::parser::PropertyDrawer;
|
||||
use crate::parser::RadioLink;
|
||||
use crate::parser::RadioTarget;
|
||||
use crate::parser::RegularLink;
|
||||
use crate::parser::Section;
|
||||
use crate::parser::Source;
|
||||
use crate::parser::SrcBlock;
|
||||
use crate::parser::StatisticsCookie;
|
||||
use crate::parser::StrikeThrough;
|
||||
use crate::parser::Subscript;
|
||||
use crate::parser::Superscript;
|
||||
use crate::parser::Table;
|
||||
use crate::parser::TableCell;
|
||||
use crate::parser::TableRow;
|
||||
use crate::parser::Target;
|
||||
use crate::parser::Timestamp;
|
||||
use crate::parser::Underline;
|
||||
use crate::parser::Verbatim;
|
||||
use crate::parser::VerseBlock;
|
||||
use crate::types::AngleLink;
|
||||
use crate::types::Bold;
|
||||
use crate::types::Citation;
|
||||
use crate::types::CitationReference;
|
||||
use crate::types::Clock;
|
||||
use crate::types::Code;
|
||||
use crate::types::Comment;
|
||||
use crate::types::CommentBlock;
|
||||
use crate::types::DiarySexp;
|
||||
use crate::types::Document;
|
||||
use crate::types::DocumentElement;
|
||||
use crate::types::Drawer;
|
||||
use crate::types::DynamicBlock;
|
||||
use crate::types::Element;
|
||||
use crate::types::Entity;
|
||||
use crate::types::ExampleBlock;
|
||||
use crate::types::ExportBlock;
|
||||
use crate::types::ExportSnippet;
|
||||
use crate::types::FixedWidthArea;
|
||||
use crate::types::FootnoteDefinition;
|
||||
use crate::types::FootnoteReference;
|
||||
use crate::types::GreaterBlock;
|
||||
use crate::types::Heading;
|
||||
use crate::types::HorizontalRule;
|
||||
use crate::types::InlineBabelCall;
|
||||
use crate::types::InlineSourceBlock;
|
||||
use crate::types::Italic;
|
||||
use crate::types::Keyword;
|
||||
use crate::types::LatexEnvironment;
|
||||
use crate::types::LatexFragment;
|
||||
use crate::types::LineBreak;
|
||||
use crate::types::Object;
|
||||
use crate::types::OrgMacro;
|
||||
use crate::types::Paragraph;
|
||||
use crate::types::PlainLink;
|
||||
use crate::types::PlainList;
|
||||
use crate::types::PlainListItem;
|
||||
use crate::types::PlainText;
|
||||
use crate::types::Planning;
|
||||
use crate::types::PropertyDrawer;
|
||||
use crate::types::RadioLink;
|
||||
use crate::types::RadioTarget;
|
||||
use crate::types::RegularLink;
|
||||
use crate::types::Section;
|
||||
use crate::types::Source;
|
||||
use crate::types::SrcBlock;
|
||||
use crate::types::StatisticsCookie;
|
||||
use crate::types::StrikeThrough;
|
||||
use crate::types::Subscript;
|
||||
use crate::types::Superscript;
|
||||
use crate::types::Table;
|
||||
use crate::types::TableCell;
|
||||
use crate::types::TableRow;
|
||||
use crate::types::Target;
|
||||
use crate::types::Timestamp;
|
||||
use crate::types::Underline;
|
||||
use crate::types::Verbatim;
|
||||
use crate::types::VerseBlock;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DiffEntry<'s> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::parser::sexp::Token;
|
||||
use crate::parser::Source;
|
||||
use crate::types::Source;
|
||||
|
||||
/// Check if the child string slice is a slice of the parent string slice.
|
||||
fn is_slice_of(parent: &str, child: &str) -> bool {
|
||||
|
17
src/context/global_settings.rs
Normal file
17
src/context/global_settings.rs
Normal file
@ -0,0 +1,17 @@
|
||||
#[derive(Debug)]
|
||||
pub struct GlobalSettings<'s> {
|
||||
#[allow(dead_code)]
|
||||
placeholder: Option<&'s str>,
|
||||
}
|
||||
|
||||
impl<'s> GlobalSettings<'s> {
|
||||
pub fn new() -> Self {
|
||||
GlobalSettings { placeholder: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Default for GlobalSettings<'s> {
|
||||
fn default() -> Self {
|
||||
GlobalSettings::new()
|
||||
}
|
||||
}
|
69
src/context/list.rs
Normal file
69
src/context/list.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct List<'parent, T> {
|
||||
data: T,
|
||||
parent: Link<'parent, T>,
|
||||
}
|
||||
|
||||
type Link<'parent, T> = Option<&'parent List<'parent, T>>;
|
||||
|
||||
impl<'parent, T> List<'parent, T> {
|
||||
pub fn new(first_item: T) -> Self {
|
||||
Self {
|
||||
data: first_item,
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> &T {
|
||||
&self.data
|
||||
}
|
||||
|
||||
pub fn get_parent(&'parent self) -> Link<'parent, T> {
|
||||
self.parent
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter<'_, T> {
|
||||
Iter { next: Some(self) }
|
||||
}
|
||||
|
||||
pub fn iter_list(&self) -> IterList<'_, T> {
|
||||
IterList { next: Some(self) }
|
||||
}
|
||||
|
||||
pub fn push(&'parent self, item: T) -> Self {
|
||||
Self {
|
||||
data: item,
|
||||
parent: Some(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Iter<'a, T> {
|
||||
next: Link<'a, T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for Iter<'a, T> {
|
||||
type Item = &'a T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let ret = self.next.map(|link| link.get_data());
|
||||
self.next = self.next.map(|link| link.get_parent()).flatten();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IterList<'a, T> {
|
||||
next: Link<'a, T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for IterList<'a, T> {
|
||||
type Item = &'a List<'a, T>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let ret = self.next;
|
||||
self.next = self.next.map(|this| this.get_parent()).flatten();
|
||||
ret
|
||||
}
|
||||
}
|
26
src/context/mod.rs
Normal file
26
src/context/mod.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::error::Res;
|
||||
use crate::parser::OrgSource;
|
||||
|
||||
mod exiting;
|
||||
mod global_settings;
|
||||
mod list;
|
||||
mod parser_context;
|
||||
mod parser_with_context;
|
||||
|
||||
pub type RefContext<'b, 'g, 'r, 's> = &'b Context<'g, 'r, 's>;
|
||||
pub trait ContextMatcher = for<'b, 'g, 'r, 's> Fn(
|
||||
RefContext<'b, 'g, 'r, 's>,
|
||||
OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>>;
|
||||
pub type DynContextMatcher<'c> = dyn ContextMatcher + 'c;
|
||||
pub trait Matcher = for<'s> Fn(OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>>;
|
||||
#[allow(dead_code)]
|
||||
pub type DynMatcher<'c> = dyn Matcher + 'c;
|
||||
|
||||
pub use exiting::ExitClass;
|
||||
pub use global_settings::GlobalSettings;
|
||||
pub use list::List;
|
||||
pub use parser_context::Context;
|
||||
pub use parser_context::ContextElement;
|
||||
pub use parser_context::ExitMatcherNode;
|
||||
pub(crate) use parser_with_context::parser_with_context;
|
@ -1,76 +1,107 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use nom::combinator::eof;
|
||||
use nom::IResult;
|
||||
|
||||
use super::exiting::ExitClass;
|
||||
use super::global_settings::GlobalSettings;
|
||||
use super::list::List;
|
||||
use super::list::Node;
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use super::Object;
|
||||
use super::DynContextMatcher;
|
||||
use super::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::OrgSource;
|
||||
use crate::types::Object;
|
||||
|
||||
type Matcher =
|
||||
dyn for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>>;
|
||||
#[derive(Debug)]
|
||||
pub enum ContextElement<'r, 's> {
|
||||
/// Stores a parser that indicates that children should exit upon matching an exit matcher.
|
||||
ExitMatcherNode(ExitMatcherNode<'r>),
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ContextTree<'r, 's> {
|
||||
tree: List<ContextElement<'r, 's>>,
|
||||
/// Stores the name of the current element to prevent directly nesting elements of the same type.
|
||||
Context(&'r str),
|
||||
|
||||
/// Indicates if elements should consume the whitespace after them.
|
||||
ConsumeTrailingWhitespace(bool),
|
||||
|
||||
/// The contents of a radio target.
|
||||
///
|
||||
/// 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>>>),
|
||||
}
|
||||
|
||||
impl<'r, 's> ContextTree<'r, 's> {
|
||||
pub fn new() -> Self {
|
||||
ContextTree { tree: List::new() }
|
||||
pub struct ExitMatcherNode<'r> {
|
||||
// TODO: Should this be "&'r DynContextMatcher<'c>" ?
|
||||
pub exit_matcher: &'r DynContextMatcher<'r>,
|
||||
pub class: ExitClass,
|
||||
}
|
||||
|
||||
pub fn branch_from(trunk: &Rc<Node<ContextElement<'r, 's>>>) -> Self {
|
||||
ContextTree {
|
||||
tree: List::branch_from(trunk),
|
||||
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");
|
||||
formatter.field("class", &self.class.to_string());
|
||||
formatter.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn ptr_eq<'x, 'y>(&self, other: &ContextTree<'x, 'y>) -> bool {
|
||||
self.tree.ptr_eq(&other.tree)
|
||||
#[derive(Debug)]
|
||||
pub struct Context<'g, 'r, 's> {
|
||||
global_settings: &'g GlobalSettings<'g>,
|
||||
tree: List<'r, &'r ContextElement<'r, 's>>,
|
||||
}
|
||||
|
||||
pub fn with_additional_node(&self, data: ContextElement<'r, 's>) -> ContextTree<'r, 's> {
|
||||
let new_list = self.tree.push_front(data);
|
||||
ContextTree { tree: new_list }
|
||||
impl<'g, 'r, 's> Context<'g, 'r, 's> {
|
||||
pub fn new(
|
||||
global_settings: &'g GlobalSettings<'g>,
|
||||
tree: List<'r, &'r ContextElement<'r, 's>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
global_settings,
|
||||
tree,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Rc<Node<ContextElement<'r, 's>>>> {
|
||||
pub fn with_additional_node(&'r self, new_element: &'r ContextElement<'r, 's>) -> Self {
|
||||
let new_tree = self.tree.push(new_element);
|
||||
Self::new(self.global_settings, new_tree)
|
||||
}
|
||||
|
||||
pub fn iter(&'r self) -> super::list::Iter<'r, &'r ContextElement<'r, 's>> {
|
||||
self.tree.iter()
|
||||
}
|
||||
|
||||
pub fn iter_context(&'r self) -> Iter<'g, 'r, 's> {
|
||||
Iter {
|
||||
next: self.tree.iter_list(),
|
||||
global_settings: self.global_settings,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_parent(&'r self) -> Option<Self> {
|
||||
self.tree.get_parent().map(|parent_tree| Self {
|
||||
global_settings: self.global_settings,
|
||||
tree: parent_tree.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> &ContextElement<'r, 's> {
|
||||
self.tree.get_data()
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn check_exit_matcher(
|
||||
&'r self,
|
||||
i: OrgSource<'s>,
|
||||
) -> IResult<OrgSource<'s>, OrgSource<'s>, CustomError<OrgSource<'s>>> {
|
||||
// Special check for EOF. We don't just make this a document-level exit matcher since the IgnoreParent ChainBehavior could cause early exit matchers to not run.
|
||||
let at_end_of_file = eof(i);
|
||||
if at_end_of_file.is_ok() {
|
||||
return at_end_of_file;
|
||||
}
|
||||
|
||||
// let blocked_context =
|
||||
// self.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
// exit_matcher: ChainBehavior::IgnoreParent(Some(&always_fail)),
|
||||
// }));
|
||||
|
||||
let mut current_class_filter = ExitClass::Gamma;
|
||||
for current_node in self.iter() {
|
||||
for current_node in self.iter_context() {
|
||||
let context_element = current_node.get_data();
|
||||
match context_element {
|
||||
ContextElement::ExitMatcherNode(exit_matcher) => {
|
||||
if exit_matcher.class as u32 <= current_class_filter as u32 {
|
||||
current_class_filter = exit_matcher.class;
|
||||
let local_context = ContextTree::branch_from(current_node);
|
||||
let local_result = (exit_matcher.exit_matcher)(&local_context, i);
|
||||
let local_result = (exit_matcher.exit_matcher)(¤t_node, i);
|
||||
if local_result.is_ok() {
|
||||
return local_result;
|
||||
}
|
||||
@ -94,8 +125,7 @@ impl<'r, 's> ContextTree<'r, 's> {
|
||||
|
||||
fn _should_consume_trailing_whitespace(&self) -> Option<bool> {
|
||||
for current_node in self.iter() {
|
||||
let context_element = current_node.get_data();
|
||||
match context_element {
|
||||
match current_node {
|
||||
ContextElement::ConsumeTrailingWhitespace(should) => {
|
||||
return Some(*should);
|
||||
}
|
||||
@ -106,34 +136,35 @@ impl<'r, 's> ContextTree<'r, 's> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ContextElement<'r, 's> {
|
||||
/// Stores a parser that indicates that children should exit upon matching an exit matcher.
|
||||
ExitMatcherNode(ExitMatcherNode<'r>),
|
||||
|
||||
/// Stores the name of the current element to prevent directly nesting elements of the same type.
|
||||
Context(&'r str),
|
||||
|
||||
/// Indicates if elements should consume the whitespace after them.
|
||||
ConsumeTrailingWhitespace(bool),
|
||||
|
||||
/// The contents of a radio target.
|
||||
///
|
||||
/// 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>>>),
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn document_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
eof(input)
|
||||
}
|
||||
|
||||
pub struct ExitMatcherNode<'r> {
|
||||
pub exit_matcher: &'r Matcher,
|
||||
pub class: ExitClass,
|
||||
pub struct Iter<'g, 'r, 's> {
|
||||
global_settings: &'g GlobalSettings<'g>,
|
||||
next: super::list::IterList<'r, &'r ContextElement<'r, 's>>,
|
||||
}
|
||||
|
||||
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");
|
||||
formatter.field("class", &self.class.to_string());
|
||||
formatter.finish()
|
||||
impl<'g, 'r, 's> Iterator for Iter<'g, 'r, 's> {
|
||||
type Item = Context<'g, 'r, 's>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let next_tree = self.next.next();
|
||||
let ret =
|
||||
next_tree.map(|parent_tree| Context::new(self.global_settings, parent_tree.clone()));
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> ContextElement<'r, 's> {
|
||||
pub fn document_context() -> Self {
|
||||
Self::ExitMatcherNode(ExitMatcherNode {
|
||||
exit_matcher: &document_end,
|
||||
class: ExitClass::Document,
|
||||
})
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#![feature(round_char_boundary)]
|
||||
#![feature(exit_status_error)]
|
||||
#![feature(trait_alias)]
|
||||
|
||||
#[cfg(feature = "compare")]
|
||||
mod compare;
|
||||
@ -14,5 +15,7 @@ pub use compare::get_emacs_version;
|
||||
#[cfg(feature = "compare")]
|
||||
pub use compare::get_org_mode_version;
|
||||
|
||||
mod context;
|
||||
mod error;
|
||||
pub mod parser;
|
||||
pub mod types;
|
||||
|
16
src/main.rs
16
src/main.rs
@ -3,7 +3,7 @@
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
||||
use ::organic::parser::document;
|
||||
use ::organic::parser::parse;
|
||||
#[cfg(feature = "compare")]
|
||||
use organic::compare_document;
|
||||
#[cfg(feature = "compare")]
|
||||
@ -68,7 +68,7 @@ fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std
|
||||
let org_contents = org_contents.as_ref();
|
||||
eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
|
||||
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
|
||||
let (remaining, rust_parsed) = document(org_contents).map_err(|e| e.to_string())?;
|
||||
let rust_parsed = parse(org_contents).map_err(|e| e.to_string())?;
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents)?;
|
||||
let (_remaining, parsed_sexp) =
|
||||
sexp_with_padding(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
@ -84,9 +84,6 @@ fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
if remaining != "" {
|
||||
Err(format!("There was unparsed text remaining: {}", remaining))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -96,7 +93,7 @@ fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std
|
||||
eprintln!(
|
||||
"This program was built with compare disabled. Only parsing with organic, not comparing."
|
||||
);
|
||||
let (_remaining, rust_parsed) = document(org_contents.as_ref()).map_err(|e| e.to_string())?;
|
||||
let rust_parsed = parse(org_contents.as_ref()).map_err(|e| e.to_string())?;
|
||||
println!("{:#?}", rust_parsed);
|
||||
Ok(())
|
||||
}
|
||||
@ -109,7 +106,7 @@ fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::err
|
||||
// TODO: This should take into account the original file path when parsing in Organic, not just in emacs.
|
||||
let org_contents = std::fs::read_to_string(org_path)?;
|
||||
let org_contents = org_contents.as_str();
|
||||
let (remaining, rust_parsed) = document(org_contents).map_err(|e| e.to_string())?;
|
||||
let rust_parsed = parse(org_contents).map_err(|e| e.to_string())?;
|
||||
let org_sexp = emacs_parse_file_org_document(org_path)?;
|
||||
let (_remaining, parsed_sexp) =
|
||||
sexp_with_padding(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
@ -125,9 +122,6 @@ fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::err
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
if remaining != "" {
|
||||
Err(format!("There was unparsed text remaining: {}", remaining))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -141,7 +135,7 @@ fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::err
|
||||
// TODO: This should take into account the original file path when parsing
|
||||
let org_contents = std::fs::read_to_string(org_path)?;
|
||||
let org_contents = org_contents.as_str();
|
||||
let (_remaining, rust_parsed) = document(org_contents).map_err(|e| e.to_string())?;
|
||||
let rust_parsed = parse(org_contents).map_err(|e| e.to_string())?;
|
||||
println!("{:#?}", rust_parsed);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -6,20 +6,20 @@ use nom::multi::many_till;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::plain_link::protocol;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::AngleLink;
|
||||
use crate::types::AngleLink;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn angle_link<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn angle_link<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, AngleLink<'s>> {
|
||||
let (remaining, _) = tag("<")(input)?;
|
||||
@ -41,15 +41,15 @@ pub fn angle_link<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn path_angle<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn path_angle<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &path_angle_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
|
||||
@ -58,8 +58,8 @@ fn path_angle<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn path_angle_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn path_angle_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
tag(">")(input)
|
||||
|
@ -14,24 +14,25 @@ use super::citation_reference::must_balance_bracket;
|
||||
use super::org_source::BracketDepth;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::citation_reference::citation_reference;
|
||||
use crate::parser::citation_reference::citation_reference_key;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object::Citation;
|
||||
use crate::parser::object_parser::standard_set_object;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::Object;
|
||||
use crate::types::Citation;
|
||||
use crate::types::Object;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn citation<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn citation<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Citation<'s>> {
|
||||
// TODO: Despite being a standard object, citations cannot exist inside the global prefix/suffix for other citations because citations must contain something that matches @key which is forbidden inside the global prefix/suffix. This TODO is to evaluate if its worth putting in an explicit check for this (which can be easily accomplished by checking the output of `get_bracket_depth()`). I suspect its not worth it because I expect, outside of intentionally crafted inputs, this parser will exit immediately inside a citation since it is unlikely to find the "[cite" substring inside a citation global prefix/suffix.
|
||||
@ -60,7 +61,7 @@ pub fn citation<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn citestyle<'r, 's>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
fn citestyle<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tuple((tag("/"), style))(input)?;
|
||||
let (remaining, _) = opt(tuple((tag("/"), variant)))(remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
@ -68,30 +69,30 @@ fn citestyle<'r, 's>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>>
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn style<'r, 's>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
fn style<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(many1(verify(anychar, |c| {
|
||||
c.is_alphanumeric() || "_-".contains(*c)
|
||||
})))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn variant<'r, 's>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
fn variant<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(many1(verify(anychar, |c| {
|
||||
c.is_alphanumeric() || "_-/".contains(*c)
|
||||
})))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn global_prefix<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn global_prefix<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
let exit_with_depth = global_prefix_end(input.get_bracket_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
parser_with_context!(standard_set_object)(&parser_context),
|
||||
@ -103,17 +104,13 @@ fn global_prefix<'r, 's>(
|
||||
Ok((remaining, children))
|
||||
}
|
||||
|
||||
fn global_prefix_end(
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> 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)
|
||||
}
|
||||
fn global_prefix_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _global_prefix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _global_prefix_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn _global_prefix_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
@ -135,16 +132,16 @@ fn _global_prefix_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn global_suffix<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn global_suffix<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
let exit_with_depth = global_suffix_end(input.get_bracket_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
parser_with_context!(standard_set_object)(&parser_context),
|
||||
@ -155,17 +152,13 @@ fn global_suffix<'r, 's>(
|
||||
Ok((remaining, children))
|
||||
}
|
||||
|
||||
fn global_suffix_end(
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> 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)
|
||||
}
|
||||
fn global_suffix_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _global_suffix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _global_suffix_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn _global_suffix_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
@ -189,19 +182,23 @@ fn _global_suffix_end<'r, 's>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::context::Context;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::source::Source;
|
||||
use crate::types::Element;
|
||||
use crate::types::Source;
|
||||
|
||||
#[test]
|
||||
fn citation_simple() {
|
||||
let input = OrgSource::new("[cite:@foo]");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let paragraph_matcher = parser_with_context!(element(true))(&initial_context);
|
||||
let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph");
|
||||
let first_paragraph = match first_paragraph {
|
||||
crate::parser::Element::Paragraph(paragraph) => paragraph,
|
||||
Element::Paragraph(paragraph) => paragraph,
|
||||
_ => panic!("Should be a paragraph!"),
|
||||
};
|
||||
assert_eq!(Into::<&str>::into(remaining), "");
|
||||
|
@ -12,24 +12,25 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::BracketDepth;
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object::CitationReference;
|
||||
use crate::parser::object_parser::minimal_set_object;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::WORD_CONSTITUENT_CHARACTERS;
|
||||
use crate::parser::Object;
|
||||
use crate::types::CitationReference;
|
||||
use crate::types::Object;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn citation_reference<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn citation_reference<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, CitationReference<'s>> {
|
||||
let (remaining, _prefix) =
|
||||
@ -48,8 +49,8 @@ pub fn citation_reference<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn citation_reference_key<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn citation_reference_key<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, source) = recognize(tuple((
|
||||
@ -68,16 +69,16 @@ pub fn citation_reference_key<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn key_prefix<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn key_prefix<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
let exit_with_depth = key_prefix_end(input.get_bracket_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
parser_with_context!(minimal_set_object)(&parser_context),
|
||||
@ -89,16 +90,16 @@ fn key_prefix<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn key_suffix<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn key_suffix<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
let exit_with_depth = key_suffix_end(input.get_bracket_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
parser_with_context!(minimal_set_object)(&parser_context),
|
||||
@ -109,17 +110,13 @@ fn key_suffix<'r, 's>(
|
||||
Ok((remaining, children))
|
||||
}
|
||||
|
||||
fn key_prefix_end(
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
_key_prefix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
fn key_prefix_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _key_prefix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _key_prefix_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn _key_prefix_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
@ -140,17 +137,13 @@ fn _key_prefix_end<'r, 's>(
|
||||
))(input)
|
||||
}
|
||||
|
||||
fn key_suffix_end(
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> 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)
|
||||
}
|
||||
fn key_suffix_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _key_suffix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _key_suffix_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _key_suffix_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
|
@ -12,16 +12,16 @@ use nom::combinator::verify;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::Clock;
|
||||
use crate::types::Clock;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn clock<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn clock<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Clock<'s>> {
|
||||
start_of_line(input)?;
|
||||
@ -44,8 +44,8 @@ pub fn clock<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn inactive_timestamp_range_duration<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn inactive_timestamp_range_duration<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(tuple((
|
||||
@ -66,8 +66,8 @@ fn inactive_timestamp_range_duration<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn inactive_timestamp<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn inactive_timestamp<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(tuple((
|
||||
|
@ -13,20 +13,20 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_consumed;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
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::immediate_in_section;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::Comment;
|
||||
use crate::types::Comment;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn comment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn comment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Comment<'s>> {
|
||||
if immediate_in_section(context, "comment") {
|
||||
@ -34,7 +34,8 @@ pub fn comment<'r, 's>(
|
||||
"Cannot nest objects of the same element".into(),
|
||||
))));
|
||||
}
|
||||
let parser_context = context.with_additional_node(ContextElement::Context("comment"));
|
||||
let parser_context = ContextElement::Context("comment");
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let comment_line_matcher = parser_with_context!(comment_line)(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
let (remaining, _first_line) = comment_line_matcher(input)?;
|
||||
@ -51,8 +52,8 @@ pub fn comment<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn comment_line<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn comment_line<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
@ -69,8 +70,10 @@ fn comment_line<'r, 's>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::context::Context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
|
||||
#[test]
|
||||
fn require_space_after_hash() {
|
||||
@ -79,7 +82,9 @@ mod tests {
|
||||
#not a comment
|
||||
# Comment again",
|
||||
);
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let comment_matcher = parser_with_context!(comment)(&initial_context);
|
||||
let (remaining, first_comment) = comment_matcher(input).expect("Parse first comment");
|
||||
assert_eq!(
|
||||
|
@ -11,15 +11,15 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::sexp::sexp;
|
||||
use super::Context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::DiarySexp;
|
||||
use crate::types::DiarySexp;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn diary_sexp<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn diary_sexp<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, DiarySexp<'s>> {
|
||||
start_of_line(input)?;
|
||||
|
@ -4,6 +4,7 @@ use nom::character::complete::anychar;
|
||||
use nom::character::complete::line_ending;
|
||||
use nom::character::complete::space0;
|
||||
use nom::character::complete::space1;
|
||||
use nom::combinator::all_consuming;
|
||||
use nom::combinator::eof;
|
||||
use nom::combinator::map;
|
||||
use nom::combinator::not;
|
||||
@ -17,96 +18,56 @@ use nom::multi::many_till;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::element::Element;
|
||||
use super::object::Object;
|
||||
use super::org_source::convert_error;
|
||||
use super::org_source::OrgSource;
|
||||
use super::parser_with_context::parser_with_context;
|
||||
use super::source::Source;
|
||||
use super::token::AllTokensIterator;
|
||||
use super::token::Token;
|
||||
use super::util::exit_matcher_parser;
|
||||
use super::util::get_consumed;
|
||||
use super::util::start_of_line;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::Context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::comment::comment;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object_parser::standard_set_object;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::planning::planning;
|
||||
use crate::parser::property_drawer::property_drawer;
|
||||
use crate::parser::util::blank_line;
|
||||
use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::types::Document;
|
||||
use crate::types::DocumentElement;
|
||||
use crate::types::Element;
|
||||
use crate::types::Heading;
|
||||
use crate::types::Object;
|
||||
use crate::types::Section;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Document<'s> {
|
||||
pub source: &'s str,
|
||||
pub zeroth_section: Option<Section<'s>>,
|
||||
pub children: Vec<Heading<'s>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Heading<'s> {
|
||||
pub source: &'s str,
|
||||
pub stars: usize,
|
||||
pub todo_keyword: Option<&'s str>,
|
||||
// TODO: add todo-type enum
|
||||
pub title: Vec<Object<'s>>,
|
||||
pub tags: Vec<&'s str>,
|
||||
pub children: Vec<DocumentElement<'s>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Section<'s> {
|
||||
pub source: &'s str,
|
||||
pub children: Vec<Element<'s>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DocumentElement<'s> {
|
||||
Heading(Heading<'s>),
|
||||
Section(Section<'s>),
|
||||
}
|
||||
|
||||
impl<'s> Source<'s> for Document<'s> {
|
||||
fn get_source(&'s self) -> &'s str {
|
||||
self.source
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Source<'s> for DocumentElement<'s> {
|
||||
fn get_source(&'s self) -> &'s str {
|
||||
match self {
|
||||
DocumentElement::Heading(obj) => obj.source,
|
||||
DocumentElement::Section(obj) => obj.source,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Source<'s> for Section<'s> {
|
||||
fn get_source(&'s self) -> &'s str {
|
||||
self.source
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Source<'s> for Heading<'s> {
|
||||
fn get_source(&'s self) -> &'s str {
|
||||
self.source
|
||||
}
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[allow(dead_code)]
|
||||
pub fn parse<'s>(input: &'s str) -> Result<Document<'s>, String> {
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let wrapped_input = OrgSource::new(input);
|
||||
let ret = all_consuming(parser_with_context!(document)(&initial_context))(wrapped_input)
|
||||
.map_err(|err| err.to_string())
|
||||
.map(|(_remaining, parsed_document)| parsed_document);
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[allow(dead_code)]
|
||||
pub fn document(input: &str) -> Res<&str, Document> {
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let wrapped_input = OrgSource::new(input);
|
||||
let (remaining, document) = _document(&initial_context, wrapped_input)
|
||||
.map(|(rem, out)| (Into::<&str>::into(rem), out))
|
||||
.map_err(convert_error)?;
|
||||
pub fn document<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Document<'s>> {
|
||||
let (remaining, document) =
|
||||
_document(context, input).map(|(rem, out)| (Into::<&str>::into(rem), out))?;
|
||||
{
|
||||
// If there are radio targets in this document then we need to parse the entire document again with the knowledge of the radio targets.
|
||||
let all_radio_targets: Vec<&Vec<Object<'_>>> = document
|
||||
@ -122,11 +83,10 @@ pub fn document(input: &str) -> Res<&str, Document> {
|
||||
.map(|rt| &rt.children)
|
||||
.collect();
|
||||
if !all_radio_targets.is_empty() {
|
||||
let initial_context = initial_context
|
||||
.with_additional_node(ContextElement::RadioTarget(all_radio_targets));
|
||||
let (remaining, document) = _document(&initial_context, wrapped_input)
|
||||
.map(|(rem, out)| (Into::<&str>::into(rem), out))
|
||||
.map_err(convert_error)?;
|
||||
let parser_context = ContextElement::RadioTarget(all_radio_targets);
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, document) = _document(&parser_context, input)
|
||||
.map(|(rem, out)| (Into::<&str>::into(rem), out))?;
|
||||
return Ok((remaining.into(), document));
|
||||
}
|
||||
}
|
||||
@ -134,8 +94,8 @@ pub fn document(input: &str) -> Res<&str, Document> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _document<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn _document<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Document<'s>> {
|
||||
let zeroth_section_matcher = parser_with_context!(zeroth_section)(context);
|
||||
@ -155,20 +115,25 @@ fn _document<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn zeroth_section<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn zeroth_section<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Section<'s>> {
|
||||
// TODO: The zeroth section is specialized so it probably needs its own parser
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("section"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("section"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Document,
|
||||
exit_matcher: §ion_end,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let without_consuming_whitespace_context = ContextElement::ConsumeTrailingWhitespace(false);
|
||||
let without_consuming_whitespace_context =
|
||||
parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false));
|
||||
parser_context.with_additional_node(&without_consuming_whitespace_context);
|
||||
|
||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
@ -209,18 +174,22 @@ fn zeroth_section<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn section<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn section<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
mut input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Section<'s>> {
|
||||
// TODO: The zeroth section is specialized so it probably needs its own parser
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("section"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("section"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Document,
|
||||
exit_matcher: §ion_end,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
let (mut remaining, (planning_element, property_drawer_element)) = tuple((
|
||||
@ -259,8 +228,8 @@ fn section<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn section_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn section_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(detect_headline)(input)
|
||||
@ -268,13 +237,16 @@ fn section_end<'r, 's>(
|
||||
|
||||
const fn heading(
|
||||
parent_stars: usize,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, Heading<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| _heading(context, input, parent_stars)
|
||||
) -> impl for<'b, 'g, 'r, 's> Fn(
|
||||
RefContext<'b, 'g, 'r, 's>,
|
||||
OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Heading<'s>> {
|
||||
move |context, input: OrgSource<'_>| _heading(context, input, parent_stars)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _heading<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn _heading<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
parent_stars: usize,
|
||||
) -> Res<OrgSource<'s>, Heading<'s>> {
|
||||
@ -320,8 +292,8 @@ fn detect_headline<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn headline<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn headline<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
parent_stars: usize,
|
||||
) -> Res<
|
||||
@ -334,11 +306,11 @@ fn headline<'r, 's>(
|
||||
Vec<&'s str>,
|
||||
),
|
||||
> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Document,
|
||||
exit_matcher: &headline_title_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
||||
|
||||
let (
|
||||
@ -375,8 +347,8 @@ fn headline<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn headline_title_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn headline_title_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(tuple((
|
||||
|
@ -11,29 +11,29 @@ use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::source::SetSource;
|
||||
use crate::parser::util::blank_line;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::immediate_in_section;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::util::WORD_CONSTITUENT_CHARACTERS;
|
||||
use crate::parser::Drawer;
|
||||
use crate::parser::Element;
|
||||
use crate::parser::Paragraph;
|
||||
use crate::types::Drawer;
|
||||
use crate::types::Element;
|
||||
use crate::types::Paragraph;
|
||||
use crate::types::SetSource;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn drawer<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn drawer<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Drawer<'s>> {
|
||||
if immediate_in_section(context, "drawer") {
|
||||
@ -50,13 +50,17 @@ pub fn drawer<'r, 's>(
|
||||
recognize(tuple((space0, line_ending))),
|
||||
))(remaining)?;
|
||||
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("drawer"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("drawer"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Alpha,
|
||||
exit_matcher: &drawer_end,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
|
||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
@ -98,8 +102,8 @@ fn name<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn drawer_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn drawer_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
|
@ -12,28 +12,28 @@ use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::greater_element::DynamicBlock;
|
||||
use crate::parser::lesser_element::Paragraph;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::source::SetSource;
|
||||
use crate::parser::util::blank_line;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::immediate_in_section;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::Element;
|
||||
use crate::types::DynamicBlock;
|
||||
use crate::types::Element;
|
||||
use crate::types::Paragraph;
|
||||
use crate::types::SetSource;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn dynamic_block<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn dynamic_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, DynamicBlock<'s>> {
|
||||
// TODO: Do I need to differentiate between different dynamic block types.
|
||||
@ -50,13 +50,17 @@ pub fn dynamic_block<'r, 's>(
|
||||
opt(tuple((space1, parameters))),
|
||||
line_ending,
|
||||
))(remaining)?;
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("dynamic block"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("dynamic block"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Alpha,
|
||||
exit_matcher: &dynamic_block_end,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let parameters = match parameters {
|
||||
Some((_ws, parameters)) => Some(parameters),
|
||||
None => None,
|
||||
@ -106,8 +110,8 @@ fn parameters<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn dynamic_block_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn dynamic_block_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
|
@ -7,7 +7,6 @@ use super::comment::comment;
|
||||
use super::diary_sexp::diary_sexp;
|
||||
use super::drawer::drawer;
|
||||
use super::dynamic_block::dynamic_block;
|
||||
use super::element::Element;
|
||||
use super::fixed_width_area::fixed_width_area;
|
||||
use super::footnote_definition::footnote_definition;
|
||||
use super::greater_block::greater_block;
|
||||
@ -24,25 +23,29 @@ use super::org_source::OrgSource;
|
||||
use super::paragraph::paragraph;
|
||||
use super::plain_list::detect_plain_list;
|
||||
use super::plain_list::plain_list;
|
||||
use super::source::SetSource;
|
||||
use super::util::get_consumed;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::table::org_mode_table;
|
||||
use crate::types::Element;
|
||||
use crate::types::SetSource;
|
||||
|
||||
pub const fn element(
|
||||
can_be_paragraph: bool,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, Element<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| _element(context, input, can_be_paragraph)
|
||||
) -> impl for<'b, 'g, 'r, 's> Fn(
|
||||
RefContext<'b, 'g, 'r, 's>,
|
||||
OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Element<'s>> {
|
||||
move |context, input: OrgSource<'_>| _element(context, input, can_be_paragraph)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _element<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn _element<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
can_be_paragraph: bool,
|
||||
) -> Res<OrgSource<'s>, Element<'s>> {
|
||||
@ -118,13 +121,14 @@ fn _element<'r, 's>(
|
||||
|
||||
pub const fn detect_element(
|
||||
can_be_paragraph: bool,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
move |context: Context, input: OrgSource<'_>| _detect_element(context, input, can_be_paragraph)
|
||||
) -> impl for<'b, 'g, 'r, 's> Fn(RefContext<'b, 'g, 'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, ()>
|
||||
{
|
||||
move |context, input: OrgSource<'_>| _detect_element(context, input, can_be_paragraph)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _detect_element<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn _detect_element<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
can_be_paragraph: bool,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
|
@ -8,12 +8,12 @@ use nom::combinator::recognize;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::object::Entity;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::types::Entity;
|
||||
|
||||
// TODO: Make this a user-provided variable corresponding to elisp's org-entities
|
||||
const ORG_ENTITIES: [&'static str; 413] = [
|
||||
@ -433,8 +433,8 @@ const ORG_ENTITIES: [&'static str; 413] = [
|
||||
];
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn entity<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn entity<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Entity<'s>> {
|
||||
let (remaining, _) = tag("\\")(input)?;
|
||||
@ -454,8 +454,8 @@ pub fn entity<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn name<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn name<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
// TODO: This should be defined by org-entities and optionally org-entities-user
|
||||
|
@ -9,28 +9,28 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::ExportSnippet;
|
||||
use crate::types::ExportSnippet;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn export_snippet<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn export_snippet<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ExportSnippet<'s>> {
|
||||
let (remaining, _) = tag("@@")(input)?;
|
||||
let (remaining, backend_name) = backend(context, remaining)?;
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &export_snippet_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, backend_contents) = opt(tuple((
|
||||
tag(":"),
|
||||
parser_with_context!(contents)(&parser_context),
|
||||
@ -50,8 +50,8 @@ pub fn export_snippet<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn backend<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn backend<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, backend_name) =
|
||||
@ -61,8 +61,8 @@ fn backend<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn contents<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn contents<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, source) = recognize(verify(
|
||||
@ -73,8 +73,8 @@ fn contents<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn export_snippet_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn export_snippet_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
tag("@@")(input)
|
||||
|
@ -12,17 +12,17 @@ use nom::sequence::preceded;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::FixedWidthArea;
|
||||
use crate::types::FixedWidthArea;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn fixed_width_area<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn fixed_width_area<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, FixedWidthArea<'s>> {
|
||||
let fixed_width_area_line_matcher = parser_with_context!(fixed_width_area_line)(context);
|
||||
@ -41,8 +41,8 @@ pub fn fixed_width_area<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn fixed_width_area_line<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn fixed_width_area_line<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
|
@ -12,26 +12,26 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::WORD_CONSTITUENT_CHARACTERS;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::greater_element::FootnoteDefinition;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::blank_line;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::immediate_in_section;
|
||||
use crate::parser::util::maybe_consume_trailing_whitespace;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::types::FootnoteDefinition;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn footnote_definition<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn footnote_definition<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, FootnoteDefinition<'s>> {
|
||||
if immediate_in_section(context, "footnote definition") {
|
||||
@ -43,13 +43,17 @@ pub fn footnote_definition<'r, 's>(
|
||||
// Cannot be indented.
|
||||
let (remaining, (_lead_in, lbl, _lead_out, _ws)) =
|
||||
tuple((tag_no_case("[fn:"), label, tag("]"), space0))(input)?;
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("footnote definition"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("footnote definition"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Alpha,
|
||||
exit_matcher: &footnote_definition_end,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
// TODO: The problem is we are not accounting for trailing whitespace like we do in section. Maybe it would be easier if we passed down whether or not to parse trailing whitespace into the element matcher similar to how tag takes in parameters.
|
||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
@ -76,8 +80,8 @@ pub fn label<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn footnote_definition_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn footnote_definition_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, source) = alt((
|
||||
@ -105,9 +109,10 @@ fn detect_footnote_definition<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::Source;
|
||||
use crate::context::Context;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::types::Source;
|
||||
|
||||
#[test]
|
||||
fn two_paragraphs() {
|
||||
@ -118,7 +123,9 @@ mod tests {
|
||||
|
||||
line footnote.",
|
||||
);
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let footnote_definition_matcher = parser_with_context!(element(true))(&initial_context);
|
||||
let (remaining, first_footnote_definition) =
|
||||
footnote_definition_matcher(input).expect("Parse first footnote_definition");
|
||||
@ -149,7 +156,9 @@ line footnote.
|
||||
|
||||
not in the footnote.",
|
||||
);
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let footnote_definition_matcher = parser_with_context!(element(true))(&initial_context);
|
||||
let (remaining, first_footnote_definition) =
|
||||
footnote_definition_matcher(input).expect("Parse first footnote_definition");
|
||||
|
@ -6,24 +6,25 @@ use nom::multi::many_till;
|
||||
|
||||
use super::org_source::BracketDepth;
|
||||
use super::org_source::OrgSource;
|
||||
use super::parser_context::ContextElement;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::footnote_definition::label;
|
||||
use crate::parser::object_parser::standard_set_object;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::FootnoteReference;
|
||||
use crate::types::FootnoteReference;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn footnote_reference<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn footnote_reference<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, FootnoteReference<'s>> {
|
||||
alt((
|
||||
@ -34,17 +35,17 @@ pub fn footnote_reference<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn anonymous_footnote<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn anonymous_footnote<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, FootnoteReference<'s>> {
|
||||
let (remaining, _) = tag_no_case("[fn::")(input)?;
|
||||
let exit_with_depth = footnote_definition_end(remaining.get_bracket_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
parser_with_context!(standard_set_object)(&parser_context),
|
||||
@ -68,19 +69,19 @@ fn anonymous_footnote<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn inline_footnote<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn inline_footnote<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, FootnoteReference<'s>> {
|
||||
let (remaining, _) = tag_no_case("[fn:")(input)?;
|
||||
let (remaining, label_contents) = label(remaining)?;
|
||||
let (remaining, _) = tag(":")(remaining)?;
|
||||
let exit_with_depth = footnote_definition_end(remaining.get_bracket_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
parser_with_context!(standard_set_object)(&parser_context),
|
||||
@ -104,8 +105,8 @@ fn inline_footnote<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn footnote_reference_only<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn footnote_reference_only<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, FootnoteReference<'s>> {
|
||||
let (remaining, _) = tag_no_case("[fn:")(input)?;
|
||||
@ -124,17 +125,15 @@ fn footnote_reference_only<'r, 's>(
|
||||
))
|
||||
}
|
||||
|
||||
fn footnote_definition_end(
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
fn footnote_definition_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| {
|
||||
_footnote_definition_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _footnote_definition_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _footnote_definition_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
|
@ -13,27 +13,28 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::in_section;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::greater_element::GreaterBlock;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::source::SetSource;
|
||||
use crate::parser::util::blank_line;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::Element;
|
||||
use crate::parser::Paragraph;
|
||||
use crate::types::Element;
|
||||
use crate::types::GreaterBlock;
|
||||
use crate::types::Paragraph;
|
||||
use crate::types::SetSource;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn greater_block<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn greater_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, GreaterBlock<'s>> {
|
||||
// TODO: Do I need to differentiate between different greater block types.
|
||||
@ -61,13 +62,17 @@ pub fn greater_block<'r, 's>(
|
||||
let exit_with_name = greater_block_end(name.into());
|
||||
let (remaining, parameters) = opt(tuple((space1, parameters)))(remaining)?;
|
||||
let (remaining, _nl) = line_ending(remaining)?;
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context(context_name.as_str()))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context(context_name.as_str()),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Alpha,
|
||||
exit_matcher: &exit_with_name,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let parameters = match parameters {
|
||||
Some((_ws, parameters)) => Some(parameters),
|
||||
None => None,
|
||||
@ -120,19 +125,16 @@ fn parameters<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
is_not("\r\n")(input)
|
||||
}
|
||||
|
||||
fn greater_block_end<'x>(
|
||||
name: &'x str,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
fn greater_block_end<'c>(name: &'c str) -> impl ContextMatcher + 'c {
|
||||
// TODO: Can this be done without making an owned copy?
|
||||
let name = name.to_owned();
|
||||
move |context: Context, input: OrgSource<'_>| _greater_block_end(context, input, name.as_str())
|
||||
move |context, input: OrgSource<'_>| _greater_block_end(context, input, name)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _greater_block_end<'r, 's, 'x>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _greater_block_end<'b, 'g, 'r, 's, 'c>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
name: &'x str,
|
||||
name: &'c str,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
|
@ -9,14 +9,14 @@ use nom::multi::many1_count;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::HorizontalRule;
|
||||
use crate::types::HorizontalRule;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn horizontal_rule<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn horizontal_rule<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, HorizontalRule<'s>> {
|
||||
start_of_line(input)?;
|
||||
|
@ -12,21 +12,22 @@ use nom::multi::many_till;
|
||||
use super::org_source::BracketDepth;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::InlineBabelCall;
|
||||
use crate::types::InlineBabelCall;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn inline_babel_call<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn inline_babel_call<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, InlineBabelCall<'s>> {
|
||||
let (remaining, _) = tag_no_case("call_")(input)?;
|
||||
@ -46,15 +47,15 @@ pub fn inline_babel_call<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn name<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn name<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &name_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, name) = recognize(many_till(
|
||||
verify(anychar, |c| !(c.is_whitespace() || "[]()".contains(*c))),
|
||||
parser_with_context!(exit_matcher_parser)(&parser_context),
|
||||
@ -63,26 +64,26 @@ fn name<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn name_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn name_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(one_of("[("))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn header<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn header<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tag("[")(input)?;
|
||||
|
||||
let exit_with_depth = header_end(remaining.get_bracket_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, name) = recognize(many_till(
|
||||
anychar,
|
||||
@ -92,17 +93,13 @@ fn header<'r, 's>(
|
||||
Ok((remaining, name))
|
||||
}
|
||||
|
||||
fn header_end(
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
_header_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
fn header_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _header_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _header_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _header_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
@ -121,18 +118,18 @@ fn _header_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn argument<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn argument<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tag("(")(input)?;
|
||||
|
||||
let exit_with_depth = argument_end(remaining.get_parenthesis_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, name) = recognize(many_till(
|
||||
anychar,
|
||||
@ -142,17 +139,13 @@ fn argument<'r, 's>(
|
||||
Ok((remaining, name))
|
||||
}
|
||||
|
||||
fn argument_end(
|
||||
starting_parenthesis_depth: BracketDepth,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
_argument_end(context, input, starting_parenthesis_depth)
|
||||
}
|
||||
fn argument_end(starting_parenthesis_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _argument_end(context, input, starting_parenthesis_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _argument_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _argument_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_parenthesis_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
|
@ -14,21 +14,22 @@ use tracing::span;
|
||||
use super::org_source::BracketDepth;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::InlineSourceBlock;
|
||||
use crate::types::InlineSourceBlock;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn inline_source_block<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn inline_source_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, InlineSourceBlock<'s>> {
|
||||
let (remaining, _) = tag_no_case("src_")(input)?;
|
||||
@ -47,15 +48,15 @@ pub fn inline_source_block<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn lang<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn lang<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &lang_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, lang) = recognize(many_till(
|
||||
verify(anychar, |c| !(c.is_whitespace() || "[{".contains(*c))),
|
||||
parser_with_context!(exit_matcher_parser)(&parser_context),
|
||||
@ -64,26 +65,26 @@ fn lang<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn lang_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn lang_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(one_of("[{"))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn header<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn header<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tag("[")(input)?;
|
||||
|
||||
let exit_with_depth = header_end(remaining.get_bracket_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, header_contents) = recognize(many_till(
|
||||
anychar,
|
||||
@ -93,17 +94,13 @@ fn header<'r, 's>(
|
||||
Ok((remaining, header_contents))
|
||||
}
|
||||
|
||||
fn header_end(
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
_header_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
fn header_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _header_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _header_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _header_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_bracket_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
@ -122,18 +119,18 @@ fn _header_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn body<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn body<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tag("{")(input)?;
|
||||
|
||||
let exit_with_depth = body_end(remaining.get_brace_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, body_contents) = recognize(many_till(
|
||||
anychar,
|
||||
@ -153,15 +150,13 @@ fn body<'r, 's>(
|
||||
Ok((remaining, body_contents))
|
||||
}
|
||||
|
||||
fn body_end(
|
||||
starting_brace_depth: BracketDepth,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| _body_end(context, input, starting_brace_depth)
|
||||
fn body_end(starting_brace_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _body_end(context, input, starting_brace_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _body_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _body_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_brace_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
|
@ -16,12 +16,12 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::BracketDepth;
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::Keyword;
|
||||
use crate::types::Keyword;
|
||||
|
||||
const ORG_ELEMENT_AFFILIATED_KEYWORDS: [&'static str; 13] = [
|
||||
"caption", "data", "header", "headers", "label", "name", "plot", "resname", "result",
|
||||
@ -30,8 +30,8 @@ const ORG_ELEMENT_AFFILIATED_KEYWORDS: [&'static str; 13] = [
|
||||
const ORG_ELEMENT_DUAL_KEYWORDS: [&'static str; 2] = ["caption", "results"];
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn keyword<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn keyword<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Keyword<'s>> {
|
||||
start_of_line(input)?;
|
||||
@ -55,8 +55,8 @@ pub fn keyword<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn affiliated_keyword<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn affiliated_keyword<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Keyword<'s>> {
|
||||
start_of_line(input)?;
|
||||
|
@ -13,19 +13,20 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_consumed;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::LatexEnvironment;
|
||||
use crate::types::LatexEnvironment;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn latex_environment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn latex_environment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, LatexEnvironment<'s>> {
|
||||
start_of_line(input)?;
|
||||
@ -39,13 +40,13 @@ pub fn latex_environment<'r, 's>(
|
||||
))(remaining)?;
|
||||
|
||||
let latex_environment_end_specialized = latex_environment_end(name.into());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &latex_environment_end_specialized,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, _contents) = contents(&latex_environment_end_specialized, context, remaining)?;
|
||||
let (remaining, _contents) = contents(&latex_environment_end_specialized)(context, remaining)?;
|
||||
let (remaining, _end) = latex_environment_end_specialized(&parser_context, remaining)?;
|
||||
|
||||
let source = get_consumed(input, remaining);
|
||||
@ -62,44 +63,42 @@ fn name<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
take_while1(|c: char| c.is_alphanumeric() || c == '*')(input)
|
||||
}
|
||||
|
||||
fn contents<F: ContextMatcher>(end_matcher: F) -> impl ContextMatcher {
|
||||
move |context, input| _contents(&end_matcher, context, input)
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(end_matcher))
|
||||
)]
|
||||
pub fn contents<
|
||||
'r,
|
||||
's,
|
||||
F: Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>>,
|
||||
>(
|
||||
fn _contents<'b, 'g, 'r, 's, F: ContextMatcher>(
|
||||
end_matcher: F,
|
||||
context: Context<'r, 's>,
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, source) = recognize(many_till(
|
||||
anychar,
|
||||
peek(alt((
|
||||
parser_with_context!(exit_matcher_parser)(context),
|
||||
parser_with_context!(end_matcher)(context),
|
||||
parser_with_context!(&end_matcher)(context),
|
||||
))),
|
||||
))(input)?;
|
||||
|
||||
Ok((remaining, source))
|
||||
}
|
||||
|
||||
fn latex_environment_end(
|
||||
current_name: &str,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
fn latex_environment_end(current_name: &str) -> impl ContextMatcher {
|
||||
let current_name_lower = current_name.to_lowercase();
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
move |context, input: OrgSource<'_>| {
|
||||
_latex_environment_end(context, input, current_name_lower.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _latex_environment_end<'r, 's, 'x>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _latex_environment_end<'b, 'g, 'r, 's, 'c>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
current_name_lower: &'x str,
|
||||
current_name_lower: &'c str,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
|
@ -14,18 +14,18 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::LatexFragment;
|
||||
use crate::types::LatexFragment;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn latex_fragment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn latex_fragment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, LatexFragment<'s>> {
|
||||
let (remaining, _) = alt((
|
||||
@ -48,8 +48,8 @@ pub fn latex_fragment<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn raw_latex_fragment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn raw_latex_fragment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tag("\\")(input)?;
|
||||
@ -61,16 +61,16 @@ fn raw_latex_fragment<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn name<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn name<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alpha1(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn brackets<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn brackets<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, body) = alt((
|
||||
@ -101,8 +101,8 @@ fn brackets<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn escaped_parenthesis_fragment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn escaped_parenthesis_fragment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tag("\\(")(input)?;
|
||||
@ -120,8 +120,8 @@ fn escaped_parenthesis_fragment<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn escaped_bracket_fragment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn escaped_bracket_fragment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tag("\\[")(input)?;
|
||||
@ -139,8 +139,8 @@ fn escaped_bracket_fragment<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn double_dollar_fragment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn double_dollar_fragment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
// TODO: The documentation on the dollar sign versions is incomplete. Test to figure out what the real requirements are. For example, can this span more than 3 lines and can this contain a single $ since its terminated by $$?
|
||||
@ -159,8 +159,8 @@ fn double_dollar_fragment<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn dollar_char_fragment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn dollar_char_fragment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (_, _) = pre(context, input)?;
|
||||
@ -174,7 +174,10 @@ fn dollar_char_fragment<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
pub fn pre<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let preceding_character = input.get_preceding_character();
|
||||
if let Some('$') = preceding_character {
|
||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||
@ -185,7 +188,10 @@ pub fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSo
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn post<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
pub fn post<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
// TODO: What about eof? Test to find out.
|
||||
|
||||
// TODO: Figure out which punctuation characters should be included.
|
||||
@ -194,8 +200,8 @@ pub fn post<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgS
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn bordered_dollar_fragment<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn bordered_dollar_fragment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (_, _) = pre(context, input)?;
|
||||
@ -220,16 +226,16 @@ fn bordered_dollar_fragment<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn open_border<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn open_border<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(verify(none_of(".,;$"), |c| !c.is_whitespace()))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn close_border<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn close_border<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let preceding_character = input.get_preceding_character();
|
||||
|
@ -12,42 +12,47 @@ use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::lesser_element::CommentBlock;
|
||||
use crate::parser::lesser_element::ExampleBlock;
|
||||
use crate::parser::lesser_element::ExportBlock;
|
||||
use crate::parser::lesser_element::SrcBlock;
|
||||
use crate::parser::lesser_element::VerseBlock;
|
||||
use crate::parser::object::Object;
|
||||
use crate::parser::object::PlainText;
|
||||
use crate::parser::object_parser::standard_set_object;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::blank_line;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::util::text_until_exit;
|
||||
use crate::types::CommentBlock;
|
||||
use crate::types::ExampleBlock;
|
||||
use crate::types::ExportBlock;
|
||||
use crate::types::Object;
|
||||
use crate::types::PlainText;
|
||||
use crate::types::SrcBlock;
|
||||
use crate::types::VerseBlock;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn verse_block<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn verse_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, VerseBlock<'s>> {
|
||||
let (remaining, name) = lesser_block_begin("verse")(context, input)?;
|
||||
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||
let (remaining, _nl) = line_ending(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("verse");
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("lesser block"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("lesser block"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &lesser_block_end_specialized,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let parameters = match parameters {
|
||||
Some((_ws, parameters)) => Some(parameters),
|
||||
None => None,
|
||||
@ -84,21 +89,25 @@ pub fn verse_block<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn comment_block<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn comment_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, CommentBlock<'s>> {
|
||||
let (remaining, name) = lesser_block_begin("comment")(context, input)?;
|
||||
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||
let (remaining, _nl) = line_ending(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("comment");
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("lesser block"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("lesser block"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &lesser_block_end_specialized,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let parameters = match parameters {
|
||||
Some((_ws, parameters)) => Some(parameters),
|
||||
None => None,
|
||||
@ -120,21 +129,25 @@ pub fn comment_block<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn example_block<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn example_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ExampleBlock<'s>> {
|
||||
let (remaining, _name) = lesser_block_begin("example")(context, input)?;
|
||||
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||
let (remaining, _nl) = line_ending(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("example");
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("lesser block"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("lesser block"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &lesser_block_end_specialized,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let parameters = match parameters {
|
||||
Some((_ws, parameters)) => Some(parameters),
|
||||
None => None,
|
||||
@ -156,8 +169,8 @@ pub fn example_block<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn export_block<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn export_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ExportBlock<'s>> {
|
||||
let (remaining, name) = lesser_block_begin("export")(context, input)?;
|
||||
@ -165,13 +178,17 @@ pub fn export_block<'r, 's>(
|
||||
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||
let (remaining, _nl) = line_ending(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("export");
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("lesser block"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("lesser block"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &lesser_block_end_specialized,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let parameters = match parameters {
|
||||
Some((_ws, parameters)) => Some(parameters),
|
||||
None => None,
|
||||
@ -193,8 +210,8 @@ pub fn export_block<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn src_block<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn src_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, SrcBlock<'s>> {
|
||||
let (remaining, name) = lesser_block_begin("src")(context, input)?;
|
||||
@ -202,13 +219,17 @@ pub fn src_block<'r, 's>(
|
||||
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||
let (remaining, _nl) = line_ending(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("src");
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("lesser block"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("lesser block"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Alpha,
|
||||
exit_matcher: &lesser_block_end_specialized,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let parameters = match parameters {
|
||||
Some((_ws, parameters)) => Some(parameters),
|
||||
None => None,
|
||||
@ -239,20 +260,18 @@ fn data<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
is_not("\r\n")(input)
|
||||
}
|
||||
|
||||
fn lesser_block_end(
|
||||
current_name: &str,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
fn lesser_block_end(current_name: &str) -> impl ContextMatcher {
|
||||
let current_name_lower = current_name.to_lowercase();
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
move |context, input: OrgSource<'_>| {
|
||||
_lesser_block_end(context, input, current_name_lower.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _lesser_block_end<'r, 's, 'x>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _lesser_block_end<'b, 'g, 'r, 's, 'c>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
current_name_lower: &'x str,
|
||||
current_name_lower: &'c str,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
@ -268,18 +287,16 @@ fn _lesser_block_end<'r, 's, 'x>(
|
||||
/// Parser for the beginning of a lesser block
|
||||
///
|
||||
/// current_name MUST be lowercase. We do not do the conversion ourselves because it is not allowed in a const fn.
|
||||
const fn lesser_block_begin(
|
||||
current_name: &'static str,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
const fn lesser_block_begin<'c>(current_name: &'c str) -> impl ContextMatcher + 'c {
|
||||
// TODO: Since this is a const fn, is there ANY way to "generate" functions at compile time?
|
||||
move |context: Context, input: OrgSource<'_>| _lesser_block_begin(context, input, current_name)
|
||||
move |context, input: OrgSource<'_>| _lesser_block_begin(context, input, current_name)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _lesser_block_begin<'r, 's, 'x>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _lesser_block_begin<'b, 'g, 'r, 's, 'c>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
current_name_lower: &'x str,
|
||||
current_name_lower: &'c str,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
|
@ -5,16 +5,16 @@ use nom::combinator::recognize;
|
||||
use nom::multi::many0;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::LineBreak;
|
||||
use crate::types::LineBreak;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn line_break<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn line_break<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, LineBreak<'s>> {
|
||||
let (remaining, _) = pre(context, input)?;
|
||||
@ -31,7 +31,10 @@ pub fn line_break<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
fn pre<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let preceding_character = input.get_preceding_character();
|
||||
match preceding_character {
|
||||
// If None, we are at the start of the file
|
||||
|
@ -1,183 +0,0 @@
|
||||
use std::fmt::Debug;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct List<T> {
|
||||
head: Option<Rc<Node<T>>>,
|
||||
}
|
||||
|
||||
impl<T> Clone for List<T> {
|
||||
fn clone(&self) -> Self {
|
||||
List {
|
||||
head: self.head.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Node<T> {
|
||||
data: T,
|
||||
parent: Option<Rc<Node<T>>>,
|
||||
}
|
||||
|
||||
impl<T> Node<T> {
|
||||
pub fn get_data(&self) -> &T {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> List<T> {
|
||||
pub fn new() -> Self {
|
||||
List { head: None }
|
||||
}
|
||||
|
||||
pub fn branch_from(trunk: &Rc<Node<T>>) -> Self {
|
||||
List {
|
||||
head: Some(trunk.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_front(&self, data: T) -> List<T> {
|
||||
List {
|
||||
head: Some(Rc::new(Node {
|
||||
data: data,
|
||||
parent: self.head.clone(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pop_front(&mut self) -> (Option<T>, List<T>) {
|
||||
match self.head.take() {
|
||||
None => (None, List::new()),
|
||||
Some(popped_node) => {
|
||||
let extracted_node = match Rc::try_unwrap(popped_node) {
|
||||
Ok(node) => node,
|
||||
Err(_) => panic!("try_unwrap failed on Rc in pop_front on List."),
|
||||
};
|
||||
(
|
||||
Some(extracted_node.data),
|
||||
List {
|
||||
head: extracted_node.parent,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn without_front(&self) -> List<T> {
|
||||
List {
|
||||
head: self.head.as_ref().map(|node| node.parent.clone()).flatten(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_data(&self) -> Option<&T> {
|
||||
self.head.as_ref().map(|rc_node| &rc_node.data)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.head.is_none()
|
||||
}
|
||||
|
||||
pub fn ptr_eq(&self, other: &List<T>) -> bool {
|
||||
match (self.head.as_ref(), other.head.as_ref()) {
|
||||
(None, None) => true,
|
||||
(None, Some(_)) | (Some(_), None) => false,
|
||||
(Some(me), Some(them)) => Rc::ptr_eq(me, them),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Rc<Node<T>>> {
|
||||
NodeIter {
|
||||
position: &self.head,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn iter_until<'a>(&'a self, other: &'a List<T>) -> impl Iterator<Item = &Rc<Node<T>>> {
|
||||
NodeIterUntil {
|
||||
position: &self.head,
|
||||
stop: &other.head,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn into_iter_until<'a>(self, other: &'a List<T>) -> impl Iterator<Item = T> + 'a {
|
||||
NodeIntoIterUntil {
|
||||
position: self,
|
||||
stop: &other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NodeIter<'a, T> {
|
||||
position: &'a Option<Rc<Node<T>>>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for NodeIter<'a, T> {
|
||||
type Item = &'a Rc<Node<T>>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (return_value, next_position) = match &self.position {
|
||||
None => return None,
|
||||
Some(rc_node) => {
|
||||
let next_position = &rc_node.parent;
|
||||
let return_value = rc_node;
|
||||
(return_value, next_position)
|
||||
}
|
||||
};
|
||||
self.position = next_position;
|
||||
Some(return_value)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NodeIterUntil<'a, T> {
|
||||
position: &'a Option<Rc<Node<T>>>,
|
||||
stop: &'a Option<Rc<Node<T>>>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for NodeIterUntil<'a, T> {
|
||||
type Item = &'a Rc<Node<T>>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match (self.position, self.stop) {
|
||||
(_, None) => {}
|
||||
(None, _) => {}
|
||||
(Some(this_rc), Some(stop_rc)) => {
|
||||
if Rc::ptr_eq(this_rc, stop_rc) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
};
|
||||
let (return_value, next_position) = match &self.position {
|
||||
None => return None,
|
||||
Some(rc_node) => {
|
||||
let next_position = &rc_node.parent;
|
||||
let return_value = rc_node;
|
||||
(return_value, next_position)
|
||||
}
|
||||
};
|
||||
self.position = next_position;
|
||||
Some(return_value)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NodeIntoIterUntil<'a, T> {
|
||||
position: List<T>,
|
||||
stop: &'a List<T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for NodeIntoIterUntil<'a, T> {
|
||||
type Item = T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.position.ptr_eq(self.stop) {
|
||||
return None;
|
||||
}
|
||||
let (popped_element, new_position) = self.position.pop_front();
|
||||
self.position = new_position;
|
||||
popped_element
|
||||
}
|
||||
}
|
@ -7,16 +7,13 @@ mod diary_sexp;
|
||||
mod document;
|
||||
mod drawer;
|
||||
mod dynamic_block;
|
||||
mod element;
|
||||
mod element_parser;
|
||||
mod entity;
|
||||
mod exiting;
|
||||
mod export_snippet;
|
||||
mod fixed_width_area;
|
||||
mod footnote_definition;
|
||||
mod footnote_reference;
|
||||
mod greater_block;
|
||||
mod greater_element;
|
||||
mod horizontal_rule;
|
||||
mod inline_babel_call;
|
||||
mod inline_source_block;
|
||||
@ -24,16 +21,11 @@ mod keyword;
|
||||
mod latex_environment;
|
||||
mod latex_fragment;
|
||||
mod lesser_block;
|
||||
mod lesser_element;
|
||||
mod line_break;
|
||||
mod list;
|
||||
mod object;
|
||||
mod object_parser;
|
||||
mod org_macro;
|
||||
mod org_source;
|
||||
mod paragraph;
|
||||
mod parser_context;
|
||||
mod parser_with_context;
|
||||
mod plain_link;
|
||||
mod plain_list;
|
||||
mod plain_text;
|
||||
@ -42,7 +34,6 @@ mod property_drawer;
|
||||
mod radio_link;
|
||||
mod regular_link;
|
||||
pub mod sexp;
|
||||
mod source;
|
||||
mod statistics_cookie;
|
||||
mod subscript_and_superscript;
|
||||
mod table;
|
||||
@ -52,62 +43,5 @@ mod timestamp;
|
||||
mod token;
|
||||
mod util;
|
||||
pub use document::document;
|
||||
pub use document::Document;
|
||||
pub use document::DocumentElement;
|
||||
pub use document::Heading;
|
||||
pub use document::Section;
|
||||
pub use element::Element;
|
||||
pub use greater_element::Drawer;
|
||||
pub use greater_element::DynamicBlock;
|
||||
pub use greater_element::FootnoteDefinition;
|
||||
pub use greater_element::GreaterBlock;
|
||||
pub use greater_element::PlainList;
|
||||
pub use greater_element::PlainListItem;
|
||||
pub use greater_element::PropertyDrawer;
|
||||
pub use greater_element::Table;
|
||||
pub use greater_element::TableRow;
|
||||
pub use lesser_element::Clock;
|
||||
pub use lesser_element::Comment;
|
||||
pub use lesser_element::CommentBlock;
|
||||
pub use lesser_element::DiarySexp;
|
||||
pub use lesser_element::ExampleBlock;
|
||||
pub use lesser_element::ExportBlock;
|
||||
pub use lesser_element::FixedWidthArea;
|
||||
pub use lesser_element::HorizontalRule;
|
||||
pub use lesser_element::Keyword;
|
||||
pub use lesser_element::LatexEnvironment;
|
||||
pub use lesser_element::Paragraph;
|
||||
pub use lesser_element::Planning;
|
||||
pub use lesser_element::SrcBlock;
|
||||
pub use lesser_element::TableCell;
|
||||
pub use lesser_element::VerseBlock;
|
||||
pub use object::AngleLink;
|
||||
pub use object::Bold;
|
||||
pub use object::Citation;
|
||||
pub use object::CitationReference;
|
||||
pub use object::Code;
|
||||
pub use object::Entity;
|
||||
pub use object::ExportSnippet;
|
||||
pub use object::FootnoteReference;
|
||||
pub use object::InlineBabelCall;
|
||||
pub use object::InlineSourceBlock;
|
||||
pub use object::Italic;
|
||||
pub use object::LatexFragment;
|
||||
pub use object::LineBreak;
|
||||
pub use object::Object;
|
||||
pub use object::OrgMacro;
|
||||
pub use object::PlainLink;
|
||||
pub use object::PlainText;
|
||||
pub use object::RadioLink;
|
||||
pub use object::RadioTarget;
|
||||
pub use object::RegularLink;
|
||||
pub use object::StatisticsCookie;
|
||||
pub use object::StrikeThrough;
|
||||
pub use object::Subscript;
|
||||
pub use object::Superscript;
|
||||
pub use object::Target;
|
||||
pub use object::Timestamp;
|
||||
pub use object::Underline;
|
||||
pub use object::Verbatim;
|
||||
pub use source::Source;
|
||||
type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>;
|
||||
pub use document::parse;
|
||||
pub use org_source::OrgSource;
|
||||
|
@ -2,10 +2,10 @@ use nom::branch::alt;
|
||||
use nom::combinator::map;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::parser_with_context::parser_with_context;
|
||||
use super::plain_text::plain_text;
|
||||
use super::regular_link::regular_link;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::angle_link::angle_link;
|
||||
use crate::parser::citation::citation;
|
||||
@ -16,7 +16,6 @@ use crate::parser::inline_babel_call::inline_babel_call;
|
||||
use crate::parser::inline_source_block::inline_source_block;
|
||||
use crate::parser::latex_fragment::latex_fragment;
|
||||
use crate::parser::line_break::line_break;
|
||||
use crate::parser::object::Object;
|
||||
use crate::parser::org_macro::org_macro;
|
||||
use crate::parser::plain_link::plain_link;
|
||||
use crate::parser::radio_link::radio_link;
|
||||
@ -27,10 +26,11 @@ use crate::parser::subscript_and_superscript::superscript;
|
||||
use crate::parser::target::target;
|
||||
use crate::parser::text_markup::text_markup;
|
||||
use crate::parser::timestamp::timestamp;
|
||||
use crate::types::Object;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn standard_set_object<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn standard_set_object<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||
let (remaining, object) = alt((
|
||||
@ -87,8 +87,8 @@ pub fn standard_set_object<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn minimal_set_object<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn minimal_set_object<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||
let (remaining, object) = alt((
|
||||
@ -109,8 +109,8 @@ pub fn minimal_set_object<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn any_object_except_plain_text<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn any_object_except_plain_text<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||
let (remaining, object) = alt((
|
||||
@ -166,8 +166,8 @@ pub fn any_object_except_plain_text<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn regular_link_description_object_set<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn regular_link_description_object_set<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||
// TODO: It can also contain another link, but only when it is a plain or angle link. It can contain square brackets, but not ]]
|
||||
@ -195,8 +195,8 @@ pub fn regular_link_description_object_set<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn table_cell_set_object<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn table_cell_set_object<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||
let (remaining, object) = alt((
|
||||
|
@ -9,17 +9,17 @@ use nom::multi::separated_list0;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::object::OrgMacro;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::types::OrgMacro;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn org_macro<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn org_macro<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgMacro<'s>> {
|
||||
let (remaining, _) = tag("{{{")(input)?;
|
||||
@ -45,8 +45,8 @@ pub fn org_macro<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn org_macro_name<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn org_macro_name<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = verify(anychar, |c| c.is_alphabetic())(input)?;
|
||||
@ -58,8 +58,8 @@ fn org_macro_name<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn org_macro_args<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn org_macro_args<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<OrgSource<'s>>> {
|
||||
let (remaining, _) = tag("(")(input)?;
|
||||
@ -71,8 +71,8 @@ fn org_macro_args<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn org_macro_arg<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn org_macro_arg<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let mut remaining = input;
|
||||
|
@ -27,7 +27,7 @@ pub struct OrgSource<'s> {
|
||||
|
||||
impl<'s> std::fmt::Debug for OrgSource<'s> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("OrgSource")
|
||||
f.debug_tuple("Org")
|
||||
.field(&Into::<&str>::into(self))
|
||||
.finish()
|
||||
}
|
||||
|
@ -7,30 +7,30 @@ use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::element_parser::detect_element;
|
||||
use super::lesser_element::Paragraph;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::blank_line;
|
||||
use super::util::get_consumed;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object_parser::standard_set_object;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::types::Paragraph;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn paragraph<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn paragraph<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Paragraph<'s>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: ¶graph_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
|
||||
@ -53,8 +53,8 @@ pub fn paragraph<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn paragraph_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn paragraph_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let non_paragraph_element_matcher = parser_with_context!(detect_element(false))(context);
|
||||
@ -67,16 +67,21 @@ fn paragraph_end<'r, 's>(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::Context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::org_source::OrgSource;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::source::Source;
|
||||
use crate::types::Source;
|
||||
|
||||
#[test]
|
||||
fn two_paragraphs() {
|
||||
let input = OrgSource::new("foo bar baz\n\nlorem ipsum");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let paragraph_matcher = parser_with_context!(element(true))(&initial_context);
|
||||
let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph");
|
||||
let (remaining, second_paragraph) =
|
||||
|
@ -11,18 +11,18 @@ use nom::combinator::verify;
|
||||
use nom::multi::many_till;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object::PlainLink;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::WORD_CONSTITUENT_CHARACTERS;
|
||||
use crate::types::PlainLink;
|
||||
|
||||
// TODO: Make this a user-provided variable corresponding to elisp's org-link-parameters
|
||||
const ORG_LINK_PARAMETERS: [&'static str; 23] = [
|
||||
@ -52,8 +52,8 @@ const ORG_LINK_PARAMETERS: [&'static str; 23] = [
|
||||
];
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn plain_link<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn plain_link<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, PlainLink<'s>> {
|
||||
let (remaining, _) = pre(context, input)?;
|
||||
@ -73,7 +73,10 @@ pub fn plain_link<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
fn pre<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let preceding_character = input.get_preceding_character();
|
||||
match preceding_character {
|
||||
// If None, we are at the start of the file which is fine
|
||||
@ -90,14 +93,17 @@ fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn post<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
fn post<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let (remaining, _) = alt((eof, recognize(none_of(WORD_CONSTITUENT_CHARACTERS))))(input)?;
|
||||
Ok((remaining, ()))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn protocol<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn protocol<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
// TODO: This should be defined by org-link-parameters
|
||||
@ -117,16 +123,16 @@ pub fn protocol<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn path_plain<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn path_plain<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
// TODO: "optionally containing parenthesis-wrapped non-whitespace non-bracket substrings up to a depth of two. The string must end with either a non-punctation non-whitespace character, a forwards slash, or a parenthesis-wrapped substring"
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &path_plain_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
|
||||
@ -139,8 +145,8 @@ fn path_plain<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn path_plain_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn path_plain_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(many_till(
|
||||
|
@ -16,26 +16,27 @@ use nom::multi::many1;
|
||||
use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::greater_element::PlainList;
|
||||
use super::greater_element::PlainListItem;
|
||||
use super::element_parser::element;
|
||||
use super::object_parser::standard_set_object;
|
||||
use super::org_source::OrgSource;
|
||||
use super::parser_with_context::parser_with_context;
|
||||
use super::util::non_whitespace_character;
|
||||
use super::Context;
|
||||
use super::Object;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::util::blank_line;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::types::Object;
|
||||
use crate::types::PlainList;
|
||||
use crate::types::PlainListItem;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn detect_plain_list<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
@ -60,17 +61,22 @@ pub fn detect_plain_list<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn plain_list<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn plain_list<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, PlainList<'s>> {
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::Context("plain list"))
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::Context("plain list"),
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &plain_list_end,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
// children stores tuple of (input string, parsed object) so we can re-parse the final item
|
||||
let mut children = Vec::new();
|
||||
let mut first_item_indentation: Option<usize> = None;
|
||||
@ -112,8 +118,8 @@ pub fn plain_list<'r, 's>(
|
||||
))));
|
||||
}
|
||||
};
|
||||
let final_item_context =
|
||||
parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false));
|
||||
let final_item_context = ContextElement::ConsumeTrailingWhitespace(false);
|
||||
let final_item_context = parser_context.with_additional_node(&final_item_context);
|
||||
let (remaining, reparsed_final_item) =
|
||||
parser_with_context!(plain_list_item)(&final_item_context)(final_child_start)?;
|
||||
children.push((final_child_start, reparsed_final_item));
|
||||
@ -129,8 +135,8 @@ pub fn plain_list<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn plain_list_item<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn plain_list_item<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, PlainListItem<'s>> {
|
||||
start_of_line(input)?;
|
||||
@ -169,12 +175,15 @@ pub fn plain_list_item<'r, 's>(
|
||||
};
|
||||
let (remaining, _ws) = item_tag_post_gap(context, remaining)?;
|
||||
let exit_matcher = plain_list_item_end(indent_level);
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &exit_matcher,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
|
||||
let (mut remaining, (mut children, _exit_contents)) = many_till(
|
||||
include_input(parser_with_context!(element(true))(&parser_context)),
|
||||
@ -182,8 +191,8 @@ pub fn plain_list_item<'r, 's>(
|
||||
)(remaining)?;
|
||||
|
||||
if !children.is_empty() && !context.should_consume_trailing_whitespace() {
|
||||
let final_item_context =
|
||||
parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false));
|
||||
let final_item_context = ContextElement::ConsumeTrailingWhitespace(false);
|
||||
let final_item_context = parser_context.with_additional_node(&final_item_context);
|
||||
let (final_child_start, _original_final_child) = children
|
||||
.pop()
|
||||
.expect("if-statement already checked that children was non-empty.");
|
||||
@ -240,8 +249,8 @@ fn counter<'s>(i: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn plain_list_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn plain_list_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(tuple((
|
||||
@ -252,11 +261,9 @@ fn plain_list_end<'r, 's>(
|
||||
)))(input)
|
||||
}
|
||||
|
||||
const fn plain_list_item_end(
|
||||
indent_level: usize,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
const fn plain_list_item_end(indent_level: usize) -> impl ContextMatcher {
|
||||
let line_indented_lte_matcher = line_indented_lte(indent_level);
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
move |context, input: OrgSource<'_>| {
|
||||
_plain_list_item_end(context, input, &line_indented_lte_matcher)
|
||||
}
|
||||
}
|
||||
@ -265,13 +272,10 @@ const fn plain_list_item_end(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(line_indented_lte_matcher))
|
||||
)]
|
||||
fn _plain_list_item_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn _plain_list_item_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
line_indented_lte_matcher: impl for<'rr, 'ss> Fn(
|
||||
Context<'rr, 'ss>,
|
||||
OrgSource<'ss>,
|
||||
) -> Res<OrgSource<'ss>, OrgSource<'ss>>,
|
||||
line_indented_lte_matcher: impl ContextMatcher,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
recognize(tuple((
|
||||
@ -280,15 +284,13 @@ fn _plain_list_item_end<'r, 's>(
|
||||
)))(input)
|
||||
}
|
||||
|
||||
const fn line_indented_lte(
|
||||
indent_level: usize,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| _line_indented_lte(context, input, indent_level)
|
||||
const fn line_indented_lte(indent_level: usize) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _line_indented_lte(context, input, indent_level)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _line_indented_lte<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _line_indented_lte<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
indent_level: usize,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
@ -302,15 +304,15 @@ fn _line_indented_lte<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn item_tag<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn item_tag<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &item_tag_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
// TODO: Should this be using a different set like the minimal set?
|
||||
@ -323,8 +325,8 @@ fn item_tag<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn item_tag_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn item_tag_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(alt((
|
||||
@ -335,8 +337,8 @@ fn item_tag_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn item_tag_post_gap<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn item_tag_post_gap<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
verify(
|
||||
@ -358,14 +360,17 @@ fn item_tag_post_gap<'r, 's>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::Source;
|
||||
use crate::context::Context;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::types::Source;
|
||||
|
||||
#[test]
|
||||
fn plain_list_item_empty() {
|
||||
let input = OrgSource::new("1.");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_item_matcher = parser_with_context!(plain_list_item)(&initial_context);
|
||||
let (remaining, result) = plain_list_item_matcher(input).unwrap();
|
||||
assert_eq!(Into::<&str>::into(remaining), "");
|
||||
@ -375,7 +380,9 @@ mod tests {
|
||||
#[test]
|
||||
fn plain_list_item_simple() {
|
||||
let input = OrgSource::new("1. foo");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_item_matcher = parser_with_context!(plain_list_item)(&initial_context);
|
||||
let (remaining, result) = plain_list_item_matcher(input).unwrap();
|
||||
assert_eq!(Into::<&str>::into(remaining), "");
|
||||
@ -385,7 +392,9 @@ mod tests {
|
||||
#[test]
|
||||
fn plain_list_empty() {
|
||||
let input = OrgSource::new("1.");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_matcher = parser_with_context!(plain_list)(&initial_context);
|
||||
let (remaining, result) = plain_list_matcher(input).unwrap();
|
||||
assert_eq!(Into::<&str>::into(remaining), "");
|
||||
@ -395,7 +404,9 @@ mod tests {
|
||||
#[test]
|
||||
fn plain_list_simple() {
|
||||
let input = OrgSource::new("1. foo");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_matcher = parser_with_context!(plain_list)(&initial_context);
|
||||
let (remaining, result) = plain_list_matcher(input).unwrap();
|
||||
assert_eq!(Into::<&str>::into(remaining), "");
|
||||
@ -406,7 +417,9 @@ mod tests {
|
||||
fn plain_list_cant_start_line_with_asterisk() {
|
||||
// Plain lists with an asterisk bullet must be indented or else they would be a headline
|
||||
let input = OrgSource::new("* foo");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_matcher = parser_with_context!(plain_list)(&initial_context);
|
||||
let result = plain_list_matcher(input);
|
||||
assert!(result.is_err());
|
||||
@ -416,7 +429,9 @@ mod tests {
|
||||
fn indented_can_start_line_with_asterisk() {
|
||||
// Plain lists with an asterisk bullet must be indented or else they would be a headline
|
||||
let input = OrgSource::new(" * foo");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_matcher = parser_with_context!(plain_list)(&initial_context);
|
||||
let result = plain_list_matcher(input);
|
||||
assert!(result.is_ok());
|
||||
@ -434,7 +449,9 @@ mod tests {
|
||||
ipsum
|
||||
"#,
|
||||
);
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_matcher = parser_with_context!(element(true))(&initial_context);
|
||||
let (remaining, result) =
|
||||
plain_list_matcher(input).expect("Should parse the plain list successfully.");
|
||||
@ -460,7 +477,9 @@ mod tests {
|
||||
|
||||
baz"#,
|
||||
);
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_matcher = parser_with_context!(element(true))(&initial_context);
|
||||
let (remaining, result) =
|
||||
plain_list_matcher(input).expect("Should parse the plain list successfully.");
|
||||
@ -491,7 +510,9 @@ baz"#,
|
||||
|
||||
dolar"#,
|
||||
);
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_list_matcher = parser_with_context!(element(true))(&initial_context);
|
||||
let (remaining, result) =
|
||||
plain_list_matcher(input).expect("Should parse the plain list successfully.");
|
||||
|
@ -7,19 +7,19 @@ use nom::combinator::recognize;
|
||||
use nom::combinator::verify;
|
||||
use nom::multi::many_till;
|
||||
|
||||
use super::object::PlainText;
|
||||
use super::object_parser::any_object_except_plain_text;
|
||||
use super::org_source::OrgSource;
|
||||
use super::radio_link::RematchObject;
|
||||
use super::Context;
|
||||
use super::Object;
|
||||
use super::util::exit_matcher_parser;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::object_parser::any_object_except_plain_text;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::types::Object;
|
||||
use crate::types::PlainText;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn plain_text<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn plain_text<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, PlainText<'s>> {
|
||||
let (remaining, source) = recognize(verify(
|
||||
@ -42,8 +42,8 @@ pub fn plain_text<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn plain_text_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn plain_text_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(parser_with_context!(any_object_except_plain_text)(context))(input)
|
||||
@ -51,9 +51,9 @@ fn plain_text_end<'r, 's>(
|
||||
|
||||
impl<'x> RematchObject<'x> for PlainText<'x> {
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn rematch_object<'r, 's>(
|
||||
fn rematch_object<'b, 'g, 'r, 's>(
|
||||
&'x self,
|
||||
_context: Context<'r, 's>,
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||
map(tag(self.source), |s| {
|
||||
@ -69,14 +69,18 @@ mod tests {
|
||||
use nom::combinator::map;
|
||||
|
||||
use super::*;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::source::Source;
|
||||
use crate::context::Context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::types::Source;
|
||||
|
||||
#[test]
|
||||
fn plain_text_simple() {
|
||||
let input = OrgSource::new("foobarbaz");
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let plain_text_matcher = parser_with_context!(plain_text)(&initial_context);
|
||||
let (remaining, result) = map(plain_text_matcher, Object::PlainText)(input).unwrap();
|
||||
assert_eq!(Into::<&str>::into(remaining), "");
|
||||
|
@ -10,15 +10,15 @@ use nom::multi::separated_list1;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::lesser_element::Planning;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::types::Planning;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn planning<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn planning<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Planning<'s>> {
|
||||
start_of_line(input)?;
|
||||
|
@ -14,25 +14,25 @@ use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use super::util::exit_matcher_parser;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::greater_element::NodeProperty;
|
||||
use crate::parser::greater_element::PropertyDrawer;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::immediate_in_section;
|
||||
use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::types::NodeProperty;
|
||||
use crate::types::PropertyDrawer;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn property_drawer<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn property_drawer<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, PropertyDrawer<'s>> {
|
||||
if immediate_in_section(context, "property-drawer") {
|
||||
@ -51,13 +51,17 @@ pub fn property_drawer<'r, 's>(
|
||||
line_ending,
|
||||
))(input)?;
|
||||
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("property-drawer"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("property-drawer"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Alpha,
|
||||
exit_matcher: &property_drawer_end,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
|
||||
let node_property_matcher = parser_with_context!(node_property)(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
@ -79,8 +83,8 @@ pub fn property_drawer<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn property_drawer_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn property_drawer_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(tuple((
|
||||
@ -93,8 +97,8 @@ fn property_drawer_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn node_property<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn node_property<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, NodeProperty<'s>> {
|
||||
let (remaining, (_start_of_line, _leading_whitespace, _open_colon, _name, _close_colon)) =
|
||||
@ -136,15 +140,15 @@ fn node_property<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn node_property_name<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn node_property_name<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &node_property_name_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, name) = recognize(tuple((
|
||||
verify(
|
||||
@ -161,8 +165,8 @@ fn node_property_name<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn node_property_name_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn node_property_name_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alt((tag("+:"), tag(":")))(input)
|
||||
|
@ -5,31 +5,31 @@ use nom::character::complete::space0;
|
||||
use nom::combinator::verify;
|
||||
use nom::multi::many_till;
|
||||
|
||||
use super::object_parser::minimal_set_object;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::exit_matcher_parser;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use super::Object;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object_parser::minimal_set_object;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::RadioLink;
|
||||
use crate::parser::RadioTarget;
|
||||
use crate::types::Object;
|
||||
use crate::types::RadioLink;
|
||||
use crate::types::RadioTarget;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn radio_link<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn radio_link<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, RadioLink<'s>> {
|
||||
let radio_targets = context
|
||||
.iter()
|
||||
.filter_map(|context_element| match context_element.get_data() {
|
||||
.filter_map(|context_element| match context_element {
|
||||
ContextElement::RadioTarget(targets) => Some(targets),
|
||||
_ => None,
|
||||
})
|
||||
@ -54,8 +54,8 @@ pub fn radio_link<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn rematch_target<'x, 'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn rematch_target<'x, 'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
target: &'x Vec<Object<'x>>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
@ -85,16 +85,16 @@ pub fn rematch_target<'x, 'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn radio_target<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn radio_target<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, RadioTarget<'s>> {
|
||||
let (remaining, _opening) = tag("<<<")(input)?;
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &radio_target_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
@ -118,17 +118,17 @@ pub fn radio_target<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn radio_target_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn radio_target_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alt((tag("<"), tag(">"), line_ending))(input)
|
||||
}
|
||||
|
||||
pub trait RematchObject<'x> {
|
||||
fn rematch_object<'r, 's>(
|
||||
fn rematch_object<'b, 'g, 'r, 's>(
|
||||
&'x self,
|
||||
context: Context<'r, 's>,
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>>;
|
||||
}
|
||||
@ -136,25 +136,28 @@ pub trait RematchObject<'x> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::context::Context;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::source::Source;
|
||||
use crate::parser::Bold;
|
||||
use crate::parser::PlainText;
|
||||
use crate::types::Bold;
|
||||
use crate::types::Element;
|
||||
use crate::types::PlainText;
|
||||
use crate::types::Source;
|
||||
|
||||
#[test]
|
||||
fn plain_text_radio_target() {
|
||||
let input = OrgSource::new("foo bar baz");
|
||||
let radio_target_match = vec![Object::PlainText(PlainText { source: "bar" })];
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let document_context = initial_context
|
||||
.with_additional_node(ContextElement::RadioTarget(vec![&radio_target_match]));
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let document_context = ContextElement::RadioTarget(vec![&radio_target_match]);
|
||||
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 first_paragraph = match first_paragraph {
|
||||
crate::parser::Element::Paragraph(paragraph) => paragraph,
|
||||
Element::Paragraph(paragraph) => paragraph,
|
||||
_ => panic!("Should be a paragraph!"),
|
||||
};
|
||||
assert_eq!(Into::<&str>::into(remaining), "");
|
||||
@ -179,14 +182,16 @@ mod tests {
|
||||
source: "*bar*",
|
||||
children: vec![Object::PlainText(PlainText { source: "bar" })],
|
||||
})];
|
||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||
let document_context = initial_context
|
||||
.with_additional_node(ContextElement::RadioTarget(vec![&radio_target_match]));
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let document_context = ContextElement::RadioTarget(vec![&radio_target_match]);
|
||||
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.into()).expect("Parse first paragraph");
|
||||
let first_paragraph = match first_paragraph {
|
||||
crate::parser::Element::Paragraph(paragraph) => paragraph,
|
||||
Element::Paragraph(paragraph) => paragraph,
|
||||
_ => panic!("Should be a paragraph!"),
|
||||
};
|
||||
assert_eq!(Into::<&str>::into(remaining), "");
|
||||
|
@ -6,23 +6,23 @@ use nom::character::complete::one_of;
|
||||
use nom::combinator::verify;
|
||||
use nom::multi::many_till;
|
||||
|
||||
use super::object_parser::regular_link_description_object_set;
|
||||
use super::org_source::OrgSource;
|
||||
use super::parser_with_context::parser_with_context;
|
||||
use super::util::exit_matcher_parser;
|
||||
use super::util::get_consumed;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use super::Object;
|
||||
use super::RegularLink;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object_parser::regular_link_description_object_set;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::types::Object;
|
||||
use crate::types::RegularLink;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn regular_link<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn regular_link<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, RegularLink<'s>> {
|
||||
alt((
|
||||
@ -32,8 +32,8 @@ pub fn regular_link<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn regular_link_without_description<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn regular_link_without_description<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, RegularLink<'s>> {
|
||||
let (remaining, _opening_bracket) = tag("[[")(input)?;
|
||||
@ -51,8 +51,8 @@ pub fn regular_link_without_description<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn regular_link_with_description<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn regular_link_with_description<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, RegularLink<'s>> {
|
||||
let (remaining, _opening_bracket) = tag("[[")(input)?;
|
||||
@ -72,8 +72,8 @@ pub fn regular_link_with_description<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn pathreg<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn pathreg<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, path) = escaped(
|
||||
@ -88,15 +88,15 @@ pub fn pathreg<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn description<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn description<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &description_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
parser_with_context!(regular_link_description_object_set)(&parser_context),
|
||||
@ -109,8 +109,8 @@ pub fn description<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn description_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn description_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
tag("]]")(input)
|
||||
|
@ -5,14 +5,14 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::StatisticsCookie;
|
||||
use crate::types::StatisticsCookie;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn statistics_cookie<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn statistics_cookie<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, StatisticsCookie<'s>> {
|
||||
alt((
|
||||
@ -22,8 +22,8 @@ pub fn statistics_cookie<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn percent_statistics_cookie<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn percent_statistics_cookie<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, StatisticsCookie<'s>> {
|
||||
let (remaining, source) =
|
||||
@ -39,8 +39,8 @@ pub fn percent_statistics_cookie<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn fraction_statistics_cookie<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn fraction_statistics_cookie<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, StatisticsCookie<'s>> {
|
||||
let (remaining, source) = recognize(tuple((
|
||||
|
@ -10,27 +10,28 @@ use nom::combinator::recognize;
|
||||
use nom::combinator::verify;
|
||||
use nom::multi::many_till;
|
||||
|
||||
use super::object_parser::standard_set_object;
|
||||
use super::org_source::BracketDepth;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::exit_matcher_parser;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use super::Object;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object_parser::standard_set_object;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::Subscript;
|
||||
use crate::parser::Superscript;
|
||||
use crate::types::Object;
|
||||
use crate::types::Subscript;
|
||||
use crate::types::Superscript;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn subscript<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn subscript<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Subscript<'s>> {
|
||||
// We check for the underscore first before checking the pre-character as a minor optimization to avoid walking up the context tree to find the document root unnecessarily.
|
||||
@ -49,8 +50,8 @@ pub fn subscript<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn superscript<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn superscript<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Superscript<'s>> {
|
||||
// We check for the circumflex first before checking the pre-character as a minor optimization to avoid walking up the context tree to find the document root unnecessarily.
|
||||
@ -69,7 +70,10 @@ pub fn superscript<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
fn pre<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let preceding_character = input.get_preceding_character();
|
||||
match preceding_character {
|
||||
Some(c) if !c.is_whitespace() => {}
|
||||
@ -89,8 +93,8 @@ enum ScriptBody<'s> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn script_body<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn script_body<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ScriptBody<'s>> {
|
||||
alt((
|
||||
@ -107,16 +111,16 @@ fn script_body<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn script_asterisk<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn script_asterisk<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
tag("*")(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn script_alphanum<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn script_alphanum<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _sign) = opt(recognize(one_of("+-")))(input)?;
|
||||
@ -129,8 +133,8 @@ fn script_alphanum<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn script_alphanum_character<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn script_alphanum_character<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(verify(anychar, |c| {
|
||||
@ -139,8 +143,8 @@ fn script_alphanum_character<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn end_script_alphanum_character<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn end_script_alphanum_character<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, final_char) = recognize(verify(anychar, |c| c.is_alphanumeric()))(input)?;
|
||||
@ -151,17 +155,17 @@ fn end_script_alphanum_character<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn script_with_braces<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn script_with_braces<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
let (remaining, _) = tag("{")(input)?;
|
||||
let exit_with_depth = script_with_braces_end(remaining.get_brace_depth());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &exit_with_depth,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, (children, _exit_contents)) = many_till(
|
||||
parser_with_context!(standard_set_object)(&parser_context),
|
||||
@ -172,17 +176,15 @@ fn script_with_braces<'r, 's>(
|
||||
Ok((remaining, children))
|
||||
}
|
||||
|
||||
fn script_with_braces_end(
|
||||
starting_brace_depth: BracketDepth,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
fn script_with_braces_end(starting_brace_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| {
|
||||
_script_with_braces_end(context, input, starting_brace_depth)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _script_with_braces_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn _script_with_braces_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
starting_brace_depth: BracketDepth,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
|
@ -14,37 +14,41 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::object_parser::table_cell_set_object;
|
||||
use super::org_source::OrgSource;
|
||||
use super::Context;
|
||||
use super::util::exit_matcher_parser;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::greater_element::TableRow;
|
||||
use crate::parser::lesser_element::TableCell;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::start_of_line;
|
||||
use crate::parser::Table;
|
||||
use crate::types::Table;
|
||||
use crate::types::TableCell;
|
||||
use crate::types::TableRow;
|
||||
|
||||
/// Parse an org-mode-style table
|
||||
///
|
||||
/// This is not the table.el style.
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn org_mode_table<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn org_mode_table<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Table<'s>> {
|
||||
start_of_line(input)?;
|
||||
peek(tuple((space0, tag("|"))))(input)?;
|
||||
|
||||
let parser_context = context
|
||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||
.with_additional_node(ContextElement::Context("table"))
|
||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("table"),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Alpha,
|
||||
exit_matcher: &table_end,
|
||||
}));
|
||||
}),
|
||||
];
|
||||
let parser_context = context.with_additional_node(&contexts[0]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
|
||||
let org_mode_table_row_matcher = parser_with_context!(org_mode_table_row)(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
@ -65,8 +69,8 @@ pub fn org_mode_table<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn table_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn table_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
start_of_line(input)?;
|
||||
@ -74,8 +78,8 @@ fn table_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn org_mode_table_row<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn org_mode_table_row<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
||||
alt((
|
||||
@ -85,8 +89,8 @@ pub fn org_mode_table_row<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn org_mode_table_row_rule<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
pub fn org_mode_table_row_rule<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
||||
start_of_line(input)?;
|
||||
@ -102,8 +106,8 @@ pub fn org_mode_table_row_rule<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn org_mode_table_row_regular<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn org_mode_table_row_regular<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
||||
start_of_line(input)?;
|
||||
@ -122,15 +126,15 @@ pub fn org_mode_table_row_regular<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn org_mode_table_cell<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn org_mode_table_cell<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, TableCell<'s>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &org_mode_table_cell_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let table_cell_set_object_matcher =
|
||||
parser_with_context!(table_cell_set_object)(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
@ -155,8 +159,8 @@ pub fn org_mode_table_cell<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn org_mode_table_cell_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn org_mode_table_cell_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(tuple((space0, alt((tag("|"), peek(line_ending))))))(input)
|
||||
|
@ -7,22 +7,22 @@ use nom::combinator::verify;
|
||||
use nom::multi::many_till;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::exit_matcher_parser;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::Target;
|
||||
use crate::types::Target;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn target<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn target<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Target<'s>> {
|
||||
let (remaining, _) = tag("<<")(input)?;
|
||||
@ -30,11 +30,11 @@ pub fn target<'r, 's>(
|
||||
!c.is_whitespace() && !"<>\n".contains(*c)
|
||||
}))(remaining)?;
|
||||
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Beta,
|
||||
exit_matcher: &target_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
let (remaining, _body) = recognize(many_till(
|
||||
anychar,
|
||||
parser_with_context!(exit_matcher_parser)(&parser_context),
|
||||
@ -62,8 +62,8 @@ pub fn target<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn target_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn target_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(one_of("<>\n"))(input)
|
||||
|
@ -15,33 +15,34 @@ use nom::sequence::terminated;
|
||||
#[cfg(feature = "tracing")]
|
||||
use tracing::span;
|
||||
|
||||
use super::object_parser::standard_set_object;
|
||||
use super::org_source::OrgSource;
|
||||
use super::radio_link::RematchObject;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::object_parser::standard_set_object;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::radio_link::rematch_target;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::preceded_by_whitespace;
|
||||
use crate::parser::Bold;
|
||||
use crate::parser::Code;
|
||||
use crate::parser::Italic;
|
||||
use crate::parser::Object;
|
||||
use crate::parser::StrikeThrough;
|
||||
use crate::parser::Underline;
|
||||
use crate::parser::Verbatim;
|
||||
use crate::types::Bold;
|
||||
use crate::types::Code;
|
||||
use crate::types::Italic;
|
||||
use crate::types::Object;
|
||||
use crate::types::StrikeThrough;
|
||||
use crate::types::Underline;
|
||||
use crate::types::Verbatim;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn text_markup<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn text_markup<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||
alt((
|
||||
@ -58,8 +59,8 @@ pub fn text_markup<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn bold<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn bold<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Bold<'s>> {
|
||||
let text_markup_object_specialized = text_markup_object("*");
|
||||
@ -75,8 +76,8 @@ pub fn bold<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn italic<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn italic<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Italic<'s>> {
|
||||
let text_markup_object_specialized = text_markup_object("/");
|
||||
@ -92,8 +93,8 @@ pub fn italic<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn underline<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn underline<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Underline<'s>> {
|
||||
let text_markup_object_specialized = text_markup_object("_");
|
||||
@ -109,8 +110,8 @@ pub fn underline<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn strike_through<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn strike_through<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, StrikeThrough<'s>> {
|
||||
let text_markup_object_specialized = text_markup_object("+");
|
||||
@ -126,8 +127,8 @@ pub fn strike_through<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn verbatim<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn verbatim<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Verbatim<'s>> {
|
||||
let text_markup_string_specialized = text_markup_string("=");
|
||||
@ -143,8 +144,8 @@ pub fn verbatim<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn code<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn code<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Code<'s>> {
|
||||
let text_markup_string_specialized = text_markup_string("~");
|
||||
@ -159,30 +160,32 @@ pub fn code<'r, 's>(
|
||||
))
|
||||
}
|
||||
|
||||
fn text_markup_object(
|
||||
marker_symbol: &str,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
fn text_markup_object<'c>(
|
||||
marker_symbol: &'c str,
|
||||
) -> impl for<'b, 'g, 'r, 's> Fn(
|
||||
RefContext<'b, 'g, 'r, 's>,
|
||||
OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>>
|
||||
+ 'c {
|
||||
let marker_symbol = marker_symbol.to_owned();
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
_text_markup_object(context, input, marker_symbol.as_str())
|
||||
}
|
||||
move |context, input: OrgSource<'_>| _text_markup_object(context, input, marker_symbol.as_str())
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _text_markup_object<'r, 's, 'x>(
|
||||
context: Context<'r, 's>,
|
||||
fn _text_markup_object<'b, 'g, 'r, 's, 'c>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
marker_symbol: &'x str,
|
||||
marker_symbol: &'c str,
|
||||
) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
||||
let (remaining, _) = pre(context, input)?;
|
||||
let (remaining, open) = tag(marker_symbol)(remaining)?;
|
||||
let (remaining, _peek_not_whitespace) = peek(not(multispace1))(remaining)?;
|
||||
let text_markup_end_specialized = text_markup_end(open.into());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &text_markup_end_specialized,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(
|
||||
@ -210,30 +213,31 @@ fn _text_markup_object<'r, 's, 'x>(
|
||||
Ok((remaining, children))
|
||||
}
|
||||
|
||||
fn text_markup_string(
|
||||
marker_symbol: &str,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let marker_symbol = marker_symbol.to_owned();
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
_text_markup_string(context, input, marker_symbol.as_str())
|
||||
}
|
||||
fn text_markup_string<'c>(
|
||||
marker_symbol: &'c str,
|
||||
) -> impl for<'b, 'g, 'r, 's> Fn(
|
||||
RefContext<'b, 'g, 'r, 's>,
|
||||
OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>>
|
||||
+ 'c {
|
||||
move |context, input: OrgSource<'_>| _text_markup_string(context, input, marker_symbol)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _text_markup_string<'r, 's, 'x>(
|
||||
context: Context<'r, 's>,
|
||||
fn _text_markup_string<'b, 'g, 'r, 's, 'c>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
marker_symbol: &'x str,
|
||||
marker_symbol: &'c str,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = pre(context, input)?;
|
||||
let (remaining, open) = tag(marker_symbol)(remaining)?;
|
||||
let (remaining, _peek_not_whitespace) = peek(not(multispace1))(remaining)?;
|
||||
let text_markup_end_specialized = text_markup_end(open.into());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &text_markup_end_specialized,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, contents) = recognize(verify(
|
||||
many_till(
|
||||
@ -262,7 +266,10 @@ fn _text_markup_string<'r, 's, 'x>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
pub fn pre<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let preceding_character = input.get_preceding_character();
|
||||
match preceding_character {
|
||||
// If None, we are at the start of the file which is technically the beginning of a line.
|
||||
@ -279,25 +286,23 @@ pub fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSo
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn post<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
pub fn post<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let (remaining, _) = alt((recognize(one_of(" \r\n\t-.,;:!?')}[\"")), line_ending))(input)?;
|
||||
Ok((remaining, ()))
|
||||
}
|
||||
|
||||
fn text_markup_end(
|
||||
marker_symbol: &str,
|
||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let marker_symbol = marker_symbol.to_owned();
|
||||
move |context: Context, input: OrgSource<'_>| {
|
||||
_text_markup_end(context, input, marker_symbol.as_str())
|
||||
}
|
||||
fn text_markup_end<'c>(marker_symbol: &'c str) -> impl ContextMatcher + 'c {
|
||||
move |context, input: OrgSource<'_>| _text_markup_end(context, input, marker_symbol)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _text_markup_end<'r, 's, 'x>(
|
||||
context: Context<'r, 's>,
|
||||
fn _text_markup_end<'b, 'g, 'r, 's, 'c>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
marker_symbol: &'x str,
|
||||
marker_symbol: &'c str,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
not(preceded_by_whitespace)(input)?;
|
||||
let (remaining, _marker) = terminated(
|
||||
@ -310,9 +315,9 @@ fn _text_markup_end<'r, 's, 'x>(
|
||||
|
||||
impl<'x> RematchObject<'x> for Bold<'x> {
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn rematch_object<'r, 's>(
|
||||
fn rematch_object<'b, 'g, 'r, 's>(
|
||||
&'x self,
|
||||
_context: Context<'r, 's>,
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||
let (remaining, children) =
|
||||
@ -329,8 +334,8 @@ impl<'x> RematchObject<'x> for Bold<'x> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _rematch_text_markup_object<'r, 's, 'x>(
|
||||
context: Context<'r, 's>,
|
||||
fn _rematch_text_markup_object<'b, 'g, 'r, 's, 'x>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
marker_symbol: &'static str,
|
||||
original_match_children: &'x Vec<Object<'x>>,
|
||||
@ -339,11 +344,11 @@ fn _rematch_text_markup_object<'r, 's, 'x>(
|
||||
let (remaining, open) = tag(marker_symbol)(remaining)?;
|
||||
let (remaining, _peek_not_whitespace) = peek(not(multispace1))(remaining)?;
|
||||
let text_markup_end_specialized = text_markup_end(open.into());
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &text_markup_end_specialized,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, children) =
|
||||
// TODO: This doesn't really check the exit matcher between each object. I think it may be possible to construct an org document that parses incorrectly with the current code.
|
||||
|
@ -11,21 +11,20 @@ use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::exit_matcher_parser;
|
||||
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
use crate::context::ExitMatcherNode;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::exiting::ExitClass;
|
||||
use crate::parser::parser_context::ContextElement;
|
||||
use crate::parser::parser_context::ContextTree;
|
||||
use crate::parser::parser_context::ExitMatcherNode;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
use crate::parser::util::exit_matcher_parser;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::Timestamp;
|
||||
use crate::types::Timestamp;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn timestamp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||
// TODO: This would be more efficient if we didn't throw away the parse result of the first half of an active/inactive date range timestamp if the parse fails (as in, the first thing active_date_range_timestamp parses is a active_timestamp but then we throw that away if it doesn't turn out to be a full active_date_range_timestamp despite the active_timestamp parse being completely valid). I am going with the simplest/cleanest approach for the first implementation.
|
||||
@ -42,8 +41,8 @@ pub fn timestamp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn diary_timestamp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn diary_timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||
let (remaining, _) = tag("<%%(")(input)?;
|
||||
@ -62,15 +61,15 @@ fn diary_timestamp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn sexp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn sexp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &sexp_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, body) = recognize(verify(
|
||||
many_till(
|
||||
@ -84,25 +83,25 @@ fn sexp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn sexp_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn sexp_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alt((tag(")>"), recognize(one_of(">\n"))))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn active_timestamp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn active_timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||
let (remaining, _) = tag("<")(input)?;
|
||||
let (remaining, _date) = date(context, remaining)?;
|
||||
let time_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let time_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &active_time_rest_end,
|
||||
}));
|
||||
});
|
||||
let time_context = context.with_additional_node(&time_context);
|
||||
let (remaining, _time) =
|
||||
opt(tuple((space1, parser_with_context!(time)(&time_context))))(remaining)?;
|
||||
let (remaining, _repeater) =
|
||||
@ -126,17 +125,17 @@ fn active_timestamp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn inactive_timestamp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn inactive_timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||
let (remaining, _) = tag("[")(input)?;
|
||||
let (remaining, _date) = date(context, remaining)?;
|
||||
let time_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let time_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &inactive_time_rest_end,
|
||||
}));
|
||||
});
|
||||
let time_context = context.with_additional_node(&time_context);
|
||||
let (remaining, _time) =
|
||||
opt(tuple((space1, parser_with_context!(time)(&time_context))))(remaining)?;
|
||||
let (remaining, _repeater) =
|
||||
@ -160,8 +159,8 @@ fn inactive_timestamp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn active_date_range_timestamp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn active_date_range_timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||
let (remaining, _first_timestamp) = active_timestamp(context, input)?;
|
||||
@ -182,22 +181,22 @@ fn active_date_range_timestamp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn active_time_range_timestamp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn active_time_range_timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||
let (remaining, _) = tag("<")(input)?;
|
||||
let (remaining, _date) = date(context, remaining)?;
|
||||
let time_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let time_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &active_time_rest_end,
|
||||
}));
|
||||
let first_time_context =
|
||||
time_context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
});
|
||||
let time_context = context.with_additional_node(&time_context);
|
||||
let first_time_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &time_range_rest_end,
|
||||
}));
|
||||
});
|
||||
let first_time_context = time_context.with_additional_node(&first_time_context);
|
||||
let (remaining, _first_time) =
|
||||
tuple((space1, parser_with_context!(time)(&first_time_context)))(remaining)?;
|
||||
let (remaining, _) = tag("-")(remaining)?;
|
||||
@ -223,8 +222,8 @@ fn active_time_range_timestamp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn inactive_date_range_timestamp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn inactive_date_range_timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||
let (remaining, _first_timestamp) = inactive_timestamp(context, input)?;
|
||||
@ -245,22 +244,22 @@ fn inactive_date_range_timestamp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn inactive_time_range_timestamp<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn inactive_time_range_timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||
let (remaining, _) = tag("[")(input)?;
|
||||
let (remaining, _date) = date(context, remaining)?;
|
||||
let time_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let time_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &inactive_time_rest_end,
|
||||
}));
|
||||
let first_time_context =
|
||||
time_context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
});
|
||||
let time_context = context.with_additional_node(&time_context);
|
||||
let first_time_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &time_range_rest_end,
|
||||
}));
|
||||
});
|
||||
let first_time_context = time_context.with_additional_node(&first_time_context);
|
||||
let (remaining, _first_time) =
|
||||
tuple((space1, parser_with_context!(time)(&first_time_context)))(remaining)?;
|
||||
let (remaining, _) = tag("-")(remaining)?;
|
||||
@ -286,8 +285,8 @@ fn inactive_time_range_timestamp<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn date<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn date<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _year) = verify(digit1, |year: &OrgSource<'_>| year.len() == 4)(input)?;
|
||||
@ -304,15 +303,15 @@ fn date<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn dayname<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn dayname<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let parser_context =
|
||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
class: ExitClass::Gamma,
|
||||
exit_matcher: &dayname_end,
|
||||
}));
|
||||
});
|
||||
let parser_context = context.with_additional_node(&parser_context);
|
||||
|
||||
let (remaining, body) = recognize(verify(
|
||||
many_till(
|
||||
@ -326,8 +325,8 @@ fn dayname<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn dayname_end<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn dayname_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(verify(anychar, |c| {
|
||||
@ -336,8 +335,8 @@ fn dayname_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn time<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn time<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _hour) = verify(digit1, |hour: &OrgSource<'_>| {
|
||||
@ -352,8 +351,8 @@ fn time<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn time_rest<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn time_rest<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, body) = recognize(verify(
|
||||
@ -365,8 +364,8 @@ fn time_rest<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn active_time_rest_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn active_time_rest_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alt((
|
||||
@ -380,8 +379,8 @@ fn active_time_rest_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn inactive_time_rest_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn inactive_time_rest_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alt((
|
||||
@ -395,21 +394,20 @@ fn inactive_time_rest_end<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn time_range_rest_end<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
fn time_range_rest_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
// We pop off the most recent context element to get a context tree with just the active/inactive_time_rest_end exit matcher (removing this function from the exit matcher chain) because the 2nd time in the range does not end when a "-TIME" pattern is found.
|
||||
let parent_node = context.iter().next().expect("Two context elements are added to the tree when adding this exit matcher, so it should be impossible for this to return None.");
|
||||
let parent_tree = ContextTree::branch_from(parent_node);
|
||||
let parent_node = context.get_parent().expect("Two context elements are added to the tree when adding this exit matcher, so it should be impossible for this to return None.");
|
||||
let exit_contents =
|
||||
recognize(tuple((tag("-"), parser_with_context!(time)(&parent_tree))))(input);
|
||||
recognize(tuple((tag("-"), parser_with_context!(time)(&parent_node))))(input);
|
||||
exit_contents
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn repeater<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn repeater<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
// + for cumulative type
|
||||
@ -424,8 +422,8 @@ fn repeater<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn warning_delay<'r, 's>(
|
||||
_context: Context<'r, 's>,
|
||||
fn warning_delay<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
// - for all type
|
||||
|
@ -1,14 +1,14 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use super::Document;
|
||||
use super::Element;
|
||||
use super::Heading;
|
||||
use super::Object;
|
||||
use super::PlainListItem;
|
||||
use super::Section;
|
||||
use super::TableCell;
|
||||
use super::TableRow;
|
||||
use crate::parser::DocumentElement;
|
||||
use crate::types::Document;
|
||||
use crate::types::DocumentElement;
|
||||
use crate::types::Element;
|
||||
use crate::types::Heading;
|
||||
use crate::types::Object;
|
||||
use crate::types::PlainListItem;
|
||||
use crate::types::Section;
|
||||
use crate::types::TableCell;
|
||||
use crate::types::TableRow;
|
||||
|
||||
pub enum Token<'r, 's> {
|
||||
Document(&'r Document<'s>),
|
||||
|
@ -14,21 +14,24 @@ use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::parser_context::ContextElement;
|
||||
use super::Context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::parser_with_context::parser_with_context;
|
||||
|
||||
pub const WORD_CONSTITUENT_CHARACTERS: &str =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
/// Check if we are below a section of the given section type regardless of depth
|
||||
#[allow(dead_code)]
|
||||
pub fn in_section<'r, 's, 'x>(context: Context<'r, 's>, section_name: &'x str) -> bool {
|
||||
pub fn in_section<'b, 'g, 'r, 's, 'x>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
section_name: &'x str,
|
||||
) -> bool {
|
||||
for thing in context.iter() {
|
||||
match thing.get_data() {
|
||||
match thing {
|
||||
ContextElement::Context(name) if *name == section_name => return true,
|
||||
_ => {}
|
||||
}
|
||||
@ -37,9 +40,12 @@ pub fn in_section<'r, 's, 'x>(context: Context<'r, 's>, section_name: &'x str) -
|
||||
}
|
||||
|
||||
/// Checks if we are currently an immediate child of the given section type
|
||||
pub fn immediate_in_section<'r, 's, 'x>(context: Context<'r, 's>, section_name: &'x str) -> bool {
|
||||
pub fn immediate_in_section<'b, 'g, 'r, 's, 'x>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
section_name: &'x str,
|
||||
) -> bool {
|
||||
for thing in context.iter() {
|
||||
match thing.get_data() {
|
||||
match thing {
|
||||
ContextElement::Context(name) if *name == section_name => return true,
|
||||
ContextElement::Context(name) if *name != section_name => return false,
|
||||
_ => {}
|
||||
@ -69,8 +75,8 @@ pub fn element_trailing_whitespace<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn maybe_consume_object_trailing_whitespace_if_not_exiting<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn maybe_consume_object_trailing_whitespace_if_not_exiting<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
||||
if exit_matcher_parser(context, input).is_err() {
|
||||
@ -81,8 +87,8 @@ pub fn maybe_consume_object_trailing_whitespace_if_not_exiting<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn maybe_consume_trailing_whitespace_if_not_exiting<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn maybe_consume_trailing_whitespace_if_not_exiting<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
||||
if context.should_consume_trailing_whitespace() && exit_matcher_parser(context, input).is_err()
|
||||
@ -94,8 +100,8 @@ pub fn maybe_consume_trailing_whitespace_if_not_exiting<'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn maybe_consume_trailing_whitespace<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn maybe_consume_trailing_whitespace<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
||||
if context.should_consume_trailing_whitespace() {
|
||||
@ -143,16 +149,16 @@ pub fn non_whitespace_character(input: OrgSource<'_>) -> Res<OrgSource<'_>, char
|
||||
|
||||
/// Check that we are at the start of a line
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn exit_matcher_parser<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn exit_matcher_parser<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
peek(|i| context.check_exit_matcher(i))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn text_until_exit<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
pub fn text_until_exit<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
recognize(verify(
|
||||
|
60
src/types/document.rs
Normal file
60
src/types/document.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use super::Element;
|
||||
use super::Object;
|
||||
use super::Source;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Document<'s> {
|
||||
pub source: &'s str,
|
||||
pub zeroth_section: Option<Section<'s>>,
|
||||
pub children: Vec<Heading<'s>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Heading<'s> {
|
||||
pub source: &'s str,
|
||||
pub stars: usize,
|
||||
pub todo_keyword: Option<&'s str>,
|
||||
// TODO: add todo-type enum
|
||||
pub title: Vec<Object<'s>>,
|
||||
pub tags: Vec<&'s str>,
|
||||
pub children: Vec<DocumentElement<'s>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Section<'s> {
|
||||
pub source: &'s str,
|
||||
pub children: Vec<Element<'s>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DocumentElement<'s> {
|
||||
Heading(Heading<'s>),
|
||||
Section(Section<'s>),
|
||||
}
|
||||
|
||||
impl<'s> Source<'s> for Document<'s> {
|
||||
fn get_source(&'s self) -> &'s str {
|
||||
self.source
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Source<'s> for DocumentElement<'s> {
|
||||
fn get_source(&'s self) -> &'s str {
|
||||
match self {
|
||||
DocumentElement::Heading(obj) => obj.source,
|
||||
DocumentElement::Section(obj) => obj.source,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Source<'s> for Section<'s> {
|
||||
fn get_source(&'s self) -> &'s str {
|
||||
self.source
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Source<'s> for Heading<'s> {
|
||||
fn get_source(&'s self) -> &'s str {
|
||||
self.source
|
||||
}
|
||||
}
|
@ -18,9 +18,9 @@ use super::lesser_element::Paragraph;
|
||||
use super::lesser_element::Planning;
|
||||
use super::lesser_element::SrcBlock;
|
||||
use super::lesser_element::VerseBlock;
|
||||
use super::source::SetSource;
|
||||
use super::source::Source;
|
||||
use super::Drawer;
|
||||
use super::SetSource;
|
||||
use super::Source;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Element<'s> {
|
@ -1,7 +1,7 @@
|
||||
use super::element::Element;
|
||||
use super::lesser_element::TableCell;
|
||||
use super::source::Source;
|
||||
use super::Object;
|
||||
use super::Source;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PlainList<'s> {
|
@ -1,6 +1,6 @@
|
||||
use super::object::Object;
|
||||
use super::source::Source;
|
||||
use super::PlainText;
|
||||
use super::Source;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Paragraph<'s> {
|
66
src/types/mod.rs
Normal file
66
src/types/mod.rs
Normal file
@ -0,0 +1,66 @@
|
||||
mod document;
|
||||
mod element;
|
||||
mod greater_element;
|
||||
mod lesser_element;
|
||||
mod object;
|
||||
mod source;
|
||||
pub use document::Document;
|
||||
pub use document::DocumentElement;
|
||||
pub use document::Heading;
|
||||
pub use document::Section;
|
||||
pub use element::Element;
|
||||
pub use greater_element::Drawer;
|
||||
pub use greater_element::DynamicBlock;
|
||||
pub use greater_element::FootnoteDefinition;
|
||||
pub use greater_element::GreaterBlock;
|
||||
pub use greater_element::NodeProperty;
|
||||
pub use greater_element::PlainList;
|
||||
pub use greater_element::PlainListItem;
|
||||
pub use greater_element::PropertyDrawer;
|
||||
pub use greater_element::Table;
|
||||
pub use greater_element::TableRow;
|
||||
pub use lesser_element::Clock;
|
||||
pub use lesser_element::Comment;
|
||||
pub use lesser_element::CommentBlock;
|
||||
pub use lesser_element::DiarySexp;
|
||||
pub use lesser_element::ExampleBlock;
|
||||
pub use lesser_element::ExportBlock;
|
||||
pub use lesser_element::FixedWidthArea;
|
||||
pub use lesser_element::HorizontalRule;
|
||||
pub use lesser_element::Keyword;
|
||||
pub use lesser_element::LatexEnvironment;
|
||||
pub use lesser_element::Paragraph;
|
||||
pub use lesser_element::Planning;
|
||||
pub use lesser_element::SrcBlock;
|
||||
pub use lesser_element::TableCell;
|
||||
pub use lesser_element::VerseBlock;
|
||||
pub use object::AngleLink;
|
||||
pub use object::Bold;
|
||||
pub use object::Citation;
|
||||
pub use object::CitationReference;
|
||||
pub use object::Code;
|
||||
pub use object::Entity;
|
||||
pub use object::ExportSnippet;
|
||||
pub use object::FootnoteReference;
|
||||
pub use object::InlineBabelCall;
|
||||
pub use object::InlineSourceBlock;
|
||||
pub use object::Italic;
|
||||
pub use object::LatexFragment;
|
||||
pub use object::LineBreak;
|
||||
pub use object::Object;
|
||||
pub use object::OrgMacro;
|
||||
pub use object::PlainLink;
|
||||
pub use object::PlainText;
|
||||
pub use object::RadioLink;
|
||||
pub use object::RadioTarget;
|
||||
pub use object::RegularLink;
|
||||
pub use object::StatisticsCookie;
|
||||
pub use object::StrikeThrough;
|
||||
pub use object::Subscript;
|
||||
pub use object::Superscript;
|
||||
pub use object::Target;
|
||||
pub use object::Timestamp;
|
||||
pub use object::Underline;
|
||||
pub use object::Verbatim;
|
||||
pub use source::SetSource;
|
||||
pub use source::Source;
|
@ -1,4 +1,4 @@
|
||||
use super::source::Source;
|
||||
use super::Source;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Object<'s> {
|
@ -6,7 +6,7 @@ fn {name}() {{
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents.as_str()).expect("Use emacs to parse org file.");
|
||||
println!("{{}}", org_sexp);
|
||||
let (_remaining, parsed_sexp) = sexp_with_padding(org_sexp.as_str()).expect("Sexp Parse failure");
|
||||
let (remaining, rust_parsed) = document(org_contents.as_str()).expect("Org Parse failure");
|
||||
let rust_parsed = parse(org_contents.as_str()).expect("Org Parse failure");
|
||||
println!("{{:#?}}", rust_parsed);
|
||||
let diff_result =
|
||||
compare_document(&parsed_sexp, &rust_parsed).expect("Compare parsed documents.");
|
||||
@ -14,5 +14,4 @@ fn {name}() {{
|
||||
.print(org_contents.as_str())
|
||||
.expect("Print document parse tree diff.");
|
||||
assert!(!diff_result.is_bad());
|
||||
assert_eq!(remaining, "");
|
||||
}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user