From 52bdc6c926e5e3e6f898dac72d0933367dca3b83 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Tue, 16 May 2023 17:36:30 -0500 Subject: [PATCH] working global assignments --- .../source/unit_tests/global/variable.meta | 2 - .../source/unit_tests/header/blank.meta | 1 + .../source/unit_tests/header/filetype.meta | 3 + .../source/unit_tests/header/pandoc.meta | 5 ++ src/builder.rs | 73 ++++++++++++++++--- src/meta.pest | 3 +- src/metafile.rs | 2 +- src/parser.rs | 40 +++++++++- 8 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 files/test_site/source/unit_tests/header/blank.meta create mode 100644 files/test_site/source/unit_tests/header/filetype.meta create mode 100644 files/test_site/source/unit_tests/header/pandoc.meta diff --git a/files/test_site/source/unit_tests/global/variable.meta b/files/test_site/source/unit_tests/global/variable.meta index d953e32..54dcf13 100644 --- a/files/test_site/source/unit_tests/global/variable.meta +++ b/files/test_site/source/unit_tests/global/variable.meta @@ -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 index 0000000..8d4c090 --- /dev/null +++ b/files/test_site/source/unit_tests/header/blank.meta @@ -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 index 0000000..18e7548 --- /dev/null +++ b/files/test_site/source/unit_tests/header/filetype.meta @@ -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 index 0000000..f182752 --- /dev/null +++ b/files/test_site/source/unit_tests/header/pandoc.meta @@ -0,0 +1,5 @@ +#{ pandoc = false } + +&{ base = 'bare' } + +# This should not become html diff --git a/src/builder.rs b/src/builder.rs index b50cb66..6e93bb3 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -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 { @@ -11,7 +10,7 @@ pub fn build_metafile(file: &MetaFile) -> Result { 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 { 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"))?, + "

GOOD GOOD

\n" + ); + + assert_eq!( + fs::read_to_string(dir.join("build/unit_tests/global/variable.html"))?, + "

GOODGOOD

\n" + ); + Ok(()) } } diff --git a/src/meta.pest b/src/meta.pest index b108f26..438e703 100644 --- a/src/meta.pest +++ b/src/meta.pest @@ -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 } diff --git a/src/metafile.rs b/src/metafile.rs index 05b811f..2532382 100644 --- a/src/metafile.rs +++ b/src/metafile.rs @@ -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) } diff --git a/src/parser.rs b/src/parser.rs index af6bc7e..c2c1262 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -27,7 +27,9 @@ fn parse_pair<'a>(pair: Pair, 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) -> HashMap { map } +fn parse_header_defs(pairs: Pairs) -> HashMap { + 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) -> HashMap> { let mut map = HashMap::new(); for pair in pairs { @@ -124,6 +137,31 @@ fn parse_assign(pair: Pair) -> (&str, &str) { (key, val) } +fn parse_header_assign(pair: Pair) -> (&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) -> (String, Vec) { let mut key = ""; let mut val = Vec::default(); -- 2.45.2