From 4c487a44208a96e3a23ab8974d224cae489688be Mon Sep 17 00:00:00 2001 From: Konsta Hölttä Date: Mon, 7 Sep 2020 01:30:34 +0300 Subject: Add support for raw directives (#17) All content under a raw directive is rendered as-is if the output format matches the writer. Otherwise none of it is shown.--- parser/src/conversion/block.rs | 15 +++++++++++++++ parser/src/rst.pest | 12 ++++++++++++ parser/src/tests.rs | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) (limited to 'parser') 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) -> Result { Rule::image => convert_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) -> Result { }; Ok(code_block) } + +fn convert_raw_directive(pair: Pair) -> Result { + 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 @@ -184,6 +184,45 @@ The end }; } +#[allow(clippy::cognitive_complexity)] +#[test] +fn raw() { + parses_to! { + parser: RstParser, + input: "\ +.. raw:: html + + hello world + +.. raw:: html + + hello
world
+
+   parse
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() { -- cgit v1.2.3