<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/scripts/theme-studio/Makefile, branch main</title>
<subtitle>My Emacs configuration
</subtitle>
<id>https://git.cjennings.net/dotemacs/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/dotemacs/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/'/>
<updated>2026-06-24T18:04:48+00:00</updated>
<entry>
<title>fix(theme-studio): render nerd-icon glyphs in previews instead of tofu</title>
<updated>2026-06-24T18:04:48+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-24T18:04:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=14f657ce0b563952b835c8d8791c53aa368c1f33'/>
<id>urn:sha1:14f657ce0b563952b835c8d8791c53aa368c1f33</id>
<content type='text'>
The legend, dashboard, and package previews drew nerd-icon glyphs as empty boxes. The font-family never reached them: PREVIEW_FONT was spliced into inline style="..." attributes with a double-quoted family name, so the inner quote closed the attribute early and the font was silently dropped. Dropping the quotes fixes it. A no-space family name needs none.

I embedded the glyph font directly: Symbols Nerd Font Mono, encoded with fontTools (woff2_compress output is rejected by headed Chrome and Firefox), inlined as a data: URI under the unique family name ThemeStudioNerd so it resolves to the embed rather than a system-installed copy of the same name. The page is self-contained and renders on any clone.

I added a #fonttest gate that parses previewLines output and asserts the resolved font-family plus glyph coverage, plus a make font target that re-encodes the woff2 with fontTools.
</content>
</entry>
<entry>
<title>feat(theme-studio): add reproducible face-coverage generator and diff</title>
<updated>2026-06-19T01:35:55+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-19T01:35:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=fc0cb229a2211036dc4fc7101a1230b2a8e9e43f'/>
<id>urn:sha1:fc0cb229a2211036dc4fc7101a1230b2a8e9e43f</id>
<content type='text'>
face-coverage.org was rebuilt by a throwaway /tmp script each time. This makes it reproducible: face-coverage-dump.el dumps every face's name, docstring, and defface file from the live daemon (plus all group docs and package summaries), and face_coverage.py turns that into the tiered worklist (emacs-core / emacs-general / per-package), classifying each face by where its defface lives. make face-coverage regenerates the file; make face-coverage-diff reports the coverage delta against the committed copy.

The dump binds coding-system-for-write so writing the docstring JSON never drops into the interactive coding-system prompt. I validated the builder by regenerating and diffing against the hand-built worklist: headings identical, only the intro and one sharper description differ.
</content>
</entry>
<entry>
<title>fix(theme-studio): name exported themes from the source filename</title>
<updated>2026-06-15T02:36:08+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-15T02:36:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=e304e34d3b115020f38e50bf4667e13b72f55692'/>
<id>urn:sha1:e304e34d3b115020f38e50bf4667e13b72f55692</id>
<content type='text'>
The converter took the theme name from the JSON's internal name field, so every draft whose field read "theme" overwrote theme-theme.el. It now uses the JSON file's basename, so WIP.json becomes WIP-theme.el and each draft lands under its own name. The reload target derives the load name from the basename too, and a regression test pins it: the filename wins over the internal field.
</content>
</entry>
<entry>
<title>feat(theme-studio): make targets for the build-theme converter</title>
<updated>2026-06-14T23:20:04+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-14T23:20:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=fe75ac13b4082644b4ce9eeba7f49d3eea2cc716'/>
<id>urn:sha1:fe75ac13b4082644b4ce9eeba7f49d3eea2cc716</id>
<content type='text'>
theme-studio-theme converts a Theme Studio JSON export to themes/&lt;name&gt;-theme.el. theme-studio-theme-load disables the custom themes and loads one in the running Emacs. theme-studio-theme-reload chains the two. Each delegates to the scripts/theme-studio/Makefile and errors clearly when its required JSON or THEME argument is missing.
</content>
</entry>
<entry>
<title>Add theme studio generated file check</title>
<updated>2026-06-13T20:21:04+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-13T20:21:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=0f63ec2e08f2a5a736eebcac7c526124080e3060'/>
<id>urn:sha1:0f63ec2e08f2a5a736eebcac7c526124080e3060</id>
<content type='text'>
</content>
</entry>
<entry>
<title>build(theme-studio): add a local Makefile; root delegates test + coverage</title>
<updated>2026-06-09T12:53:12+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-09T12:53:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=3d7cc92a1d845caa845c5af0ef586694bdc40556'/>
<id>urn:sha1:3d7cc92a1d845caa845c5af0ef586694bdc40556</id>
<content type='text'>
theme-studio is a self-contained Python + JS subproject with its own toolchain (python3, node, uvx, headless Chrome), unrelated to the root Makefile's Elisp/ERT world. Gave it a local Makefile that owns that toolchain — test, check (fast, no browser), coverage, gen, open — so the build logic lives with the code and the short target names don't collide with the root's Elisp-flavored test/coverage.

The root keeps the discoverable entry points: theme-studio-test and a new theme-studio-coverage now delegate via make -C. run-tests.sh grows a --no-browser flag so `make check` can skip the headless-Chrome gates for a fast inner loop. gen/open take an optional SEED to view a specific palette.

coverage reports both halves: node --experimental-test-coverage for the three JS modules (all 100% line, ~96% branch) and uvx coverage for generate.py (89% lines; the rest is the __main__ writer and the optional seed-env branch).
</content>
</entry>
</feed>
