Compare commits
No commits in common. "dd3de67a8cd7c62be04b1c81566a2fa66da82d71" and "f49a1853ad58693140c73a9ca98a4ea22398cba6" have entirely different histories.
dd3de67a8c
...
f49a1853ad
@ -1,3 +0,0 @@
|
|||||||
#+call:
|
|
||||||
|
|
||||||
#+call:
|
|
@ -1,3 +0,0 @@
|
|||||||
#+call: foo[inside](bar="baz")[outside]
|
|
||||||
|
|
||||||
#+call: foo[](bar="baz")[]
|
|
@ -1,7 +0,0 @@
|
|||||||
#+call: foo[inside](bar="baz")[outside]
|
|
||||||
|
|
||||||
#+call: foo[[inside]](bar="baz")[outside]
|
|
||||||
|
|
||||||
#+call: foo[inside]((bar="baz"))[outside]
|
|
||||||
|
|
||||||
#+call: foo[inside](bar="baz")[[outside]]
|
|
@ -1 +0,0 @@
|
|||||||
#+call: foo(bar="baz"
|
|
@ -1,7 +1 @@
|
|||||||
#+call: foo(bar="baz")
|
#+call: foo(bar="baz")
|
||||||
|
|
||||||
#+call: lorem ipsum
|
|
||||||
|
|
||||||
#+call: dolar cat(dog)
|
|
||||||
|
|
||||||
#+call: (bat)
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
#+call: foo [inside] (bar="baz") [outside]
|
|
||||||
|
|
||||||
#+call: foo (bar="baz") [outside]
|
|
@ -2403,6 +2403,8 @@ fn compare_babel_call<'b, 's>(
|
|||||||
let mut this_status = DiffStatus::Good;
|
let mut this_status = DiffStatus::Good;
|
||||||
let mut message = None;
|
let mut message = None;
|
||||||
|
|
||||||
|
// TODO: Compare :call :inside-header :arguments :end-header
|
||||||
|
|
||||||
// TODO: Compare :caption
|
// TODO: Compare :caption
|
||||||
// Compare name
|
// Compare name
|
||||||
let name = get_property_quoted_string(emacs, ":name")?;
|
let name = get_property_quoted_string(emacs, ":name")?;
|
||||||
@ -2414,56 +2416,19 @@ fn compare_babel_call<'b, 's>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare value
|
let value = unquote(
|
||||||
let value = get_property_quoted_string(emacs, ":value")?.unwrap_or(String::new());
|
get_property(emacs, ":value")?
|
||||||
|
.ok_or("Emacs keywords should have a :value")?
|
||||||
|
.as_atom()?,
|
||||||
|
)?;
|
||||||
if value != rust.value {
|
if value != rust.value {
|
||||||
this_status = DiffStatus::Bad;
|
this_status = DiffStatus::Bad;
|
||||||
message = Some(format!(
|
message = Some(format!(
|
||||||
"Value mismatch (emacs != rust) {:?} != {:?}",
|
"Mismatchs keyword values (emacs != rust) {:?} != {:?}",
|
||||||
value, rust.value
|
value, rust.value
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare call
|
|
||||||
let call = get_property_quoted_string(emacs, ":call")?;
|
|
||||||
if call.as_ref().map(String::as_str) != rust.call {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Call mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
call, rust.call
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare arguments
|
|
||||||
let arguments = get_property_quoted_string(emacs, ":arguments")?;
|
|
||||||
if arguments.as_ref().map(String::as_str) != rust.arguments {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Arguments mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
arguments, rust.arguments
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare inside header
|
|
||||||
let inside_header = get_property_quoted_string(emacs, ":inside-header")?;
|
|
||||||
if inside_header.as_ref().map(String::as_str) != rust.inside_header {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Inside header mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
inside_header, rust.inside_header
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare end header
|
|
||||||
let end_header = get_property_quoted_string(emacs, ":end-header")?;
|
|
||||||
if end_header.as_ref().map(String::as_str) != rust.end_header {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"End header mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
end_header, rust.end_header
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(DiffResult {
|
Ok(DiffResult {
|
||||||
status: this_status,
|
status: this_status,
|
||||||
name: rust.get_elisp_name(),
|
name: rust.get_elisp_name(),
|
||||||
|
@ -1,235 +0,0 @@
|
|||||||
use nom::branch::alt;
|
|
||||||
use nom::bytes::complete::tag;
|
|
||||||
use nom::bytes::complete::tag_no_case;
|
|
||||||
use nom::character::complete::anychar;
|
|
||||||
use nom::character::complete::one_of;
|
|
||||||
use nom::character::complete::space0;
|
|
||||||
use nom::combinator::consumed;
|
|
||||||
use nom::combinator::opt;
|
|
||||||
use nom::combinator::peek;
|
|
||||||
use nom::combinator::recognize;
|
|
||||||
use nom::combinator::verify;
|
|
||||||
use nom::multi::many0;
|
|
||||||
use nom::multi::many_till;
|
|
||||||
use nom::sequence::tuple;
|
|
||||||
use nom::InputTake;
|
|
||||||
|
|
||||||
use super::keyword::affiliated_keyword;
|
|
||||||
use super::org_source::BracketDepth;
|
|
||||||
use super::util::get_name;
|
|
||||||
use super::util::start_of_line;
|
|
||||||
use super::OrgSource;
|
|
||||||
use crate::context::Matcher;
|
|
||||||
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::util::org_line_ending;
|
|
||||||
use crate::types::BabelCall;
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
pub(crate) fn babel_call<'b, 'g, 'r, 's>(
|
|
||||||
_context: RefContext<'b, 'g, 'r, 's>,
|
|
||||||
input: OrgSource<'s>,
|
|
||||||
) -> Res<OrgSource<'s>, BabelCall<'s>> {
|
|
||||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
|
||||||
|
|
||||||
start_of_line(input)?;
|
|
||||||
let (remaining, _) = tuple((space0, tag("#+"), tag_no_case("call"), tag(":")))(input)?;
|
|
||||||
|
|
||||||
if let Ok((remaining, (_, line_break))) = tuple((space0, org_line_ending))(remaining) {
|
|
||||||
let source = get_consumed(input, remaining);
|
|
||||||
return Ok((
|
|
||||||
remaining,
|
|
||||||
BabelCall {
|
|
||||||
source: Into::<&str>::into(source),
|
|
||||||
name: get_name(&affiliated_keywords),
|
|
||||||
value: Into::<&str>::into(line_break.take(0)),
|
|
||||||
call: None,
|
|
||||||
inside_header: None,
|
|
||||||
arguments: None,
|
|
||||||
end_header: None,
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let (remaining, _ws) = space0(remaining)?;
|
|
||||||
let (remaining, (value, (call, inside_header, arguments, end_header))) =
|
|
||||||
consumed(babel_call_value)(remaining)?;
|
|
||||||
let (remaining, _ws) = tuple((space0, org_line_ending))(remaining)?;
|
|
||||||
|
|
||||||
let source = get_consumed(input, remaining);
|
|
||||||
|
|
||||||
Ok((
|
|
||||||
remaining,
|
|
||||||
BabelCall {
|
|
||||||
source: Into::<&str>::into(source),
|
|
||||||
name: get_name(&affiliated_keywords),
|
|
||||||
value: Into::<&str>::into(value).trim_end(),
|
|
||||||
call: call.map(Into::<&str>::into),
|
|
||||||
inside_header: inside_header.map(Into::<&str>::into),
|
|
||||||
arguments: arguments.map(Into::<&str>::into),
|
|
||||||
end_header: end_header.map(Into::<&str>::into),
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
fn babel_call_value<'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, inside_header) = opt(inside_header)(remaining)?;
|
|
||||||
let (remaining, arguments) = opt(arguments)(remaining)?;
|
|
||||||
let (remaining, end_header) = opt(end_header)(remaining)?;
|
|
||||||
Ok((
|
|
||||||
remaining,
|
|
||||||
(call, inside_header, arguments.flatten(), end_header),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
fn babel_call_call<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|
||||||
verify(
|
|
||||||
recognize(many_till(
|
|
||||||
anychar,
|
|
||||||
alt((
|
|
||||||
peek(recognize(one_of("[("))),
|
|
||||||
recognize(tuple((space0, org_line_ending))),
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
|s| s.len() > 0,
|
|
||||||
)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
fn inside_header<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|
||||||
let (remaining, contents) = balanced_bracket(
|
|
||||||
|i| tag("[")(i),
|
|
||||||
|i| peek(tag("]"))(i),
|
|
||||||
|i| recognize(tuple((space0, org_line_ending)))(i),
|
|
||||||
|i| tag("]")(i),
|
|
||||||
|s| s.get_bracket_depth(),
|
|
||||||
)(input)?;
|
|
||||||
let (contents_start, _) = tag("[")(input)?;
|
|
||||||
Ok((remaining, contents.unwrap_or(contents_start.take(0))))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
fn arguments<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
|
||||||
balanced_bracket(
|
|
||||||
|i| tag("(")(i),
|
|
||||||
|i| peek(tag(")"))(i),
|
|
||||||
|i| recognize(tuple((space0, org_line_ending)))(i),
|
|
||||||
|i| tag(")")(i),
|
|
||||||
|s| s.get_parenthesis_depth(),
|
|
||||||
)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
fn end_header<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|
||||||
let (remaining, _) = space0(input)?;
|
|
||||||
verify(
|
|
||||||
recognize(many_till(anychar, peek(tuple((space0, org_line_ending))))),
|
|
||||||
|s| s.len() > 0,
|
|
||||||
)(remaining)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn balanced_bracket<
|
|
||||||
O: Matcher,
|
|
||||||
S: Matcher,
|
|
||||||
F: Matcher,
|
|
||||||
E: Matcher,
|
|
||||||
D: for<'ss> Fn(OrgSource<'ss>) -> BracketDepth,
|
|
||||||
>(
|
|
||||||
opening_parser: O,
|
|
||||||
stop_parser: S,
|
|
||||||
fail_parser: F,
|
|
||||||
end_parser: E,
|
|
||||||
depth_function: D,
|
|
||||||
) -> impl for<'s> Fn(OrgSource<'s>) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
|
||||||
move |input| {
|
|
||||||
impl_balanced_bracket::<&O, &S, &F, &E, &D>(
|
|
||||||
input,
|
|
||||||
&opening_parser,
|
|
||||||
&stop_parser,
|
|
||||||
&fail_parser,
|
|
||||||
&end_parser,
|
|
||||||
&depth_function,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn impl_balanced_bracket<
|
|
||||||
's,
|
|
||||||
O: Matcher,
|
|
||||||
S: Matcher,
|
|
||||||
F: Matcher,
|
|
||||||
E: Matcher,
|
|
||||||
D: for<'ss> Fn(OrgSource<'ss>) -> BracketDepth,
|
|
||||||
>(
|
|
||||||
input: OrgSource<'s>,
|
|
||||||
opening_parser: O,
|
|
||||||
stop_parser: S,
|
|
||||||
fail_parser: F,
|
|
||||||
end_parser: E,
|
|
||||||
depth_function: D,
|
|
||||||
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
|
||||||
let (mut remaining, _) = opening_parser(input)?;
|
|
||||||
let contents_start = remaining;
|
|
||||||
let original_depth = depth_function(remaining);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let bracket_depth = depth_function(remaining);
|
|
||||||
if bracket_depth == original_depth {
|
|
||||||
let (remain, stop_result) = opt(&stop_parser)(remaining)?;
|
|
||||||
remaining = remain;
|
|
||||||
if stop_result.is_some() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if fail_parser(remaining).is_ok() {
|
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
|
||||||
"Fail parser matched.",
|
|
||||||
))));
|
|
||||||
}
|
|
||||||
|
|
||||||
let (remain, _) = anychar(remaining)?;
|
|
||||||
remaining = remain;
|
|
||||||
}
|
|
||||||
let contents_end = remaining;
|
|
||||||
|
|
||||||
let (remaining, _) = end_parser(remaining)?;
|
|
||||||
let contents = if contents_start != contents_end {
|
|
||||||
Some(contents_start.get_until(contents_end))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
Ok((remaining, contents))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use nom::combinator::opt;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn simple_call() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let input = OrgSource::new("()");
|
|
||||||
let (remaining, call) = opt(babel_call_call)(input)?;
|
|
||||||
assert_eq!(Into::<&str>::into(remaining), "()");
|
|
||||||
assert_eq!(call, None);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ use nom::sequence::tuple;
|
|||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
use tracing::span;
|
use tracing::span;
|
||||||
|
|
||||||
use super::babel_call::babel_call;
|
|
||||||
use super::clock::clock;
|
use super::clock::clock;
|
||||||
use super::comment::comment;
|
use super::comment::comment;
|
||||||
use super::comment::detect_comment;
|
use super::comment::detect_comment;
|
||||||
@ -21,6 +20,7 @@ use super::footnote_definition::footnote_definition;
|
|||||||
use super::greater_block::greater_block;
|
use super::greater_block::greater_block;
|
||||||
use super::horizontal_rule::horizontal_rule;
|
use super::horizontal_rule::horizontal_rule;
|
||||||
use super::keyword::affiliated_keyword;
|
use super::keyword::affiliated_keyword;
|
||||||
|
use super::keyword::babel_call_keyword;
|
||||||
use super::keyword::keyword;
|
use super::keyword::keyword;
|
||||||
use super::latex_environment::latex_environment;
|
use super::latex_environment::latex_environment;
|
||||||
use super::lesser_block::comment_block;
|
use super::lesser_block::comment_block;
|
||||||
@ -76,7 +76,7 @@ fn _element<'b, 'g, 'r, 's>(
|
|||||||
let fixed_width_area_matcher = parser_with_context!(fixed_width_area)(context);
|
let fixed_width_area_matcher = parser_with_context!(fixed_width_area)(context);
|
||||||
let horizontal_rule_matcher = parser_with_context!(horizontal_rule)(context);
|
let horizontal_rule_matcher = parser_with_context!(horizontal_rule)(context);
|
||||||
let keyword_matcher = parser_with_context!(keyword)(context);
|
let keyword_matcher = parser_with_context!(keyword)(context);
|
||||||
let babel_keyword_matcher = parser_with_context!(babel_call)(context);
|
let babel_keyword_matcher = parser_with_context!(babel_call_keyword)(context);
|
||||||
let paragraph_matcher = parser_with_context!(paragraph)(context);
|
let paragraph_matcher = parser_with_context!(paragraph)(context);
|
||||||
let latex_environment_matcher = parser_with_context!(latex_environment)(context);
|
let latex_environment_matcher = parser_with_context!(latex_environment)(context);
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ use crate::error::CustomError;
|
|||||||
use crate::error::MyError;
|
use crate::error::MyError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use crate::parser::util::start_of_line;
|
use crate::parser::util::start_of_line;
|
||||||
|
use crate::types::BabelCall;
|
||||||
use crate::types::Keyword;
|
use crate::types::Keyword;
|
||||||
|
|
||||||
const ORG_ELEMENT_AFFILIATED_KEYWORDS: [&'static str; 13] = [
|
const ORG_ELEMENT_AFFILIATED_KEYWORDS: [&'static str; 13] = [
|
||||||
@ -103,6 +104,29 @@ pub(crate) fn affiliated_keyword<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>,
|
|||||||
filtered_keyword(affiliated_key)(input)
|
filtered_keyword(affiliated_key)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
pub(crate) fn babel_call_keyword<'b, 'g, 'r, 's>(
|
||||||
|
_context: RefContext<'b, 'g, 'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, BabelCall<'s>> {
|
||||||
|
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||||
|
let (remaining, kw) = filtered_keyword(babel_call_key)(input)?;
|
||||||
|
Ok((
|
||||||
|
remaining,
|
||||||
|
BabelCall {
|
||||||
|
source: kw.source,
|
||||||
|
name: get_name(&affiliated_keywords),
|
||||||
|
key: kw.key,
|
||||||
|
value: kw.value,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
fn babel_call_key<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
|
tag_no_case("call")(input)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub(crate) fn table_formula_keyword<'b, 'g, 'r, 's>(
|
pub(crate) fn table_formula_keyword<'b, 'g, 'r, 's>(
|
||||||
_context: RefContext<'b, 'g, 'r, 's>,
|
_context: RefContext<'b, 'g, 'r, 's>,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
mod angle_link;
|
mod angle_link;
|
||||||
mod babel_call;
|
|
||||||
mod citation;
|
mod citation;
|
||||||
mod citation_reference;
|
mod citation_reference;
|
||||||
mod clock;
|
mod clock;
|
||||||
|
@ -138,11 +138,8 @@ pub struct Keyword<'s> {
|
|||||||
pub struct BabelCall<'s> {
|
pub struct BabelCall<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub name: Option<&'s str>,
|
pub name: Option<&'s str>,
|
||||||
|
pub key: &'s str,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
pub call: Option<&'s str>,
|
|
||||||
pub inside_header: Option<&'s str>,
|
|
||||||
pub arguments: Option<&'s str>,
|
|
||||||
pub end_header: Option<&'s str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user