Move consuming trailing element whitespace inside the parsers.
This ensures the parsers can take into account the affiliated keywords when setting their source without needing the SetSource trait.
This commit is contained in:
parent
f79606047e
commit
758e224e6d
@ -2497,11 +2497,11 @@ fn compare_latex_environment<'b, 's>(
|
||||
|
||||
// Compare value
|
||||
let value = get_property_quoted_string(emacs, ":value")?;
|
||||
if value.as_ref().map(String::as_str) != Some(rust.source) {
|
||||
if value.as_ref().map(String::as_str) != Some(rust.value) {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Value mismatch (emacs != rust) {:?} != {:?}",
|
||||
value, rust.source
|
||||
value, rust.value
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ use nom::InputTake;
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::org_source::BracketDepth;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::start_of_line;
|
||||
use super::OrgSource;
|
||||
use crate::context::Matcher;
|
||||
@ -30,15 +31,17 @@ 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>,
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, BabelCall<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
|
||||
start_of_line(input)?;
|
||||
let (remaining, _) = tuple((space0, tag("#+"), tag_no_case("call"), tag(":")))(input)?;
|
||||
start_of_line(remaining)?;
|
||||
let (remaining, _) = tuple((space0, tag("#+"), tag_no_case("call"), tag(":")))(remaining)?;
|
||||
|
||||
if let Ok((remaining, (_, line_break))) = tuple((space0, org_line_ending))(remaining) {
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
return Ok((
|
||||
remaining,
|
||||
@ -59,6 +62,8 @@ pub(crate) fn babel_call<'b, 'g, 'r, 's>(
|
||||
consumed(babel_call_value)(remaining)?;
|
||||
let (remaining, _ws) = tuple((space0, org_line_ending))(remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
|
||||
Ok((
|
||||
|
@ -13,6 +13,7 @@ use super::org_source::OrgSource;
|
||||
use super::timestamp::inactive_date_range_timestamp;
|
||||
use super::timestamp::inactive_time_range_timestamp;
|
||||
use super::timestamp::inactive_timestamp;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::org_line_ending;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
@ -36,6 +37,8 @@ pub(crate) fn clock<'b, 'g, 'r, 's>(
|
||||
let (remaining, (timestamp, duration)) = clock_timestamp(context, remaining)?;
|
||||
let (remaining, _) = tuple((space0, org_line_ending))(remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
|
@ -13,6 +13,7 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_consumed;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::org_line_ending;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
@ -43,6 +44,8 @@ pub(crate) fn comment<'b, 'g, 'r, 's>(
|
||||
let (remaining, mut remaining_lines) =
|
||||
many0(preceded(not(exit_matcher), comment_line_matcher))(remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
let mut value = Vec::with_capacity(remaining_lines.len() + 1);
|
||||
let last_line = remaining_lines.pop();
|
||||
|
@ -7,6 +7,7 @@ use nom::sequence::tuple;
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::org_line_ending;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
@ -16,14 +17,16 @@ use crate::types::DiarySexp;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub(crate) fn diary_sexp<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, DiarySexp<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(input)?;
|
||||
let (remaining, value) = recognize(tuple((tag("%%("), is_not("\r\n"))))(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(remaining)?;
|
||||
let (remaining, value) = recognize(tuple((tag("%%("), is_not("\r\n"))))(remaining)?;
|
||||
let (remaining, _eol) = org_line_ending(remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
|
@ -14,6 +14,7 @@ use nom::sequence::tuple;
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
@ -44,9 +45,9 @@ pub(crate) fn drawer<'b, 'g, 'r, 's>(
|
||||
"Cannot nest objects of the same element".into(),
|
||||
))));
|
||||
}
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(remaining)?;
|
||||
let (remaining, _leading_whitespace) = space0(remaining)?;
|
||||
let (remaining, (_open_colon, drawer_name, _close_colon, _new_line)) = tuple((
|
||||
tag(":"),
|
||||
name,
|
||||
@ -88,6 +89,8 @@ pub(crate) fn drawer<'b, 'g, 'r, 's>(
|
||||
};
|
||||
let (remaining, _end) = drawer_end(&parser_context, remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
|
||||
Ok((
|
||||
|
@ -20,6 +20,7 @@ use nom::sequence::tuple;
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
@ -49,10 +50,10 @@ pub(crate) fn dynamic_block<'b, 'g, 'r, 's>(
|
||||
"Cannot nest objects of the same element".into(),
|
||||
))));
|
||||
}
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
start_of_line(remaining)?;
|
||||
let (remaining, _leading_whitespace) = space0(remaining)?;
|
||||
let (remaining, (_, name, parameters, _, _)) = tuple((
|
||||
recognize(tuple((tag_no_case("#+begin:"), space1))),
|
||||
name,
|
||||
@ -96,6 +97,8 @@ pub(crate) fn dynamic_block<'b, 'g, 'r, 's>(
|
||||
|
||||
let (remaining, _end) = dynamic_block_end(&parser_context, remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
|
@ -21,6 +21,7 @@ use super::footnote_definition::footnote_definition;
|
||||
use super::greater_block::greater_block;
|
||||
use super::horizontal_rule::horizontal_rule;
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::keyword::affiliated_keyword_as_regular_keyword;
|
||||
use super::keyword::keyword;
|
||||
use super::latex_environment::latex_environment;
|
||||
use super::lesser_block::comment_block;
|
||||
@ -33,8 +34,6 @@ use super::paragraph::paragraph;
|
||||
use super::plain_list::detect_plain_list;
|
||||
use super::plain_list::plain_list;
|
||||
use super::table::detect_table;
|
||||
use super::util::get_consumed;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
@ -42,7 +41,6 @@ use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::table::org_mode_table;
|
||||
use crate::types::Element;
|
||||
use crate::types::SetSource;
|
||||
|
||||
pub(crate) const fn element(
|
||||
can_be_paragraph: bool,
|
||||
@ -137,7 +135,10 @@ fn _element<'b, 'g, 'r, 's>(
|
||||
#[cfg(feature = "tracing")]
|
||||
let _enter = span.enter();
|
||||
|
||||
let (remain, kw) = opt(map(affiliated_keyword, Element::Keyword))(remaining)?;
|
||||
let (remain, kw) = opt(map(
|
||||
parser_with_context!(affiliated_keyword_as_regular_keyword)(context),
|
||||
Element::Keyword,
|
||||
))(remaining)?;
|
||||
if kw.is_some() {
|
||||
maybe_element = kw;
|
||||
remaining = remain;
|
||||
@ -164,13 +165,7 @@ fn _element<'b, 'g, 'r, 's>(
|
||||
"No element.",
|
||||
))));
|
||||
}
|
||||
let mut element = maybe_element.expect("The above if-statement ensures this is Some().");
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
|
||||
let source = get_consumed(input, remaining);
|
||||
element.set_source(source.into());
|
||||
let element = maybe_element.expect("The above if-statement ensures this is Some().");
|
||||
|
||||
Ok((remaining, element))
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ use nom::sequence::tuple;
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::org_line_ending;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::RefContext;
|
||||
@ -26,13 +27,15 @@ pub(crate) fn fixed_width_area<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, FixedWidthArea<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let fixed_width_area_line_matcher = parser_with_context!(fixed_width_area_line)(context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(context);
|
||||
let (remaining, first_line) = fixed_width_area_line_matcher(input)?;
|
||||
let (remaining, first_line) = fixed_width_area_line_matcher(remaining)?;
|
||||
let (remaining, mut remaining_lines) =
|
||||
many0(preceded(not(exit_matcher), fixed_width_area_line_matcher))(remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
let mut value = Vec::with_capacity(remaining_lines.len() + 1);
|
||||
let last_line = remaining_lines.pop();
|
||||
|
@ -15,6 +15,7 @@ use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_name;
|
||||
use super::util::include_input;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::WORD_CONSTITUENT_CHARACTERS;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
@ -43,8 +44,8 @@ pub(crate) fn footnote_definition<'b, 'g, 'r, 's>(
|
||||
"Cannot nest objects of the same element".into(),
|
||||
))));
|
||||
}
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(remaining)?;
|
||||
// Cannot be indented.
|
||||
let (remaining, (_, lbl, _, _, _)) = tuple((
|
||||
tag_no_case("[fn:"),
|
||||
@ -54,7 +55,7 @@ pub(crate) fn footnote_definition<'b, 'g, 'r, 's>(
|
||||
opt(verify(many0(blank_line), |lines: &Vec<OrgSource<'_>>| {
|
||||
lines.len() <= 2
|
||||
})),
|
||||
))(input)?;
|
||||
))(remaining)?;
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
ContextElement::Context("footnote definition"),
|
||||
@ -83,6 +84,8 @@ pub(crate) fn footnote_definition<'b, 'g, 'r, 's>(
|
||||
}
|
||||
}
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
|
@ -21,6 +21,7 @@ use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_name;
|
||||
use super::util::in_section;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
@ -48,6 +49,7 @@ pub(crate) fn greater_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Element<'s>> {
|
||||
let pre_affiliated_keywords_input = input;
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
@ -62,9 +64,24 @@ pub(crate) fn greater_block<'b, 'g, 'r, 's>(
|
||||
))(remaining)?;
|
||||
let name = Into::<&str>::into(name);
|
||||
let (remaining, element) = match name.to_lowercase().as_str() {
|
||||
"center" => center_block(context, remaining, input, &affiliated_keywords)?,
|
||||
"quote" => quote_block(context, remaining, input, &affiliated_keywords)?,
|
||||
_ => special_block(name)(context, remaining, input, &affiliated_keywords)?,
|
||||
"center" => center_block(
|
||||
context,
|
||||
remaining,
|
||||
pre_affiliated_keywords_input,
|
||||
&affiliated_keywords,
|
||||
)?,
|
||||
"quote" => quote_block(
|
||||
context,
|
||||
remaining,
|
||||
pre_affiliated_keywords_input,
|
||||
&affiliated_keywords,
|
||||
)?,
|
||||
_ => special_block(name)(
|
||||
context,
|
||||
remaining,
|
||||
pre_affiliated_keywords_input,
|
||||
&affiliated_keywords,
|
||||
)?,
|
||||
};
|
||||
Ok((remaining, element))
|
||||
}
|
||||
@ -73,11 +90,16 @@ pub(crate) fn greater_block<'b, 'g, 'r, 's>(
|
||||
fn center_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
original_input: OrgSource<'s>,
|
||||
pre_affiliated_keywords_input: OrgSource<'s>,
|
||||
affiliated_keywords: &Vec<Keyword<'s>>,
|
||||
) -> Res<OrgSource<'s>, Element<'s>> {
|
||||
let (remaining, (source, children)) =
|
||||
greater_block_body(context, input, original_input, "center", "center block")?;
|
||||
let (remaining, (source, children)) = greater_block_body(
|
||||
context,
|
||||
input,
|
||||
pre_affiliated_keywords_input,
|
||||
"center",
|
||||
"center block",
|
||||
)?;
|
||||
Ok((
|
||||
remaining,
|
||||
Element::CenterBlock(CenterBlock {
|
||||
@ -92,11 +114,16 @@ fn center_block<'b, 'g, 'r, 's>(
|
||||
fn quote_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
original_input: OrgSource<'s>,
|
||||
pre_affiliated_keywords_input: OrgSource<'s>,
|
||||
affiliated_keywords: &Vec<Keyword<'s>>,
|
||||
) -> Res<OrgSource<'s>, Element<'s>> {
|
||||
let (remaining, (source, children)) =
|
||||
greater_block_body(context, input, original_input, "quote", "quote block")?;
|
||||
let (remaining, (source, children)) = greater_block_body(
|
||||
context,
|
||||
input,
|
||||
pre_affiliated_keywords_input,
|
||||
"quote",
|
||||
"quote block",
|
||||
)?;
|
||||
Ok((
|
||||
remaining,
|
||||
Element::QuoteBlock(QuoteBlock {
|
||||
@ -117,11 +144,11 @@ fn special_block<'s>(
|
||||
) -> Res<OrgSource<'s>, Element<'s>>
|
||||
+ 's {
|
||||
let context_name = format!("special block {}", name);
|
||||
move |context, input, original_input, affiliated_keywords| {
|
||||
move |context, input, pre_affiliated_keywords_input, affiliated_keywords| {
|
||||
_special_block(
|
||||
context,
|
||||
input,
|
||||
original_input,
|
||||
pre_affiliated_keywords_input,
|
||||
name,
|
||||
context_name.as_str(),
|
||||
affiliated_keywords,
|
||||
@ -133,14 +160,19 @@ fn special_block<'s>(
|
||||
fn _special_block<'c, 'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
original_input: OrgSource<'s>,
|
||||
pre_affiliated_keywords_input: OrgSource<'s>,
|
||||
name: &'s str,
|
||||
context_name: &'c str,
|
||||
affiliated_keywords: &Vec<Keyword<'s>>,
|
||||
) -> Res<OrgSource<'s>, Element<'s>> {
|
||||
let (remaining, parameters) = opt(tuple((space1, parameters)))(input)?;
|
||||
let (remaining, (source, children)) =
|
||||
greater_block_body(context, remaining, original_input, name, context_name)?;
|
||||
let (remaining, (source, children)) = greater_block_body(
|
||||
context,
|
||||
remaining,
|
||||
pre_affiliated_keywords_input,
|
||||
name,
|
||||
context_name,
|
||||
)?;
|
||||
Ok((
|
||||
remaining,
|
||||
Element::SpecialBlock(SpecialBlock {
|
||||
@ -157,7 +189,7 @@ fn _special_block<'c, 'b, 'g, 'r, 's>(
|
||||
fn greater_block_body<'c, 'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
original_input: OrgSource<'s>,
|
||||
pre_affiliated_keywords_input: OrgSource<'s>,
|
||||
name: &'c str,
|
||||
context_name: &'c str,
|
||||
) -> Res<OrgSource<'s>, (&'s str, Vec<Element<'s>>)> {
|
||||
@ -202,7 +234,9 @@ fn greater_block_body<'c, 'b, 'g, 'r, 's>(
|
||||
|
||||
// Not checking if parent exit matcher is causing exit because the greater_block_end matcher asserts we matched a full greater block
|
||||
|
||||
let source = get_consumed(original_input, remaining);
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(pre_affiliated_keywords_input, remaining);
|
||||
Ok((remaining, (Into::<&str>::into(source), children)))
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,9 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_consumed;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::Res;
|
||||
use crate::parser::util::start_of_line;
|
||||
@ -19,21 +21,24 @@ use crate::types::HorizontalRule;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub(crate) fn horizontal_rule<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, HorizontalRule<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(input)?;
|
||||
let (remaining, rule) = recognize(tuple((
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(remaining)?;
|
||||
let (remaining, _rule) = recognize(tuple((
|
||||
space0,
|
||||
verify(many1_count(tag("-")), |dashes| *dashes >= 5),
|
||||
space0,
|
||||
alt((line_ending, eof)),
|
||||
)))(input)?;
|
||||
)))(remaining)?;
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
HorizontalRule {
|
||||
source: rule.into(),
|
||||
source: source.into(),
|
||||
name: get_name(&affiliated_keywords),
|
||||
},
|
||||
))
|
||||
|
@ -19,7 +19,9 @@ use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::BracketDepth;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_consumed;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::Matcher;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
@ -89,12 +91,29 @@ fn _filtered_keyword<'s, F: Matcher>(
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub(crate) fn keyword<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Keyword<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, mut kw) = filtered_keyword(regular_keyword_key)(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, mut kw) = filtered_keyword(regular_keyword_key)(remaining)?;
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
kw.name = get_name(&affiliated_keywords);
|
||||
kw.source = Into::<&str>::into(source);
|
||||
Ok((remaining, kw))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub(crate) fn affiliated_keyword_as_regular_keyword<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Keyword<'s>> {
|
||||
let (remaining, mut kw) = affiliated_keyword(input)?;
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
kw.source = Into::<&str>::into(source);
|
||||
Ok((remaining, kw))
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_consumed;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
@ -32,9 +33,10 @@ pub(crate) fn latex_environment<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, LatexEnvironment<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(input)?;
|
||||
let (remaining, _leading_whitespace) = space0(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let value_start = remaining;
|
||||
start_of_line(remaining)?;
|
||||
let (remaining, _leading_whitespace) = space0(remaining)?;
|
||||
let (remaining, (_opening, name, _open_close_brace, _ws, _line_ending)) = tuple((
|
||||
tag_no_case(r#"\begin{"#),
|
||||
name,
|
||||
@ -52,13 +54,18 @@ pub(crate) fn latex_environment<'b, 'g, 'r, 's>(
|
||||
|
||||
let (remaining, _contents) = contents(&latex_environment_end_specialized)(context, remaining)?;
|
||||
let (remaining, _end) = latex_environment_end_specialized(&parser_context, remaining)?;
|
||||
let value_end = remaining;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
let value = get_consumed(value_start, value_end);
|
||||
Ok((
|
||||
remaining,
|
||||
LatexEnvironment {
|
||||
source: source.into(),
|
||||
name: get_name(&affiliated_keywords),
|
||||
value: value.into(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use nom::sequence::tuple;
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ContextMatcher;
|
||||
@ -52,8 +53,8 @@ pub(crate) fn verse_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, VerseBlock<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("verse")(context, input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("verse")(context, remaining)?;
|
||||
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||
let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("verse");
|
||||
@ -91,6 +92,8 @@ pub(crate) fn verse_block<'b, 'g, 'r, 's>(
|
||||
};
|
||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
@ -108,8 +111,8 @@ pub(crate) fn comment_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, CommentBlock<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("comment")(context, input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("comment")(context, remaining)?;
|
||||
let (remaining, _parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||
let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("comment");
|
||||
@ -128,6 +131,8 @@ pub(crate) fn comment_block<'b, 'g, 'r, 's>(
|
||||
let (remaining, contents) = parser_with_context!(text_until_exit)(&parser_context)(remaining)?;
|
||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
@ -144,8 +149,8 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ExampleBlock<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("example")(context, input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("example")(context, remaining)?;
|
||||
let (remaining, parameters) = opt(tuple((space1, example_switches)))(remaining)?;
|
||||
let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("example");
|
||||
@ -165,6 +170,8 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
|
||||
let (remaining, contents) = content(&parser_context, remaining)?;
|
||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = {
|
||||
if let Some(parameters) = parameters {
|
||||
@ -205,8 +212,8 @@ pub(crate) fn export_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ExportBlock<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("export")(context, input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("export")(context, remaining)?;
|
||||
// https://orgmode.org/worg/org-syntax.html#Blocks claims that export blocks must have a single word for data but testing shows no data and multi-word data still parses as an export block.
|
||||
let (remaining, export_type) = opt(map(
|
||||
tuple((space1, switch_word, peek(tuple((space0, line_ending))))),
|
||||
@ -231,6 +238,8 @@ pub(crate) fn export_block<'b, 'g, 'r, 's>(
|
||||
let (remaining, contents) = content(&parser_context, remaining)?;
|
||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
@ -249,8 +258,8 @@ pub(crate) fn src_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, SrcBlock<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("src")(context, input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, _) = lesser_block_begin("src")(context, remaining)?;
|
||||
// https://orgmode.org/worg/org-syntax.html#Blocks claims that data is mandatory and must follow the LANGUAGE SWITCHES ARGUMENTS pattern but testing has shown that no data and incorrect data here will still parse to a src block.
|
||||
let (remaining, language) =
|
||||
opt(map(tuple((space1, switch_word)), |(_, language)| language))(remaining)?;
|
||||
@ -274,6 +283,8 @@ pub(crate) fn src_block<'b, 'g, 'r, 's>(
|
||||
let (remaining, contents) = content(&parser_context, remaining)?;
|
||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = {
|
||||
if let Some(switches) = switches {
|
||||
|
@ -14,6 +14,7 @@ use super::util::blank_line;
|
||||
use super::util::get_consumed;
|
||||
use super::util::get_has_affiliated_keyword;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::ExitClass;
|
||||
@ -33,10 +34,10 @@ pub(crate) fn paragraph<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Paragraph<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let contexts = [
|
||||
ContextElement::HasAffiliatedKeyword(HasAffiliatedKeywordInner {
|
||||
start_after_affiliated_keywords: input,
|
||||
start_after_affiliated_keywords: remaining,
|
||||
keywords: &affiliated_keywords,
|
||||
}),
|
||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||
@ -52,10 +53,12 @@ pub(crate) fn paragraph<'b, 'g, 'r, 's>(
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
many_till(standard_set_object_matcher, exit_matcher),
|
||||
|(children, _exit_contents)| !children.is_empty(),
|
||||
)(input)?;
|
||||
)(remaining)?;
|
||||
|
||||
// Not checking parent exit matcher because if there are any children matched then we have a valid paragraph.
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
|
||||
Ok((
|
||||
|
@ -81,7 +81,7 @@ pub(crate) fn plain_list<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, PlainList<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
|
||||
let contexts = [
|
||||
ContextElement::Context("plain list"),
|
||||
@ -99,7 +99,7 @@ pub(crate) fn plain_list<'b, 'g, 'r, 's>(
|
||||
let mut children = Vec::new();
|
||||
let mut first_item_indentation: Option<IndentationLevel> = None;
|
||||
let mut first_item_list_type: Option<PlainListType> = None;
|
||||
let mut remaining = input;
|
||||
let mut remaining = remaining;
|
||||
|
||||
// The final list item does not consume trailing blank lines (which instead get consumed by the list). We have three options here:
|
||||
//
|
||||
@ -150,6 +150,8 @@ pub(crate) fn plain_list<'b, 'g, 'r, 's>(
|
||||
parser_with_context!(plain_list_item)(&final_item_context)(final_child_start)?;
|
||||
children.push((final_child_start, reparsed_final_item));
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
|
@ -19,6 +19,7 @@ use super::object_parser::table_cell_set_object;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::exit_matcher_parser;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::org_line_ending;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::ContextElement;
|
||||
@ -40,9 +41,9 @@ pub(crate) fn org_mode_table<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Table<'s>> {
|
||||
let (input, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(input)?;
|
||||
peek(tuple((space0, tag("|"))))(input)?;
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
start_of_line(remaining)?;
|
||||
peek(tuple((space0, tag("|"))))(remaining)?;
|
||||
|
||||
let contexts = [
|
||||
ContextElement::ConsumeTrailingWhitespace(true),
|
||||
@ -60,11 +61,13 @@ pub(crate) fn org_mode_table<'b, 'g, 'r, 's>(
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
|
||||
let (remaining, (children, _exit_contents)) =
|
||||
many_till(org_mode_table_row_matcher, exit_matcher)(input)?;
|
||||
many_till(org_mode_table_row_matcher, exit_matcher)(remaining)?;
|
||||
|
||||
let (remaining, formulas) =
|
||||
many0(parser_with_context!(table_formula_keyword)(context))(remaining)?;
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
|
||||
Ok((
|
||||
|
@ -149,6 +149,7 @@ pub struct BabelCall<'s> {
|
||||
pub struct LatexEnvironment<'s> {
|
||||
pub source: &'s str,
|
||||
pub name: Option<&'s str>,
|
||||
pub value: &'s str,
|
||||
}
|
||||
|
||||
/// A line number used in switches to lesser blocks.
|
||||
|
Loading…
x
Reference in New Issue
Block a user