Merge branch 'latex_environment_properties'
This commit is contained in:
		
						commit
						627c785e24
					
				| @ -2484,8 +2484,6 @@ fn compare_latex_environment<'b, 's>( | ||||
|     let mut this_status = DiffStatus::Good; | ||||
|     let mut message = None; | ||||
| 
 | ||||
|     // TODO: Compare :value
 | ||||
| 
 | ||||
|     // TODO: Compare :caption
 | ||||
|     // Compare name
 | ||||
|     let name = get_property_quoted_string(emacs, ":name")?; | ||||
| @ -2497,6 +2495,16 @@ 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.value) { | ||||
|         this_status = DiffStatus::Bad; | ||||
|         message = Some(format!( | ||||
|             "Value mismatch (emacs != rust) {:?} != {:?}", | ||||
|             value, rust.value | ||||
|         )); | ||||
|     } | ||||
| 
 | ||||
|     Ok(DiffResult { | ||||
|         status: this_status, | ||||
|         name: rust.get_elisp_name(), | ||||
|  | ||||
| @ -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
	 Tom Alexander
						Tom Alexander