Apply more suggestions.
This commit is contained in:
parent
4b6c717812
commit
3069711447
@ -348,10 +348,7 @@ mod tests {
|
|||||||
let input = r#" (foo "b(a)r" baz ) "#;
|
let input = r#" (foo "b(a)r" baz ) "#;
|
||||||
let (remaining, parsed) = sexp(input).expect("Parse the input");
|
let (remaining, parsed) = sexp(input).expect("Parse the input");
|
||||||
assert_eq!(remaining, "");
|
assert_eq!(remaining, "");
|
||||||
assert!(match parsed {
|
assert!(matches!(parsed, Token::List(_)));
|
||||||
Token::List(_) => true,
|
|
||||||
_ => false,
|
|
||||||
});
|
|
||||||
let children = match parsed {
|
let children = match parsed {
|
||||||
Token::List(children) => children,
|
Token::List(children) => children,
|
||||||
_ => panic!("Should be a list."),
|
_ => panic!("Should be a list."),
|
||||||
@ -364,14 +361,14 @@ mod tests {
|
|||||||
r#"foo"#
|
r#"foo"#
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
match children.iter().nth(1) {
|
match children.get(1) {
|
||||||
Some(Token::Atom(body)) => *body,
|
Some(Token::Atom(body)) => *body,
|
||||||
_ => panic!("Second child should be an atom."),
|
_ => panic!("Second child should be an atom."),
|
||||||
},
|
},
|
||||||
r#""b(a)r""#
|
r#""b(a)r""#
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
match children.iter().nth(2) {
|
match children.get(2) {
|
||||||
Some(Token::Atom(body)) => *body,
|
Some(Token::Atom(body)) => *body,
|
||||||
_ => panic!("Third child should be an atom."),
|
_ => panic!("Third child should be an atom."),
|
||||||
},
|
},
|
||||||
|
@ -117,10 +117,7 @@ fn get_emacs_standard_properties<'b, 's>(
|
|||||||
emacs: &'b Token<'s>,
|
emacs: &'b Token<'s>,
|
||||||
) -> Result<EmacsStandardProperties, Box<dyn std::error::Error>> {
|
) -> Result<EmacsStandardProperties, Box<dyn std::error::Error>> {
|
||||||
let children = emacs.as_list()?;
|
let children = emacs.as_list()?;
|
||||||
let attributes_child = children
|
let attributes_child = children.get(1).ok_or("Should have an attributes child.")?;
|
||||||
.iter()
|
|
||||||
.nth(1)
|
|
||||||
.ok_or("Should have an attributes child.")?;
|
|
||||||
let attributes_map = attributes_child.as_map()?;
|
let attributes_map = attributes_child.as_map()?;
|
||||||
let standard_properties = attributes_map.get(":standard-properties");
|
let standard_properties = attributes_map.get(":standard-properties");
|
||||||
Ok(if standard_properties.is_some() {
|
Ok(if standard_properties.is_some() {
|
||||||
|
@ -20,8 +20,7 @@ impl FileAccessInterface for LocalFileAccessInterface {
|
|||||||
fn read_file(&self, path: &str) -> Result<String, std::io::Error> {
|
fn read_file(&self, path: &str) -> Result<String, std::io::Error> {
|
||||||
let final_path = self
|
let final_path = self
|
||||||
.working_directory
|
.working_directory
|
||||||
.as_ref()
|
.as_deref()
|
||||||
.map(PathBuf::as_path)
|
|
||||||
.map(|pb| pb.join(path))
|
.map(|pb| pb.join(path))
|
||||||
.unwrap_or_else(|| PathBuf::from(path));
|
.unwrap_or_else(|| PathBuf::from(path));
|
||||||
Ok(std::fs::read_to_string(final_path)?)
|
Ok(std::fs::read_to_string(final_path)?)
|
||||||
|
@ -126,14 +126,10 @@ impl<'g, 's> Default for GlobalSettings<'g, 's> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Default)]
|
||||||
pub enum HeadlineLevelFilter {
|
pub enum HeadlineLevelFilter {
|
||||||
Odd,
|
Odd,
|
||||||
|
|
||||||
|
#[default]
|
||||||
OddEven,
|
OddEven,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for HeadlineLevelFilter {
|
|
||||||
fn default() -> Self {
|
|
||||||
HeadlineLevelFilter::OddEven
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -64,7 +64,7 @@ impl<'a, T> Iterator for IterList<'a, T> {
|
|||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let ret = self.next;
|
let ret = self.next;
|
||||||
self.next = self.next.map(|this| this.get_parent()).flatten();
|
self.next = self.next.and_then(|link| link.get_parent());
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ pub(crate) use parser_with_context;
|
|||||||
|
|
||||||
macro_rules! bind_context {
|
macro_rules! bind_context {
|
||||||
($target:expr, $context:expr) => {
|
($target:expr, $context:expr) => {
|
||||||
move |i| $target($context, i)
|
|i| $target($context, i)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub(crate) use bind_context;
|
pub(crate) use bind_context;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#[allow(clippy::module_inception)]
|
||||||
mod error;
|
mod error;
|
||||||
pub(crate) use error::CustomError;
|
pub(crate) use error::CustomError;
|
||||||
pub(crate) use error::MyError;
|
pub(crate) use error::MyError;
|
||||||
|
@ -16,7 +16,7 @@ use nom::sequence::tuple;
|
|||||||
|
|
||||||
use super::object_parser::standard_set_object;
|
use super::object_parser::standard_set_object;
|
||||||
use super::util::confine_context;
|
use super::util::confine_context;
|
||||||
use crate::context::parser_with_context;
|
use crate::context::bind_context;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::context::ContextElement;
|
use crate::context::ContextElement;
|
||||||
use crate::context::GlobalSettings;
|
use crate::context::GlobalSettings;
|
||||||
@ -64,7 +64,7 @@ where
|
|||||||
eof,
|
eof,
|
||||||
)),
|
)),
|
||||||
|(_, _, objects, _, _)| objects,
|
|(_, _, objects, _, _)| objects,
|
||||||
)))(kw.key.into())
|
)))(kw.key)
|
||||||
.expect("Parser should always succeed.");
|
.expect("Parser should always succeed.");
|
||||||
ret.insert(
|
ret.insert(
|
||||||
translated_name,
|
translated_name,
|
||||||
@ -85,8 +85,9 @@ where
|
|||||||
map_parser(
|
map_parser(
|
||||||
recognize(many_till(anychar, peek(tuple((tag("]"), eof))))),
|
recognize(many_till(anychar, peek(tuple((tag("]"), eof))))),
|
||||||
confine_context(|i| {
|
confine_context(|i| {
|
||||||
all_consuming(many0(parser_with_context!(standard_set_object)(
|
all_consuming(many0(bind_context!(
|
||||||
&initial_context,
|
standard_set_object,
|
||||||
|
&initial_context
|
||||||
)))(i)
|
)))(i)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@ -98,11 +99,11 @@ where
|
|||||||
.expect("Object parser should always succeed.");
|
.expect("Object parser should always succeed.");
|
||||||
|
|
||||||
// TODO: This should be omitting footnote references
|
// TODO: This should be omitting footnote references
|
||||||
let (_remaining, objects) =
|
let (_remaining, objects) = all_consuming(many0(bind_context!(
|
||||||
all_consuming(many0(parser_with_context!(standard_set_object)(
|
standard_set_object,
|
||||||
&initial_context,
|
&initial_context
|
||||||
)))(kw.value.into())
|
)))(kw.value.into())
|
||||||
.expect("Object parser should always succeed.");
|
.expect("Object parser should always succeed.");
|
||||||
|
|
||||||
let entry_per_keyword_list = ret
|
let entry_per_keyword_list = ret
|
||||||
.entry(translated_name)
|
.entry(translated_name)
|
||||||
@ -121,7 +122,7 @@ where
|
|||||||
|
|
||||||
fn translate_name<'g, 's>(global_settings: &'g GlobalSettings<'g, 's>, name: &'s str) -> String {
|
fn translate_name<'g, 's>(global_settings: &'g GlobalSettings<'g, 's>, name: &'s str) -> String {
|
||||||
let name_until_optval = name
|
let name_until_optval = name
|
||||||
.split_once("[")
|
.split_once('[')
|
||||||
.map(|(before, _after)| before)
|
.map(|(before, _after)| before)
|
||||||
.unwrap_or(name);
|
.unwrap_or(name);
|
||||||
for (src, dst) in global_settings.element_keyword_translation_alist {
|
for (src, dst) in global_settings.element_keyword_translation_alist {
|
||||||
|
@ -66,8 +66,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (remaining, _ws) = space0(remaining)?;
|
let (remaining, _ws) = space0(remaining)?;
|
||||||
let (remaining, (value, (call, inside_header, arguments, end_header))) =
|
let (remaining, (value, babel_call_value)) = consumed(babel_call_value)(remaining)?;
|
||||||
consumed(babel_call_value)(remaining)?;
|
|
||||||
let (remaining, _ws) = tuple((space0, org_line_ending))(remaining)?;
|
let (remaining, _ws) = tuple((space0, org_line_ending))(remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, _trailing_ws) =
|
||||||
@ -83,33 +82,36 @@ where
|
|||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
value: Into::<&str>::into(value).trim_end(),
|
value: Into::<&str>::into(value).trim_end(),
|
||||||
call: call.map(Into::<&str>::into),
|
call: babel_call_value.call.map(Into::<&str>::into),
|
||||||
inside_header: inside_header.map(Into::<&str>::into),
|
inside_header: babel_call_value.inside_header.map(Into::<&str>::into),
|
||||||
arguments: arguments.map(Into::<&str>::into),
|
arguments: babel_call_value.arguments.map(Into::<&str>::into),
|
||||||
end_header: end_header.map(Into::<&str>::into),
|
end_header: babel_call_value.end_header.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct BabelCallValue<'s> {
|
||||||
|
call: Option<OrgSource<'s>>,
|
||||||
|
inside_header: Option<OrgSource<'s>>,
|
||||||
|
arguments: Option<OrgSource<'s>>,
|
||||||
|
end_header: Option<OrgSource<'s>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn babel_call_value<'s>(
|
fn babel_call_value<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, BabelCallValue<'s>> {
|
||||||
input: OrgSource<'s>,
|
|
||||||
) -> Res<
|
|
||||||
OrgSource<'s>,
|
|
||||||
(
|
|
||||||
Option<OrgSource<'s>>,
|
|
||||||
Option<OrgSource<'s>>,
|
|
||||||
Option<OrgSource<'s>>,
|
|
||||||
Option<OrgSource<'s>>,
|
|
||||||
),
|
|
||||||
> {
|
|
||||||
let (remaining, call) = opt(babel_call_call)(input)?;
|
let (remaining, call) = opt(babel_call_call)(input)?;
|
||||||
let (remaining, inside_header) = opt(inside_header)(remaining)?;
|
let (remaining, inside_header) = opt(inside_header)(remaining)?;
|
||||||
let (remaining, arguments) = opt(arguments)(remaining)?;
|
let (remaining, arguments) = opt(arguments)(remaining)?;
|
||||||
let (remaining, end_header) = opt(end_header)(remaining)?;
|
let (remaining, end_header) = opt(end_header)(remaining)?;
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
(call, inside_header, arguments.flatten(), end_header),
|
BabelCallValue {
|
||||||
|
call,
|
||||||
|
inside_header,
|
||||||
|
arguments: arguments.flatten(),
|
||||||
|
end_header,
|
||||||
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +205,7 @@ fn _global_suffix_end<'b, 'g, 'r, 's>(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::context::bind_context;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::context::GlobalSettings;
|
use crate::context::GlobalSettings;
|
||||||
use crate::context::List;
|
use crate::context::List;
|
||||||
@ -219,7 +220,7 @@ mod tests {
|
|||||||
let global_settings = GlobalSettings::default();
|
let global_settings = GlobalSettings::default();
|
||||||
let initial_context = ContextElement::document_context();
|
let initial_context = ContextElement::document_context();
|
||||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||||
let paragraph_matcher = parser_with_context!(element(true))(&initial_context);
|
let paragraph_matcher = bind_context!(element(true), &initial_context);
|
||||||
let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph");
|
let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph");
|
||||||
let first_paragraph = match first_paragraph {
|
let first_paragraph = match first_paragraph {
|
||||||
Element::Paragraph(paragraph) => paragraph,
|
Element::Paragraph(paragraph) => paragraph,
|
||||||
|
@ -200,7 +200,7 @@ where
|
|||||||
let (remaining, output) = inner(input)?;
|
let (remaining, output) = inner(input)?;
|
||||||
if remaining.get_bracket_depth() - pre_bracket_depth != 0 {
|
if remaining.get_bracket_depth() - pre_bracket_depth != 0 {
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"UnbalancedBrackets".into(),
|
"UnbalancedBrackets",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
Ok((remaining, output))
|
Ok((remaining, output))
|
||||||
|
@ -36,7 +36,7 @@ pub(crate) fn comment<'b, 'g, 'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, Comment<'s>> {
|
) -> Res<OrgSource<'s>, Comment<'s>> {
|
||||||
if immediate_in_section(context, "comment") {
|
if immediate_in_section(context, "comment") {
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"Cannot nest objects of the same element".into(),
|
"Cannot nest objects of the same element",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
let parser_context = ContextElement::Context("comment");
|
let parser_context = ContextElement::Context("comment");
|
||||||
@ -104,6 +104,7 @@ pub(crate) fn detect_comment<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()>
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::context::bind_context;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::context::ContextElement;
|
use crate::context::ContextElement;
|
||||||
use crate::context::GlobalSettings;
|
use crate::context::GlobalSettings;
|
||||||
@ -119,7 +120,7 @@ mod tests {
|
|||||||
let global_settings = GlobalSettings::default();
|
let global_settings = GlobalSettings::default();
|
||||||
let initial_context = ContextElement::document_context();
|
let initial_context = ContextElement::document_context();
|
||||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||||
let comment_matcher = parser_with_context!(comment)(&initial_context);
|
let comment_matcher = bind_context!(comment, &initial_context);
|
||||||
let (remaining, first_comment) = comment_matcher(input).expect("Parse first comment");
|
let (remaining, first_comment) = comment_matcher(input).expect("Parse first comment");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Into::<&str>::into(remaining),
|
Into::<&str>::into(remaining),
|
||||||
|
@ -11,6 +11,7 @@ use super::in_buffer_settings::scan_for_in_buffer_settings;
|
|||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
use super::section::zeroth_section;
|
use super::section::zeroth_section;
|
||||||
use super::util::get_consumed;
|
use super::util::get_consumed;
|
||||||
|
use crate::context::bind_context;
|
||||||
use crate::context::parser_with_context;
|
use crate::context::parser_with_context;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::context::ContextElement;
|
use crate::context::ContextElement;
|
||||||
@ -30,7 +31,7 @@ use crate::types::Object;
|
|||||||
///
|
///
|
||||||
/// This is a main entry point for Organic. It will parse the full contents of the input string as an org-mode document without an underlying file attached.
|
/// This is a main entry point for Organic. It will parse the full contents of the input string as an org-mode document without an underlying file attached.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn parse<'s>(input: &'s str) -> Result<Document<'s>, Box<dyn std::error::Error>> {
|
pub fn parse(input: &str) -> Result<Document<'_>, Box<dyn std::error::Error>> {
|
||||||
parse_file_with_settings::<&Path>(input, &GlobalSettings::default(), None)
|
parse_file_with_settings::<&Path>(input, &GlobalSettings::default(), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,10 +41,10 @@ pub fn parse<'s>(input: &'s str) -> Result<Document<'s>, Box<dyn std::error::Err
|
|||||||
///
|
///
|
||||||
/// file_path is not used for reading the file contents. It is only used for determining the document category and filling in the path attribute on the Document.
|
/// file_path is not used for reading the file contents. It is only used for determining the document category and filling in the path attribute on the Document.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn parse_file<'s, P: AsRef<Path>>(
|
pub fn parse_file<P: AsRef<Path>>(
|
||||||
input: &'s str,
|
input: &str,
|
||||||
file_path: Option<P>,
|
file_path: Option<P>,
|
||||||
) -> Result<Document<'s>, Box<dyn std::error::Error>> {
|
) -> Result<Document<'_>, Box<dyn std::error::Error>> {
|
||||||
parse_file_with_settings(input, &GlobalSettings::default(), file_path)
|
parse_file_with_settings(input, &GlobalSettings::default(), file_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ pub fn parse_file_with_settings<'g, 's, P: AsRef<Path>>(
|
|||||||
let initial_context = Context::new(global_settings, List::new(&initial_context));
|
let initial_context = Context::new(global_settings, List::new(&initial_context));
|
||||||
let wrapped_input = OrgSource::new(input);
|
let wrapped_input = OrgSource::new(input);
|
||||||
let mut doc =
|
let mut doc =
|
||||||
all_consuming(parser_with_context!(document_org_source)(&initial_context))(wrapped_input)
|
all_consuming(bind_context!(document_org_source, &initial_context))(wrapped_input)
|
||||||
.map_err(|err| err.to_string())
|
.map_err(|err| err.to_string())
|
||||||
.map(|(_remaining, parsed_document)| parsed_document)?;
|
.map(|(_remaining, parsed_document)| parsed_document)?;
|
||||||
if let Some(file_path) = file_path {
|
if let Some(file_path) = file_path {
|
||||||
@ -101,10 +102,7 @@ pub fn parse_file_with_settings<'g, 's, P: AsRef<Path>>(
|
|||||||
///
|
///
|
||||||
/// This will not prevent additional settings from being learned during parsing, for example when encountering a "#+TODO".
|
/// This will not prevent additional settings from being learned during parsing, for example when encountering a "#+TODO".
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn document<'b, 'g, 'r, 's>(
|
fn document<'s>(context: RefContext<'_, '_, '_, 's>, input: &'s str) -> Res<&'s str, Document<'s>> {
|
||||||
context: RefContext<'b, 'g, 'r, 's>,
|
|
||||||
input: &'s str,
|
|
||||||
) -> Res<&'s str, Document<'s>> {
|
|
||||||
let (remaining, doc) = document_org_source(context, input.into()).map_err(convert_error)?;
|
let (remaining, doc) = document_org_source(context, input.into()).map_err(convert_error)?;
|
||||||
Ok((Into::<&str>::into(remaining), doc))
|
Ok((Into::<&str>::into(remaining), doc))
|
||||||
}
|
}
|
||||||
@ -137,8 +135,7 @@ fn document_org_source<'b, 'g, 'r, 's>(
|
|||||||
scan_for_in_buffer_settings(setup_file.into()).map_err(|err| {
|
scan_for_in_buffer_settings(setup_file.into()).map_err(|err| {
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
nom::Err::Error(CustomError::MyError(MyError(
|
nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"TODO: make this take an owned string so I can dump err.to_string() into it."
|
"TODO: make this take an owned string so I can dump err.to_string() into it.",
|
||||||
.into(),
|
|
||||||
)))
|
)))
|
||||||
})?;
|
})?;
|
||||||
final_settings.extend(setup_file_settings);
|
final_settings.extend(setup_file_settings);
|
||||||
@ -148,8 +145,7 @@ fn document_org_source<'b, 'g, 'r, 's>(
|
|||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
nom::Err::Error(CustomError::MyError(MyError(
|
nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"TODO: make this take an owned string so I can dump err.to_string() into it."
|
"TODO: make this take an owned string so I can dump err.to_string() into it.",
|
||||||
.into(),
|
|
||||||
)))
|
)))
|
||||||
})?;
|
})?;
|
||||||
let new_context = context.with_global_settings(&new_settings);
|
let new_context = context.with_global_settings(&new_settings);
|
||||||
|
@ -49,7 +49,7 @@ where
|
|||||||
{
|
{
|
||||||
if immediate_in_section(context, "drawer") {
|
if immediate_in_section(context, "drawer") {
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"Cannot nest objects of the same element".into(),
|
"Cannot nest objects of the same element",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
start_of_line(remaining)?;
|
start_of_line(remaining)?;
|
||||||
|
@ -55,7 +55,7 @@ where
|
|||||||
{
|
{
|
||||||
if immediate_in_section(context, "dynamic block") {
|
if immediate_in_section(context, "dynamic block") {
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"Cannot nest objects of the same element".into(),
|
"Cannot nest objects of the same element",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,10 +79,7 @@ where
|
|||||||
let parser_context = context.with_additional_node(&contexts[0]);
|
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[1]);
|
||||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||||
let parameters = match parameters {
|
let parameters = parameters.map(|(_ws, parameters)| parameters);
|
||||||
Some((_ws, parameters)) => Some(parameters),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||||
not(exit_matcher)(remaining)?;
|
not(exit_matcher)(remaining)?;
|
||||||
|
@ -301,9 +301,7 @@ fn _detect_element<'b, 'g, 'r, 's>(
|
|||||||
input
|
input
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Ok((_, _)) = detect_comment(input) {
|
element!(detect_comment, input);
|
||||||
return Ok((input, ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
ak_element!(
|
ak_element!(
|
||||||
detect_fixed_width_area,
|
detect_fixed_width_area,
|
||||||
@ -326,6 +324,6 @@ fn _detect_element<'b, 'g, 'r, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Err(nom::Err::Error(CustomError::MyError(MyError(
|
Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"No element detected.".into(),
|
"No element detected.",
|
||||||
))))
|
))))
|
||||||
}
|
}
|
||||||
|
@ -60,21 +60,16 @@ fn name<'b, 'g, 'r, 's>(
|
|||||||
let result = tuple((
|
let result = tuple((
|
||||||
tag::<_, _, CustomError<_>>(entity.name),
|
tag::<_, _, CustomError<_>>(entity.name),
|
||||||
alt((
|
alt((
|
||||||
verify(map(tag("{}"), |_| true), |_| !entity.name.ends_with(" ")),
|
verify(map(tag("{}"), |_| true), |_| !entity.name.ends_with(' ')),
|
||||||
map(peek(recognize(entity_end)), |_| false),
|
map(peek(recognize(entity_end)), |_| false),
|
||||||
)),
|
)),
|
||||||
))(input);
|
))(input);
|
||||||
match result {
|
if let Ok((remaining, (ent, use_brackets))) = result {
|
||||||
Ok((remaining, (ent, use_brackets))) => {
|
return Ok((remaining, (entity, ent, use_brackets)));
|
||||||
return Ok((remaining, (entity, ent, use_brackets)));
|
|
||||||
}
|
|
||||||
Err(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(nom::Err::Error(CustomError::MyError(MyError(
|
Err(nom::Err::Error(CustomError::MyError(MyError("NoEntity"))))
|
||||||
"NoEntity".into(),
|
|
||||||
))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
@ -49,7 +49,7 @@ where
|
|||||||
{
|
{
|
||||||
if immediate_in_section(context, "footnote definition") {
|
if immediate_in_section(context, "footnote definition") {
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"Cannot nest objects of the same element".into(),
|
"Cannot nest objects of the same element",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
start_of_line(remaining)?;
|
start_of_line(remaining)?;
|
||||||
@ -157,6 +157,7 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::context::bind_context;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::context::GlobalSettings;
|
use crate::context::GlobalSettings;
|
||||||
use crate::context::List;
|
use crate::context::List;
|
||||||
@ -174,7 +175,7 @@ line footnote.",
|
|||||||
let global_settings = GlobalSettings::default();
|
let global_settings = GlobalSettings::default();
|
||||||
let initial_context = ContextElement::document_context();
|
let initial_context = ContextElement::document_context();
|
||||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||||
let footnote_definition_matcher = parser_with_context!(element(true))(&initial_context);
|
let footnote_definition_matcher = bind_context!(element(true), &initial_context);
|
||||||
let (remaining, first_footnote_definition) =
|
let (remaining, first_footnote_definition) =
|
||||||
footnote_definition_matcher(input).expect("Parse first footnote_definition");
|
footnote_definition_matcher(input).expect("Parse first footnote_definition");
|
||||||
let (remaining, second_footnote_definition) =
|
let (remaining, second_footnote_definition) =
|
||||||
@ -211,7 +212,7 @@ not in the footnote.",
|
|||||||
let global_settings = GlobalSettings::default();
|
let global_settings = GlobalSettings::default();
|
||||||
let initial_context = ContextElement::document_context();
|
let initial_context = ContextElement::document_context();
|
||||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||||
let footnote_definition_matcher = parser_with_context!(element(true))(&initial_context);
|
let footnote_definition_matcher = bind_context!(element(true), &initial_context);
|
||||||
let (remaining, first_footnote_definition) =
|
let (remaining, first_footnote_definition) =
|
||||||
footnote_definition_matcher(input).expect("Parse first footnote_definition");
|
footnote_definition_matcher(input).expect("Parse first footnote_definition");
|
||||||
assert_eq!(Into::<&str>::into(remaining), "not in the footnote.");
|
assert_eq!(Into::<&str>::into(remaining), "not in the footnote.");
|
||||||
|
@ -177,7 +177,7 @@ fn _footnote_definition_end<'b, 'g, 'r, 's>(
|
|||||||
if current_depth > 0 {
|
if current_depth > 0 {
|
||||||
// Its impossible for the next character to end the footnote reference definition if we're any amount of brackets deep
|
// Its impossible for the next character to end the footnote reference definition if we're any amount of brackets deep
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"NoFootnoteReferenceDefinitionEnd".into(),
|
"NoFootnoteReferenceDefinitionEnd",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
if current_depth < 0 {
|
if current_depth < 0 {
|
||||||
|
@ -61,10 +61,10 @@ where
|
|||||||
let (remaining, (_begin, name)) = tuple((
|
let (remaining, (_begin, name)) = tuple((
|
||||||
tag_no_case("#+begin_"),
|
tag_no_case("#+begin_"),
|
||||||
verify(name, |name: &OrgSource<'_>| {
|
verify(name, |name: &OrgSource<'_>| {
|
||||||
match Into::<&str>::into(name).to_lowercase().as_str() {
|
!matches!(
|
||||||
"comment" | "example" | "export" | "src" | "verse" => false,
|
Into::<&str>::into(name).to_lowercase().as_str(),
|
||||||
_ => true,
|
"comment" | "example" | "export" | "src" | "verse",
|
||||||
}
|
)
|
||||||
}),
|
}),
|
||||||
))(remaining)?;
|
))(remaining)?;
|
||||||
let name = Into::<&str>::into(name);
|
let name = Into::<&str>::into(name);
|
||||||
@ -233,7 +233,7 @@ fn greater_block_body<'c, 'b, 'g, 'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, (&'s str, Vec<Element<'s>>)> {
|
) -> Res<OrgSource<'s>, (&'s str, Vec<Element<'s>>)> {
|
||||||
if in_section(context, context_name) {
|
if in_section(context, context_name) {
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"Cannot nest objects of the same element".into(),
|
"Cannot nest objects of the same element",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
let exit_with_name = greater_block_end(name);
|
let exit_with_name = greater_block_end(name);
|
||||||
@ -288,7 +288,7 @@ fn parameters<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|||||||
recognize(many_till(anychar, peek(tuple((space0, line_ending)))))(input)
|
recognize(many_till(anychar, peek(tuple((space0, line_ending)))))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn greater_block_end<'c>(name: &'c str) -> impl ContextMatcher + 'c {
|
fn greater_block_end(name: &str) -> impl ContextMatcher + '_ {
|
||||||
move |context, input: OrgSource<'_>| _greater_block_end(context, input, name)
|
move |context, input: OrgSource<'_>| _greater_block_end(context, input, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,11 +206,7 @@ fn headline<'b, 'g, 'r, 's>(
|
|||||||
.map(|(_, (_, title))| title)
|
.map(|(_, (_, title))| title)
|
||||||
.unwrap_or(Vec::new()),
|
.unwrap_or(Vec::new()),
|
||||||
tags: maybe_tags
|
tags: maybe_tags
|
||||||
.map(|(_ws, tags)| {
|
.map(|(_ws, tags)| tags.into_iter().map(Into::<&str>::into).collect())
|
||||||
tags.into_iter()
|
|
||||||
.map(|single_tag| Into::<&str>::into(single_tag))
|
|
||||||
.collect()
|
|
||||||
})
|
|
||||||
.unwrap_or(Vec::new()),
|
.unwrap_or(Vec::new()),
|
||||||
is_footnote_section,
|
is_footnote_section,
|
||||||
},
|
},
|
||||||
@ -265,11 +261,8 @@ fn heading_keyword<'b, 'g, 'r, 's>(
|
|||||||
.map(String::as_str)
|
.map(String::as_str)
|
||||||
{
|
{
|
||||||
let result = tag::<_, _, CustomError<_>>(todo_keyword)(input);
|
let result = tag::<_, _, CustomError<_>>(todo_keyword)(input);
|
||||||
match result {
|
if let Ok((remaining, ent)) = result {
|
||||||
Ok((remaining, ent)) => {
|
return Ok((remaining, (TodoKeywordType::Todo, ent)));
|
||||||
return Ok((remaining, (TodoKeywordType::Todo, ent)));
|
|
||||||
}
|
|
||||||
Err(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for todo_keyword in global_settings
|
for todo_keyword in global_settings
|
||||||
@ -278,20 +271,17 @@ fn heading_keyword<'b, 'g, 'r, 's>(
|
|||||||
.map(String::as_str)
|
.map(String::as_str)
|
||||||
{
|
{
|
||||||
let result = tag::<_, _, CustomError<_>>(todo_keyword)(input);
|
let result = tag::<_, _, CustomError<_>>(todo_keyword)(input);
|
||||||
match result {
|
if let Ok((remaining, ent)) = result {
|
||||||
Ok((remaining, ent)) => {
|
return Ok((remaining, (TodoKeywordType::Done, ent)));
|
||||||
return Ok((remaining, (TodoKeywordType::Done, ent)));
|
|
||||||
}
|
|
||||||
Err(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(nom::Err::Error(CustomError::MyError(MyError(
|
Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"NoTodoKeyword".into(),
|
"NoTodoKeyword",
|
||||||
))))
|
))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn priority_cookie<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, PriorityCookie> {
|
fn priority_cookie(input: OrgSource<'_>) -> Res<OrgSource<'_>, PriorityCookie> {
|
||||||
let (remaining, (_, priority_character, _)) = tuple((
|
let (remaining, (_, priority_character, _)) = tuple((
|
||||||
tag("[#"),
|
tag("[#"),
|
||||||
verify(anychar, |c| c.is_alphanumeric()),
|
verify(anychar, |c| c.is_alphanumeric()),
|
||||||
@ -299,7 +289,7 @@ fn priority_cookie<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, PriorityCooki
|
|||||||
))(input)?;
|
))(input)?;
|
||||||
let cookie = PriorityCookie::try_from(priority_character).map_err(|_| {
|
let cookie = PriorityCookie::try_from(priority_character).map_err(|_| {
|
||||||
nom::Err::Error(CustomError::MyError(MyError(
|
nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"Failed to cast priority cookie to number.".into(),
|
"Failed to cast priority cookie to number.",
|
||||||
)))
|
)))
|
||||||
})?;
|
})?;
|
||||||
Ok((remaining, cookie))
|
Ok((remaining, cookie))
|
||||||
|
@ -132,7 +132,7 @@ fn _header_end<'b, 'g, 'r, 's>(
|
|||||||
if current_depth > 0 {
|
if current_depth > 0 {
|
||||||
// Its impossible for the next character to end the header if we're any amount of bracket deep
|
// Its impossible for the next character to end the header if we're any amount of bracket deep
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
"NoHeaderEnd".into(),
|
"NoHeaderEnd",
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
if current_depth < 0 {
|
if current_depth < 0 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user