summaryrefslogtreecommitdiff
path: root/src/codegen.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.rs')
-rw-r--r--src/codegen.rs33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/codegen.rs b/src/codegen.rs
index 5c4255f..5855d8b 100644
--- a/src/codegen.rs
+++ b/src/codegen.rs
@@ -1,10 +1,11 @@
+use crate::html::Location;
use crate::{resource, Document, SubplotError, TemplateSpec};
use std::collections::HashMap;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
-use base64::encode;
+use base64::prelude::{Engine as _, BASE64_STANDARD};
use serde::Serialize;
use tera::{Context, Tera, Value};
@@ -32,7 +33,7 @@ fn context(doc: &mut Document, template: &str) -> Result<Context, SubplotError>
let mut context = Context::new();
let scenarios = doc.matched_scenarios(template)?;
context.insert("scenarios", &scenarios);
- context.insert("files", doc.files());
+ context.insert("files", doc.embedded_files());
let mut funcs = vec![];
if let Some(docimpl) = doc.meta().document_impl(template) {
@@ -53,12 +54,11 @@ fn context(doc: &mut Document, template: &str) -> Result<Context, SubplotError>
}
fn tera(tmplspec: &TemplateSpec, templatename: &str) -> Result<Tera, SubplotError> {
- // Tera insists on a glob, but we want to load a specific template
- // only, so we use a glob that doesn't match anything.
- let mut tera = Tera::new("/..IGNORE-THIS../..SUBPLOT-TERA-NOT-EXIST../*").expect("new");
+ let mut tera = Tera::default();
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);
@@ -88,13 +88,28 @@ fn write(filename: &Path, content: &str) -> Result<(), SubplotError> {
fn base64(v: &Value, _: &HashMap<String, Value>) -> tera::Result<Value> {
match v {
- Value::String(s) => Ok(Value::String(encode(s))),
+ Value::String(s) => Ok(Value::String(BASE64_STANDARD.encode(s))),
_ => Err(tera::Error::msg(
"can only base64 encode strings".to_string(),
)),
}
}
+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) => {
@@ -170,10 +185,10 @@ mod test {
#[test]
fn verify_name_slugification() {
static GOOD_CASES: &[(&str, &str)] = &[
- ("foobar", "foobar"), // Simple words pass through
- ("FooBar", "foobar"), // Capital letters are lowercased
+ ("foobar", "foobar"), // Simple words pass through
+ ("FooBar", "foobar"), // Capital letters are lowercased
("Motörhead", "mot_rhead"), // Non-ascii characters are changed for underscores
- ("foo bar", "foo_bar"), // As is whitespace etc.
+ ("foo bar", "foo_bar"), // As is whitespace etc.
];
for (input, output) in GOOD_CASES.iter().copied() {
let input = Value::from(input);