summaryrefslogtreecommitdiff
path: root/src/typeset.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2019-11-30 17:36:10 +0200
committerLars Wirzenius <liw@liw.fi>2019-11-30 19:23:56 +0200
commit3ccba3039795ce0be3e5f5cec6216dc853da76c2 (patch)
treee03e78189d0465660aabe68cf531dd50f19cd51a /src/typeset.rs
parentbdf25e5964865b0faef15e1e330e482f2510054b (diff)
downloadsubplot-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.rs81
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])
}