diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2023-08-12 11:34:57 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2023-08-12 11:34:57 +0100 |
commit | db8aef62e629b1bac2c72bb2590ba4caa90aa8d9 (patch) | |
tree | 9058546eb10974f2d4a61007b5395953a54ef06e /src | |
parent | 985ec2f83c9f679ff9b50c6d1e856db2502c3114 (diff) | |
download | subplot-db8aef62e629b1bac2c72bb2590ba4caa90aa8d9.tar.gz |
subplot: Enable passing of location into the template expansion
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings.rs | 2 | ||||
-rw-r--r-- | src/codegen.rs | 17 | ||||
-rw-r--r-- | src/html.rs | 2 | ||||
-rw-r--r-- | src/matches.rs | 7 | ||||
-rw-r--r-- | src/scenarios.rs | 4 | ||||
-rw-r--r-- | src/steps.rs | 4 |
6 files changed, 33 insertions, 3 deletions
diff --git a/src/bindings.rs b/src/bindings.rs index e94b64e..b629992 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -242,7 +242,7 @@ impl Binding { let caps = self.regex.captures(step_text)?; // If there is only one capture, it's the whole string. - let mut m = MatchedStep::new(self, template); + let mut m = MatchedStep::new(self, template, step.origin().clone()); if caps.len() == 1 { m.append_part(PartialStep::uncaptured(step_text)); return Some(m); diff --git a/src/codegen.rs b/src/codegen.rs index 41b5556..5855d8b 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -1,3 +1,4 @@ +use crate::html::Location; use crate::{resource, Document, SubplotError, TemplateSpec}; use std::collections::HashMap; use std::fs::File; @@ -57,6 +58,7 @@ fn tera(tmplspec: &TemplateSpec, templatename: &str) -> Result<Tera, SubplotErro tera.register_filter("base64", base64); tera.register_filter("nameslug", nameslug); tera.register_filter("commentsafe", commentsafe); + tera.register_filter("location", locationfilter); let dirname = tmplspec.template_filename().parent().unwrap(); for helper in tmplspec.helpers() { let helper_path = dirname.join(helper); @@ -93,6 +95,21 @@ fn base64(v: &Value, _: &HashMap<String, Value>) -> tera::Result<Value> { } } +fn locationfilter(v: &Value, _: &HashMap<String, Value>) -> tera::Result<Value> { + let location: Location = serde_json::from_value(v.clone())?; + Ok(Value::String(format!( + "{:?}", + match location { + Location::Known { + filename, + line, + col, + } => format!("{}:{}:{}", filename.display(), line, col), + Location::Unknown => "unknown".to_string(), + } + ))) +} + fn nameslug(name: &Value, _: &HashMap<String, Value>) -> tera::Result<Value> { match name { Value::String(s) => { diff --git a/src/html.rs b/src/html.rs index c5edc5b..f863727 100644 --- a/src/html.rs +++ b/src/html.rs @@ -99,7 +99,7 @@ pub fn parse(filename: &Path, markdown: &str) -> Result<Element, HtmlError> { HeadingLevel::H5 => ElementTag::H5, HeadingLevel::H6 => ElementTag::H6, }; - let mut h = Element::new(tag); + let mut h = Element::new(tag).with_location(loc); if let Some(id) = id { h.push_attribute(Attribute::new("id", id)); } diff --git a/src/matches.rs b/src/matches.rs index 9130641..f8de59a 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -1,3 +1,4 @@ +use crate::html::Location; use crate::Binding; use crate::Scenario; use crate::StepKind; @@ -12,6 +13,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] pub struct MatchedScenario { title: String, + origin: Location, steps: Vec<MatchedStep>, } @@ -29,6 +31,7 @@ impl MatchedScenario { .collect(); Ok(MatchedScenario { title: scen.title().to_string(), + origin: scen.origin().clone(), steps: steps?, }) } @@ -73,6 +76,7 @@ pub struct MatchedStep { kind: StepKind, pattern: String, text: String, + origin: Location, parts: Vec<PartialStep>, function: Option<String>, cleanup: Option<String>, @@ -81,12 +85,13 @@ pub struct MatchedStep { impl MatchedStep { /// Return a new empty match. Empty means it has no step parts. - pub fn new(binding: &Binding, template: &str) -> MatchedStep { + pub fn new(binding: &Binding, template: &str, origin: Location) -> MatchedStep { let bimpl = binding.step_impl(template); MatchedStep { kind: binding.kind(), pattern: binding.pattern().to_string(), text: "".to_string(), + origin, parts: vec![], function: bimpl.clone().map(|b| b.function().to_owned()), cleanup: bimpl.and_then(|b| b.cleanup().map(String::from)), diff --git a/src/scenarios.rs b/src/scenarios.rs index 7039d98..17549d2 100644 --- a/src/scenarios.rs +++ b/src/scenarios.rs @@ -45,6 +45,10 @@ impl Scenario { pub fn add(&mut self, step: &ScenarioStep) { self.steps.push(step.clone()); } + + pub(crate) fn origin(&self) -> &Location { + &self.origin + } } #[cfg(test)] diff --git a/src/steps.rs b/src/steps.rs index 43e66e2..d9d1725 100644 --- a/src/steps.rs +++ b/src/steps.rs @@ -84,6 +84,10 @@ impl ScenarioStep { } Ok(ScenarioStep::new(kind, keyword, &joined, origin)) } + + pub(crate) fn origin(&self) -> &Location { + &self.origin + } } impl fmt::Display for ScenarioStep { |