From 8f8270f4b4745087dcddba60b23d88d6f3fa4fb6 Mon Sep 17 00:00:00 2001 From: Philipp A Date: Fri, 16 Nov 2018 15:15:37 +0100 Subject: First doctree conversion code --- src/parser.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) (limited to 'src/parser.rs') diff --git a/src/parser.rs b/src/parser.rs index 026024a..fa12b3e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3,8 +3,82 @@ pub mod serialize; #[cfg(test)] pub mod tests; -use pest_derive::Parser; +mod pest_rst { + use pest_derive::Parser; + + #[derive(Parser)] + #[grammar = "rst.pest"] + pub struct RstParser; +} +use self::pest_rst::Rule; -#[derive(Parser)] -#[grammar = "rst.pest"] -pub struct RstParser; +use std::io::Write; + +use failure::Error; +use failure_derive::Fail; + +use pest::Parser; + +use crate::document_tree::{ + HasChildren, + elements::{ + Document, + Title, + }, + element_categories::{ + StructuralSubElement + }, +}; + + +#[derive(Debug, Fail)] +enum ConversionError { + #[fail(display = "unknown rule: {:?}", rule)] + UnknownRuleError { + rule: Rule, + }, +} + + +fn convert_ssubel(pair: pest::iterators::Pair) -> Result { + match pair.as_rule() { + Rule::title => Ok(convert_title(pair).into()), + rule => Err(ConversionError::UnknownRuleError { rule }.into()), + } +} + + +fn convert_title(pair: pest::iterators::Pair) -> Title { + let mut title: Option<&str> = None; + let mut adornment_char: Option = None; + for p in pair.into_inner() { + match p.as_rule() { + Rule::line => title = Some(p.as_str()), + Rule::adornments => adornment_char = Some(p.as_str().chars().next().expect("Empty adornment?")), + rule => panic!("Unexpected rule in title: {:?}", rule), + }; + } + // TODO adornment char + Title::with_children(vec![ + title.expect("No text in title").into() + ]) +} + + +/// tokens to Document tree. resolves sections, but not references +pub fn parse(source: &str) -> Result { + let pairs = pest_rst::RstParser::parse(pest_rst::Rule::document, source)?; + let structural_elems = pairs.map(convert_ssubel).collect::>()?; + Ok(Document::with_children(structural_elems)) +} + + +/// only until we can serialize DocumentTrees +pub fn serialize_json(source: &str, stream: W) -> Result<(), Error> where W: Write { + use self::pest_rst::{RstParser, Rule}; + use self::serialize::PairsWrap; + + let parsed = RstParser::parse(Rule::document, source)?; + serde_json::to_writer(stream, &PairsWrap(parsed))?; + Ok(()) +} -- cgit v1.2.3