diff options
Diffstat (limited to 'parser')
| -rw-r--r-- | parser/src/conversion/block.rs | 40 | ||||
| -rw-r--r-- | parser/src/rst.pest | 17 | ||||
| -rw-r--r-- | parser/src/tests.rs | 40 |
3 files changed, 70 insertions, 27 deletions
diff --git a/parser/src/conversion/block.rs b/parser/src/conversion/block.rs index e23cce2..626bc20 100644 --- a/parser/src/conversion/block.rs +++ b/parser/src/conversion/block.rs @@ -53,9 +53,10 @@ fn convert_body_elem(pair: Pair<Rule>) -> Result<c::BodyElement, Error> { Rule::admonition_gen => convert_admonition_gen(pair)?.into(), 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::block_comment => convert_comment(pair)?.into(), + Rule::literal_block => convert_literal_block(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), }) } @@ -204,25 +205,34 @@ fn convert_bullet_item(pair: Pair<Rule>) -> Result<e::ListItem, Error> { Ok(e::ListItem::with_children(children)) } -fn convert_code_directive(pair: Pair<Rule>) -> Result<e::LiteralBlock, Error> { +fn convert_literal_block(pair: Pair<Rule>) -> e::LiteralBlock { + convert_literal_lines(pair.into_inner().next().unwrap()) +} + +fn convert_literal_lines(pair: Pair<Rule>) -> e::LiteralBlock { + let children = pair.into_inner().map(|l| match l.as_rule() { + Rule::literal_line => l.as_str(), + Rule::literal_line_blank => "\n", + _ => unreachable!(), + }.into()).collect(); + return e::LiteralBlock::with_children(children); +} + +fn convert_code_directive(pair: Pair<Rule>) -> e::LiteralBlock { let mut iter = pair.into_inner(); let (lang, code) = match (iter.next().unwrap(), iter.next()) { (lang, Some(code)) => (Some(lang), code), (code, None) => (None, code), }; - let children = code.into_inner().map(|l| match l.as_rule() { - Rule::code_line => l.as_str(), - Rule::code_line_blank => "\n", - _ => unreachable!(), - }.into()).collect(); - let mut code_block = e::LiteralBlock::with_children(children); + let mut code_block = convert_literal_lines(code); + code_block.classes_mut().push("code".to_owned()); if let Some(lang) = lang { code_block.classes_mut().push(lang.as_str().to_owned()); }; - Ok(code_block) + code_block } -fn convert_raw_directive(pair: Pair<Rule>) -> Result<e::Raw, Error> { +fn convert_raw_directive(pair: Pair<Rule>) -> e::Raw { let mut iter = pair.into_inner(); let format = iter.next().unwrap(); let block = iter.next().unwrap(); @@ -233,14 +243,14 @@ fn convert_raw_directive(pair: Pair<Rule>) -> Result<e::Raw, Error> { }.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) + raw_block } -fn convert_comment(pair: Pair<Rule>) -> Result<e::Comment, Error> { +fn convert_comment(pair: Pair<Rule>) -> e::Comment { let lines = pair.into_inner().map(|l| match l.as_rule() { Rule::comment_line_blank => "\n", Rule::comment_line => l.as_str(), _ => unreachable!(), }.into()).collect(); - Ok(e::Comment::with_children(lines)) + e::Comment::with_children(lines) } diff --git a/parser/src/rst.pest b/parser/src/rst.pest index ed0236e..d9fb668 100644 --- a/parser/src/rst.pest +++ b/parser/src/rst.pest @@ -11,7 +11,6 @@ block = _{ PEEK[..] ~ hanging_block } // This is the list of all block-level elements // They’re defined hanging, i.e. without the first PEEK[..] -// This is d hanging_block = _{ substitution_def | image_directive @@ -20,6 +19,7 @@ hanging_block = _{ | admonition | admonition_gen | target + | literal_block // 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 @@ -62,6 +62,14 @@ blist_body = _{ PEEK[..-1] ~ PUSH(" " ~ POP) ~ hanging_block ~ block* } // paragraph. A block type. paragraph = { inlines } +// literal_block +literal_block = { + "::" ~ " "* ~ NEWLINE ~ + blank_line+ ~ PUSH(" "+) ~ literal_lines ~ DROP +} +literal_lines = { literal_line ~ (literal_line_blank* ~ PEEK[..] ~ literal_line)* } +literal_line_blank = { " "* ~ NEWLINE } +literal_line = { (!NEWLINE ~ ANY)+ ~ NEWLINE } /* Directives: http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#directives * .. name:: arguments ~ :options: ~ blank_line+ ~ content @@ -84,16 +92,13 @@ image_opt_block = _{ PEEK[..-1] ~ PUSH(" " ~ POP) ~ image_option } //TODO: merg image_option = { ":" ~ image_opt_name ~ ":" ~ line } image_opt_name = { common_opt_name | "alt" | "height" | "width" | "scale" | "align" | "target" } -// Code block. A directive +// Code block. A directive that allows adding a language to a literal block code_directive = { ".." ~ PUSH(" "+) ~ "code" ~ "-block"? ~ "::" ~ (" "+ ~ source)? ~ NEWLINE ~ - blank_line+ ~ PEEK[..-1] ~ PUSH(" " ~ POP) ~ code_block ~ DROP + blank_line+ ~ PEEK[..-1] ~ PUSH(" " ~ POP) ~ literal_lines ~ DROP } source = { (!NEWLINE ~ ANY)+ } -code_block = { code_line ~ (code_line_blank* ~ PEEK[..] ~ code_line)* } -code_line_blank = { " "* ~ NEWLINE } -code_line = { (!NEWLINE ~ ANY)+ ~ NEWLINE } // Raw block. A directive diff --git a/parser/src/tests.rs b/parser/src/tests.rs index 5a9ee9a..ffe0ee7 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -150,7 +150,35 @@ fn admonitions() { #[allow(clippy::cognitive_complexity)] #[test] -fn code() { +fn literal_block() { + parses_to! { + parser: RstParser, + input: "\ +:: + + print('x') + + # second line + +The end +", + rule: Rule::document, + tokens: [ + literal_block(0, 36, [ + literal_lines(7, 36, [ + literal_line(7, 18), + literal_line_blank(18, 19), + literal_line(22, 36), + ]), + ]), + paragraph(37, 44, [ str(37, 44) ]), + ] + }; +} + +#[allow(clippy::cognitive_complexity)] +#[test] +fn code_directive() { parses_to! { parser: RstParser, input: "\ @@ -169,14 +197,14 @@ The end rule: Rule::document, tokens: [ code_directive(0, 26, [ - code_block(14, 26, [ code_line(14, 26) ]), + literal_lines(14, 26, [ literal_line(14, 26) ]), ]), code_directive(27, 83, [ source(43, 49), - code_block(54, 83, [ - code_line(54, 65), - code_line_blank(65, 66), - code_line(69, 83), + literal_lines(54, 83, [ + literal_line(54, 65), + literal_line_blank(65, 66), + literal_line(69, 83), ]), ]), paragraph(84, 91, [ str(84, 91) ]), |
