aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.vscode/launch.json41
-rw-r--r--Cargo.toml2
-rw-r--r--src/parser/conversion.rs11
-rw-r--r--src/parser/conversion/block.rs13
-rw-r--r--src/parser/conversion/inline.rs38
-rw-r--r--src/rst.pest115
6 files changed, 148 insertions, 72 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..acc54de
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,41 @@
+{
+ // Verwendet IntelliSense zum Ermitteln möglicher Attribute.
+ // Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
+ // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "lldb",
+ "request": "launch",
+ "name": "Debug executable on README",
+ "cargo": {
+ "args": [ "build", "--bin=rst", "--package=rst" ],
+ "filter": { "kind": "bin" }
+ },
+ "args": [ "README.rst" ],
+ "cwd": "${workspaceFolder}"
+ },
+ {
+ "type": "lldb",
+ "request": "launch",
+ "name": "Debug unit tests in lib",
+ "cargo": {
+ "args": [ "test", "--no-run", "--lib", "--package=rst" ],
+ "filter": { "kind": "lib" }
+ },
+ "args": [],
+ "cwd": "${workspaceFolder}"
+ },
+ {
+ "type": "lldb",
+ "request": "launch",
+ "name": "Debug unit tests in bin",
+ "cargo": {
+ "args": [ "test", "--no-run", "--bin=rst", "--package=rst" ],
+ "filter": { "kind": "bin" }
+ },
+ "args": [],
+ "cwd": "${workspaceFolder}"
+ }
+ ]
+} \ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 7f2f6c1..b5aa79e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,7 +24,7 @@ path = 'src/bin.rs'
failure = '0.1.3'
failure_derive = '0.1.3'
url = '1.7.2'
-regex = '1.0.6'
+regex = '1.1.0'
bitflags = '1.0.4'
unicode_categories = '0.1.1'
pest = { git = 'https://github.com/pest-parser/pest' }
diff --git a/src/parser/conversion.rs b/src/parser/conversion.rs
index def67e5..ad214d5 100644
--- a/src/parser/conversion.rs
+++ b/src/parser/conversion.rs
@@ -1,7 +1,7 @@
mod block;
+mod inline;
use failure::Error;
-use failure_derive::Fail;
use pest::iterators::Pairs;
use crate::document_tree::{
@@ -12,15 +12,6 @@ use crate::document_tree::{
use super::pest_rst::Rule;
-#[derive(Debug, Fail)]
-enum ConversionError {
- #[fail(display = "unknown rule: {:?}", rule)]
- UnknownRuleError {
- rule: Rule,
- },
-}
-
-
pub fn convert_document(pairs: Pairs<Rule>) -> Result<e::Document, Error> {
let structural_elems = pairs.map(block::convert_ssubel)
.filter_map(|elem| match elem { Ok(Some(e)) => Some(Ok(e)), Err(e) => Some(Err(e)), Ok(None) => None })
diff --git a/src/parser/conversion/block.rs b/src/parser/conversion/block.rs
index 0b638e7..5a92ed6 100644
--- a/src/parser/conversion/block.rs
+++ b/src/parser/conversion/block.rs
@@ -13,20 +13,20 @@ use crate::parser::{
pest_rst::Rule,
pair_ext_parse::PairExt,
};
-use super::ConversionError;
+use super::inline::convert_inline;
pub fn convert_ssubel(pair: Pair<Rule>) -> Result<Option<c::StructuralSubElement>, Error> {
// TODO: This is just a proof of concep. Keep closely to DTD in final version!
Ok(Some(match pair.as_rule() {
Rule::title => convert_title(pair).into(),
- Rule::paragraph => e::Paragraph::with_children(vec![pair.as_str().into()]).into(),
+ Rule::paragraph => convert_paragraph(pair)?.into(),
Rule::target => convert_target(pair)?.into(),
Rule::substitution_def => convert_substitution_def(pair)?.into(),
Rule::admonition_gen => convert_admonition_gen(pair)?.into(),
Rule::image => convert_image::<e::Image>(pair)?.into(),
Rule::EOI => return Ok(None),
- rule => return Err(ConversionError::UnknownRuleError { rule }.into()),
+ rule => panic!("unknown rule {:?}", rule),
}))
}
@@ -47,6 +47,13 @@ fn convert_title(pair: Pair<Rule>) -> e::Title {
])
}
+
+fn convert_paragraph(pair: Pair<Rule>) -> Result<e::Paragraph, Error> {
+ let children = pair.into_inner().map(convert_inline).collect::<Result<_,_>>()?;
+ Ok(e::Paragraph::with_children(children))
+}
+
+
fn convert_target(pair: Pair<Rule>) -> Result<e::Target, Error> {
let mut attrs = a::Target {
anonymous: false,
diff --git a/src/parser/conversion/inline.rs b/src/parser/conversion/inline.rs
new file mode 100644
index 0000000..0b6f659
--- /dev/null
+++ b/src/parser/conversion/inline.rs
@@ -0,0 +1,38 @@
+use failure::Error;
+use pest::iterators::Pair;
+
+use crate::document_tree::{
+ ExtraAttributes,
+ elements as e,
+ element_categories as c,
+// attribute_types::ID,
+ extra_attributes as a,
+};
+
+use crate::parser::{
+ pest_rst::Rule,
+// pair_ext_parse::PairExt,
+};
+
+
+pub fn convert_inline(pair: Pair<Rule>) -> Result<c::TextOrInlineElement, Error> {
+ Ok(match pair.as_rule() {
+ Rule::str => pair.as_str().into(),
+ Rule::reference => convert_reference(pair)?.into(),
+ rule => panic!("unknown rule {:?}", rule),
+ })
+}
+
+fn convert_reference(pair: Pair<Rule>) -> Result<e::Reference, Error> {
+ let name = None;
+ let uri = None;
+ let id = None;
+ let name_tokens = vec![];
+ let extra = a::Reference {
+ name: name,
+ refuri: uri,
+ refid: id,
+ refname: name_tokens,
+ };
+ Ok(e::Reference::with_extra(extra))
+}
diff --git a/src/rst.pest b/src/rst.pest
index e1e14ee..9d1bd54 100644
--- a/src/rst.pest
+++ b/src/rst.pest
@@ -63,7 +63,7 @@ bullet_item = { bullet_marker ~ PUSH(" "+) ~ line ~ blank_line* ~ blist_body? ~
blist_body = _{ PEEK[..-1] ~ PUSH(" " ~ POP) ~ hanging_block ~ block* }
// paragraph. A block type.
-paragraph = { line ~ (PEEK[..] ~ line)* }
+paragraph = { inlines }
/* Directives: http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#directives
@@ -89,9 +89,61 @@ 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?
-// TODO: use inlines here
-line = { !marker ~ !blank_line ~ (!NEWLINE ~ ANY)+ ~ NEWLINE }
-blank_line = _{ !marker ~ " "* ~ NEWLINE }
+
+
+/*
+ * inlines
+ */
+
+
+line = { !marker ~ inline+ ~ NEWLINE }
+blank_line = _{ !marker ~ !inline ~ " "* ~ NEWLINE }
+
+inlines = _{ !marker ~ inline+ ~ (NEWLINE ~ PEEK[..] ~ !marker ~ inline+ ~ NEWLINE)* }
+inline = _{
+ reference
+ | str
+// link ✓
+// | str ✓
+// | endline
+// | ul_or_star_line
+// | space
+// | strong
+// | emph
+// | strike
+// | note_reference
+// | footnote
+// //| citation
+// | code
+// | application_depent
+// | entity
+// | escaped_char
+// | smart
+// | symbol
+}
+
+str = { (!(NEWLINE | reference) ~ ANY)+ }
+
+// inline links
+reference = { reference_target | reference_explicit | reference_auto }
+
+reference_target = { reference_target_uq ~ "_" | reference_target_qu }
+reference_target_uq = { (!("_"|":"|"`") ~ nonspacechar)* }
+reference_target_qu = _{ ( !("`"? ~ "`_") ~ "`" ~ !"``" ) ~ target_name_qu ~ ( "`" ~ !"``" ) ~ "_" }
+
+reference_explicit = { reference_label ~ "(" ~ " "* ~ reference_source ~ " "* ~ (NEWLINE ~ PEEK[..])? ~ reference_title ~ " "* ~ ")" }
+reference_label = { "[" ~ !"^" ~ (!"]" ~ inline)* ~ "]" }
+reference_source = { reference_source_contents }
+reference_source_contents = _{ ( (!("("|")"|">") ~ nonspacechar)+ | "(" ~ reference_source_contents ~ ")" )* }
+reference_title = { ( reference_title_single | reference_title_double | "" ) }
+reference_title_single = { "'" ~ ( !("'" ~ " "+ ~ (")" | NEWLINE)) ~ ANY )* ~ "'" }
+reference_title_double = { "\"" ~ ( !("\"" ~ " "+ ~ (")" | NEWLINE)) ~ ANY )* ~ "\"" }
+
+reference_auto = { reference_embedded | reference_auto_url | reference_auto_email }
+reference_embedded = { "`" ~ reference_embedded_source ~ "<" ~ ASCII_ALPHA+ ~ "://" ~ (!(NEWLINE|">") ~ ANY)+ ~ ">`_" ~ "_"? }
+reference_embedded_source = { ( !("<"|":"|"`") ~ ( " " | nonspacechar | blank_line ) )* }
+reference_auto_url = { ASCII_ALPHA+ ~ "://" ~ (!(NEWLINE|">") ~ ANY)+ }
+reference_auto_email = { "<" ~ "mailto:"? ~ (ASCII_ALPHANUMERIC|"-"|"+"|"_"|"."|"/"|"!"|"%"|"~"|"$")+ ~ "@" ~ (!(NEWLINE | ">") ~ ANY)+ ~ ">" }
/*
@@ -206,36 +258,12 @@ marker = _{ (bullet_marker | "..") ~ " " }
// optionally_indented_line
// }
-// inlines = { ( !endline ~ inline | endline ~ &inline )+ ~ endline? }
-// inline = {
-// link
-// | str
-// | endline
-// | ul_or_star_line
-// | space
-// | strong
-// | emph
-// | strike
-// | note_reference
-// | footnote
-// //| citation
-// | code
-// | application_depent
-// | entity
-// | escaped_char
-// | smart
-// | symbol
-// }
// space = _{ spacechar+ }
// str = { normal_char+ ~ str_chunk* }
-// str_chunk = _{ (normal_char | "_"+ ~ &alphanumeric)+ | apos_chunk }
-// apos_chunk = {
-// // &{ extension(EXT_SMART) } ~
-// "'" ~ &alphanumeric
-// }
+// str_chunk = _{ (normal_char | "_"+ ~ &alphanumeric)+ }
// escaped_char = { "\\" ~ !NEWLINE ~ ("-" | "\\" | "`" | "|" | "*" | "_" | "{" | "}" | "[" | "]" | "(" | ")" | "#" | "+" | "." | "!" | ">" | "<") }
@@ -265,36 +293,7 @@ marker = _{ (bullet_marker | "..") ~ " " }
// "~~" ~ !whitespace ~ (!"~~" ~ inline)+ ~ "~~"
// }
-// link = { reference_link | explicit_link | auto_link }
-
-// reference_link = { unquoted_ref_link_underbar | quoted_ref_link_underbar }
-// unquoted_ref_link_underbar = { unquoted_link_source ~ "_" }
-// quoted_ref_link_underbar = { ( !("`_" | "``_") ~ "`" ~ !"``" ) ~ target_name_qu ~ ( "`" ~ !"``" ) ~ "_" }
-
-// explicit_link = { label ~ "(" ~ sp ~ source ~ spnl ~ title ~ sp ~ ")" }
-// source = { source_contents }
-// source_contents = { ( (!("(" | ")" | ">") ~ nonspacechar)+ | "(" ~ source_contents ~ ")" )* }
-
-// title = { ( title_single | title_double | "" ) }
-// title_single = { "'" ~ ( !("'" ~ sp ~ (")" | NEWLINE)) ~ ANY )* ~ "'" }
-// title_double = { "\"" ~ ( !("\"" ~ sp ~ (")" | NEWLINE)) ~ ANY )* ~ "\"" }
-
-// auto_link = { embedded_link | auto_link_url | auto_link_email }
-// embedded_link = { "`" ~ embedded_ref_source ~ "<" ~ ASCII_ALPHA+ ~ "://" ~ (!(NEWLINE | ">") ~ ANY)+ ~ ">`_" ~ "_"? }
-// auto_link_url = { ASCII_ALPHA+ ~ "://" ~ (!(NEWLINE|">") ~ ANY)+ }
-// auto_link_email = { "<" ~ "mailto:"? ~ (ASCII_ALPHANUMERIC|"-"|"+"|"_"|"."|"/"|"!"|"%"|"~"|"$")+ ~ "@" ~ (!(NEWLINE | ">") ~ ANY)+ ~ ">" }
-
-// unquoted_link_source = { (!("_"|":"|"`") ~ nonspacechar)* }
-
-// embedded_ref_source = { ( !("<"|":"|"`") ~ ( " " | nonspacechar | blank_line ) )* }
-
-// label = {
-// "[" ~ (
-// !"^" //~ &{ extension(EXT_NOTES) }
-// | &ANY //~ &{ extension(EXT_NOTES) }
-// ) ~ (!"]" ~ inline)* ~ "]"
-// }
// empty_title = { "" }