diff options
author | Lars Wirzenius <liw@liw.fi> | 2019-11-30 17:36:10 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2019-11-30 19:23:56 +0200 |
commit | 3ccba3039795ce0be3e5f5cec6216dc853da76c2 (patch) | |
tree | e03e78189d0465660aabe68cf531dd50f19cd51a /src/typeset.rs | |
parent | bdf25e5964865b0faef15e1e330e482f2510054b (diff) | |
download | subplot-3ccba3039795ce0be3e5f5cec6216dc853da76c2.tar.gz |
Change: typeset using bindings information
Read bindings from the file named in the document meta data.
Diffstat (limited to 'src/typeset.rs')
-rw-r--r-- | src/typeset.rs | 81 |
1 files changed, 61 insertions, 20 deletions
diff --git a/src/typeset.rs b/src/typeset.rs index 6b83d51..46be484 100644 --- a/src/typeset.rs +++ b/src/typeset.rs @@ -1,13 +1,22 @@ use pandoc_ast::{Block, Inline}; use crate::parser::parse_scenario_snippet; +use crate::Bindings; +use crate::ScenarioStep; +use crate::StepKind; +use crate::PartialStep; /// Typeset an error from dot as a Pandoc AST Block element. pub fn error(err: Box<dyn std::error::Error>) -> Block { let msg = format!("ERROR: {}", err.to_string()); - let msg = Inline::Str(msg); + Block::Para(error_msg(&msg)) +} + +// Typeset an error message a vector of inlines. +pub fn error_msg(msg: &str) -> Vec<Inline> { + let msg = Inline::Str(msg.into()); let msg = Inline::Strong(vec![msg]); - Block::Para(vec![msg]) + vec![msg] } @@ -15,39 +24,71 @@ pub fn error(err: Box<dyn std::error::Error>) -> Block { /// /// The snippet is given as a text string, which is parsed. It need /// not be a complete scenario, but it should consist of complete steps. -pub fn scenario_snippet(snippet: &str) -> Block { +pub fn scenario_snippet(bindings: &Bindings, snippet: &str) -> Block { let steps = parse_scenario_snippet(snippet) - .map(|s| step(s)) + .map(|s| step(bindings, s)) .collect(); Block::LineBlock(steps) } // Typeset a single scenario step as a sequence of Pandoc AST Inlines. -fn step(text: &str) -> Vec<Inline> { - let mut words = text.split_whitespace(); - let mut inlines = Vec::new(); +fn step(bindings: &Bindings, text: &str) -> Vec<Inline> { + let step = ScenarioStep::from_str(text); + if step.is_none() { + eprintln!("Could not parse step: {}", text); + return error_msg(&format!("Could not parse step: {}", text)); + } + let step = step.unwrap(); - if let Some(keyword) = words.next() { - typeset_keyword(keyword, &mut inlines); - inlines.push(typeset_str(" ")); + let m = bindings.find(&step); + if m.is_none() { + eprintln!("Could not findind binding for: {}", text); + return error_msg(&format!("Could not find binding for: {}", text)); } + let m = m.unwrap(); - for word in words { - inlines.push(typeset_str(word)); - inlines.push(typeset_str(" ")); + let mut inlines = Vec::new(); + + inlines.push(keyword(&step)); + inlines.push(space()); + + for part in m.parts() { + match part { + PartialStep::UncapturedText(s) => inlines.push(uncaptured(s.text())), + PartialStep::CapturedText(s) => inlines.push(captured(s.text())), + } } + inlines } // Typeset first word, which is assumed to be a keyword, of a scenario // step. -fn typeset_keyword(word: &str, inlines: &mut Vec<Inline>) { - let word = typeset_str(word); - let emph = Inline::Emph(vec![word]); - inlines.push(emph); +fn keyword(step: &ScenarioStep) -> Inline { + let word = match step.kind() { + StepKind::Given => "given", + StepKind::When => "when", + StepKind::Then => "then", + }; + let word = Inline::Str(word.into()); + Inline::Emph(vec![word]) } -// Typeset a single inline string as an Inline element. -fn typeset_str(s: &str) -> Inline { - Inline::Str(s.to_string()) + +// Typeset a space between words. +fn space() -> Inline { + Inline::Space +} + + +// Typeset an uncaptured part of a step. +fn uncaptured(s: &str) -> Inline { + Inline::Str(s.into()) +} + + +// Typeset a captured part of a step. +fn captured(s: &str) -> Inline { + let s = Inline::Str(s.into()); + Inline::Strong(vec![s]) } |