ishou_render/lib.rs
1//! ishou-render — target-specific renderers from `ishou_tokens::TokenSet`.
2//!
3//! Every renderer is a pure function: `TokenSet → String`. Determinism is a
4//! test invariant — same tokens produce byte-identical output.
5//!
6//! Morphism table (identical in spirit to arch-synthesizer's morphism graph):
7//!
8//! | Source | Target | Module |
9//! |----------------|----------------------------------------|--------------|
10//! | `TokenSet` | CSS custom properties + utility classes | `css` |
11//! | `TokenSet` | tailwind.config.js | `tailwind` |
12//! | `TokenSet` | SCSS variables | `scss` |
13//! | `TokenSet` | Rust `pub const` module | `rust` |
14//! | `TokenSet` | W3C Design Tokens JSON | `json` |
15//! | `TokenSet` | GLSL `#define` header | `glsl` |
16//! | `TokenSet` | Ghostty config block | `ghostty` |
17//! | `TokenSet` | TUI ratatui / crossterm Color table | `tui` |
18//! | `TokenSet` | SVG (brand mark + swerve) | `svg` |
19//! | `TokenSet` | stylix base16 YAML | `stylix` |
20//! | `TokenSet` | base16 bat `.tmTheme` (Sublime plist) | `bat` |
21
22pub mod bat;
23pub mod css;
24pub mod md3;
25pub mod fleet_fonts;
26pub mod ghostty;
27pub mod glsl;
28pub mod json;
29pub mod nix;
30pub mod nix_ast;
31pub mod rust;
32pub mod scss;
33pub mod stylix;
34pub mod stylix_fonts;
35pub mod svg;
36pub mod tailwind;
37pub mod tui;
38pub mod vellum;
39
40/// Every renderable target ishou-cli understands. The string here matches the
41/// CLI flag users type (`ishou render --target css`).
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub enum Target {
44 Css,
45 /// Material Design 3 system colors (`--md-sys-color-*`) mapped from the
46 /// TokenSet — the target Material consumers (`pleme-mui`) bind to so they
47 /// can consume ishou instead of forking a hard-coded MD3 palette.
48 Md3,
49 Tailwind,
50 Scss,
51 Rust,
52 Json,
53 Glsl,
54 Ghostty,
55 Tui,
56 Svg,
57 Stylix,
58 /// base16 bat `.tmTheme` (Sublime-Text XML plist) — the FIRST per-app
59 /// *config-file* target. bat consumes it as a custom theme; this is the
60 /// M0 proof ishou can natively emit a per-app config file (toward ishou
61 /// replacing stylix as the fleet theming engine). Same base16 slot→Nord
62 /// mapping as `Stylix`.
63 Bat,
64 Nix,
65 StylixFonts,
66 /// Fleet-fonts attrset — `{ primary, italic, bold, symbols, emoji,
67 /// fallback_chain }` consumed directly by every pleme-io GPU app
68 /// HM module (mado, blackmatter-ghostty, fumi, kagi, …) to name
69 /// the canonical family AND install the underlying nixpkgs
70 /// package via `home.packages`. Sibling of `StylixFonts` — same
71 /// typed Typography source, different consumer-side shape.
72 FleetFonts,
73 /// Vellum base16 stylix scheme YAML (the prescribed fleet theme).
74 /// Sourced from the BORN `VellumPalette`, not the Nord `TokenSet`.
75 StylixVellum,
76 /// Vellum base24 stylix scheme YAML — base16 + the real two-tier
77 /// brights (base10–17).
78 StylixVellumBase24,
79 /// Vellum palette preview SVG — one labelled chip per BORN token.
80 SvgVellumPalette,
81 /// Vellum skim/fzf `--color=k:v,…` string — the fleet picker theme.
82 /// Generated from the BORN `VellumPalette`, byte-equivalent to the
83 /// hand-authored `skim-tab::NORD_COLORS`.
84 SkimVellum,
85 /// Vellum escriba theme `*.lisp` — `(deftheme)` + `(defpalette)` +
86 /// `(defhighlight …)` over escriba's `CANONICAL_GROUPS`, sourced from
87 /// the BORN `VellumPalette`. Mirrors `escriba/configs/vellum.lisp`.
88 EscribaVellum,
89}
90
91impl Target {
92 pub fn from_str(s: &str) -> Option<Self> {
93 Some(match s {
94 "css" => Self::Css,
95 "md3" | "material" | "md-sys-color" => Self::Md3,
96 "tailwind" => Self::Tailwind,
97 "scss" => Self::Scss,
98 "rust" => Self::Rust,
99 "json" => Self::Json,
100 "glsl" => Self::Glsl,
101 "ghostty" => Self::Ghostty,
102 "tui" => Self::Tui,
103 "svg" => Self::Svg,
104 "stylix" | "stylix-base16" => Self::Stylix,
105 "bat" | "bat-tmtheme" => Self::Bat,
106 "stylix-fonts" | "fonts-nix" => Self::StylixFonts,
107 "nix" | "nord-palette-nix" => Self::Nix,
108 "fleet-fonts" | "fleet_fonts" => Self::FleetFonts,
109 "stylix-vellum" | "stylix-base16-vellum" => Self::StylixVellum,
110 "stylix-vellum-base24" | "stylix-base24-vellum" => Self::StylixVellumBase24,
111 "svg-vellum-palette" | "vellum-palette" => Self::SvgVellumPalette,
112 "skim-vellum" | "skim" => Self::SkimVellum,
113 "escriba-vellum" | "escriba" => Self::EscribaVellum,
114 _ => return None,
115 })
116 }
117
118 pub fn render(&self, tokens: &ishou_tokens::TokenSet) -> String {
119 match self {
120 Self::Css => css::render(tokens),
121 Self::Md3 => md3::render(tokens),
122 Self::Tailwind => tailwind::render(tokens),
123 Self::Scss => scss::render(tokens),
124 Self::Rust => rust::render(tokens),
125 Self::Json => json::render(tokens),
126 Self::Glsl => glsl::render(tokens),
127 Self::Ghostty => ghostty::render(tokens),
128 Self::Tui => tui::render(tokens),
129 Self::Svg => svg::render(tokens),
130 Self::Stylix => stylix::render(tokens),
131 Self::Bat => bat::render(tokens),
132 Self::Nix => nix::render(tokens),
133 Self::StylixFonts => stylix_fonts::render(tokens),
134 Self::FleetFonts => fleet_fonts::render(tokens),
135 // Vellum targets are their own BORN source — the Nord
136 // `TokenSet` argument is unused.
137 Self::StylixVellum => vellum::render_base16(),
138 Self::StylixVellumBase24 => vellum::render_base24(),
139 Self::SvgVellumPalette => vellum::render_svg_palette(),
140 Self::SkimVellum => vellum::render_skim(),
141 Self::EscribaVellum => vellum::render_escriba_lisp(),
142 }
143 }
144
145 pub fn all() -> [Target; 20] {
146 [
147 Self::Css,
148 Self::Md3,
149 Self::Tailwind,
150 Self::Scss,
151 Self::Rust,
152 Self::Json,
153 Self::Glsl,
154 Self::Ghostty,
155 Self::Tui,
156 Self::Svg,
157 Self::Stylix,
158 Self::Bat,
159 Self::Nix,
160 Self::StylixFonts,
161 Self::FleetFonts,
162 Self::StylixVellum,
163 Self::StylixVellumBase24,
164 Self::SvgVellumPalette,
165 Self::SkimVellum,
166 Self::EscribaVellum,
167 ]
168 }
169}