summaryrefslogtreecommitdiff
path: root/src/md.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/md.rs')
-rw-r--r--src/md.rs110
1 files changed, 83 insertions, 27 deletions
diff --git a/src/md.rs b/src/md.rs
index 64cfc44..85fb895 100644
--- a/src/md.rs
+++ b/src/md.rs
@@ -2,8 +2,8 @@
use crate::{
html::{parse, Attribute, Content, Element, ElementTag, Location},
- parse_scenario_snippet, Bindings, EmbeddedFile, EmbeddedFiles, Scenario, ScenarioStep, Style,
- SubplotError, Warnings,
+ steps::parse_scenario_snippet,
+ Bindings, EmbeddedFile, EmbeddedFiles, Scenario, Style, SubplotError, Warnings,
};
use log::trace;
use std::collections::HashSet;
@@ -88,8 +88,13 @@ impl Markdown {
}
/// Typeset.
- pub fn typeset(&mut self, _style: Style, _bindings: &Bindings) -> Warnings {
- let result = typeset::typeset_element(&self.html);
+ pub fn typeset(
+ &mut self,
+ _style: Style,
+ template: Option<&str>,
+ bindings: &Bindings,
+ ) -> Warnings {
+ let result = typeset::typeset_element(&self.html, template, bindings);
if let Ok(html) = result {
self.html = html;
Warnings::default()
@@ -278,7 +283,6 @@ fn extract_scenario(e: &[StructureElement]) -> Result<(Option<Scenario>, usize),
StructureElement::Snippet(_, loc) => Err(SubplotError::ScenarioBeforeHeading(loc.clone())),
StructureElement::Heading(title, level, loc) => {
let mut scen = Scenario::new(title, loc.clone());
- let mut prevkind = None;
for (i, item) in e.iter().enumerate().skip(1) {
match item {
StructureElement::Heading(_, level2, _loc) => {
@@ -295,22 +299,9 @@ fn extract_scenario(e: &[StructureElement]) -> Result<(Option<Scenario>, usize),
}
}
StructureElement::Snippet(text, loc) => {
- for (idx, line) in parse_scenario_snippet(text).enumerate() {
- let line_loc = match loc.clone() {
- Location::Known {
- filename,
- line,
- col,
- } => Location::Known {
- filename,
- line: line + idx,
- col,
- },
- Location::Unknown => Location::Unknown,
- };
- let step = ScenarioStep::new_from_str(line, prevkind, line_loc)?;
+ let steps = parse_scenario_snippet(text, loc)?;
+ for step in steps {
scen.add(&step);
- prevkind = Some(step.kind());
}
}
}
@@ -327,21 +318,30 @@ fn extract_scenario(e: &[StructureElement]) -> Result<(Option<Scenario>, usize),
mod typeset {
const UNWANTED_ATTRS: &[&str] = &["add-newline"];
- use crate::html::{Attribute, Content, Element, ElementTag};
+ use crate::{
+ html::{Attribute, Content, Element, ElementTag, Location},
+ Bindings, PartialStep,
+ };
// use crate::parser::parse_scenario_snippet;
// use crate::Bindings;
// use crate::PartialStep;
// use crate::ScenarioStep;
// use crate::StepKind;
use crate::SubplotError;
- use crate::{DiagramMarkup, DotMarkup, PikchrMarkup, PlantumlMarkup, Svg};
+ use crate::{DiagramMarkup, DotMarkup, MatchedStep, PikchrMarkup, PlantumlMarkup, Svg};
// use crate::{Warning, Warnings};
use base64::prelude::{Engine as _, BASE64_STANDARD};
- pub(crate) fn typeset_element(e: &Element) -> Result<Element, SubplotError> {
+ pub(crate) fn typeset_element(
+ e: &Element,
+ template: Option<&str>,
+ bindings: &Bindings,
+ ) -> Result<Element, SubplotError> {
let new = match e.tag() {
- ElementTag::Pre if e.has_attr("class", "scenario") => typeset_scenario(e),
+ ElementTag::Pre if e.has_attr("class", "scenario") => {
+ typeset_scenario(e, template, bindings)
+ }
ElementTag::Pre if e.has_attr("class", "file") => typeset_file(e),
ElementTag::Pre if e.has_attr("class", "example") => typeset_example(e),
ElementTag::Pre if e.has_attr("class", "dot") => typeset_dot(e),
@@ -355,7 +355,7 @@ mod typeset {
}
for child in e.children() {
if let Content::Elt(ce) = child {
- new.push_child(Content::Elt(typeset_element(ce)?));
+ new.push_child(Content::Elt(typeset_element(ce, template, bindings)?));
} else {
new.push_child(child.clone());
}
@@ -368,8 +368,64 @@ mod typeset {
Ok(new)
}
- fn typeset_scenario(e: &Element) -> Result<Element, SubplotError> {
- Ok(e.clone()) // FIXME
+ fn typeset_scenario(
+ e: &Element,
+ template: Option<&str>,
+ bindings: &Bindings,
+ ) -> Result<Element, SubplotError> {
+ let template = template.unwrap_or("python"); // FIXME
+
+ let text = e.content();
+ let steps = crate::steps::parse_scenario_snippet(&text, &Location::Unknown)?;
+
+ let mut scenario = Element::new(ElementTag::Div);
+ scenario.push_attribute(Attribute::new("class", "scenario"));
+
+ for step in steps {
+ if let Ok(matched) = bindings.find(template, &step) {
+ scenario.push_child(Content::Elt(typeset_step(&matched)));
+ } else {
+ scenario.push_child(Content::Text(step.text().into()));
+ }
+ }
+
+ Ok(scenario)
+ }
+
+ fn typeset_step(matched: &MatchedStep) -> Element {
+ let mut e = Element::new(ElementTag::Div);
+ let mut keyword = Element::new(ElementTag::Span);
+ keyword.push_attribute(Attribute::new("class", "keyword"));
+ keyword.push_child(Content::Text(matched.kind().to_string()));
+ keyword.push_child(Content::Text(" ".into()));
+ e.push_child(Content::Elt(keyword));
+ for part in matched.parts() {
+ match part {
+ PartialStep::UncapturedText(snippet) => {
+ let text = snippet.text();
+ if !text.trim().is_empty() {
+ let mut estep = Element::new(ElementTag::Span);
+ estep.push_attribute(Attribute::new("class", "uncaptured"));
+ estep.push_child(Content::Text(text.into()));
+ e.push_child(Content::Elt(estep));
+ }
+ }
+ PartialStep::CapturedText {
+ name: _,
+ text,
+ kind,
+ } => {
+ if !text.trim().is_empty() {
+ let mut estep = Element::new(ElementTag::Span);
+ let class = format!("capture-{}", kind.as_str());
+ estep.push_attribute(Attribute::new("class", &class));
+ estep.push_child(Content::Text(text.into()));
+ e.push_child(Content::Elt(estep));
+ }
+ }
+ }
+ }
+ e
}
fn typeset_file(e: &Element) -> Result<Element, SubplotError> {