From 2067e8d96e38b77a09e868e35d604a8a98030f78 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Wed, 31 May 2023 14:54:09 -0500 Subject: [PATCH 01/16] added: copy_only header directory --- files/README/source/docs/header.meta | 1 + .../source/unit_tests/header/copy.meta | 3 +++ src/metafile/dir/node.rs | 6 ++++++ src/metafile/file.rs | 7 +++++++ src/metafile/header.rs | 3 +++ src/tests.rs | 20 +++++++++++++++++-- 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 files/test_site/source/unit_tests/header/copy.meta diff --git a/files/README/source/docs/header.meta b/files/README/source/docs/header.meta index 88a5351..5df7eb2 100644 --- a/files/README/source/docs/header.meta +++ b/files/README/source/docs/header.meta @@ -45,3 +45,4 @@ normal definition blocks. - source = **STRING** - change the the filetype of the source file - filetype = **STRING** - change the filetype of the output file - pandoc = **BOOL** - toggles if pandoc is ran on this file to convert between filetypes +- copy_only = **BOOL** - copys file or directory without processing anything diff --git a/files/test_site/source/unit_tests/header/copy.meta b/files/test_site/source/unit_tests/header/copy.meta new file mode 100644 index 0000000..fa04ce3 --- /dev/null +++ b/files/test_site/source/unit_tests/header/copy.meta @@ -0,0 +1,3 @@ +#{ copy_only = true } + +variable: ${this} should get copied verbatim diff --git a/src/metafile/dir/node.rs b/src/metafile/dir/node.rs index e57630e..5b878f4 100644 --- a/src/metafile/dir/node.rs +++ b/src/metafile/dir/node.rs @@ -43,6 +43,12 @@ impl<'a> DirNode<'a> { for f in fs::read_dir(&self.path)? { let file = f?.path(); + if self.global.header.copy_only { + let dest = self.global.dest()?; + fs::copy(file, &dest.parent().unwrap_or(&self.opts.build))?; + continue; + } + if file.is_dir() { let dir = DirNode::build(file, self.opts)?; self.dirs.push(dir); diff --git a/src/metafile/file.rs b/src/metafile/file.rs index a91843c..4e7a51b 100644 --- a/src/metafile/file.rs +++ b/src/metafile/file.rs @@ -63,6 +63,13 @@ impl<'a> MetaFile<'a> { return Err(Box::new(MetaError::Ignored)); } + if self.header.copy_only { + let dest = self.dest().map_err(MetaError::from)?; + let source: String = self.source.iter().map(|s| s.to_string()).collect(); + std::fs::write(dest, source).unwrap(); + return Err(Box::new(MetaError::Ignored)); + } + let html = self.to_html().map_err(MetaError::from)?; let pattern = self.get_pattern("base").map_err(MetaError::from)?; diff --git a/src/metafile/header.rs b/src/metafile/header.rs index fdaed0a..7f88674 100644 --- a/src/metafile/header.rs +++ b/src/metafile/header.rs @@ -10,6 +10,7 @@ pub struct Header { pub source: String, pub pandoc: bool, pub ignore: bool, + pub copy_only: bool, } impl Header { @@ -23,6 +24,7 @@ impl Header { source: String::from("markdown"), pandoc: true, ignore: false, + copy_only: false, } } } @@ -40,6 +42,7 @@ impl From> for Header { "filetype" => header.filetype = val.to_string(), "source" => header.source = val.to_string(), "ignore" => header.ignore = val == "true", + "copy_only" => header.copy_only = val == "true", _ => continue, } } diff --git a/src/tests.rs b/src/tests.rs index aaa3fc0..f265a7f 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,4 +1,4 @@ -use crate::{MetaFile, Options}; +use crate::{MetaError, MetaFile, Options}; use eyre::Result; use std::{fs, path::PathBuf}; @@ -18,7 +18,17 @@ macro_rules! unit_test ( let mut path = test_dir.join($file); path.set_extension("meta"); let file = MetaFile::build(path, &opts)?; - assert_eq!(file.construct()?, $test); + + let str = match file.construct() { + Ok(f) => f, + Err(e) => match *e { + MetaError::Ignored => return Ok(()), + e => return Err(e.into()) + } + + }; + + assert_eq!(str, $test); Ok(()) } }; @@ -125,6 +135,12 @@ unit_test!( "\n

GOOD GOOD

\n\n\n\n\n" ); +unit_test!( + copy_header, + "header/copy", + r#"variable: ${this} should get copied verbatim"# +); + panic_test!(ignore, "ignore.meta", ""); #[test] -- 2.44.2 From 1a0b45640c8af5dd9d5d1c2c5679098dcb2fadb5 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Wed, 31 May 2023 14:54:25 -0500 Subject: [PATCH 02/16] edited: docs homepage with newest version info --- files/README/source/index.meta | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/files/README/source/index.meta b/files/README/source/index.meta index 8a2b159..34fde86 100644 --- a/files/README/source/index.meta +++ b/files/README/source/index.meta @@ -13,6 +13,7 @@ you can change anything in the **README** directory and see how it affects the s you rebuild it. ## contents + - [syntax](docs/syntax.html) - [definitions](docs/definitions.html) - [expansions](docs/expansions.html) @@ -20,6 +21,12 @@ you rebuild it. - [headers](docs/header.html) - [flags](docs/flags.html) +## new in this version + +- spaces are correctly preserved between directly adjacent substitutions +- copy_only header directive + ## versions +- 0.1.3: grammar update - 0.1.2: multithreading - 0.1.1: initial release -- 2.44.2 From 768d1af3a1da2bc594aa0808b22178f0da638ae1 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Wed, 31 May 2023 16:24:42 -0500 Subject: [PATCH 03/16] edited: pandoc header to run on pattern files --- files/README/source/docs/header.meta | 6 +++--- files/README/source/index.meta | 3 ++- files/test_site/pattern/test/pandoc.meta | 3 +++ .../source/unit_tests/header/expandoc.meta | 3 +++ src/lib.rs | 2 +- src/metafile/file.rs | 13 ++++++++++--- src/metafile/file/patterns.rs | 6 +++++- src/metafile/file/source.rs | 5 +++-- src/metafile/header.rs | 6 +++--- src/tests.rs | 10 ++++++++-- 10 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 files/test_site/pattern/test/pandoc.meta create mode 100644 files/test_site/source/unit_tests/header/expandoc.meta diff --git a/files/README/source/docs/header.meta b/files/README/source/docs/header.meta index 5df7eb2..48dca52 100644 --- a/files/README/source/docs/header.meta +++ b/files/README/source/docs/header.meta @@ -37,12 +37,12 @@ normal definition blocks. - blank = **BOOL** - if true, stops parsing and returns an empty string - panic_default = **BOOL** - if true, panics on an undefined default pattern - panic_undefined = **BOOL** - if true, panics on an undefined variable or array +- source = **STRING** - change the the filetype of the source file +- filetype = **STRING** - change the filetype of the output file - equal_arrays = **BOOL** - if true, panics if arrays in the same pattern have different sizes +- pandoc = **BOOL** - toggles if pandoc is ran on this file to convert between filetypes, defaults to *true* in **source** dir, and *false* in **pattern** dir. ### source - ignore = **BOOL** - stops parsing and skips this file, useful for ignoring directories with scoped definitions -- source = **STRING** - change the the filetype of the source file -- filetype = **STRING** - change the filetype of the output file -- pandoc = **BOOL** - toggles if pandoc is ran on this file to convert between filetypes - copy_only = **BOOL** - copys file or directory without processing anything diff --git a/files/README/source/index.meta b/files/README/source/index.meta index 34fde86..dfbb4bd 100644 --- a/files/README/source/index.meta +++ b/files/README/source/index.meta @@ -25,8 +25,9 @@ you rebuild it. - spaces are correctly preserved between directly adjacent substitutions - copy_only header directive +- pandoc header now works on pattern files ## versions -- 0.1.3: grammar update +- 0.1.3: grammar update, new header directives - 0.1.2: multithreading - 0.1.1: initial release diff --git a/files/test_site/pattern/test/pandoc.meta b/files/test_site/pattern/test/pandoc.meta new file mode 100644 index 0000000..6d3869a --- /dev/null +++ b/files/test_site/pattern/test/pandoc.meta @@ -0,0 +1,3 @@ +#{ pandoc = true } + +# GOOD diff --git a/files/test_site/source/unit_tests/header/expandoc.meta b/files/test_site/source/unit_tests/header/expandoc.meta new file mode 100644 index 0000000..aa6c241 --- /dev/null +++ b/files/test_site/source/unit_tests/header/expandoc.meta @@ -0,0 +1,3 @@ +&{test = 'pandoc'} + +source diff --git a/src/lib.rs b/src/lib.rs index 1f34105..696d5eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,7 +83,7 @@ pub fn single_file(opts: &Options) -> Result { })), }?; - let file = parse_string(source, opts)?; + let mut file = parse_string(source, opts)?; Ok(file.construct()?) } diff --git a/src/metafile/file.rs b/src/metafile/file.rs index 4e7a51b..b865709 100644 --- a/src/metafile/file.rs +++ b/src/metafile/file.rs @@ -10,6 +10,7 @@ use pandoc::{InputFormat, InputKind, OutputFormat, OutputKind, Pandoc}; use std::{collections::HashMap, path::PathBuf}; use super::*; + #[derive(Debug, Clone)] pub struct MetaFile<'a> { pub opts: &'a Options, @@ -54,7 +55,7 @@ impl<'a> MetaFile<'a> { Ok(metafile) } - pub fn construct(&self) -> Result> { + pub fn construct(&mut self) -> Result> { log!(self.opts, format!("building {}", self.path.display()), 1); if self.header.blank { @@ -70,7 +71,12 @@ impl<'a> MetaFile<'a> { return Err(Box::new(MetaError::Ignored)); } - let html = self.to_html().map_err(MetaError::from)?; + let src_str: String; + if self.header.pandoc.map_or(true, |x| x) { + src_str = self.pandoc().map_err(MetaError::from)?; + } else { + src_str = self.get_source().map_err(MetaError::from)?; + } let pattern = self.get_pattern("base").map_err(MetaError::from)?; let mut base = parse_string(pattern, self.opts).map_err(|e| MetaError::ParserError { @@ -79,7 +85,8 @@ impl<'a> MetaFile<'a> { })?; base.merge(self); - base.patterns.insert(Scope::create_global("SOURCE"), html); + base.patterns + .insert(Scope::create_global("SOURCE"), src_str); let mut base_path = self.opts.pattern.join("base").join( self.patterns .get(&Scope::create_global("base")) diff --git a/src/metafile/file/patterns.rs b/src/metafile/file/patterns.rs index d019484..f50fd6f 100644 --- a/src/metafile/file/patterns.rs +++ b/src/metafile/file/patterns.rs @@ -69,6 +69,10 @@ impl<'a> MetaFile<'a> { // copy over maps for expanding contained variables pattern.merge(self); - pattern.get_source() + if pattern.header.pandoc.unwrap_or(false) { + pattern.pandoc() + } else { + pattern.get_source() + } } } diff --git a/src/metafile/file/source.rs b/src/metafile/file/source.rs index 6ffad58..3aca3b4 100644 --- a/src/metafile/file/source.rs +++ b/src/metafile/file/source.rs @@ -1,10 +1,10 @@ use super::*; impl<'a> MetaFile<'a> { - pub fn to_html(&self) -> Result { + pub fn pandoc(&mut self) -> Result { let string = self.get_source()?; - if self.opts.no_pandoc || !self.header.pandoc || string.is_empty() { + if self.opts.no_pandoc || string.is_empty() { return Ok(string); } @@ -28,6 +28,7 @@ impl<'a> MetaFile<'a> { .set_output_format(output, vec![]); if let pandoc::PandocOutput::ToBuffer(s) = pandoc.execute()? { + self.header.pandoc = Some(false); Ok(s) } else { Err(MetaError::Pandoc { file: self.name()? }.into()) diff --git a/src/metafile/header.rs b/src/metafile/header.rs index 7f88674..d99d5c4 100644 --- a/src/metafile/header.rs +++ b/src/metafile/header.rs @@ -8,7 +8,7 @@ pub struct Header { pub equal_arrays: bool, pub filetype: String, pub source: String, - pub pandoc: bool, + pub pandoc: Option, pub ignore: bool, pub copy_only: bool, } @@ -22,7 +22,7 @@ impl Header { equal_arrays: false, filetype: String::from("html"), source: String::from("markdown"), - pandoc: true, + pandoc: None, ignore: false, copy_only: false, } @@ -38,7 +38,7 @@ impl From> for Header { "panic_default" => header.panic_default = val == "true", "panic_undefined" => header.panic_undefined = val == "true", "equal_arrays" => header.equal_arrays = val == "true", - "pandoc" => header.pandoc = val == "true", + "pandoc" => header.pandoc = Some(val == "true"), "filetype" => header.filetype = val.to_string(), "source" => header.source = val.to_string(), "ignore" => header.ignore = val == "true", diff --git a/src/tests.rs b/src/tests.rs index f265a7f..b0086f6 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -17,7 +17,7 @@ macro_rules! unit_test ( let test_dir = opts.source.join("unit_tests"); let mut path = test_dir.join($file); path.set_extension("meta"); - let file = MetaFile::build(path, &opts)?; + let mut file = MetaFile::build(path, &opts)?; let str = match file.construct() { Ok(f) => f, @@ -50,7 +50,7 @@ macro_rules! panic_test ( let test_dir = opts.source.join("unit_tests"); let mut path = test_dir.join($file); path.set_extension("meta"); - let file = MetaFile::build(path, &opts).unwrap(); + let mut file = MetaFile::build(path, &opts).unwrap(); assert_eq!(file.construct().unwrap(), $test); } }; @@ -141,6 +141,12 @@ unit_test!( r#"variable: ${this} should get copied verbatim"# ); +unit_test!( + expandoc, + "header/expandoc", + "\n

GOOD

\n\n\n\n" +); + panic_test!(ignore, "ignore.meta", ""); #[test] -- 2.44.2 From 5176dc914b210abe5d5a66825426f831d5bcae5a Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Thu, 1 Jun 2023 13:07:12 -0500 Subject: [PATCH 04/16] updated: bench function description --- benches/parallel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benches/parallel.rs b/benches/parallel.rs index b31ed61..9e7a694 100644 --- a/benches/parallel.rs +++ b/benches/parallel.rs @@ -13,7 +13,7 @@ pub fn parallel_build_dir(c: &mut Criterion) { opts.clean = true; opts.parallel = true; - c.bench_function("build dir", |b| { + c.bench_function("parallel build", |b| { if opts.build.exists() { std::fs::remove_dir_all(&opts.build).expect("clean build dir"); } -- 2.44.2 From 0c684e1fa26a4021c569d86c4539f1371fb6bfbf Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Thu, 1 Jun 2023 13:26:31 -0500 Subject: [PATCH 05/16] updated: bump to 0.1.3 --- files/README/source/default.meta | 2 +- src/metafile.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/files/README/source/default.meta b/files/README/source/default.meta index 3c3a9fb..6c8c868 100644 --- a/files/README/source/default.meta +++ b/files/README/source/default.meta @@ -1,5 +1,5 @@ ${ author = 'huck boles' - version = '0.1.2' + version = '0.1.3' home = './index.html' } diff --git a/src/metafile.rs b/src/metafile.rs index 54f6879..b3c1f5f 100644 --- a/src/metafile.rs +++ b/src/metafile.rs @@ -35,7 +35,6 @@ impl Src { } pub fn to_str(str: impl Display) -> Self { - println!("{}", str.to_string()); Src::Str(str.to_string()) } } -- 2.44.2 From c5a6733624f5d5ed67c2f8e25cdf01f5bae4326b Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Thu, 1 Jun 2023 13:28:36 -0500 Subject: [PATCH 06/16] updated: Cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a515fcc..e855186 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "metaforge" -version = "0.1.2" +version = "0.1.3" edition = "2021" [dependencies] -- 2.44.2 From 693a371efa057d700c0391caa9bbcc755058b083 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 17:05:29 -0500 Subject: [PATCH 07/16] added: html minifier --- Cargo.lock | 168 ++++++++++++++++++++++++++++----- Cargo.toml | 1 + files/README/source/index.meta | 1 + src/metafile/dir/node.rs | 19 +++- src/tests.rs | 4 +- 5 files changed, 169 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72cbf58..1f37171 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + [[package]] name = "anes" version = "0.1.6" @@ -154,9 +163,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.0" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93aae7a4192245f70fe75dd9157fc7b4a5bf53e88d30bd4396f7d8f9284d5acc" +checksum = "b4ed2379f8603fa2b7509891660e802b88c70a79a6427a70abb5968054de2c28" dependencies = [ "clap_builder", "clap_derive", @@ -165,9 +174,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.0" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990" +checksum = "72394f3339a76daf211e57d4bcb374410f3965dcc606dd0e03738c7888766980" dependencies = [ "anstream", "anstyle", @@ -178,14 +187,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.0" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "191d9573962933b4027f932c600cd252ce27a8ad5979418fe78e43c07996f27b" +checksum = "59e9ef9a08ee1c0e1f2e162121665ac45ac3783b0f897db7244ae75ad9a8f65b" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -209,6 +218,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "cpufeatures" version = "0.2.7" @@ -307,6 +322,30 @@ dependencies = [ "typenum", ] +[[package]] +name = "css-minify" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874c6e2d19f8d4a285083b11a3241bfbe01ac3ed85f26e1e6b34888d960552bd" +dependencies = [ + "derive_more", + "indexmap", + "nom", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.10.7" @@ -498,12 +537,15 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "log" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" @@ -516,11 +558,12 @@ dependencies = [ [[package]] name = "metaforge" -version = "0.1.2" +version = "0.1.3" dependencies = [ - "clap 4.3.0", + "clap 4.3.1", "criterion", "eyre", + "minify-html", "pandoc", "pest", "pest_derive", @@ -528,6 +571,46 @@ dependencies = [ "thiserror", ] +[[package]] +name = "minify-html" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4d9147754a49e80557df835eb59e743eab1bf75410a134f55dc4b9dbb692ad" +dependencies = [ + "aho-corasick", + "css-minify", + "lazy_static", + "memchr", + "minify-js", + "rustc-hash", +] + +[[package]] +name = "minify-js" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c300f90ba1138b5c5daf5d9441dc9bdc67b808aac22cf638362a2647bc213be4" +dependencies = [ + "lazy_static", + "parse-js", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -549,9 +632,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] name = "oorandom" @@ -574,6 +657,17 @@ dependencies = [ "itertools 0.8.2", ] +[[package]] +name = "parse-js" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30534759e6ad87aa144c396544747e1c25b1020bd133356fd758c8facec764e5" +dependencies = [ + "aho-corasick", + "lazy_static", + "memchr", +] + [[package]] name = "pest" version = "2.6.0" @@ -604,7 +698,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -701,6 +795,21 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.37.19" @@ -736,6 +845,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + [[package]] name = "serde" version = "1.0.163" @@ -753,7 +868,7 @@ checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -784,6 +899,17 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.18" @@ -818,7 +944,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -892,7 +1018,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.18", "wasm-bindgen-shared", ] @@ -914,7 +1040,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index e855186..30560cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ eyre = "0.6" pest = "2" pest_derive = "2" rayon = "1.7" +minify-html = "0.11" [dev-dependencies] criterion = "0.4" diff --git a/files/README/source/index.meta b/files/README/source/index.meta index dfbb4bd..fb8a466 100644 --- a/files/README/source/index.meta +++ b/files/README/source/index.meta @@ -26,6 +26,7 @@ you rebuild it. - spaces are correctly preserved between directly adjacent substitutions - copy_only header directive - pandoc header now works on pattern files +- html minification ## versions - 0.1.3: grammar update, new header directives diff --git a/src/metafile/dir/node.rs b/src/metafile/dir/node.rs index 5b878f4..40e3d0c 100644 --- a/src/metafile/dir/node.rs +++ b/src/metafile/dir/node.rs @@ -1,9 +1,26 @@ use crate::{error::*, Options}; use eyre::Result; +use minify_html::{minify, Cfg}; use std::{fs, path::PathBuf}; use super::*; +const HTML_CFG: Cfg = Cfg { + do_not_minify_doctype: false, + ensure_spec_compliant_unquoted_attribute_values: false, + keep_closing_tags: true, + keep_html_and_head_opening_tags: true, + keep_spaces_between_attributes: false, + keep_comments: false, + minify_css: true, + minify_css_level_1: false, + minify_css_level_2: true, + minify_css_level_3: false, + minify_js: true, + remove_bangs: true, + remove_processing_instructions: true, +}; + impl<'a> DirNode<'a> { pub fn build(path: PathBuf, opts: &'a Options) -> Result { assert!(path.is_dir() && path.exists()); @@ -69,7 +86,7 @@ impl<'a> DirNode<'a> { file.merge(&self.global); match file.construct() { Ok(str) => { - fs::write(file.dest()?, str)?; + fs::write(file.dest()?, minify(str.as_bytes(), &HTML_CFG))?; } Err(e) => { // print a line to stderr about failure but continue with other files diff --git a/src/tests.rs b/src/tests.rs index b0086f6..8e69a06 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -189,12 +189,12 @@ fn test_global() -> Result<()> { assert_eq!( fs::read_to_string(dir.join("build/unit_tests/global/pattern.html"))?, - "

GOOD

\n

GOOD

\n\n" + "

GOOD

GOOD

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

GOOD GOOD

\n\n" + "

GOOD GOOD

" ); Ok(()) -- 2.44.2 From 1ecd5fd58f8d7718c8cd72e8cff4f18cf6eacfca Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 17:55:44 -0500 Subject: [PATCH 08/16] added: minify header and flag --- files/README/source/docs/header.meta | 1 + src/metafile/dir/node.rs | 6 +++++- src/metafile/header.rs | 3 +++ src/options.rs | 6 ++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/files/README/source/docs/header.meta b/files/README/source/docs/header.meta index 48dca52..1bda89c 100644 --- a/files/README/source/docs/header.meta +++ b/files/README/source/docs/header.meta @@ -41,6 +41,7 @@ normal definition blocks. - filetype = **STRING** - change the filetype of the output file - equal_arrays = **BOOL** - if true, panics if arrays in the same pattern have different sizes - pandoc = **BOOL** - toggles if pandoc is ran on this file to convert between filetypes, defaults to *true* in **source** dir, and *false* in **pattern** dir. +- minify = **BOOL** - toggles html minification ### source diff --git a/src/metafile/dir/node.rs b/src/metafile/dir/node.rs index 40e3d0c..d9b2a05 100644 --- a/src/metafile/dir/node.rs +++ b/src/metafile/dir/node.rs @@ -86,7 +86,11 @@ impl<'a> DirNode<'a> { file.merge(&self.global); match file.construct() { Ok(str) => { - fs::write(file.dest()?, minify(str.as_bytes(), &HTML_CFG))?; + if file.header.minify && self.opts.minify { + fs::write(file.dest()?, minify(str.as_bytes(), &HTML_CFG))?; + } else { + fs::write(file.dest()?, str)?; + } } Err(e) => { // print a line to stderr about failure but continue with other files diff --git a/src/metafile/header.rs b/src/metafile/header.rs index d99d5c4..a895ac3 100644 --- a/src/metafile/header.rs +++ b/src/metafile/header.rs @@ -11,6 +11,7 @@ pub struct Header { pub pandoc: Option, pub ignore: bool, pub copy_only: bool, + pub minify: bool, } impl Header { @@ -25,6 +26,7 @@ impl Header { pandoc: None, ignore: false, copy_only: false, + minify: true, } } } @@ -43,6 +45,7 @@ impl From> for Header { "source" => header.source = val.to_string(), "ignore" => header.ignore = val == "true", "copy_only" => header.copy_only = val == "true", + "minify" => header.copy_only = val == "true", _ => continue, } } diff --git a/src/options.rs b/src/options.rs index 704d2cb..11e8a2c 100644 --- a/src/options.rs +++ b/src/options.rs @@ -53,6 +53,9 @@ pub struct Opts { /// don't call pandoc on source files #[arg(long, default_value_t = false)] pub no_pandoc: bool, + /// don't minify resulting html + #[arg(long, default_value_t = false)] + pub no_minify: bool, } #[derive(Debug, Clone, Default)] @@ -72,6 +75,7 @@ pub struct Options { pub clean: bool, pub no_pandoc: bool, pub new: bool, + pub minify: bool, } impl Options { @@ -92,6 +96,7 @@ impl Options { clean: false, no_pandoc: false, new: false, + minify: true, } } } @@ -109,6 +114,7 @@ impl TryFrom for Options { opts.no_pandoc = value.no_pandoc; opts.new = value.new; opts.parallel = value.parallel; + opts.minify = !value.no_minify; opts.root = if let Some(root) = value.root.as_deref() { PathBuf::from(root).canonicalize() -- 2.44.2 From e62267ae7a16b4fba8333424d6421217b1d8d3e3 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 18:27:49 -0500 Subject: [PATCH 09/16] added: include and expand files from source dir --- files/test_site/pattern/test/expand_source.meta | 1 + .../source/unit_tests/expand/source.meta | 3 +++ .../source/unit_tests/expand/source_expand.meta | 2 ++ src/metafile/file/patterns.rs | 15 ++++++++++++--- src/tests.rs | 6 ++++++ 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 files/test_site/pattern/test/expand_source.meta create mode 100644 files/test_site/source/unit_tests/expand/source.meta create mode 100644 files/test_site/source/unit_tests/expand/source_expand.meta diff --git a/files/test_site/pattern/test/expand_source.meta b/files/test_site/pattern/test/expand_source.meta new file mode 100644 index 0000000..c2d0d56 --- /dev/null +++ b/files/test_site/pattern/test/expand_source.meta @@ -0,0 +1 @@ +&{SOURCE.unit_tests.expand.source_expand} diff --git a/files/test_site/source/unit_tests/expand/source.meta b/files/test_site/source/unit_tests/expand/source.meta new file mode 100644 index 0000000..c97e3bc --- /dev/null +++ b/files/test_site/source/unit_tests/expand/source.meta @@ -0,0 +1,3 @@ +${ var = 'GOOD' } + +&{ test = 'expand_source' } diff --git a/files/test_site/source/unit_tests/expand/source_expand.meta b/files/test_site/source/unit_tests/expand/source_expand.meta new file mode 100644 index 0000000..c290b5a --- /dev/null +++ b/files/test_site/source/unit_tests/expand/source_expand.meta @@ -0,0 +1,2 @@ +GOOD +${var} diff --git a/src/metafile/file/patterns.rs b/src/metafile/file/patterns.rs index f50fd6f..304254f 100644 --- a/src/metafile/file/patterns.rs +++ b/src/metafile/file/patterns.rs @@ -12,6 +12,8 @@ impl<'a> MetaFile<'a> { } } + let is_source = key.split('.').next().unwrap_or("") == "SOURCE"; + let mut filename = if let Some(name) = self.patterns.get(&Scope::create_local(key)) { Ok(name.to_string()) } else if let Some(name) = self.patterns.get(&Scope::create_global(key)) { @@ -21,6 +23,7 @@ impl<'a> MetaFile<'a> { .pattern .join(key.replace(".", "/") + ".meta") .exists() + || is_source { Ok(String::new()) } else if self.header.panic_default { @@ -61,15 +64,21 @@ impl<'a> MetaFile<'a> { } let pattern_path = key.replace('.', "/") + "/" + &filename; - let mut path = self.opts.pattern.join(pattern_path); - path.set_extension("meta"); + let mut path = if is_source { + let pattern_path = pattern_path.replace("SOURCE/", ""); + self.opts.source.join(pattern_path) + } else { + self.opts.pattern.join(pattern_path) + }; + + path.set_extension("meta"); let mut pattern = MetaFile::build(path, self.opts)?; // copy over maps for expanding contained variables pattern.merge(self); - if pattern.header.pandoc.unwrap_or(false) { + if pattern.header.pandoc.unwrap_or(false) || is_source { pattern.pandoc() } else { pattern.get_source() diff --git a/src/tests.rs b/src/tests.rs index 8e69a06..8564ce7 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -147,6 +147,12 @@ unit_test!( "\n

GOOD

\n\n\n\n" ); +unit_test!( + include_source, + "expand/source", + "\n

GOOD GOOD

\n\n\n\n\n" +); + panic_test!(ignore, "ignore.meta", ""); #[test] -- 2.44.2 From 1338cdb1b7ec222f43ab948e77f8d20ecb33721e Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 18:45:35 -0500 Subject: [PATCH 10/16] moved: README to docs dir --- docs/build/docs/definitions.html | 25 ++++++++ docs/build/docs/expansions.html | 28 +++++++++ docs/build/docs/flags.html | 59 +++++++++++++++++++ docs/build/docs/header.html | 4 ++ docs/build/docs/structure.html | 14 +++++ docs/build/docs/syntax.html | 40 +++++++++++++ docs/build/index.html | 1 + .../README => docs}/pattern/base/default.meta | 0 .../README => docs}/pattern/body/default.meta | 0 .../README => docs}/pattern/foot/default.meta | 0 .../README => docs}/pattern/head/default.meta | 0 {files/README => docs}/source/default.meta | 0 .../README => docs}/source/docs/default.meta | 0 .../source/docs/definitions.meta | 0 .../source/docs/expansions.meta | 12 +++- {files/README => docs}/source/docs/flags.meta | 5 +- .../README => docs}/source/docs/header.meta | 2 +- .../source/docs/structure.meta | 0 .../README => docs}/source/docs/syntax.meta | 7 ++- {files/README => docs}/source/index.meta | 9 +-- tests/readme.rs | 2 +- 21 files changed, 196 insertions(+), 12 deletions(-) create mode 100644 docs/build/docs/definitions.html create mode 100644 docs/build/docs/expansions.html create mode 100644 docs/build/docs/flags.html create mode 100644 docs/build/docs/header.html create mode 100644 docs/build/docs/structure.html create mode 100644 docs/build/docs/syntax.html create mode 100644 docs/build/index.html rename {files/README => docs}/pattern/base/default.meta (100%) rename {files/README => docs}/pattern/body/default.meta (100%) rename {files/README => docs}/pattern/foot/default.meta (100%) rename {files/README => docs}/pattern/head/default.meta (100%) rename {files/README => docs}/source/default.meta (100%) rename {files/README => docs}/source/docs/default.meta (100%) rename {files/README => docs}/source/docs/definitions.meta (100%) rename {files/README => docs}/source/docs/expansions.meta (87%) rename {files/README => docs}/source/docs/flags.meta (93%) rename {files/README => docs}/source/docs/header.meta (100%) rename {files/README => docs}/source/docs/structure.meta (100%) rename {files/README => docs}/source/docs/syntax.meta (93%) rename {files/README => docs}/source/index.meta (73%) diff --git a/docs/build/docs/definitions.html b/docs/build/docs/definitions.html new file mode 100644 index 0000000..107e42b --- /dev/null +++ b/docs/build/docs/definitions.html @@ -0,0 +1,25 @@ +definitionshome

definitions - 0.1.3

definining variables and patterns

rules

definition blocks are allowed in all files, but have to be before any source text, and after any header settings (which are a special type of definition block).

a block consists of a sigil for the definition type, followed by braces that surround assignment statements.

assignments are identifiers, followed by an equals sign (=), then a value

definition blocks can have spaces and new lines arbitrarily inserted between each component, and support multiple assignments per block.

identifiers

identifiers can contain alphanumeric ascii values and underscores [a-zA-Z0-9_], as well as separating dots (.)

variable identifiers without dots are available to any pattern called by the file.

array identifiers without dots are available only to the pattern they are defined in.

variable and array identifiers with separating dots use the final item as the identifier, and the preceding items are expanded like a pattern identifier to make a mask on the definition. the definition is only valid in that pattern directory (not children), otherwise it is undefined.

pattern identifiers expand to a directory of files in the pattern directory by replacing .’s with /’s, appending necessary file extensions when called. the value selects a single file in the directory as the desired pattern.

an identifier preceded by an star (*) will be marked as local to the file it is defined in. entire blocks can be marked as local by preceding them with a star. if necessary, a single assignment in a local block can be made global again by prefixing it with an exclamation mark (!).

values

values can be a double or single quoted string, if defining an array, a value is a bracket surrounded, comma separated list of strings.

all values can optionally be assigned as BLANK, which expands to nothing.

patterns can also be assigned as DEFAULT, for overriding globally defined patterns.

scope

any value defined in a file called default.meta in the source directory is defined in all files in the current and child directories.

values defined normally are defined for any file called in the chain of expansion. this value can be overridden, either for a single file in the chain by prefixing the definition with a star (*), or for any files further down the chain, by defining a new value normally.

examples

${ 
+   *foo = 'bar' -{  foo is only equal to bar in this file }
+   bar.baz = BLANK -{  this only applies to pattern/bar/*.meta }
+   baz = quux -{  baz is equal to quux in every file called during
+                 expansion, unless it gets overridden }
+}
+
+@{ 
+   bar = ['foo','bar']
+   baz.blank = BLANK -{  this inserts nothing }
+
+   foo.bar = [ 'foobar', 'foobaz' ]
+   -{  this will copy pattern/foo/*.meta twice, inserting 'foobar and 'foobaz'
+      once each at the location of @{bar} }
+}
+
+-{  all of these patterns are only defined for this file }
+*&{ 
+   foo.bar = BLANK
+   bar.default = DEFAULT
+
+   !baz = "bar"
+   -{  except for this definition, which
+      continues down the expansion chain }
+}
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/expansions.html b/docs/build/docs/expansions.html new file mode 100644 index 0000000..a2bb9a7 --- /dev/null +++ b/docs/build/docs/expansions.html @@ -0,0 +1,28 @@ +expansionshome

expansions - 0.1.3

expanding variables and patterns in a file

syntax

a sigil followed by braces, with an identifier inside.

happens inside the source, expanding to the relevant value when the file is built

examples

...this is a string with a ${variable} to be expanded...
+
+...this line has a &{pattern} inside of it...
+
+...this @{array} will be replaced...

behavior

all expansions are decided by the value defined for the identifier, following inheritance rules, and directory masking for variables and arrays.

variables

variables are simply replaced by the defined value, with no other substitution. they’re useful for small things that are frequently changed in a pattern, but don’t need any extra expansion.

example

definition:
+    ${ 
+       baz = "foo"
+       bar.baz = "quux"
+       quux = BLANK
+    }
+
+pattern [foo]: <p>${baz} ${ quux}</p>
+
+expanded [foo]: <p>foo </p>
+
+pattern [bar]: <p>${baz} ${ quux}</p>
+
+expanded [bar]: <p>quux </p>

arrays

arrays are similar to variables, but are closely related to the masking pattern. after all expansions happen in a pattern, each defined array maps its contents across copies of the pattern, resulting in a easy method for duplicating repetitive parts of patterns.

example

pattern [foo]: <p>@{bar}</p>
+
+defintion: @{  foo.bar = ['foo', 'bar', 'baz'] }
+
+expands to: <p>foo</p><p>bar</p><p>baz</p>

it’s generally best to keep arrays inside small self-contained patterns, otherwise unwanted parts of the file may be duplicated.

patterns

patterns expand by looking for files using the pattern directory as a root. the identifier becomes a directory by changing .’s to /’s. if a defined value exists, it’s used as the filename, with a .meta extension added automatically. if no value is defined, metaforge next looks for files with the exact name in the identifier, again substituting .’s to /’s. if a file still hasn’t been found, or the pattern has most recently been defined as DEFAULT, then default.meta is selected from the identified directory.

foo.bar => pattern/foo/bar/*.meta => pattern/foo/bar.meta => pattern/foo/bar/default.meta

if no file is found metaforge will either insert an empty string, or panic depending on the flags and header settings in effect. a pattern defined as BLANK will always expand to a blank string without errors.

if the identifier in the pattern is SOURCE, the pattern will expand using the processed source from the original calling file in the source directory. this goes through an extra step right before insertion, calling pandoc on the file to convert between the chosen filetypes.

once the filename is determined, it is parsed and expands any contained variables, arrays and patterns. if it is a SOURCE pattern, it is converted to html after the expansions. the expanded pattern is then inserted in place of the calling identifier.

building

as each file is built, the first thing expanded is the relevant base/[FILE].meta pattern, so it is required to have at least a default.meta in the pattern/base directory

example

pattern [base]: <html>&{body}</html>
+
+pattern [body]: <body>&{SOURCE}</body>
+
+source [SOURCE]: foo *bar* baz
+
+expanded [base] : <html><body><p>foo <italic>bar</italic> baz</p></body></html>
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/flags.html b/docs/build/docs/flags.html new file mode 100644 index 0000000..c4b5f60 --- /dev/null +++ b/docs/build/docs/flags.html @@ -0,0 +1,59 @@ +flagshome

flags - 0.1.3

available flags for running metaforge

available flags

-r, --root <ROOT_DIR>
+        root directory, contains source, pattern and build directories
+        defaults to current working directory
+-s, --source <SOURCE_DIR>
+        source file directory, contains directory structure and .meta files for completed site
+        defaults to [root_dir]/source
+-b, --build <BUILD_DIR>
+        build directory, directory where the final site gets built
+        defaults to [root_dir]/build
+-p, --pattern <PATTERN_DIR>
+        pattern directory, contains .meta files that are available for expansion
+        defaults to [root_dir]/pattern
+-f, --file <FILENAME>
+        builds a single file and outputs it to stdout
+-l  --parallel
+        enable parallel processing for faster build times
+        interleaves output from files in verbose mode
+-v, --verbose
+        enable extra output. repeated flags give more info
+            v   => list source files/directories being created
+            vv  => list expansions and substitutions
+            vvv => full debug information (function calls, interior parameters)
+-q, --quiet
+        minimal output
+-o, --output <OUTPUT_FILETYPE>
+        output filetype, defaults to html
+        options:
+            - html
+            - markdown
+            - json
+            - latex
+            - man
+            - txt
+            - asciidoc
+            - pdf
+-i, --input <INPUT_FILETYPE>
+        input filetype, defaults to markdown
+        options:
+            - markdown
+            - html
+            - json
+            - latex
+            - org
+-h, --help
+        print a brief help page
+-V, --version
+        print version
+    --clean
+        clean build directory before building site,
+        will remove anything currently in build directory
+    --new
+        create a new skeleton directory in the root dir
+    --force
+        don't stop building site if a single file fails
+    --undefined
+        panics and stops building site if any undefined variables are encountered
+    --no-pandoc
+        don't call pandoc on source files
+        allows metaforge to run without pandoc installed
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/header.html b/docs/build/docs/header.html new file mode 100644 index 0000000..7b65386 --- /dev/null +++ b/docs/build/docs/header.html @@ -0,0 +1,4 @@ +headershome

headers - 0.1.3

file headers to change behavior

header blocks

define settings for the parser, allowing better control over how a single file gets processed.

header blocks works similarly as any other definition block, with keys consisting of pre-defined keywords, and values consisting of booleans (unquoted) or strings, as well as DEFAULT option for overriding.

the header block must be the first block in a file, as it determines how the parser reads and constructs the rest of the file

in a default.meta file, any keys preceded by an exclamation mark (!) get applied as header settings for the entire directory and children, following the same inheritance rules as other definitions.

prefixing a definition block with an exclamation mark makes the entire block globally defined. inside, you can mark individual assignments as local by preceding them with a star (*) as in normal definition blocks.

example

#{ 
+   filetype = 'txt'
+   !pandoc = 'false'
+}

keywords

any

  • blank = BOOL - if true, stops parsing and returns an empty string
  • panic_default = BOOL - if true, panics on an undefined default pattern
  • panic_undefined = BOOL - if true, panics on an undefined variable or array
  • source = STRING - change the the filetype of the source file
  • filetype = STRING - change the filetype of the output file
  • equal_arrays = BOOL - if true, panics if arrays in the same pattern have different sizes
  • pandoc = BOOL - toggles if pandoc is ran on this file to convert between filetypes, defaults to true in source dir, and false in pattern dir.

source

  • ignore = BOOL - stops parsing and skips this file, useful for ignoring directories with scoped definitions
  • copy_only = BOOL - copys file or directory without processing anything
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/structure.html b/docs/build/docs/structure.html new file mode 100644 index 0000000..9c7f9e5 --- /dev/null +++ b/docs/build/docs/structure.html @@ -0,0 +1,14 @@ +structurehome

structure - 0.1.3

directory structure for metaforge

file locations

metaforge parses files with the .meta extension.

files in the pattern directory are available for file expansion. default.meta files are fallback files if the pattern directory gets called without a defined value.

the structure of the source directory gets mirrored to the build directory as the site is build, with any .meta files becoming .html files, except default.meta files, which define default values for a directory and its children.

the source section of files in the source directory can be written in markdown and will converted to html.

files from the pattern directory the should generally contain html snippets, but can contain anything that you’d like to substitute.

required directories are: - source (site structure and contents) - pattern (patterns for expansion) - pattern/base (gets expanded to start building each pattern)

the build directory doesn’t need to exist, as metaforge will create a new one if it’s missing

a new skeleton site can be built in the given root directory by passing the –new flag to metaforge,

skeleton structure

./
+L pattern/
+|   L base/
+|   |    L default.meta
+|   L body/
+|   |    L default.meta
+|   L head/
+|   |    L default.meta
+|   L foot/
+|        L default.meta
+L source/
+|   L hello_world.meta
+L build/
+    L hello_world.html
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/syntax.html b/docs/build/docs/syntax.html new file mode 100644 index 0000000..16b757a --- /dev/null +++ b/docs/build/docs/syntax.html @@ -0,0 +1,40 @@ +syntaxhome

syntax - 0.1.3

basic syntax rules

sigils

  • $ variables
  • @ arrays
  • & patterns
  • # settings
  • - comments

definition block

a sigil followed by assignment operations enclosed by brackets

examples

${  foo = 'bar' }
+
+&{ 
+   foo.bar = "baz"
+   bar.baz = 'foo'
+}

strings

double or single quoted strings, double quoted strings require escaping control characters, and single quoted strings get copied as is. single quoted strings can stretch across newlines.

examples

"foo bar baz\n"
+
+'foo
+bar
+baz'

arrays

a list of strings, separated by commas, enclosed by brackets. whitespace and newlines between list values are accepted

examples

[ 'foo', 'bar', 'baz', 'quux' ]
+
+["foo","bar","baz"]
+
+[
+    'foo',
+    'bar',
+    'baz'
+]

comments

a comment sigil (-) followed by a comment in braces. the only characters not allowed are braces.

comments get removed during the first pass through of parsing, and can occur anywhere in or across a line.

examples

-{  foobar }
+
+-{ 
+   foobar
+   foobaz }

layout

  • optional header definition block
  • optional variable, array, pattern definition blocks
  • source

example

#{  foo = 'bar' } -{  settings for parsing file }
+
+${ 
+   foo = 'foobar'
+   bar.foo = 'foobaz'
+}
+
+@{ 
+   foo = ['foobar','foobaz']
+   foo.bar.baz = [ 'foobar', 'foobaz', 'barbaz' ]
+}
+
+&{ 
+   foo.bar = 'foobar'
+   bar = "foo_bar"
+}
+
+# FOOBAR
+Foo bar baz quux lorem ipsum...
made with metaforge \ No newline at end of file diff --git a/docs/build/index.html b/docs/build/index.html new file mode 100644 index 0000000..b7c9631 --- /dev/null +++ b/docs/build/index.html @@ -0,0 +1 @@ +metaforge documentationhome

metaforge documentation - 0.1.3

this is the documentation for metaforge, generated by metaforge itself.

currently it’s unstyled html rendered by your browser, so it’s pretty bare-bones.

open files/README in metaforge’s repository and explore the source and pattern files to get some examples of how this site works.

you can change anything in the README directory and see how it affects the site once you rebuild it.

contents

new in this version

  • spaces are correctly preserved between directly adjacent substitutions
  • copy_only header directive
  • pandoc header now works on pattern files

versions

  • 0.1.3: grammar update, new header directives
  • 0.1.2: multithreading
  • 0.1.1: initial release
made with metaforge \ No newline at end of file diff --git a/files/README/pattern/base/default.meta b/docs/pattern/base/default.meta similarity index 100% rename from files/README/pattern/base/default.meta rename to docs/pattern/base/default.meta diff --git a/files/README/pattern/body/default.meta b/docs/pattern/body/default.meta similarity index 100% rename from files/README/pattern/body/default.meta rename to docs/pattern/body/default.meta diff --git a/files/README/pattern/foot/default.meta b/docs/pattern/foot/default.meta similarity index 100% rename from files/README/pattern/foot/default.meta rename to docs/pattern/foot/default.meta diff --git a/files/README/pattern/head/default.meta b/docs/pattern/head/default.meta similarity index 100% rename from files/README/pattern/head/default.meta rename to docs/pattern/head/default.meta diff --git a/files/README/source/default.meta b/docs/source/default.meta similarity index 100% rename from files/README/source/default.meta rename to docs/source/default.meta diff --git a/files/README/source/docs/default.meta b/docs/source/docs/default.meta similarity index 100% rename from files/README/source/docs/default.meta rename to docs/source/docs/default.meta diff --git a/files/README/source/docs/definitions.meta b/docs/source/docs/definitions.meta similarity index 100% rename from files/README/source/docs/definitions.meta rename to docs/source/docs/definitions.meta diff --git a/files/README/source/docs/expansions.meta b/docs/source/docs/expansions.meta similarity index 87% rename from files/README/source/docs/expansions.meta rename to docs/source/docs/expansions.meta index f3d9212..165ebf9 100644 --- a/files/README/source/docs/expansions.meta +++ b/docs/source/docs/expansions.meta @@ -89,14 +89,22 @@ processed source from the original calling file in the source directory. this goes through an extra step right before insertion, calling pandoc on the file to convert between the chosen filetypes. +***SOURCE*** can also be used as a standin for the source directory while writing expansions, +allowing patterns to call the same source file every time, or source files to expand other +source files. + +### example + ...lorem &{SOURCE.foo.bar} ipsum dolor... + once the filename is determined, it is parsed and expands any contained variables, arrays and patterns. if it is a ***SOURCE*** pattern, it is converted to html after the expansions. the expanded pattern is then inserted in place of the calling identifier. ## building -as each file is built, the first thing expanded is the relevant **base/[FILE].meta** pattern, -so it is required to have at least a **default.meta** in the **pattern/base** directory +as each source file is built, the first thing expanded is the defined or default +**[SOURCE]/base/[FILE].meta** pattern, so it is required to have at least a **default.meta** +in the **pattern/base** directory ### example diff --git a/files/README/source/docs/flags.meta b/docs/source/docs/flags.meta similarity index 93% rename from files/README/source/docs/flags.meta rename to docs/source/docs/flags.meta index 4a00fbf..e5fa294 100644 --- a/files/README/source/docs/flags.meta +++ b/docs/source/docs/flags.meta @@ -62,5 +62,6 @@ ${ --undefined panics and stops building site if any undefined variables are encountered --no-pandoc - don't call pandoc on source files - allows metaforge to run without pandoc installed + don't call pandoc on source files. allows metaforge to run without pandoc installed + --no-minify + don't minify resulting html diff --git a/files/README/source/docs/header.meta b/docs/source/docs/header.meta similarity index 100% rename from files/README/source/docs/header.meta rename to docs/source/docs/header.meta index 1bda89c..60900a7 100644 --- a/files/README/source/docs/header.meta +++ b/docs/source/docs/header.meta @@ -40,8 +40,8 @@ normal definition blocks. - source = **STRING** - change the the filetype of the source file - filetype = **STRING** - change the filetype of the output file - equal_arrays = **BOOL** - if true, panics if arrays in the same pattern have different sizes -- pandoc = **BOOL** - toggles if pandoc is ran on this file to convert between filetypes, defaults to *true* in **source** dir, and *false* in **pattern** dir. - minify = **BOOL** - toggles html minification +- pandoc = **BOOL** - toggles if pandoc is ran on this file to convert between filetypes, defaults to *true* in **source** dir, and *false* in **pattern** dir. ### source diff --git a/files/README/source/docs/structure.meta b/docs/source/docs/structure.meta similarity index 100% rename from files/README/source/docs/structure.meta rename to docs/source/docs/structure.meta diff --git a/files/README/source/docs/syntax.meta b/docs/source/docs/syntax.meta similarity index 93% rename from files/README/source/docs/syntax.meta rename to docs/source/docs/syntax.meta index 72deca7..1f55255 100644 --- a/files/README/source/docs/syntax.meta +++ b/docs/source/docs/syntax.meta @@ -63,8 +63,11 @@ anywhere in or across a line. foobaz } ## layout -- optional header definition block -- optional variable, array, pattern definition blocks + +*all sections are optional* + +- header definition block +- variable, array, pattern definition blocks - source ### example diff --git a/files/README/source/index.meta b/docs/source/index.meta similarity index 73% rename from files/README/source/index.meta rename to docs/source/index.meta index fb8a466..2c13574 100644 --- a/files/README/source/index.meta +++ b/docs/source/index.meta @@ -6,10 +6,10 @@ this is the documentation for metaforge, generated by metaforge itself. currently it's unstyled html rendered by your browser, so it's pretty bare-bones. -open **files/README** in metaforge's repository and explore the source and pattern +open **docs/source** in metaforge's repository and explore the source and pattern files to get some examples of how this site works. -you can change anything in the **README** directory and see how it affects the site once +you can change anything in the **docs** directory and see how it affects the site once you rebuild it. ## contents @@ -24,11 +24,12 @@ you rebuild it. ## new in this version - spaces are correctly preserved between directly adjacent substitutions +- include from source dir - copy_only header directive - pandoc header now works on pattern files -- html minification +- html minification header and flags ## versions -- 0.1.3: grammar update, new header directives +- 0.1.3: grammar and headers - 0.1.2: multithreading - 0.1.1: initial release diff --git a/tests/readme.rs b/tests/readme.rs index 01279d7..543bf2e 100644 --- a/tests/readme.rs +++ b/tests/readme.rs @@ -3,7 +3,7 @@ use eyre::Result; #[test] #[ignore = "generates README site"] fn readme() -> Result<()> { - let dir = std::path::PathBuf::from("files/README") + let dir = std::path::PathBuf::from("docs") .canonicalize() .unwrap(); -- 2.44.2 From e2a3ce16886e7019cbbfae1e9ddd4a6e9a6007df Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 18:46:08 -0500 Subject: [PATCH 11/16] removed: docs build dir --- .gitignore | 2 +- docs/build/docs/definitions.html | 25 -------------- docs/build/docs/expansions.html | 28 --------------- docs/build/docs/flags.html | 59 -------------------------------- docs/build/docs/header.html | 4 --- docs/build/docs/structure.html | 14 -------- docs/build/docs/syntax.html | 40 ---------------------- docs/build/index.html | 1 - 8 files changed, 1 insertion(+), 172 deletions(-) delete mode 100644 docs/build/docs/definitions.html delete mode 100644 docs/build/docs/expansions.html delete mode 100644 docs/build/docs/flags.html delete mode 100644 docs/build/docs/header.html delete mode 100644 docs/build/docs/structure.html delete mode 100644 docs/build/docs/syntax.html delete mode 100644 docs/build/index.html diff --git a/.gitignore b/.gitignore index d8450c1..16e17a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /target files/test_site/build -files/README/build +docs/build files/bench_site/build bacon.toml diff --git a/docs/build/docs/definitions.html b/docs/build/docs/definitions.html deleted file mode 100644 index 107e42b..0000000 --- a/docs/build/docs/definitions.html +++ /dev/null @@ -1,25 +0,0 @@ -definitionshome

definitions - 0.1.3

definining variables and patterns

rules

definition blocks are allowed in all files, but have to be before any source text, and after any header settings (which are a special type of definition block).

a block consists of a sigil for the definition type, followed by braces that surround assignment statements.

assignments are identifiers, followed by an equals sign (=), then a value

definition blocks can have spaces and new lines arbitrarily inserted between each component, and support multiple assignments per block.

identifiers

identifiers can contain alphanumeric ascii values and underscores [a-zA-Z0-9_], as well as separating dots (.)

variable identifiers without dots are available to any pattern called by the file.

array identifiers without dots are available only to the pattern they are defined in.

variable and array identifiers with separating dots use the final item as the identifier, and the preceding items are expanded like a pattern identifier to make a mask on the definition. the definition is only valid in that pattern directory (not children), otherwise it is undefined.

pattern identifiers expand to a directory of files in the pattern directory by replacing .’s with /’s, appending necessary file extensions when called. the value selects a single file in the directory as the desired pattern.

an identifier preceded by an star (*) will be marked as local to the file it is defined in. entire blocks can be marked as local by preceding them with a star. if necessary, a single assignment in a local block can be made global again by prefixing it with an exclamation mark (!).

values

values can be a double or single quoted string, if defining an array, a value is a bracket surrounded, comma separated list of strings.

all values can optionally be assigned as BLANK, which expands to nothing.

patterns can also be assigned as DEFAULT, for overriding globally defined patterns.

scope

any value defined in a file called default.meta in the source directory is defined in all files in the current and child directories.

values defined normally are defined for any file called in the chain of expansion. this value can be overridden, either for a single file in the chain by prefixing the definition with a star (*), or for any files further down the chain, by defining a new value normally.

examples

${ 
-   *foo = 'bar' -{  foo is only equal to bar in this file }
-   bar.baz = BLANK -{  this only applies to pattern/bar/*.meta }
-   baz = quux -{  baz is equal to quux in every file called during
-                 expansion, unless it gets overridden }
-}
-
-@{ 
-   bar = ['foo','bar']
-   baz.blank = BLANK -{  this inserts nothing }
-
-   foo.bar = [ 'foobar', 'foobaz' ]
-   -{  this will copy pattern/foo/*.meta twice, inserting 'foobar and 'foobaz'
-      once each at the location of @{bar} }
-}
-
--{  all of these patterns are only defined for this file }
-*&{ 
-   foo.bar = BLANK
-   bar.default = DEFAULT
-
-   !baz = "bar"
-   -{  except for this definition, which
-      continues down the expansion chain }
-}
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/expansions.html b/docs/build/docs/expansions.html deleted file mode 100644 index a2bb9a7..0000000 --- a/docs/build/docs/expansions.html +++ /dev/null @@ -1,28 +0,0 @@ -expansionshome

expansions - 0.1.3

expanding variables and patterns in a file

syntax

a sigil followed by braces, with an identifier inside.

happens inside the source, expanding to the relevant value when the file is built

examples

...this is a string with a ${variable} to be expanded...
-
-...this line has a &{pattern} inside of it...
-
-...this @{array} will be replaced...

behavior

all expansions are decided by the value defined for the identifier, following inheritance rules, and directory masking for variables and arrays.

variables

variables are simply replaced by the defined value, with no other substitution. they’re useful for small things that are frequently changed in a pattern, but don’t need any extra expansion.

example

definition:
-    ${ 
-       baz = "foo"
-       bar.baz = "quux"
-       quux = BLANK
-    }
-
-pattern [foo]: <p>${baz} ${ quux}</p>
-
-expanded [foo]: <p>foo </p>
-
-pattern [bar]: <p>${baz} ${ quux}</p>
-
-expanded [bar]: <p>quux </p>

arrays

arrays are similar to variables, but are closely related to the masking pattern. after all expansions happen in a pattern, each defined array maps its contents across copies of the pattern, resulting in a easy method for duplicating repetitive parts of patterns.

example

pattern [foo]: <p>@{bar}</p>
-
-defintion: @{  foo.bar = ['foo', 'bar', 'baz'] }
-
-expands to: <p>foo</p><p>bar</p><p>baz</p>

it’s generally best to keep arrays inside small self-contained patterns, otherwise unwanted parts of the file may be duplicated.

patterns

patterns expand by looking for files using the pattern directory as a root. the identifier becomes a directory by changing .’s to /’s. if a defined value exists, it’s used as the filename, with a .meta extension added automatically. if no value is defined, metaforge next looks for files with the exact name in the identifier, again substituting .’s to /’s. if a file still hasn’t been found, or the pattern has most recently been defined as DEFAULT, then default.meta is selected from the identified directory.

foo.bar => pattern/foo/bar/*.meta => pattern/foo/bar.meta => pattern/foo/bar/default.meta

if no file is found metaforge will either insert an empty string, or panic depending on the flags and header settings in effect. a pattern defined as BLANK will always expand to a blank string without errors.

if the identifier in the pattern is SOURCE, the pattern will expand using the processed source from the original calling file in the source directory. this goes through an extra step right before insertion, calling pandoc on the file to convert between the chosen filetypes.

once the filename is determined, it is parsed and expands any contained variables, arrays and patterns. if it is a SOURCE pattern, it is converted to html after the expansions. the expanded pattern is then inserted in place of the calling identifier.

building

as each file is built, the first thing expanded is the relevant base/[FILE].meta pattern, so it is required to have at least a default.meta in the pattern/base directory

example

pattern [base]: <html>&{body}</html>
-
-pattern [body]: <body>&{SOURCE}</body>
-
-source [SOURCE]: foo *bar* baz
-
-expanded [base] : <html><body><p>foo <italic>bar</italic> baz</p></body></html>
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/flags.html b/docs/build/docs/flags.html deleted file mode 100644 index c4b5f60..0000000 --- a/docs/build/docs/flags.html +++ /dev/null @@ -1,59 +0,0 @@ -flagshome

flags - 0.1.3

available flags for running metaforge

available flags

-r, --root <ROOT_DIR>
-        root directory, contains source, pattern and build directories
-        defaults to current working directory
--s, --source <SOURCE_DIR>
-        source file directory, contains directory structure and .meta files for completed site
-        defaults to [root_dir]/source
--b, --build <BUILD_DIR>
-        build directory, directory where the final site gets built
-        defaults to [root_dir]/build
--p, --pattern <PATTERN_DIR>
-        pattern directory, contains .meta files that are available for expansion
-        defaults to [root_dir]/pattern
--f, --file <FILENAME>
-        builds a single file and outputs it to stdout
--l  --parallel
-        enable parallel processing for faster build times
-        interleaves output from files in verbose mode
--v, --verbose
-        enable extra output. repeated flags give more info
-            v   => list source files/directories being created
-            vv  => list expansions and substitutions
-            vvv => full debug information (function calls, interior parameters)
--q, --quiet
-        minimal output
--o, --output <OUTPUT_FILETYPE>
-        output filetype, defaults to html
-        options:
-            - html
-            - markdown
-            - json
-            - latex
-            - man
-            - txt
-            - asciidoc
-            - pdf
--i, --input <INPUT_FILETYPE>
-        input filetype, defaults to markdown
-        options:
-            - markdown
-            - html
-            - json
-            - latex
-            - org
--h, --help
-        print a brief help page
--V, --version
-        print version
-    --clean
-        clean build directory before building site,
-        will remove anything currently in build directory
-    --new
-        create a new skeleton directory in the root dir
-    --force
-        don't stop building site if a single file fails
-    --undefined
-        panics and stops building site if any undefined variables are encountered
-    --no-pandoc
-        don't call pandoc on source files
-        allows metaforge to run without pandoc installed
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/header.html b/docs/build/docs/header.html deleted file mode 100644 index 7b65386..0000000 --- a/docs/build/docs/header.html +++ /dev/null @@ -1,4 +0,0 @@ -headershome

headers - 0.1.3

file headers to change behavior

header blocks

define settings for the parser, allowing better control over how a single file gets processed.

header blocks works similarly as any other definition block, with keys consisting of pre-defined keywords, and values consisting of booleans (unquoted) or strings, as well as DEFAULT option for overriding.

the header block must be the first block in a file, as it determines how the parser reads and constructs the rest of the file

in a default.meta file, any keys preceded by an exclamation mark (!) get applied as header settings for the entire directory and children, following the same inheritance rules as other definitions.

prefixing a definition block with an exclamation mark makes the entire block globally defined. inside, you can mark individual assignments as local by preceding them with a star (*) as in normal definition blocks.

example

#{ 
-   filetype = 'txt'
-   !pandoc = 'false'
-}

keywords

any

  • blank = BOOL - if true, stops parsing and returns an empty string
  • panic_default = BOOL - if true, panics on an undefined default pattern
  • panic_undefined = BOOL - if true, panics on an undefined variable or array
  • source = STRING - change the the filetype of the source file
  • filetype = STRING - change the filetype of the output file
  • equal_arrays = BOOL - if true, panics if arrays in the same pattern have different sizes
  • pandoc = BOOL - toggles if pandoc is ran on this file to convert between filetypes, defaults to true in source dir, and false in pattern dir.

source

  • ignore = BOOL - stops parsing and skips this file, useful for ignoring directories with scoped definitions
  • copy_only = BOOL - copys file or directory without processing anything
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/structure.html b/docs/build/docs/structure.html deleted file mode 100644 index 9c7f9e5..0000000 --- a/docs/build/docs/structure.html +++ /dev/null @@ -1,14 +0,0 @@ -structurehome

structure - 0.1.3

directory structure for metaforge

file locations

metaforge parses files with the .meta extension.

files in the pattern directory are available for file expansion. default.meta files are fallback files if the pattern directory gets called without a defined value.

the structure of the source directory gets mirrored to the build directory as the site is build, with any .meta files becoming .html files, except default.meta files, which define default values for a directory and its children.

the source section of files in the source directory can be written in markdown and will converted to html.

files from the pattern directory the should generally contain html snippets, but can contain anything that you’d like to substitute.

required directories are: - source (site structure and contents) - pattern (patterns for expansion) - pattern/base (gets expanded to start building each pattern)

the build directory doesn’t need to exist, as metaforge will create a new one if it’s missing

a new skeleton site can be built in the given root directory by passing the –new flag to metaforge,

skeleton structure

./
-L pattern/
-|   L base/
-|   |    L default.meta
-|   L body/
-|   |    L default.meta
-|   L head/
-|   |    L default.meta
-|   L foot/
-|        L default.meta
-L source/
-|   L hello_world.meta
-L build/
-    L hello_world.html
made with metaforge \ No newline at end of file diff --git a/docs/build/docs/syntax.html b/docs/build/docs/syntax.html deleted file mode 100644 index 16b757a..0000000 --- a/docs/build/docs/syntax.html +++ /dev/null @@ -1,40 +0,0 @@ -syntaxhome

syntax - 0.1.3

basic syntax rules

sigils

  • $ variables
  • @ arrays
  • & patterns
  • # settings
  • - comments

definition block

a sigil followed by assignment operations enclosed by brackets

examples

${  foo = 'bar' }
-
-&{ 
-   foo.bar = "baz"
-   bar.baz = 'foo'
-}

strings

double or single quoted strings, double quoted strings require escaping control characters, and single quoted strings get copied as is. single quoted strings can stretch across newlines.

examples

"foo bar baz\n"
-
-'foo
-bar
-baz'

arrays

a list of strings, separated by commas, enclosed by brackets. whitespace and newlines between list values are accepted

examples

[ 'foo', 'bar', 'baz', 'quux' ]
-
-["foo","bar","baz"]
-
-[
-    'foo',
-    'bar',
-    'baz'
-]

comments

a comment sigil (-) followed by a comment in braces. the only characters not allowed are braces.

comments get removed during the first pass through of parsing, and can occur anywhere in or across a line.

examples

-{  foobar }
-
--{ 
-   foobar
-   foobaz }

layout

  • optional header definition block
  • optional variable, array, pattern definition blocks
  • source

example

#{  foo = 'bar' } -{  settings for parsing file }
-
-${ 
-   foo = 'foobar'
-   bar.foo = 'foobaz'
-}
-
-@{ 
-   foo = ['foobar','foobaz']
-   foo.bar.baz = [ 'foobar', 'foobaz', 'barbaz' ]
-}
-
-&{ 
-   foo.bar = 'foobar'
-   bar = "foo_bar"
-}
-
-# FOOBAR
-Foo bar baz quux lorem ipsum...
made with metaforge \ No newline at end of file diff --git a/docs/build/index.html b/docs/build/index.html deleted file mode 100644 index b7c9631..0000000 --- a/docs/build/index.html +++ /dev/null @@ -1 +0,0 @@ -metaforge documentationhome

metaforge documentation - 0.1.3

this is the documentation for metaforge, generated by metaforge itself.

currently it’s unstyled html rendered by your browser, so it’s pretty bare-bones.

open files/README in metaforge’s repository and explore the source and pattern files to get some examples of how this site works.

you can change anything in the README directory and see how it affects the site once you rebuild it.

contents

new in this version

  • spaces are correctly preserved between directly adjacent substitutions
  • copy_only header directive
  • pandoc header now works on pattern files

versions

  • 0.1.3: grammar update, new header directives
  • 0.1.2: multithreading
  • 0.1.1: initial release
made with metaforge \ No newline at end of file -- 2.44.2 From bb407e75d85fd13db52ab13e372d269ddf04a90c Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 18:47:49 -0500 Subject: [PATCH 12/16] edited: expansions example --- docs/source/docs/expansions.meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/docs/expansions.meta b/docs/source/docs/expansions.meta index 165ebf9..63b1085 100644 --- a/docs/source/docs/expansions.meta +++ b/docs/source/docs/expansions.meta @@ -94,7 +94,7 @@ allowing patterns to call the same source file every time, or source files to ex source files. ### example - ...lorem &{SOURCE.foo.bar} ipsum dolor... + ...lorem ${pat_sub}SOURCE.foo.bar} ipsum dolor... once the filename is determined, it is parsed and expands any contained variables, arrays and patterns. if it is a ***SOURCE*** pattern, it is converted to html after -- 2.44.2 From cab2ea4f2ef7ad3e0e1894698f6c8c2c43104ef2 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 19:54:47 -0500 Subject: [PATCH 13/16] updated: -V version number --- src/options.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/options.rs b/src/options.rs index 11e8a2c..0b021e7 100644 --- a/src/options.rs +++ b/src/options.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; #[derive(Parser, Debug)] #[command(author = "huck boles")] -#[command(version = "0.1.2")] +#[command(version = "0.1.3")] #[command(about = "customizable template driven static site generator")] #[command(long_about = None)] pub struct Opts { -- 2.44.2 From e68c55f27283e78029a652f29e01b51164f18401 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 20:20:46 -0500 Subject: [PATCH 14/16] merged: with main --- README.md | 13 +++++++------ docs/source/docs/default.meta | 10 +++++----- docs/source/docs/definitions.meta | 3 +-- docs/source/docs/expansions.meta | 23 ++++++++++------------- docs/source/docs/structure.meta | 1 + 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 4614ad0..6e2e3b8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# metaforge - v0.1.2 +# metaforge - v0.1.3 a pattern driven static site generator for extensible snippet insertion. @@ -15,9 +15,10 @@ a pattern driven static site generator for extensible snippet insertion. ## about metaforge is a static site generator that lets you write something once, and re-use it -across your site. it requires previous knowledge of html, and doesn't come with pre-made -themes or templates except for a completely bare skeleton directory. it gives you extremely -fine grained control over the generated html, customizing each pattern to a source file +across your site. + +metaforge doesn't come with pre-made themes or templates except for a completely bare skeleton directory. +it gives you extremely fine grained control over the generated html, customizing each pattern to a source file with variables and mappable arrays. metaforge also lets you write metapatterns that contain classes, masking choices to a @@ -31,7 +32,7 @@ this can be set on both a site and file level, allowing single files in the site such as an rss feed. metaforge can also technically translate between any two document formats pandoc supports, but nothing other than the default markdown to html gets tested. -the full documentation is available in this repository under the **files/README/source/docs** +the full documentation is available in this repository under the **docs/source** directory. it's currently setup as a working example of a metaforge site, so you can poke around and see one way a site can be setup. @@ -41,4 +42,4 @@ and see one way a site can be setup. this command can be run as many times as needed to regenerate the documentation, and is reccomended after upgrading to a new version to see what's changed. the generated docs will -be available in **files/README/build**, and can be looked at in any web browser. +be available in **docs/build**, and can be looked at in any web browser. diff --git a/docs/source/docs/default.meta b/docs/source/docs/default.meta index 8103058..cf0bd60 100644 --- a/docs/source/docs/default.meta +++ b/docs/source/docs/default.meta @@ -2,9 +2,9 @@ ${ -{ index is a folder up in this directory } home = '../index.html' -{ using substitutions for example code so it doesn't mess up parsing } - var = '${ ' - arr = '@{ ' - pat = '&{ ' - head = '#{ ' - com = '-{ ' + var = '${' + arr = '@{' + pat = '&{' + head = '#{' + com = '-{' } diff --git a/docs/source/docs/definitions.meta b/docs/source/docs/definitions.meta index 2d790ec..7543ffa 100644 --- a/docs/source/docs/definitions.meta +++ b/docs/source/docs/definitions.meta @@ -1,7 +1,6 @@ ${ title = 'definitions' description = 'definining variables and patterns' - arr_sub = '@{' } ## rules @@ -73,7 +72,7 @@ value normally. foo.bar = [ 'foobar', 'foobaz' ] ${com} this will copy pattern/foo/*.meta twice, inserting 'foobar and 'foobaz' - once each at the location of ${arr_sub}bar} } + once each at the location of ${arr}bar} } } ${com} all of these patterns are only defined for this file } diff --git a/docs/source/docs/expansions.meta b/docs/source/docs/expansions.meta index 63b1085..2fb7ae0 100644 --- a/docs/source/docs/expansions.meta +++ b/docs/source/docs/expansions.meta @@ -1,9 +1,6 @@ ${ title = 'expansions' description = 'expanding variables and patterns in a file' - var_sub = '${' - arr_sub = '@{' - pat_sub = '&{' } ## syntax @@ -15,11 +12,11 @@ when the file is built ### examples - ...this is a string with a ${var_sub}variable} to be expanded... + ...this is a string with a ${var}variable} to be expanded... - ...this line has a ${pat_sub}pattern} inside of it... + ...this line has a ${pat}pattern} inside of it... - ...this ${arr_sub}array} will be replaced... + ...this ${arr}array} will be replaced... ## behavior @@ -41,11 +38,11 @@ don't need any extra expansion. quux = BLANK } - pattern [foo]:

${var_sub}baz} ${var}quux}

+ pattern [foo]:

${var}baz} ${var}quux}

expanded [foo]:

foo

- pattern [bar]:

${var_sub}baz} ${var}quux}

+ pattern [bar]:

${var}baz} ${var}quux}

expanded [bar]:

quux

@@ -58,7 +55,7 @@ parts of patterns. #### example - pattern [foo]:

${arr_sub}bar}

+ pattern [foo]:

${arr}bar}

defintion: ${arr} foo.bar = ['foo', 'bar', 'baz'] } @@ -94,7 +91,7 @@ allowing patterns to call the same source file every time, or source files to ex source files. ### example - ...lorem ${pat_sub}SOURCE.foo.bar} ipsum dolor... + ...lorem ${pat}SOURCE.foo.bar} ipsum dolor... once the filename is determined, it is parsed and expands any contained variables, arrays and patterns. if it is a ***SOURCE*** pattern, it is converted to html after @@ -103,14 +100,14 @@ the expansions. the expanded pattern is then inserted in place of the calling id ## building as each source file is built, the first thing expanded is the defined or default -**[SOURCE]/base/[FILE].meta** pattern, so it is required to have at least a **default.meta** +**[PATTERN]/base/[FILE].meta** pattern, so it is required to have at least a **default.meta** in the **pattern/base** directory ### example - pattern [base]: ${pat_sub}body} + pattern [base]: ${pat}body} - pattern [body]: ${pat_sub}SOURCE} + pattern [body]: ${pat}SOURCE} source [SOURCE]: foo *bar* baz diff --git a/docs/source/docs/structure.meta b/docs/source/docs/structure.meta index b8c51dc..22a5bef 100644 --- a/docs/source/docs/structure.meta +++ b/docs/source/docs/structure.meta @@ -22,6 +22,7 @@ files from the pattern directory the should generally contain html snippets, but can contain anything that you'd like to substitute. required directories are: + - source (site structure and contents) - pattern (patterns for expansion) - pattern/base (gets expanded to start building each pattern) -- 2.44.2 From 7a74a03d411362c64604329d1f0ba4b46b91325e Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Fri, 2 Jun 2023 20:21:39 -0500 Subject: [PATCH 15/16] added: escapes in docs --- docs/source/docs/structure.meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/docs/structure.meta b/docs/source/docs/structure.meta index 22a5bef..df6bf64 100644 --- a/docs/source/docs/structure.meta +++ b/docs/source/docs/structure.meta @@ -31,7 +31,7 @@ the build directory doesn't need to exist, as metaforge will create a new one if it's missing a new skeleton site can be built in the given root directory by passing -the ***--new*** flag to metaforge, +the ***\-\-new*** flag to metaforge, ## skeleton structure ./ -- 2.44.2 From 2c81d2cf35c0e6605b0740c41ac691e89cf0a7de Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Sat, 3 Jun 2023 10:14:25 -0500 Subject: [PATCH 16/16] fixed: minify header directive --- files/test_site/source/unit_tests/find_dest.meta | 2 +- .../source/unit_tests/global/no_minify.meta | 7 +++++++ src/error.rs | 4 +++- src/lib.rs | 4 ++-- src/metafile/dir/node.rs | 4 ++-- src/metafile/file.rs | 12 +++++------- src/metafile/file/patterns.rs | 2 +- src/metafile/file/variables.rs | 8 ++------ src/metafile/header.rs | 13 ++++++++----- src/parser.rs | 2 +- src/tests.rs | 5 +++++ 11 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 files/test_site/source/unit_tests/global/no_minify.meta diff --git a/files/test_site/source/unit_tests/find_dest.meta b/files/test_site/source/unit_tests/find_dest.meta index b27622f..1a2a819 100644 --- a/files/test_site/source/unit_tests/find_dest.meta +++ b/files/test_site/source/unit_tests/find_dest.meta @@ -1 +1 @@ -#{ skip = 'true' } +#{ ignore = 'true' } diff --git a/files/test_site/source/unit_tests/global/no_minify.meta b/files/test_site/source/unit_tests/global/no_minify.meta new file mode 100644 index 0000000..02d1ba3 --- /dev/null +++ b/files/test_site/source/unit_tests/global/no_minify.meta @@ -0,0 +1,7 @@ +#{ minify = false } + +&{ base = DEFAULT } + +# TEST + +this shouldn't get minified diff --git a/src/error.rs b/src/error.rs index 4f82158..241edcd 100644 --- a/src/error.rs +++ b/src/error.rs @@ -24,6 +24,8 @@ pub enum MetaError { UndefinedDefault { pattern: String, path: String }, #[error("the parser cannot resolve this input: {input}")] UnreachableRule { input: String }, + #[error("unknown option in header: {opt}")] + Header { opt: String }, #[error("{file}\n{error}")] ParserError { file: String, error: String }, #[error(transparent)] @@ -39,7 +41,7 @@ pub fn check_ignore(result: Result) -> Result, MetaEr Ok(f) => Ok(Some(f)), Err(e) => match e { MetaError::Ignored => Ok(None), - e => Err(e.into()), + e => Err(e), }, } } diff --git a/src/lib.rs b/src/lib.rs index 696d5eb..017094f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,9 +54,9 @@ pub fn build_site(opts: &Options) -> Result<()> { let mut source = DirNode::build(opts.source.clone(), opts)?; let global_init = if source.path.join("default.meta").exists() { - MetaFile::build(source.path.join("default.meta"), &opts)? + MetaFile::build(source.path.join("default.meta"), opts)? } else { - MetaFile::new(&opts) + MetaFile::new(opts) }; source.map(&global_init)?; diff --git a/src/metafile/dir/node.rs b/src/metafile/dir/node.rs index d9b2a05..94071bf 100644 --- a/src/metafile/dir/node.rs +++ b/src/metafile/dir/node.rs @@ -62,7 +62,7 @@ impl<'a> DirNode<'a> { if self.global.header.copy_only { let dest = self.global.dest()?; - fs::copy(file, &dest.parent().unwrap_or(&self.opts.build))?; + fs::copy(file, dest.parent().unwrap_or(&self.opts.build))?; continue; } @@ -86,7 +86,7 @@ impl<'a> DirNode<'a> { file.merge(&self.global); match file.construct() { Ok(str) => { - if file.header.minify && self.opts.minify { + if file.header.minify && &file.header.filetype == "html" { fs::write(file.dest()?, minify(str.as_bytes(), &HTML_CFG))?; } else { fs::write(file.dest()?, str)?; diff --git a/src/metafile/file.rs b/src/metafile/file.rs index b865709..71e0535 100644 --- a/src/metafile/file.rs +++ b/src/metafile/file.rs @@ -41,8 +41,7 @@ impl<'a> MetaFile<'a> { Err(_) => { return Err(MetaError::FileNotFound { path: path.to_string_lossy().to_string(), - } - .into()) + }) } }; @@ -71,12 +70,11 @@ impl<'a> MetaFile<'a> { return Err(Box::new(MetaError::Ignored)); } - let src_str: String; - if self.header.pandoc.map_or(true, |x| x) { - src_str = self.pandoc().map_err(MetaError::from)?; + let src_str = if self.header.pandoc.map_or(true, |x| x) { + self.pandoc().map_err(MetaError::from) } else { - src_str = self.get_source().map_err(MetaError::from)?; - } + self.get_source().map_err(MetaError::from) + }?; let pattern = self.get_pattern("base").map_err(MetaError::from)?; let mut base = parse_string(pattern, self.opts).map_err(|e| MetaError::ParserError { diff --git a/src/metafile/file/patterns.rs b/src/metafile/file/patterns.rs index 304254f..012c561 100644 --- a/src/metafile/file/patterns.rs +++ b/src/metafile/file/patterns.rs @@ -21,7 +21,7 @@ impl<'a> MetaFile<'a> { } else if self .opts .pattern - .join(key.replace(".", "/") + ".meta") + .join(key.replace('.', "/") + ".meta") .exists() || is_source { diff --git a/src/metafile/file/variables.rs b/src/metafile/file/variables.rs index 08f09f8..e217ee7 100644 --- a/src/metafile/file/variables.rs +++ b/src/metafile/file/variables.rs @@ -4,14 +4,10 @@ impl<'a> MetaFile<'a> { pub fn get_variable(&self, key: &str) -> Result { log!( self.opts, - format!( - "substituting {} in {}", - key.to_string(), - self.path.display() - ), + format!("substituting {key} in {}", self.path.display()), 2 ); - let long_key = self.name()? + "." + &key.to_string(); + let long_key = self.name()? + "." + key; if let Some(val) = self.variables.get(&Scope::create_local(&long_key)) { Ok(val.clone()) } else if let Some(val) = self.variables.get(&Scope::create_global(&long_key)) { diff --git a/src/metafile/header.rs b/src/metafile/header.rs index a895ac3..fb428ba 100644 --- a/src/metafile/header.rs +++ b/src/metafile/header.rs @@ -1,5 +1,7 @@ use std::collections::HashMap; +use crate::MetaError; + #[derive(Debug, Clone, Default)] pub struct Header { pub blank: bool, @@ -31,8 +33,9 @@ impl Header { } } -impl From> for Header { - fn from(value: HashMap) -> Self { +impl TryFrom> for Header { + type Error = MetaError; + fn try_from(value: HashMap) -> Result { let mut header = Header::new(); for (key, val) in value.iter() { match &key[..] { @@ -45,10 +48,10 @@ impl From> for Header { "source" => header.source = val.to_string(), "ignore" => header.ignore = val == "true", "copy_only" => header.copy_only = val == "true", - "minify" => header.copy_only = val == "true", - _ => continue, + "minify" => header.minify = val == "true", + x => return Err(MetaError::Header { opt: x.to_string() }), } } - header + Ok(header) } } diff --git a/src/parser.rs b/src/parser.rs index d30dea5..a4ae372 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -32,7 +32,7 @@ pub fn parse_string(file: String, opts: &Options) -> Result { match pair.as_rule() { Rule::source => meta_file.source = parse_source(pair.into_inner()), Rule::header => { - meta_file.header = Header::from(parse_header_defs(pair.into_inner())) + meta_file.header = Header::try_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())?, diff --git a/src/tests.rs b/src/tests.rs index 8564ce7..6acef57 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -203,5 +203,10 @@ fn test_global() -> Result<()> { "

GOOD GOOD

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

TEST

\n

this shouldn’t get minified

\n\n\n\n\n" + ); + Ok(()) } -- 2.44.2