Compare commits
	
		
			4 Commits
		
	
	
		
			f65e659052
			...
			45d5ebaa18
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 45d5ebaa18 | ||
|   | cdd813fbe6 | ||
|   | d24c26de7b | ||
|   | c0371ff958 | 
							
								
								
									
										2
									
								
								build.rs
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								build.rs
									
									
									
									
									
								
							| @ -58,7 +58,7 @@ fn write_header(test_file: &mut File) { | ||||
|     write!( | ||||
|         test_file, | ||||
|         r#" | ||||
| #[feature(exit_status_error)] | ||||
| #![feature(exit_status_error)] | ||||
| use organic::compare_document; | ||||
| use organic::parser::document; | ||||
| use organic::emacs_parse_org_document; | ||||
|  | ||||
							
								
								
									
										3
									
								
								org_mode_samples/macro/built_in_macro.org
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								org_mode_samples/macro/built_in_macro.org
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| #+title: built_in_macro | ||||
| 
 | ||||
| {{{title}}} | ||||
							
								
								
									
										1
									
								
								org_mode_samples/macro/macro_with_args.org
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								org_mode_samples/macro/macro_with_args.org
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| {{{foo(bar, baz)}}} | ||||
| @ -24,6 +24,7 @@ use crate::parser::Italic; | ||||
| use crate::parser::Keyword; | ||||
| use crate::parser::LatexEnvironment; | ||||
| use crate::parser::Object; | ||||
| use crate::parser::OrgMacro; | ||||
| use crate::parser::Paragraph; | ||||
| use crate::parser::PlainLink; | ||||
| use crate::parser::PlainList; | ||||
| @ -152,6 +153,7 @@ fn compare_object<'s>( | ||||
|         Object::RadioTarget(obj) => compare_radio_target(source, emacs, obj), | ||||
|         Object::PlainLink(obj) => compare_plain_link(source, emacs, obj), | ||||
|         Object::AngleLink(obj) => compare_angle_link(source, emacs, obj), | ||||
|         Object::OrgMacro(obj) => compare_org_macro(source, emacs, obj), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -1213,3 +1215,26 @@ fn compare_angle_link<'s>( | ||||
|         children: Vec::new(), | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| fn compare_org_macro<'s>( | ||||
|     source: &'s str, | ||||
|     emacs: &'s Token<'s>, | ||||
|     rust: &'s OrgMacro<'s>, | ||||
| ) -> Result<DiffResult, Box<dyn std::error::Error>> { | ||||
|     let mut this_status = DiffStatus::Good; | ||||
|     let emacs_name = "macro"; | ||||
|     if assert_name(emacs, emacs_name).is_err() { | ||||
|         this_status = DiffStatus::Bad; | ||||
|     } | ||||
| 
 | ||||
|     if assert_bounds(source, emacs, rust).is_err() { | ||||
|         this_status = DiffStatus::Bad; | ||||
|     } | ||||
| 
 | ||||
|     Ok(DiffResult { | ||||
|         status: this_status, | ||||
|         name: emacs_name.to_owned(), | ||||
|         message: None, | ||||
|         children: Vec::new(), | ||||
|     }) | ||||
| } | ||||
|  | ||||
| @ -20,6 +20,7 @@ mod lesser_element; | ||||
| mod list; | ||||
| mod object; | ||||
| mod object_parser; | ||||
| mod org_macro; | ||||
| mod paragraph; | ||||
| mod parser_context; | ||||
| mod parser_with_context; | ||||
| @ -70,6 +71,7 @@ pub use object::Bold; | ||||
| pub use object::Code; | ||||
| pub use object::Italic; | ||||
| pub use object::Object; | ||||
| pub use object::OrgMacro; | ||||
| pub use object::PlainLink; | ||||
| pub use object::PlainText; | ||||
| pub use object::RadioLink; | ||||
|  | ||||
| @ -2,11 +2,6 @@ use super::source::Source; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq)] | ||||
| pub enum Object<'s> { | ||||
|     RegularLink(RegularLink<'s>), | ||||
|     RadioLink(RadioLink<'s>), | ||||
|     RadioTarget(RadioTarget<'s>), | ||||
|     PlainLink(PlainLink<'s>), | ||||
|     AngleLink(AngleLink<'s>), | ||||
|     Bold(Bold<'s>), | ||||
|     Italic(Italic<'s>), | ||||
|     Underline(Underline<'s>), | ||||
| @ -14,6 +9,12 @@ pub enum Object<'s> { | ||||
|     Code(Code<'s>), | ||||
|     Verbatim(Verbatim<'s>), | ||||
|     PlainText(PlainText<'s>), | ||||
|     RegularLink(RegularLink<'s>), | ||||
|     RadioLink(RadioLink<'s>), | ||||
|     RadioTarget(RadioTarget<'s>), | ||||
|     PlainLink(PlainLink<'s>), | ||||
|     AngleLink(AngleLink<'s>), | ||||
|     OrgMacro(OrgMacro<'s>), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, PartialEq)] | ||||
| @ -88,6 +89,13 @@ pub struct AngleLink<'s> { | ||||
|     pub path: &'s str, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, PartialEq)] | ||||
| pub struct OrgMacro<'s> { | ||||
|     pub source: &'s str, | ||||
|     pub macro_name: &'s str, | ||||
|     pub macro_args: Vec<&'s str>, | ||||
| } | ||||
| 
 | ||||
| impl<'s> Source<'s> for Object<'s> { | ||||
|     fn get_source(&'s self) -> &'s str { | ||||
|         match self { | ||||
| @ -103,6 +111,7 @@ impl<'s> Source<'s> for Object<'s> { | ||||
|             Object::RadioTarget(obj) => obj.source, | ||||
|             Object::PlainLink(obj) => obj.source, | ||||
|             Object::AngleLink(obj) => obj.source, | ||||
|             Object::OrgMacro(obj) => obj.source, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -172,3 +181,9 @@ impl<'s> Source<'s> for AngleLink<'s> { | ||||
|         self.source | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'s> Source<'s> for OrgMacro<'s> { | ||||
|     fn get_source(&'s self) -> &'s str { | ||||
|         self.source | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -8,6 +8,7 @@ use super::regular_link::regular_link; | ||||
| use super::Context; | ||||
| use crate::error::Res; | ||||
| use crate::parser::angle_link::angle_link; | ||||
| use crate::parser::org_macro::org_macro; | ||||
| use crate::parser::object::Object; | ||||
| use crate::parser::plain_link::plain_link; | ||||
| use crate::parser::radio_link::radio_link; | ||||
| @ -35,6 +36,7 @@ pub fn standard_set_object<'r, 's>( | ||||
|         ), | ||||
|         map(parser_with_context!(plain_link)(context), Object::PlainLink), | ||||
|         map(parser_with_context!(angle_link)(context), Object::AngleLink), | ||||
|         map(parser_with_context!(org_macro)(context), Object::OrgMacro), | ||||
|         map(parser_with_context!(plain_text)(context), Object::PlainText), | ||||
|     ))(input) | ||||
| } | ||||
| @ -72,6 +74,7 @@ pub fn any_object_except_plain_text<'r, 's>( | ||||
|         ), | ||||
|         map(parser_with_context!(plain_link)(context), Object::PlainLink), | ||||
|         map(parser_with_context!(angle_link)(context), Object::AngleLink), | ||||
|         map(parser_with_context!(org_macro)(context), Object::OrgMacro), | ||||
|     ))(input) | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										78
									
								
								src/parser/org_macro.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/parser/org_macro.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,78 @@ | ||||
| use nom::bytes::complete::tag; | ||||
| use nom::character::complete::anychar; | ||||
| use nom::combinator::not; | ||||
| use nom::combinator::opt; | ||||
| use nom::combinator::peek; | ||||
| use nom::combinator::verify; | ||||
| use nom::multi::many0; | ||||
| use nom::multi::separated_list0; | ||||
| 
 | ||||
| use super::Context; | ||||
| use crate::error::Res; | ||||
| use crate::parser::object::OrgMacro; | ||||
| use crate::parser::parser_with_context::parser_with_context; | ||||
| use crate::parser::util::exit_matcher_parser; | ||||
| use crate::parser::util::get_consumed; | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| pub fn org_macro<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, OrgMacro<'s>> { | ||||
|     let (remaining, _) = tag("{{{")(input)?; | ||||
|     let (remaining, macro_name) = org_macro_name(context, remaining)?; | ||||
|     let (remaining, macro_args) = opt(parser_with_context!(org_macro_args)(context))(remaining)?; | ||||
|     let (remaining, _) = tag("}}}")(remaining)?; | ||||
| 
 | ||||
|     let source = get_consumed(input, remaining); | ||||
|     Ok(( | ||||
|         remaining, | ||||
|         OrgMacro { | ||||
|             source, | ||||
|             macro_name, | ||||
|             macro_args: macro_args.unwrap_or_else(|| Vec::with_capacity(0)), | ||||
|         }, | ||||
|     )) | ||||
| } | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| fn org_macro_name<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { | ||||
|     let (remaining, _) = verify(anychar, |c| c.is_alphabetic())(input)?; | ||||
|     let (remaining, _) = many0(verify(anychar, |c| { | ||||
|         c.is_alphanumeric() || *c == '-' || *c == '_' | ||||
|     }))(remaining)?; | ||||
|     let source = get_consumed(input, remaining); | ||||
|     Ok((remaining, source)) | ||||
| } | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| fn org_macro_args<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Vec<&'s str>> { | ||||
|     let (remaining, _) = tag("(")(input)?; | ||||
|     let (remaining, args) = | ||||
|         separated_list0(tag(","), parser_with_context!(org_macro_arg)(context))(remaining)?; | ||||
|     let (remaining, _) = tag(")")(remaining)?; | ||||
| 
 | ||||
|     Ok((remaining, args)) | ||||
| } | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| fn org_macro_arg<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { | ||||
|     let mut remaining = input; | ||||
|     let mut escaping: bool = false; | ||||
|     loop { | ||||
|         not(parser_with_context!(exit_matcher_parser)(context))(remaining)?; | ||||
|         not(peek(tag("}}}")))(remaining)?; | ||||
|         let (new_remaining, next_char) = anychar(remaining)?; | ||||
|         if escaping { | ||||
|             remaining = new_remaining; | ||||
|             escaping = false; | ||||
|             continue; | ||||
|         } | ||||
|         if next_char == '\\' { | ||||
|             escaping = true; | ||||
|         } | ||||
|         if next_char == ',' || next_char == ')' { | ||||
|             break; | ||||
|         } | ||||
|         remaining = new_remaining; | ||||
|     } | ||||
|     let source = get_consumed(input, remaining); | ||||
|     Ok((remaining, source)) | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user