# theme/generate-theme.py """Generate desktop config artifacts from theme/colors.json (single source of truth).""" import json import os def load_palette(path): with open(path) as f: return json.load(f) def hex_to_rgb(h): h = h.lstrip("#") return (int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)) def hex_to_hyprlock_rgba(h): return f"rgba({h.lstrip('#')}ff)" # (key in colors.json) -> (css variable suffix) _CSS_MAP = [ ("background", "bg"), ("background_alt", "bg-alt"), ("background_high", "bg-high"), ("foreground", "fg"), ("foreground_dim", "fg-dim"), ("foreground_muted", "fg-muted"), ("blue", "blue"), ("green", "green"), ("yellow", "yellow"), ("red", "red"), ("magenta", "magenta"), ("cyan", "cyan"), ] _ALPHA_VARIANTS = [("a90", "0.90"), ("a95", "0.95"), ("a96", "0.96")] def render_mako_config(pal): return ( f"background-color={pal['background']}\n" f"text-color={pal['foreground']}\n" "border-size=2\n" f"border-color={pal['blue']}\n" "default-timeout=4000\n" ) def render_colors_css(pal): lines = ["/* Tomorrow Night - GENERATED from colors.json by generate-theme.py. DO NOT EDIT. */", ""] for key, suffix in _CSS_MAP: lines.append(f"@define-color tn-{suffix} {pal[key]};") lines.append("") r, g, b = hex_to_rgb(pal["background"]) for name, alpha in _ALPHA_VARIANTS: lines.append(f"@define-color tn-bg-{name} rgba({r}, {g}, {b}, {alpha});") return "\n".join(lines) + "\n" # (colors.json key) -> (hyprlock variable name) _HYPRLOCK_MAP = [ ("foreground", "tn_fg"), ("foreground_dim", "tn_fg_dim"), ("background_alt", "tn_bg_alt"), ("blue", "tn_blue"), ("red", "tn_red"), ("green", "tn_green"), ] def render_hyprlock_colors(pal): lines = ["# GENERATED from colors.json by generate-theme.py. DO NOT EDIT."] for key, var in _HYPRLOCK_MAP: lines.append(f"${var} = {hex_to_hyprlock_rgba(pal[key])}") return "\n".join(lines) + "\n" def main(): here = os.path.dirname(os.path.abspath(__file__)) pal = load_palette(os.path.join(here, "colors.json")) cfgdir = os.path.expanduser("~/.config") os.makedirs(os.path.join(cfgdir, "theme"), exist_ok=True) os.makedirs(os.path.join(cfgdir, "mako"), exist_ok=True) writes = { os.path.join(cfgdir, "theme", "colors.css"): render_colors_css(pal), os.path.join(cfgdir, "mako", "config"): render_mako_config(pal), os.path.join(cfgdir, "theme", "hyprlock-colors.conf"): render_hyprlock_colors(pal), } for path, content in writes.items(): with open(path, "w") as f: f.write(content) print(f" generated {path}") if __name__ == "__main__": main()