diff --git a/Cargo.lock b/Cargo.lock index e5e17356..6f1e276c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,6 +173,7 @@ dependencies = [ "color-eyre", "css-colors", "handlebars", + "indexmap", "regex", "serde", "serde_json", @@ -438,12 +439,13 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown", + "serde", ] [[package]] @@ -742,6 +744,7 @@ version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ + "indexmap", "itoa", "ryu", "serde", diff --git a/whiskers/Cargo.toml b/whiskers/Cargo.toml index df97bcb5..19dbb5f5 100644 --- a/whiskers/Cargo.toml +++ b/whiskers/Cargo.toml @@ -16,6 +16,7 @@ path = "src/main.rs" [dependencies] base64 = "0.21" catppuccin = { version = "1.3", features = ["css"] } +indexmap = { version = "2.1.0", features = ["serde", "std"] } clap = { version = "4.4", features = ["derive"] } clap-stdin = "0.2" color-eyre = { version = "0.6", default-features = false } @@ -23,7 +24,7 @@ css-colors = "1.0" handlebars = "4.5" regex = "1.10" serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" +serde_json = { version = "1.0", features = ["preserve_order"] } serde_yaml = "0.9" tempfile = "3.8" thiserror = "1.0" diff --git a/whiskers/examples/nested.hbs b/whiskers/examples/nested.hbs index 7790c76c..7468a589 100644 --- a/whiskers/examples/nested.hbs +++ b/whiskers/examples/nested.hbs @@ -1,11 +1,13 @@ --- -accent: {{mauve}} +accent: {{flavors.frappe.mauve}} --- How do we want to handle frontmatter? It makes sense when a single flavour is being rendered, but not when multiple are... at the minute anyways. -{{ #each flavors as | flavor flavour | }} -## {{titlecase flavour}} -Base: {{base}} +{{#each flavors as | flavor flavour | }} +- **{{flavour}}** + {{ #each colors as | color colorName | }} + - **{{colorName}}** + {{/each}} {{/each}} diff --git a/whiskers/src/template.rs b/whiskers/src/template.rs index 910a2688..7372ccf6 100644 --- a/whiskers/src/template.rs +++ b/whiskers/src/template.rs @@ -1,6 +1,6 @@ -use std::collections::HashMap; - -use handlebars::{Handlebars, HelperDef}; +use handlebars::Handlebars; +use handlebars::HelperDef; +use indexmap::IndexMap; use crate::helper; @@ -182,14 +182,59 @@ pub fn make_registry() -> Handlebars<'static> { reg } +fn flavor_priority(flavor: &str) -> u32 { + match flavor { + "latte" => 1, + "frappe" => 2, + "macchiato" => 3, + "mocha" => 4, + _ => unreachable!(), + } +} + +fn color_priority(color: &str) -> u32 { + match color { + "rosewater" => 1, + "flamingo" => 2, + "pink" => 3, + "mauve" => 4, + "red" => 5, + "maroon" => 6, + "peach" => 7, + "yellow" => 8, + "green" => 9, + "teal" => 10, + "sky" => 11, + "sapphire" => 12, + "blue" => 13, + "lavender" => 14, + "text" => 15, + "subtext1" => 16, + "subtext0" => 17, + "overlay2" => 18, + "overlay1" => 19, + "overlay0" => 20, + "surface2" => 21, + "surface1" => 22, + "surface0" => 23, + "base" => 24, + "mantle" => 25, + "crust" => 26, + _ => unreachable!(), + } +} + #[must_use] #[allow(clippy::missing_panics_doc)] // panic here implies an internal issue pub fn make_context_all() -> serde_json::Value { - let flavours: HashMap<&str, serde_json::Value> = catppuccin::Flavour::into_iter() + let mut flavours: IndexMap<&str, serde_json::Value> = catppuccin::Flavour::into_iter() .map(|f| (f.name(), make_context(f))) .collect(); - let flavours_map = HashMap::from([("flavors", flavours)]); - serde_json::to_value(flavours_map).expect("flavours can be serialized") + flavours.sort_by(|a, _, b, _| flavor_priority(a).cmp(&flavor_priority(b))); + + let context = IndexMap::from([("flavors", flavours)]); + + serde_json::to_value(context).expect("flavours can be serialized") } #[must_use] @@ -197,10 +242,11 @@ pub fn make_context_all() -> serde_json::Value { pub fn make_context(flavor: catppuccin::Flavour) -> serde_json::Value { let colors = flavor.colours(); - let color_map: HashMap = colors + let mut color_map: IndexMap = colors .into_fields_iter() .map(|(name, c)| (name.to_string(), c.hex().to_ascii_lowercase())) .collect(); + color_map.sort_by(|a, _, b, _| color_priority(a).cmp(&color_priority(b))); let mut context = serde_json::to_value(color_map.clone()).expect("color names & hexcodes can be serialized");