diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-29 10:14:23 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-29 10:14:23 +0200 |
| commit | 457bb2ca770e7fa94a9401e637bfeac6fc61c462 (patch) | |
| tree | ec3e475af362d5a2556691d7331f8b638d5576c0 | |
| parent | fe118f0dffcd6f80c20a6c69b33232f2207ebf1f (diff) | |
| download | grub-theme-udt-457bb2ca770e7fa94a9401e637bfeac6fc61c462.tar.gz grub-theme-udt-457bb2ca770e7fa94a9401e637bfeac6fc61c462.zip | |
build: read colours from rendered theme.txt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| -rwxr-xr-x | build | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -11,11 +11,39 @@ current wallpaper next to theme.txt. Everything is staged in a temporary directory and swapped in at the end, so a failed run leaves the previous dist/udt/ untouched. Never touches /boot: root copies dist/udt/ there. """ +import re import struct import sys import zlib +from pathlib import Path PNG_SIG = b"\x89PNG\r\n\x1a\n" +REPO = Path(__file__).resolve().parent +PLACEHOLDERS = {f"@{r}@" for r in ( + "SCHEME", "BG", "BG_ALT", "BG_DEEP", "SURFACE", "FG", "FG_DIM", "FG_FAINT", "ACCENT")} +# file name: (fc-match pattern, size, the name grub-mkfont records and theme.txt uses) +FONTS = { + "noto-sans-regular-24.pf2": ("Noto Sans:regular", 24, "Noto Sans Regular 24"), + "noto-sans-bold-32.pf2": ("Noto Sans:bold", 32, "Noto Sans Bold 32"), + "inconsolata-18.pf2": ("Inconsolata Nerd Font Mono", 18, + "Inconsolata Nerd Font Mono Regular 18"), +} + + +def die(msg): + sys.exit(f"build: {msg}") + + +def read_colours(text): + """The colours on the '# udt:' line, as RGB tuples, from a rendered theme.""" + left = sorted(set(re.findall(r"@[A-Z_]+@", text))) + if left: + die(f"theme.txt still has placeholders {' '.join(left)}; rerun udt-palette") + m = re.search(r"^# udt: (.+)$", text, re.M) + if not m: + die("theme.txt has no '# udt:' colour line") + return {k: tuple(bytes.fromhex(v.lstrip("#"))) + for k, v in (kv.split("=") for kv in m.group(1).split())} def chunk(tag, data): @@ -58,6 +86,19 @@ def unpng(data): def selftest(): w, h, px = unpng(png(3, 2, (0x12, 0x34, 0x56, 0xd9))) assert (w, h, px) == (3, 2, {(0x12, 0x34, 0x56, 0xd9)}), (w, h, px) + good = "# udt: bg_alt=#1e2030 accent=#b7bdf8\ncolor = \"#cad3f5\"\n" + assert read_colours(good) == {"bg_alt": (0x1e, 0x20, 0x30), "accent": (0xb7, 0xbd, 0xf8)} + for bad in (good + 'color = "@FG@"\n', 'color = "#cad3f5"\n'): + try: + read_colours(bad) + except SystemExit: + pass + else: + raise AssertionError(f"accepted: {bad!r}") + tpl = (REPO / "theme.txt.in").read_text() + assert set(re.findall(r"@[A-Z_]+@", tpl)) <= PLACEHOLDERS, "template token udt does not fill" + for _, _, name in FONTS.values(): + assert f'"{name}"' in tpl, f"template does not use font {name}" print("selftest ok") |
