aboutsummaryrefslogtreecommitdiffstats
path: root/parser
diff options
context:
space:
mode:
Diffstat (limited to 'parser')
-rw-r--r--parser/Cargo.toml2
-rw-r--r--parser/src/conversion/block.rs19
-rw-r--r--parser/src/rst.pest32
-rw-r--r--parser/src/tests.rs35
4 files changed, 68 insertions, 20 deletions
diff --git a/parser/Cargo.toml b/parser/Cargo.toml
index 997cc35..a423fbe 100644
--- a/parser/Cargo.toml
+++ b/parser/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = 'rst_parser'
-version = '0.3.0'
+version = '0.3.1'
authors = ['Philipp A. <flying-sheep@web.de>']
edition = '2018'
description = 'a reStructuredText parser'
diff --git a/parser/src/conversion/block.rs b/parser/src/conversion/block.rs
index ab18c48..64aa33e 100644
--- a/parser/src/conversion/block.rs
+++ b/parser/src/conversion/block.rs
@@ -53,6 +53,7 @@ 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 => unimplemented!("unhandled rule {:?}", rule),
})
}
@@ -200,3 +201,21 @@ 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> {
+ 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);
+ if let Some(lang) = lang {
+ code_block.classes_mut().push(lang.as_str().to_owned());
+ };
+ Ok(code_block)
+}
diff --git a/parser/src/rst.pest b/parser/src/rst.pest
index f3a1516..18708c2 100644
--- a/parser/src/rst.pest
+++ b/parser/src/rst.pest
@@ -15,6 +15,7 @@ block = _{ PEEK[..] ~ hanging_block }
hanging_block = _{
substitution_def
| image_directive
+ | code_directive
| admonition
| admonition_gen
| target
@@ -24,17 +25,10 @@ hanging_block = _{
// TODO: implement all those things:
// | block_quote
// | verbatim
-// | image ✓
-// | code_block
// | doctest_block
-// | admonition ✓
-// | target ✓
// | horizontal_rule
-// | title ✓
// | table
// | ordered_list
-// | bullet_list ✓
-// | paragraph ✓
// | plain
}
@@ -86,9 +80,20 @@ 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_directive = {
+ ".." ~ PUSH(" "+) ~ "code" ~ "-block"? ~ "::" ~ (" "+ ~ source)? ~ NEWLINE ~
+ blank_line+ ~ PEEK[..-1] ~ PUSH(" " ~ POP) ~ code_block ~ DROP
+}
+source = { (!NEWLINE ~ ANY)+ }
+code_block = { code_line ~ (code_line_blank* ~ PEEK[..] ~ code_line)* }
+code_line_blank = { " "* ~ NEWLINE }
+code_line = { (!NEWLINE ~ ANY)+ ~ NEWLINE }
+
// Admonition. A directive. The generic one has a title
-admonition = { ".." ~ PUSH(" "+) ~ ^"admonition::" ~ line ~ blank_line* ~ admonition_content? ~ DROP }
+admonition = { ".." ~ PUSH(" "+) ~ ^"admonition::" ~ line ~ blank_line* ~ admonition_content? ~ DROP }
admonition_gen = { ".." ~ PUSH(" "+) ~ admonition_type ~ "::" ~ (blank_line | line) ~ blank_line* ~ admonition_content? ~ DROP }
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?
@@ -272,11 +277,6 @@ marker = _{ (bullet_marker | "..") ~ " " }
-// code_block = {
-// ".. code" ~ "-block"? ~ ":: " ~ source ~ blank_line ~
-// NEWLINE ~ verbatim_chunk+
-// }
-
// doctest_block = { (doctest_line+ ~ (!(">" | blank_line) ~ line)*)+ }
// block_quote_raw = { ":" ~ blank_line ~ NEWLINE ~ nonblank_indented_line+ }
@@ -290,12 +290,6 @@ marker = _{ (bullet_marker | "..") ~ " " }
// block_quote = { block_quote_chunk+ }
-// nonblank_indented_line = { !blank_line ~ indented_line }
-
-// verbatim_chunk = { blank_line* ~ nonblank_indented_line+ }
-
-// verbatim = { verbatim_chunk+ }
-
// horizontal_rule = {
// ( "=" ~ sp ~ "=" ~ sp ~ "=" ~ (sp ~ "=")*
// | "-" ~ sp ~ "-" ~ sp ~ "-" ~ (sp ~ "-")*
diff --git a/parser/src/tests.rs b/parser/src/tests.rs
index 1ef965a..b4da633 100644
--- a/parser/src/tests.rs
+++ b/parser/src/tests.rs
@@ -136,6 +136,41 @@ fn admonitions() {
};
}
+#[allow(clippy::cognitive_complexity)]
+#[test]
+fn code() {
+ parses_to! {
+ parser: RstParser,
+ input: "\
+.. code::
+
+ Single line
+
+.. code-block:: python
+
+ print('x')
+
+ # second line
+
+The end
+",
+ rule: Rule::document,
+ tokens: [
+ code_directive(0, 26, [
+ code_block(14, 26, [ code_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),
+ ]),
+ ]),
+ paragraph(84, 91, [ str(84, 91) ]),
+ ]
+ };
+}
#[allow(clippy::cognitive_complexity)]
#[test]