Parser for dynamic blocks.
This commit is contained in:
		
							parent
							
								
									0d07a6aad3
								
							
						
					
					
						commit
						cab5ba70e5
					
				| @ -1,10 +1,33 @@ | ||||
| use super::error::Res; | ||||
| use super::Context; | ||||
| use crate::parser::element::element; | ||||
| use crate::parser::error::CustomError; | ||||
| use crate::parser::error::MyError; | ||||
| use crate::parser::exiting::ExitClass; | ||||
| use crate::parser::greater_element::DynamicBlock; | ||||
| use crate::parser::lesser_element::Paragraph; | ||||
| use crate::parser::parser_context::ContextElement; | ||||
| use crate::parser::parser_context::ExitMatcherNode; | ||||
| use crate::parser::parser_with_context::parser_with_context; | ||||
| use crate::parser::util::blank_line; | ||||
| use crate::parser::util::exit_matcher_parser; | ||||
| use crate::parser::util::get_consumed; | ||||
| use crate::parser::util::immediate_in_section; | ||||
| use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; | ||||
| use crate::parser::util::start_of_line; | ||||
| use crate::parser::Element; | ||||
| use nom::branch::alt; | ||||
| use nom::bytes::complete::is_not; | ||||
| use nom::bytes::complete::tag_no_case; | ||||
| use nom::character::complete::line_ending; | ||||
| use nom::character::complete::space0; | ||||
| use nom::character::complete::space1; | ||||
| use nom::combinator::consumed; | ||||
| use nom::combinator::eof; | ||||
| use nom::combinator::opt; | ||||
| use nom::combinator::recognize; | ||||
| use nom::multi::many_till; | ||||
| use nom::sequence::tuple; | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| pub fn dynamic_block<'r, 's>( | ||||
| @ -18,5 +41,71 @@ pub fn dynamic_block<'r, 's>( | ||||
|         )))); | ||||
|     } | ||||
|     start_of_line(context, input)?; | ||||
|     todo!() | ||||
|     let (remaining, _leading_whitespace) = space0(input)?; | ||||
|     let (remaining, (_begin, name, parameters, _ws)) = tuple(( | ||||
|         recognize(tuple((tag_no_case("#+begin:"), space1))), | ||||
|         name, | ||||
|         opt(tuple((space1, parameters))), | ||||
|         line_ending, | ||||
|     ))(remaining)?; | ||||
|     let parser_context = context | ||||
|         .with_additional_node(ContextElement::ConsumeTrailingWhitespace(true)) | ||||
|         .with_additional_node(ContextElement::Context("dynamic block")) | ||||
|         .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Alpha, | ||||
|             exit_matcher: &dynamic_block_end, | ||||
|         })); | ||||
|     let parameters = match parameters { | ||||
|         Some((_ws, parameters)) => Some(parameters), | ||||
|         None => None, | ||||
|     }; | ||||
|     let element_matcher = parser_with_context!(element)(&parser_context); | ||||
|     let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); | ||||
|     let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { | ||||
|         Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( | ||||
|             remaining, | ||||
|             vec![Element::Paragraph(Paragraph::of_text(whitespace))], | ||||
|         ), | ||||
|         Err(_) => { | ||||
|             let (remaining, (children, _exit_contents)) = | ||||
|                 many_till(element_matcher, exit_matcher)(remaining)?; | ||||
|             (remaining, children) | ||||
|         } | ||||
|     }; | ||||
|     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, | ||||
|         DynamicBlock { | ||||
|             source, | ||||
|             name, | ||||
|             parameters, | ||||
|             children, | ||||
|         }, | ||||
|     )) | ||||
| } | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| fn name<'s>(input: &'s str) -> Res<&'s str, &'s str> { | ||||
|     is_not(" \t\r\n")(input) | ||||
| } | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| fn parameters<'s>(input: &'s str) -> Res<&'s str, &'s str> { | ||||
|     is_not("\r\n")(input) | ||||
| } | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| fn dynamic_block_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { | ||||
|     start_of_line(context, input)?; | ||||
|     let (remaining, source) = recognize(tuple(( | ||||
|         space0, | ||||
|         tag_no_case("#+end:"), | ||||
|         alt((eof, line_ending)), | ||||
|     )))(input)?; | ||||
|     Ok((remaining, source)) | ||||
| } | ||||
|  | ||||
| @ -67,10 +67,9 @@ pub fn greater_block<'r, 's>( | ||||
| 
 | ||||
|     let element_matcher = parser_with_context!(element)(&parser_context); | ||||
|     let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); | ||||
|     // TODO: Not handling nested greater blocks
 | ||||
|     // Check for a completely empty block
 | ||||
|     let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { | ||||
|         Ok((remaining, (whitespace, (children, _exit_contents)))) => ( | ||||
|         Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( | ||||
|             remaining, | ||||
|             vec![Element::Paragraph(Paragraph::of_text(whitespace))], | ||||
|         ), | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander