From b0393b8e851f3f4e8355f0e513e9129bfc115611 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 7 Jun 2026 16:45:31 -0500 Subject: feat(theme-selector): add browser-based theme design tool A self-contained tool for building Emacs color themes by eye. generate.py emits one HTML page with six languages of tree-sitter-tokenized code, a category-to-color assignment table, a UI-faces table, and an editable palette. Reassign colors from the palette, toggle weight and slant per category, set foreground and background per UI face, then export a theme.json a later build step turns into theme files. The export carries the name, palette, syntax assignments, bold and italic sets, and a ui object of per-face foreground and background. The theme name is both the json name field and the download filename. samples.py holds the language samples and the default color map. theme-selector.html is the generated output. The json-to-theme converter is the next piece, and the part worth TDD. --- scripts/theme-selector/README.md | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 scripts/theme-selector/README.md (limited to 'scripts/theme-selector/README.md') diff --git a/scripts/theme-selector/README.md b/scripts/theme-selector/README.md new file mode 100644 index 00000000..a8be0a10 --- /dev/null +++ b/scripts/theme-selector/README.md @@ -0,0 +1,67 @@ +# theme-selector + +A self-contained tool for designing Emacs color themes by eye. It renders six +languages of tree-sitter-tokenized code, a category→color assignment table, a +UI-faces table, and an editable palette into one HTML page you drive in the +browser. Reassign colors, toggle weight/slant, edit the palette, then export a +`theme.json` that a build step turns into `themes/-*.el`. + +## Run + +```bash +python3 generate.py # writes theme-selector.html beside this script +``` + +Then open it in Chrome (Firefox had color-rendering flakiness during design): + +```bash +WAYLAND_DISPLAY=wayland-1 google-chrome-stable theme-selector.html +``` + +During color work, disable Hyprland inactive-window dimming so colors read true: + +```bash +hyprctl keyword decoration:dim_inactive false +``` + +## Files + +- `generate.py` — emits the HTML+JS. Edit here to change layout or behavior. +- `samples.py` — the language code samples and the default category→color map + (`COLS`). `generate.py` reads the part before the `cols=` marker. +- `theme-selector.html` — generated output. Regenerate; don't hand-edit. + +## What it captures + +- Background and foreground (the `default` face's `:background` / `:foreground`). +- The syntax layer: every font-lock / tree-sitter category (keyword, string, + function, type, comment, and the rest), each with normal/bold/italic. +- UI faces: cursor, region, mode-line, fringe, line numbers, isearch, paren + match, link, error/warning/success, and more — foreground and background per + face. +- The palette itself: add by hex or swatch, remove, rename, drag to reorder. + +## theme.json contract + +The export (and what a build step consumes): + +```json +{ + "name": "dupre-revision", + "palette": [["#67809c", "blue"], ["#e8bd30", "gold"]], + "assignments": {"kw": "#67809c", "str": "#5d9b86", "bg": "#0d0b0a", "p": "#cdced1"}, + "bold": ["kw", "fnd"], + "italic": [], + "ui": {"region": {"fg": null, "bg": "#264364"}, "cursor": {"fg": null, "bg": "#a9b2bb"}} +} +``` + +The theme name is both the `name` field and the download filename +(`.json`, sanitized). Upload a `theme.json` to start from a prior theme. + +## Next step (not yet built) + +A `theme.json` → `themes/-palette.el` + `-faces.el` + `-theme.el` +converter. That step is the correctness-sensitive part and is the one worth +TDD: JSON in, valid Emacs palette + faces out, every face mapped, WCAG-contrast +asserted on the result. -- cgit v1.2.3