Merge branch 'comment'
This commit is contained in:
		
						commit
						ea74e329b2
					
				
							
								
								
									
										23
									
								
								org_mode_samples/comment/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								org_mode_samples/comment/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| SHELL := bash | ||||
| .ONESHELL: | ||||
| .SHELLFLAGS := -eu -o pipefail -c | ||||
| .DELETE_ON_ERROR: | ||||
| MAKEFLAGS += --warn-undefined-variables | ||||
| MAKEFLAGS += --no-builtin-rules | ||||
| SRCFILES := $(wildcard *.org) | ||||
| OUTFILES := $(patsubst %.org,%.tree.txt,$(SRCFILES)) | ||||
| 
 | ||||
| ifeq ($(origin .RECIPEPREFIX), undefined) | ||||
|   $(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later) | ||||
| endif | ||||
| .RECIPEPREFIX = > | ||||
| 
 | ||||
| .PHONY: all | ||||
| all: $(OUTFILES) | ||||
| 
 | ||||
| .PHONY: clean | ||||
| clean: | ||||
| > rm -rf $(OUTFILES) | ||||
| 
 | ||||
| %.tree.txt: %.org ../common.el ../dump_org_ast.bash | ||||
| > ../dump_org_ast.bash $< $@ | ||||
							
								
								
									
										8
									
								
								org_mode_samples/comment/indented.org
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								org_mode_samples/comment/indented.org
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| # Comment | ||||
|   # indented line | ||||
| #        At the top of the file | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| foo | ||||
| # Another comment | ||||
							
								
								
									
										5
									
								
								org_mode_samples/comment/multiline_comment.org
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								org_mode_samples/comment/multiline_comment.org
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # Comment | ||||
| # | ||||
| # At the top of the file | ||||
| foo | ||||
| # Another comment | ||||
| @ -0,0 +1,3 @@ | ||||
| # Comment line | ||||
| #not a comment | ||||
| # Comment again | ||||
| @ -1,5 +1,6 @@ | ||||
| use super::sexp::Token; | ||||
| use crate::compare::util::get_offsets; | ||||
| use crate::parser::Comment; | ||||
| use crate::parser::Document; | ||||
| use crate::parser::DocumentElement; | ||||
| use crate::parser::Element; | ||||
| @ -216,6 +217,7 @@ fn compare_element<'s>( | ||||
|         Element::PlainList(obj) => compare_plain_list(source, emacs, obj), | ||||
|         Element::GreaterBlock(obj) => compare_greater_block(source, emacs, obj), | ||||
|         Element::FootnoteDefinition(obj) => compare_footnote_definition(source, emacs, obj), | ||||
|         Element::Comment(obj) => compare_comment(source, emacs, obj), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -453,3 +455,44 @@ fn compare_footnote_definition<'s>( | ||||
|         children: child_status, | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| fn compare_comment<'s>( | ||||
|     source: &'s str, | ||||
|     emacs: &'s Token<'s>, | ||||
|     rust: &'s Comment<'s>, | ||||
| ) -> Result<DiffResult, Box<dyn std::error::Error>> { | ||||
|     let children = emacs.as_list()?; | ||||
|     let first_child = children | ||||
|         .first() | ||||
|         .ok_or("Should have at least one child.")? | ||||
|         .as_atom()?; | ||||
|     if first_child != "comment" { | ||||
|         return Err("Comment should correspond to a comment cell.".into()); | ||||
|     } | ||||
|     let mut child_status = Vec::new(); | ||||
|     let mut this_status = DiffStatus::Good; | ||||
| 
 | ||||
|     let attributes_child = children | ||||
|         .iter() | ||||
|         .nth(1) | ||||
|         .ok_or("Should have an attributes child.")?; | ||||
|     let attributes_map = attributes_child.as_map()?; | ||||
|     let begin = attributes_map | ||||
|         .get(":begin") | ||||
|         .ok_or("Missing :begin attribute.")? | ||||
|         .as_atom()?; | ||||
|     let end = attributes_map | ||||
|         .get(":end") | ||||
|         .ok_or("Missing :end attribute.")? | ||||
|         .as_atom()?; | ||||
|     let (rust_begin, rust_end) = get_offsets(source, rust); | ||||
|     if (rust_begin + 1).to_string() != begin || (rust_end + 1).to_string() != end { | ||||
|         this_status = DiffStatus::Bad; | ||||
|     } | ||||
| 
 | ||||
|     Ok(DiffResult { | ||||
|         status: this_status, | ||||
|         name: "comment".to_owned(), | ||||
|         children: child_status, | ||||
|     }) | ||||
| } | ||||
|  | ||||
							
								
								
									
										76
									
								
								src/parser/comment.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/parser/comment.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | ||||
| use nom::branch::alt; | ||||
| use nom::bytes::complete::is_not; | ||||
| use nom::bytes::complete::tag; | ||||
| use nom::character::complete::line_ending; | ||||
| use nom::character::complete::space0; | ||||
| use nom::character::complete::space1; | ||||
| use nom::combinator::eof; | ||||
| use nom::combinator::not; | ||||
| use nom::combinator::opt; | ||||
| use nom::multi::many0; | ||||
| use nom::sequence::preceded; | ||||
| use nom::sequence::tuple; | ||||
| 
 | ||||
| use super::util::get_consumed; | ||||
| use super::Context; | ||||
| use crate::parser::error::Res; | ||||
| use crate::parser::parser_with_context::parser_with_context; | ||||
| use crate::parser::util::exit_matcher_parser; | ||||
| use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; | ||||
| use crate::parser::util::start_of_line; | ||||
| use crate::parser::Comment; | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| pub fn comment<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Comment<'s>> { | ||||
|     let comment_line_matcher = parser_with_context!(comment_line)(context); | ||||
|     let exit_matcher = parser_with_context!(exit_matcher_parser)(context); | ||||
|     let (remaining, first_line) = comment_line_matcher(input)?; | ||||
|     let (remaining, 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); | ||||
|     Ok((remaining, Comment { source })) | ||||
| } | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| fn comment_line<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { | ||||
|     start_of_line(context, input)?; | ||||
|     let (remaining, _indent) = space0(input)?; | ||||
|     let (remaining, (_hash, _leading_whitespace_and_content, _line_ending)) = | ||||
|         tuple((tag("#"), opt(tuple((space1, is_not("\r\n")))), alt((line_ending, eof))))(remaining)?; | ||||
|     let source = get_consumed(input, remaining); | ||||
|     Ok((remaining, source)) | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::parser::parser_context::ContextElement; | ||||
|     use crate::parser::parser_context::ContextTree; | ||||
|     use crate::parser::parser_with_context::parser_with_context; | ||||
| 
 | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn require_space_after_hash() { | ||||
|         let input = "# Comment line
 | ||||
| #not a comment | ||||
| # Comment again";
 | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let document_context = | ||||
|             initial_context.with_additional_node(ContextElement::DocumentRoot(input)); | ||||
|         let comment_matcher = | ||||
|             parser_with_context!(comment)(&document_context); | ||||
|         let (remaining, first_comment) = | ||||
|             comment_matcher(input).expect("Parse first comment"); | ||||
|         assert_eq!(remaining, r#"#not a comment
 | ||||
| # Comment again"#);
 | ||||
|         assert_eq!( | ||||
|             first_comment.source, | ||||
|             "# Comment line
 | ||||
| " | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @ -1,15 +1,17 @@ | ||||
| use super::PlainListItem; | ||||
| use super::comment::comment; | ||||
| use super::error::Res; | ||||
| use super::footnote_definition::footnote_definition; | ||||
| use super::greater_block::greater_block; | ||||
| use super::greater_element::FootnoteDefinition; | ||||
| use super::greater_element::GreaterBlock; | ||||
| use super::greater_element::PlainList; | ||||
| use super::lesser_element::Comment; | ||||
| use super::lesser_element::Paragraph; | ||||
| use super::paragraph::paragraph; | ||||
| use super::plain_list::plain_list; | ||||
| use super::source::Source; | ||||
| use super::Context; | ||||
| use super::PlainListItem; | ||||
| use crate::parser::parser_with_context::parser_with_context; | ||||
| use nom::branch::alt; | ||||
| use nom::combinator::map; | ||||
| @ -20,6 +22,7 @@ pub enum Element<'s> { | ||||
|     PlainList(PlainList<'s>), | ||||
|     GreaterBlock(GreaterBlock<'s>), | ||||
|     FootnoteDefinition(FootnoteDefinition<'s>), | ||||
|     Comment(Comment<'s>), | ||||
| } | ||||
| 
 | ||||
| impl<'s> Source<'s> for Element<'s> { | ||||
| @ -29,6 +32,7 @@ impl<'s> Source<'s> for Element<'s> { | ||||
|             Element::PlainList(obj) => obj.source, | ||||
|             Element::GreaterBlock(obj) => obj.source, | ||||
|             Element::FootnoteDefinition(obj) => obj.source, | ||||
|             Element::Comment(obj) => obj.source, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -63,6 +67,12 @@ impl<'s> Source<'s> for FootnoteDefinition<'s> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'s> Source<'s> for Comment<'s> { | ||||
|     fn get_source(&'s self) -> &'s str { | ||||
|         self.source | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[tracing::instrument(ret, level = "debug")] | ||||
| pub fn element<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Element<'s>> { | ||||
|     let non_paragraph_matcher = parser_with_context!(non_paragraph_element)(context); | ||||
| @ -81,9 +91,11 @@ pub fn non_paragraph_element<'r, 's>( | ||||
|     let plain_list_matcher = parser_with_context!(plain_list)(context); | ||||
|     let greater_block_matcher = parser_with_context!(greater_block)(context); | ||||
|     let footnote_definition_matcher = parser_with_context!(footnote_definition)(context); | ||||
|     let comment_matcher = parser_with_context!(comment)(context); | ||||
|     alt(( | ||||
|         map(plain_list_matcher, Element::PlainList), | ||||
|         map(greater_block_matcher, Element::GreaterBlock), | ||||
|         map(footnote_definition_matcher, Element::FootnoteDefinition), | ||||
|         map(comment_matcher, Element::Comment), | ||||
|     ))(input) | ||||
| } | ||||
|  | ||||
| @ -5,3 +5,8 @@ pub struct Paragraph<'s> { | ||||
|     pub source: &'s str, | ||||
|     pub children: Vec<Object<'s>>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Comment<'s> { | ||||
|     pub source: &'s str, | ||||
| } | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| mod comment; | ||||
| mod document; | ||||
| mod element; | ||||
| mod error; | ||||
| @ -24,6 +25,7 @@ pub use greater_element::FootnoteDefinition; | ||||
| pub use greater_element::GreaterBlock; | ||||
| pub use greater_element::PlainList; | ||||
| pub use greater_element::PlainListItem; | ||||
| pub use lesser_element::Comment; | ||||
| pub use lesser_element::Paragraph; | ||||
| pub use source::Source; | ||||
| type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander