diff options
| author | nitnelave | 2020-10-25 16:32:35 +0100 | 
|---|---|---|
| committer | GitHub | 2020-10-25 16:32:35 +0100 | 
| commit | 273a69564f03d65c2040b25b68a7ddb2c8aa2087 (patch) | |
| tree | ed15a7a73e4fb0a6aa309de04e88f5f72050e3ad | |
| parent | 4c487a44208a96e3a23ab8974d224cae489688be (diff) | |
| download | rust-rst-273a69564f03d65c2040b25b68a7ddb2c8aa2087.tar.bz2 | |
Add support for parsing comments (#23)
| -rw-r--r-- | parser/src/conversion/block.rs | 24 | ||||
| -rw-r--r-- | parser/src/rst.pest | 12 | ||||
| -rw-r--r-- | parser/src/tests.rs | 70 | 
3 files changed, 105 insertions, 1 deletions
| diff --git a/parser/src/conversion/block.rs b/parser/src/conversion/block.rs index 9498b32..f5697fc 100644 --- a/parser/src/conversion/block.rs +++ b/parser/src/conversion/block.rs @@ -55,6 +55,7 @@ fn convert_body_elem(pair: Pair<Rule>) -> Result<c::BodyElement, Error> {  		Rule::bullet_list      => convert_bullet_list(pair)?.into(),  		Rule::code_directive   => convert_code_directive(pair)?.into(),  		Rule::raw_directive    => convert_raw_directive(pair)?.into(), +		Rule::block_comment    => convert_comment(pair)?.into(),  		rule => unimplemented!("unhandled rule {:?}", rule),  	})  } @@ -134,7 +135,7 @@ fn convert_replace(pair: Pair<Rule>) -> Result<Vec<c::TextOrInlineElement>, Erro  	let mut pairs = pair.into_inner();  	let paragraph = pairs.next().unwrap();  	convert_inlines(paragraph) -}  +}  fn convert_image<I>(pair: Pair<Rule>) -> Result<I, Error> where I: Element + ExtraAttributes<a::Image> {  	let mut pairs = pair.into_inner(); @@ -234,3 +235,24 @@ fn convert_raw_directive(pair: Pair<Rule>) -> Result<e::Raw, Error> {  	raw_block.extra_mut().format.push(at::NameToken(format.as_str().to_owned()));  	Ok(raw_block)  } + +fn convert_comment_block(pair: Pair<Rule>) -> String { +	let iter = pair.into_inner(); +	let block = iter.skip(1).next().unwrap(); +	let text = block.into_inner().map(|l| match l.as_rule() { +		Rule::comment_line_blank => "", +		Rule::comment_line => l.as_str(), +		_ => unreachable!(), +	}.into()).collect::<Vec<&str>>().join("\n"); +	text +} + +fn convert_comment(pair: Pair<Rule>) -> Result<e::Comment, Error> { +	let block = pair.into_inner().skip(1).next().unwrap(); +	let children = block.into_inner().map(|l| match l.as_rule() { +		Rule::comment_title => String::from(l.as_str()), +		Rule::comment_block => convert_comment_block(l), +		_ => unreachable!(), +	}.into()).collect(); +	Ok(e::Comment::with_children(children)) +} diff --git a/parser/src/rst.pest b/parser/src/rst.pest index 8885109..4329e84 100644 --- a/parser/src/rst.pest +++ b/parser/src/rst.pest @@ -20,6 +20,9 @@ hanging_block = _{      | admonition      | admonition_gen      | target +    // Comments should be below the directives to try to match them first, but +    // above the title that will interpret ".." as a title marker. +    | block_comment      | title      | bullet_list      | paragraph @@ -110,6 +113,15 @@ admonition_gen     =  { ".." ~ PUSH(" "+) ~  admonition_type ~ "::" ~ (blank_lin  admonition_type    =  { ^"attention" | ^"caution" | ^"danger" | ^"error" | ^"hint" | ^"important" | ^"note" | ^"tip" | ^"warning" }  admonition_content = _{ PEEK[..-1] ~ PUSH("  " ~ POP) ~ hanging_block ~ block* } //TODO: merge with other directives? +// Comments. + +block_comment   = { +    ".." ~ PUSH(" "*) ~ comment_title? ~ NEWLINE? ~ comment_block? ~ (" "* ~ NEWLINE)* ~ DROP +} +comment_title = { (!NEWLINE ~ ANY)+ } +comment_block = { (comment_line_blank* ~ PEEK[..] ~ comment_line)+ } +comment_line_blank = { " "* ~ NEWLINE } +comment_line       = { " "+ ~ (!NEWLINE ~ ANY)+ ~ NEWLINE }  /* diff --git a/parser/src/tests.rs b/parser/src/tests.rs index 93e20ec..b4b9e19 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -225,6 +225,76 @@ The end  #[allow(clippy::cognitive_complexity)]  #[test] +fn comments() { +	parses_to! { +		parser: RstParser, +		input: "\ +.. This is a comment + +.. +   This as well. + +.. +   _so: is this! +.. +   [and] this! +.. +   this:: too! +.. +   |even| this:: ! +.. With a title.. + +   and a blank line... +   followed by a non-blank line + +   and another one. +", +		rule: Rule::document, +		tokens: [ +			block_comment(0, 22, [ +				comment_title(3, 20), +			]), +			block_comment(22, 43, [ +				comment_block(25, 42, [ +					comment_line(25, 42), +				]) +			]), +			block_comment(43, 63, [ +				comment_block(46, 63, [ +					comment_line(46, 63), +				]) +			]), +			block_comment(63, 81, [ +				comment_block(66, 81, [ +					comment_line(66, 81), +				]) +			]), +			block_comment(81, 99, [ +				comment_block(84, 99, [ +					comment_line(84, 99), +				]) +			]), +			block_comment(99, 121, [ +				comment_block(102, 121, [ +					comment_line(102, 121), +				]) +			]), +			block_comment(121, 216, [ +				comment_title(124, 138), +				comment_block(139, 216, [ +					comment_line_blank(139, 140), +					comment_line(141, 163), +					comment_line(164, 195), +					comment_line_blank(195, 196), +					comment_line(197, 216), +				]) +			]), +		] +	}; +} + +#[allow(clippy::cognitive_complexity)] +#[test]  fn substitutions() {  	parses_to! {  		parser: RstParser, | 
