#!/usr/bin/env python3 """Generate the Dupre palette preview HTML from dupre-palette.el. Reads the (name "#hex") pairs straight from the palette source so the preview can't drift from the theme. Groups colors into one row per family (by name prefix, e.g. gray-2/gray/gray+1 share the "gray" row), with fixed-width swatches so columns line up across rows. Regenerate the PNG from the HTML afterwards: google-chrome-stable --headless=new --screenshot=themes/dupre-palette.png \\ --window-size=975,1520 --hide-scrollbars --default-background-color=151311FF \\ "file://$PWD/themes/dupre-color-palette.html" """ import re from pathlib import Path HERE = Path(__file__).resolve().parent SRC = HERE / "dupre-palette.el" OUT = HERE / "dupre-color-palette.html" text = open(SRC).read() # Only the dupre-palette defconst has (name "#hex") pairs; semantic mappings are # (name colorname) with no hex, so this regex selects exactly the base palette. pairs = re.findall(r'\(([a-z0-9]+(?:[+\-]\d+)?(?:-[a-z]+)?)\s+"(#[0-9a-fA-F]{6})"\)', text) def family(name): m = re.match(r'^([a-z]+(?:-[a-z]+)??)(?:[+\-]\d+)?$', name) return m.group(1) if m else name # Group consecutive same-family entries (palette.el already orders them so). rows, cur_fam, cur = [], None, [] for name, hexv in pairs: fam = family(name) if fam != cur_fam: if cur: rows.append((cur_fam, cur)) cur_fam, cur = fam, [] cur.append((name, hexv)) if cur: rows.append((cur_fam, cur)) def swatch(name, hexv): return (f'