diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..78f9b19 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target +*.code-workspace \ No newline at end of file diff --git a/static-site-builder/Cargo.lock b/static-site-builder/Cargo.lock new file mode 100644 index 0000000..9bc6ece --- /dev/null +++ b/static-site-builder/Cargo.lock @@ -0,0 +1,439 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "cc" +version = "1.2.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "find-msvc-tools" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json-builder-macro" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa0a35ce526cad28e8487490a9852c420ab24f130587c96a5cb6ba64d9e038d" + +[[package]] +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simple-markdown-parser" +version = "0.0.7" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "serde", + "serde-wasm-bindgen", + "simple-yaml-parser", + "tsify", + "wasm-bindgen", +] + +[[package]] +name = "simple-yaml-parser" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d79b1476a927af5cc88678adf66095da3f7ede2cf13658470687495db8f5f41" + +[[package]] +name = "static-site-builder" +version = "0.0.0" +dependencies = [ + "json-builder-macro", + "libloading", + "simple-markdown-parser", + "tree-sitter", +] + +[[package]] +name = "streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tree-sitter" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87" +dependencies = [ + "cc", + "regex", + "regex-syntax", + "serde_json", + "streaming-iterator", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-language" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8" + +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "wasm-bindgen" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" diff --git a/static-site-builder/Cargo.toml b/static-site-builder/Cargo.toml new file mode 100644 index 0000000..c39c49a --- /dev/null +++ b/static-site-builder/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "static-site-builder" +version = "0.0.0" +edition = "2024" +publish = false + +[[bin]] +path = "main.rs" +name = "main" + +# TODO YAML parser for configuration +[dependencies] +json-builder-macro = "0.0.3" +libloading = "0.9.0" +simple-markdown-parser = { git = "https://github.com/kaleidawave/simple-markdown-parser", branch = "improvements", version = "0.0.7" } +tree-sitter = "0.25.10" + +# simple-markdown-parser = { path = "/Users/Benjamin/Projects/simple-markdown-parser", version = "0.0.7" } diff --git a/static-site-builder/README.md b/static-site-builder/README.md new file mode 100644 index 0000000..4e809a0 --- /dev/null +++ b/static-site-builder/README.md @@ -0,0 +1,114 @@ +### Wants + +- A simpler process for building kaleidawave-github-io +- Something for publishing the new specification tests for ezno + +and + +- To use simple-markdown-parser with HTML extra add-ons like `include` etc +- A TSX based templating (not nunjucks) + - May be more minimal with functions etc +- A single file transform? + +### Included + +- A static server for development +- RSS generation +- TSX execution + - Partial runtime? Only supports certain constructs +- Code highlighting + - Using `tree-sitter` grammars +- Warnings? (or seperate tool) + - `#TODO` warnings + +### Not included + +- Formatter (use simple-markdown-parser formatter binary) +- Spell checker (use wip tool) +- Markdown checker (use simple-markdown-parser statistics tool) +- Publishing / deploy (use GitHub pages or other) +- Post view count +- GitHub comments +- CSS minifier + +### Process + +- New branch for kaleidawave-github-io + +### Implementation details + +- Have a cache of templates and things + +Steps + +- Parse YAML configuration +- Run through each path building files + +### Libraries + +- simple-markdown-parser (off improvements branch until know this is stable) + - for parsing of markdown + - for HTML emit +- ezno-parser? + - maybe for templating + - if we use the JSX feature we do not need the + - how do we evaluate the data? +- YAML parser (included in simple-markdown-parser) + - for markdown frontmatter + - for setup +- json-builder-macro + - for RSS generation +- glob + - for finding files +- tree-siiter and libloading + - for loading languages for highlighting +- general-parser + - for mathematics blocks + +### YAML configuration + +```yaml +name: Ben's engineering blog +host: ... +paths: + - path: "/" + page: "pages/index.tsx" + - path: "/about" + page: "pages/about.html" + - path: "/posts/$identifier" + page: "posts/**.md" + ... +``` + +> Auto find? Distinguish between single and multiple pages? Auto assets + +### Page frontmatter + +> Maybe this inherits from the parent? + +```yml +url: "/posts/..." # TODO this is specified in the main YAML configuration +identifier: ... +description: ... +banner: ... +publish_date: ... +start_date: ... +edits: + - date: ... + change: ... +template: + path: ... + arguments: + x: ... +``` + +> `template: *path*` is allowed (arguments empty) + +### Other + +For blog + +- `val.town` based analytics? `navigator.sendBeacon` +- replace discus comment section implementation + - uses next.js 👎 +- ??? diff --git a/static-site-builder/main.rs b/static-site-builder/main.rs new file mode 100644 index 0000000..2e61f68 --- /dev/null +++ b/static-site-builder/main.rs @@ -0,0 +1,119 @@ +use simple_markdown_parser::emit::{FeatureEmitter, markdown_to_html}; +use simple_markdown_parser::{Frontmatter, ParseOptions, simple_yaml_parser}; +use std::path::Path; + +fn main() { + todo!(); +} + +#[derive(Debug)] +pub struct Template { + includes: Vec, + buf: String, + // TODO + footer: String, + header: String, +} + +#[derive(Debug)] +pub enum Kind { + StyleSheet, + Script, +} + +#[derive(Debug)] +pub enum Include { + Reference { path: String, kind: Kind }, + Content { content: String, kind: Kind }, +} + +use std::fmt::Write; + +impl Template { + pub fn new(includes: Vec, header: String, footer: String) -> Self { + let start = r#""#; + let buf = start.to_owned(); + Self { + buf, + header, + footer, + includes, + } + } + + pub fn title(&mut self, title: &str) { + // TODO metadata + write!(&mut self.buf, "{title}").unwrap(); + } + + pub fn finish_head(&mut self) { + for include in self.includes.drain(..) { + match include { + Include::Content { + content, + kind: Kind::StyleSheet, + } => { + write!(&mut self.buf, "").unwrap(); + } + include => todo!("{include:?}"), + } + } + write!(&mut self.buf, "").unwrap(); + write!( + &mut self.buf, + "
{header}
", + header = &self.header + ) + .unwrap(); + } + + pub fn finish(mut self, path: &str) { + write!( + &mut self.buf, + "", + footer = self.footer + ) + .unwrap(); + write!(&mut self.buf, "").unwrap(); + std::fs::write(path, self.buf).unwrap(); + } +} + +impl Write for Template { + fn write_str(&mut self, s: &str) -> Result<(), std::fmt::Error> { + String::write_str(&mut self.buf, s) + } +} + +impl FeatureEmitter for Template { + fn frontmatter(&mut self, frontmatter: Frontmatter<'_>) { + let _ = frontmatter.parse_yaml(|key, value| { + if let [simple_yaml_parser::YAMLKey::Slice("title")] = key { + let simple_yaml_parser::RootYAMLValue::String(value) = value else { + panic!("bad value"); + }; + self.title(&value); + } else { + println!("TODO {key:?} -> {value:?}"); + } + }); + self.finish_head(); + // TODO + } + + fn code_block(&mut self, language: &str, code: &str) { + eprintln!("TODO code block {language} {code:?}"); + } + + fn mathematics(&mut self, code: &str, display: bool) { + eprintln!("TODO {code} {display:?}"); + } + + fn command(&mut self, name: &str, args: Vec<(&str, &str)>, inner: &str, options: ParseOptions) { + eprintln!("TODO command {name}"); + } + + fn interpolation(&mut self, expression: &str) { + eprintln!("TODO interpolation{expression}"); + } +}