chiark / gitweb /
specs: Add a templating facility for game specs
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 7 Jun 2021 23:25:36 +0000 (00:25 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 8 Jun 2021 00:28:32 +0000 (01:28 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bundles.rs

index 9fd4477a1a541343d26020aedd184569108af1da..d95d8f85f95a1cbcdce3767a60f173627bb3b476 100644 (file)
@@ -900,7 +900,36 @@ pub fn load_spec_to_read(ig: &Instance, spec_name: &str) -> String {
       ErrorKind::UnexpectedEof => ME::BadBundle(e.to_string()),
       _ => e_f(e),
     })?;
-    buf
+
+    if ! buf.starts_with("{#") { return buf }
+
+    (||{
+      let templates: Vec<(&str, Cow<str>)> = match buf.rfind("\n{% endmacro") {
+        None => vec![ ("spec", buf.into()) ],
+        Some(endm_base) => {
+          let endm_sol = endm_base + 1;
+          let endm_end = endm_sol + 1 +
+            buf[endm_sol..].find('\n')
+            .ok_or_else(|| anyhow!("endmacro line not terminated"))?;
+          let mac_data = &buf[0..endm_end];
+          let spec_data = 
+            r#"{% import "m" as m %}"#.to_string()
+            + &"\n".repeat(mac_data.matches('\n').count())
+            + &buf[endm_end..];
+          vec![ ("m",    mac_data .into()),
+                ("spec", spec_data.into()) ]
+        },
+      };
+      let mut tera = tera_standalone::Tera::default();
+      tera.add_raw_templates(templates).context("load")?;
+      let mut out: Vec<u8> = vec![];
+      tera.render_to("spec", &default(), &mut out).context("render")?;
+      let out = String::from_utf8(out).context("reparse as utf-8")?;
+      Ok::<_,AE>(out)
+    })()
+      .map_err(|ae| ME::BadBundle(
+        format!("process spec as Tera template: {}", ae.d())
+      ))?
   }
 
   let spec_leaf = format!("{}.game.toml", spec_name);