diff options
| -rw-r--r-- | parser/src/conversion/block.rs | 15 | ||||
| -rw-r--r-- | parser/src/rst.pest | 12 | ||||
| -rw-r--r-- | parser/src/tests.rs | 39 | ||||
| -rw-r--r-- | renderer/src/html.rs | 8 | ||||
| -rw-r--r-- | renderer/src/html/tests.rs | 25 | 
5 files changed, 97 insertions, 2 deletions
| diff --git a/parser/src/conversion/block.rs b/parser/src/conversion/block.rs index 64aa33e..9498b32 100644 --- a/parser/src/conversion/block.rs +++ b/parser/src/conversion/block.rs @@ -54,6 +54,7 @@ fn convert_body_elem(pair: Pair<Rule>) -> Result<c::BodyElement, Error> {  		Rule::image            => convert_image::<e::Image>(pair)?.into(),  		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 => unimplemented!("unhandled rule {:?}", rule),  	})  } @@ -219,3 +220,17 @@ fn convert_code_directive(pair: Pair<Rule>) -> Result<e::LiteralBlock, Error> {  	};  	Ok(code_block)  } + +fn convert_raw_directive(pair: Pair<Rule>) -> Result<e::Raw, Error> { +	let mut iter = pair.into_inner(); +	let format = iter.next().unwrap(); +    let block = iter.next().unwrap(); +	let children = block.into_inner().map(|l| match l.as_rule() { +		Rule::raw_line => l.as_str(), +		Rule::raw_line_blank => "\n", +		_ => unreachable!(), +	}.into()).collect(); +	let mut raw_block = e::Raw::with_children(children); +	raw_block.extra_mut().format.push(at::NameToken(format.as_str().to_owned())); +	Ok(raw_block) +} diff --git a/parser/src/rst.pest b/parser/src/rst.pest index 322ad08..8885109 100644 --- a/parser/src/rst.pest +++ b/parser/src/rst.pest @@ -16,6 +16,7 @@ hanging_block = _{      substitution_def      | image_directive      | code_directive +    | raw_directive      | admonition      | admonition_gen      | target @@ -91,6 +92,17 @@ code_block = { code_line ~ (code_line_blank* ~ PEEK[..] ~ code_line)* }  code_line_blank = { " "* ~ NEWLINE }  code_line       = { (!NEWLINE ~ ANY)+ ~ NEWLINE } +// Raw block. A directive + +raw_directive = { +    ".." ~ PUSH(" "+) ~ "raw::" ~ " "+ ~ raw_output_format ~ NEWLINE ~ +    blank_line+ ~ PEEK[..-1] ~ PUSH("  " ~ POP) ~ raw_block ~ DROP +} +raw_output_format = { (!NEWLINE ~ ANY)+ } +raw_block = { raw_line ~ (raw_line_blank* ~ PEEK[..] ~ raw_line)* } +raw_line_blank = { " "* ~ NEWLINE } +raw_line       = { (!NEWLINE ~ ANY)+ ~ NEWLINE } +  // Admonition. A directive. The generic one has a title  admonition         =  { ".." ~ PUSH(" "+) ~ ^"admonition::" ~ line  ~ blank_line* ~ admonition_content? ~ DROP } diff --git a/parser/src/tests.rs b/parser/src/tests.rs index 504d13b..93e20ec 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -186,6 +186,45 @@ The end  #[allow(clippy::cognitive_complexity)]  #[test] +fn raw() { +	parses_to! { +		parser: RstParser, +		input: "\ +.. raw:: html + +   hello <span>world</span> + +.. raw:: html + +   hello <pre>world + +   parse</pre> this + +The end +", +		rule: Rule::document, +		tokens: [ +			raw_directive(0, 43, [ +				raw_output_format(9, 13), +				raw_block(18, 43, [ +					raw_line(18, 43), +				]), +			]), +			raw_directive(44, 100, [ +				raw_output_format(53, 57), +				raw_block(62, 100, [ +					raw_line(62, 79), +					raw_line_blank(79, 80), +					raw_line(83, 100), +				]), +			]), +			paragraph(101, 108, [ str(101, 108) ]), +		] +	}; +} + +#[allow(clippy::cognitive_complexity)] +#[test]  fn substitutions() {  	parses_to! {  		parser: RstParser, diff --git a/renderer/src/html.rs b/renderer/src/html.rs index fe934e7..0092315 100644 --- a/renderer/src/html.rs +++ b/renderer/src/html.rs @@ -11,6 +11,7 @@ use document_tree::{  	elements as e,  	extra_attributes as a,  	element_categories as c, +	attribute_types as at,  }; @@ -238,8 +239,11 @@ impl HTMLRender for e::Target {  impl HTMLRender for e::Raw {  	fn render_html<W>(&self, renderer: &mut HTMLRenderer<W>) -> Result<(), Error> where W: Write { -		for c in self.children() { -			write!(renderer.stream, "{}", c)?; +		let extra = self.extra(); +		if extra.format.contains(&at::NameToken("html".to_owned())) { +			for c in self.children() { +				write!(renderer.stream, "{}", c)?; +			}  		}  		Ok(())  	} diff --git a/renderer/src/html/tests.rs b/renderer/src/html/tests.rs index afd2d24..b380847 100644 --- a/renderer/src/html/tests.rs +++ b/renderer/src/html/tests.rs @@ -264,6 +264,31 @@ fn code() {  ");  } +#[test] +fn raw_html() { +	check_renders_to("\ +.. raw:: html + +   hello <span>world</span> +   <p>paragraph + +   paragraph</p> + +after + +.. raw:: something_else + +   into a black hole this goes +", "\ +hello <span>world</span> +<p>paragraph + +paragraph</p> + +<p>after</p>\ +"); +} +  /*  #[test]  fn test_field_list() { | 
