diff options
| author | Philipp A | 2018-12-02 17:22:51 +0100 |
|---|---|---|
| committer | Philipp A | 2018-12-02 17:22:51 +0100 |
| commit | d067cee68744691f3aebd939befc9837247e639c (patch) | |
| tree | 6f8ff1ba9617a6f55f7c667457c0f009f01300fe | |
| parent | c7bf1a581871a5bb13195d116d9dc7b83eb83c3a (diff) | |
| download | rust-rst-d067cee68744691f3aebd939befc9837247e639c.tar.bz2 | |
First bit of inlines parsing
| -rw-r--r-- | .vscode/launch.json | 41 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/parser/conversion.rs | 11 | ||||
| -rw-r--r-- | src/parser/conversion/block.rs | 13 | ||||
| -rw-r--r-- | src/parser/conversion/inline.rs | 38 | ||||
| -rw-r--r-- | src/rst.pest | 115 |
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 @@ -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 = { "" } |
