]> git.huck.website - metaforge.git/commitdiff
working global assignments
authorHuck Boles <huck@huck.website>
Tue, 16 May 2023 22:36:30 +0000 (17:36 -0500)
committerHuck Boles <huck@huck.website>
Tue, 16 May 2023 22:36:30 +0000 (17:36 -0500)
files/test_site/source/unit_tests/global/variable.meta
files/test_site/source/unit_tests/header/blank.meta [new file with mode: 0644]
files/test_site/source/unit_tests/header/filetype.meta [new file with mode: 0644]
files/test_site/source/unit_tests/header/pandoc.meta [new file with mode: 0644]
src/builder.rs
src/meta.pest
src/metafile.rs
src/parser.rs

index d953e32fe613c08d872e4ca422e598dcd78b8da9..54dcf1356d869791e6dfed9cf703e525b4b821c6 100644 (file)
@@ -1,4 +1,2 @@
-&{base = 'bare'}
-
 ${local_global}
 ${global}
diff --git a/files/test_site/source/unit_tests/header/blank.meta b/files/test_site/source/unit_tests/header/blank.meta
new file mode 100644 (file)
index 0000000..8d4c090
--- /dev/null
@@ -0,0 +1 @@
+#{ blank = true } This should not output anything
diff --git a/files/test_site/source/unit_tests/header/filetype.meta b/files/test_site/source/unit_tests/header/filetype.meta
new file mode 100644 (file)
index 0000000..18e7548
--- /dev/null
@@ -0,0 +1,3 @@
+#{ filetype = 'rss' }
+
+This should have an rss filetype
diff --git a/files/test_site/source/unit_tests/header/pandoc.meta b/files/test_site/source/unit_tests/header/pandoc.meta
new file mode 100644 (file)
index 0000000..f182752
--- /dev/null
@@ -0,0 +1,5 @@
+#{ pandoc = false }
+
+&{ base = 'bare' }
+
+# This should not become html
index b50cb669a50f67fde55bbd6531d37dd27eed05b5..6e93bb31f787b745315d1b136d4ebe7a8238fcbf 100644 (file)
@@ -1,6 +1,5 @@
-use crate::{parse_file, MetaFile, Src, Sub};
+use crate::{MetaFile, Src, Sub};
 use color_eyre::{eyre::bail, Result};
-use pandoc::{InputFormat, InputKind, OutputFormat, OutputKind, Pandoc, PandocOutput};
 use std::{collections::HashMap, fs};
 
 pub fn build_metafile(file: &MetaFile) -> Result<String> {
@@ -11,7 +10,7 @@ pub fn build_metafile(file: &MetaFile) -> Result<String> {
     let html = get_source_html(file)?;
 
     let pattern = get_pattern("base", file)?;
-    let mut base = parse_file(pattern, file.opts)?;
+    let mut base = crate::parse_file(pattern, file.opts)?;
 
     base.merge(file);
     base.patterns.insert("SOURCE".to_string(), html);
@@ -66,14 +65,14 @@ fn get_source_html(file: &MetaFile) -> Result<String> {
         return Ok(string);
     }
 
-    let mut pandoc = Pandoc::new();
+    let mut pandoc = pandoc::Pandoc::new();
     pandoc
-        .set_input(InputKind::Pipe(string))
-        .set_output(OutputKind::Pipe)
-        .set_input_format(InputFormat::Markdown, vec![])
-        .set_output_format(OutputFormat::Html, vec![]);
+        .set_input(pandoc::InputKind::Pipe(string))
+        .set_output(pandoc::OutputKind::Pipe)
+        .set_input_format(pandoc::InputFormat::Markdown, vec![])
+        .set_output_format(pandoc::OutputFormat::Html, vec![]);
 
-    if let Ok(PandocOutput::ToBuffer(html)) = pandoc.execute() {
+    if let Ok(pandoc::PandocOutput::ToBuffer(html)) = pandoc.execute() {
         Ok(html)
     } else {
         bail!("pandoc could not write to buffer")
@@ -279,10 +278,60 @@ mod tests {
     }
 
     #[test]
-    #[ignore = "fix global variables"]
+    fn test_headers() -> Result<()> {
+        unit_test("header/pandoc", "# This should not become html\n")?;
+        unit_test("header/blank", "")?;
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_filetype_header() -> Result<()> {
+        let dir = PathBuf::from("files/test_site").canonicalize()?;
+
+        let mut opts = Options::new();
+        opts.root = dir.clone();
+        opts.source = dir.join("source");
+        opts.build = dir.join("build");
+
+        let path = opts.source.join("unit_tests/header/filetype.meta");
+        let file = MetaFile::build(path, &opts)?;
+
+        assert_eq!(
+            file.dest()?,
+            PathBuf::from(
+                "/home/huck/repos/metaforge/files/test_site/build/unit_tests/header/filetype.rss"
+            )
+        );
+
+        Ok(())
+    }
+
+    #[test]
     fn test_global() -> Result<()> {
-        unit_test("global/variable", "GOODGOOD\n")?;
-        unit_test("global/pattern", "GOODGOOD")?;
+        let dir = PathBuf::from("files/test_site/").canonicalize()?;
+
+        let mut opts = Options::new();
+        opts.root = dir.clone();
+        opts.source = dir.join("source");
+        opts.build = dir.join("build");
+        opts.pattern = dir.join("pattern");
+
+        let mut dir_node = crate::DirNode::build(dir.join("source/unit_tests/global"), &opts)?;
+        let global = MetaFile::build(dir.join("source/default.meta"), &opts)?;
+        dir_node.map(&global)?;
+        dir_node.build_dir()?;
+
+        assert_eq!(
+            fs::read_to_string(dir.join("build/unit_tests/global/pattern.html"))?,
+            "<p>GOOD GOOD</p>\n"
+        );
+
+        assert_eq!(
+            fs::read_to_string(dir.join("build/unit_tests/global/variable.html"))?,
+            "<p>GOODGOOD</p>\n"
+        );
+
         Ok(())
     }
 }
index b108f261e08bd108c09ec86da124d2b9fcaa7b5e..438e703df76a4dfadfa10d2a46041b72eeb952d5 100644 (file)
@@ -31,7 +31,8 @@ arr_def    =  { &("@") ~ def_block }
 pat_def    =  { &("&") ~ def_block }
 definition = _{ var_def | arr_def | pat_def }
 
-header_assign =  { "!"? ~ key ~ "=" ~ value }
+header_value = ${ string | "true" | "false" | "DEFAULT" }
+header_assign =  { "!"? ~ key ~ "=" ~ header_value }
 header_block  = _{ sigil ~ header_assign* ~ "}" }
 header    =  { &("#") ~ header_block }
 
index 05b811f7330197dfbb3507f0ed0f333e4871a521..25323823dcd3f9b0d72ec258dfd926e92b49c22d 100644 (file)
@@ -83,7 +83,7 @@ impl<'a> MetaFile<'a> {
             .opts
             .build
             .join(self.path.strip_prefix(&self.opts.source)?);
-        path.set_extension("html");
+        path.set_extension(&self.header.filetype);
 
         Ok(path)
     }
index af6bc7e5a605a75ff037cc591d0b601f093106b2..c2c12625fc688b67ff420a8420ba5b02495c49b5 100644 (file)
@@ -27,7 +27,9 @@ fn parse_pair<'a>(pair: Pair<Rule>, opts: &'a Options) -> MetaFile<'a> {
         for pair in pair.into_inner() {
             match pair.as_rule() {
                 Rule::source => meta_file.source = parse_source(pair.into_inner()),
-                Rule::header => meta_file.header = Header::from(parse_defs(pair.into_inner())),
+                Rule::header => {
+                    meta_file.header = Header::from(parse_header_defs(pair.into_inner()))
+                }
                 Rule::var_def => meta_file.variables = parse_defs(pair.into_inner()),
                 Rule::arr_def => meta_file.arrays = parse_array_defs(pair.into_inner()),
                 Rule::pat_def => meta_file.patterns = parse_defs(pair.into_inner()),
@@ -54,6 +56,17 @@ fn parse_defs(pairs: Pairs<Rule>) -> HashMap<String, String> {
     map
 }
 
+fn parse_header_defs(pairs: Pairs<Rule>) -> HashMap<String, String> {
+    let mut map = HashMap::new();
+    for pair in pairs {
+        if Rule::header_assign == pair.as_rule() {
+            let (key, val) = parse_header_assign(pair);
+            map.insert(key.to_string(), val.to_string());
+        }
+    }
+    map
+}
+
 fn parse_array_defs(pairs: Pairs<Rule>) -> HashMap<String, Vec<String>> {
     let mut map = HashMap::new();
     for pair in pairs {
@@ -124,6 +137,31 @@ fn parse_assign(pair: Pair<Rule>) -> (&str, &str) {
     (key, val)
 }
 
+fn parse_header_assign(pair: Pair<Rule>) -> (&str, &str) {
+    let mut key = "";
+    let mut val = "";
+
+    for pair in pair.into_inner() {
+        if Rule::key == pair.as_rule() {
+            key = pair.as_str();
+        }
+        if Rule::header_value == pair.as_rule() {
+            let tmp = pair.as_str();
+            // blank and default shoud be handled by whoever is getting the value
+            if tmp == "BLANK" || tmp == "true" || tmp == "false" {
+                return (key, tmp);
+            }
+            // remove surrounding quotes from values by returning
+            // everything except first and last characters
+            // a string is defined as " ... " or ' ... '
+            // so it's safe to strip these characters
+            val = &tmp[1..tmp.len() - 1];
+        }
+    }
+
+    (key, val)
+}
+
 fn parse_assign_array(pair: Pair<Rule>) -> (String, Vec<String>) {
     let mut key = "";
     let mut val = Vec::default();