From 7f655fe4de2419164aee592eaa27d2e8751d1cb3 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 8 Jun 2026 06:39:38 -0500 Subject: feat(theme-selector): bold/italic/underline/strike controls on the UI face table The UI face table gains a style column with the same B/I/U/S toggle buttons the package table has, so built-in UI faces reach parity. Each toggle updates the per-face preview cell and the live mock buffer (mode-line, minibuffer-prompt, link, error/warning/success now reflect weight, slant, and decoration). The link face is seeded underlined to match the built-in default, and the converter already reads these fields off the ui objects, so they export and convert without further change. --- scripts/theme-selector/generate.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'scripts/theme-selector/generate.py') diff --git a/scripts/theme-selector/generate.py b/scripts/theme-selector/generate.py index 8ebf4388..38629269 100644 --- a/scripts/theme-selector/generate.py +++ b/scripts/theme-selector/generate.py @@ -38,6 +38,8 @@ UIMAP={"cursor":{"fg":None,"bg":"#a9b2bb"},"region":{"fg":None,"bg":"#264364"}, "show-paren-mismatch":{"fg":"#0d0b0a","bg":"#cb6b4d"},"link":{"fg":"#67809c","bg":None}, "error":{"fg":"#cb6b4d","bg":None},"warning":{"fg":"#e8bd30","bg":None}, "success":{"fg":"#5d9b86","bg":None},"vertical-border":{"fg":"#2f343a","bg":None}} +# link is underlined by default (matches the built-in link face). +UIMAP["link"]["underline"]=True # Tier-3 package faces (Phase 2): complete own-defface sets for org/magit/elfeed, # built from face-name lists + a curated seed-color map. Prominent faces are # seeded; the long tail seeds to the default foreground for the user to tune. @@ -479,7 +481,7 @@ HTML = """theme-selector

ui faces

-
faceforegroundbackgroundpreview
+
faceforegroundbackgroundstylepreview
@@ -649,6 +651,7 @@ function importFile(ev){const f=ev.target.files[0];if(!f)return;const r=new File r.readAsText(f);ev.target.value='';} function applyGround(){document.querySelectorAll('pre').forEach(p=>p.style.background=MAP['bg']);document.querySelectorAll('.ex').forEach(e=>e.style.background=MAP['bg']);} function uf(f){return UIMAP[f]||{};} +function udeco(o){return `font-weight:${o.bold?'bold':'normal'};font-style:${o.italic?'italic':'normal'};text-decoration:${(o.underline?'underline ':'')+(o.strike?'line-through':'')||'none'}`;} function flashRow(tr){if(!tr)return;tr.scrollIntoView({block:'center',behavior:'smooth'});tr.classList.remove('flash');void tr.offsetWidth;tr.classList.add('flash');} function flashEl(el){if(!el)return;el.classList.remove('flashtok');void el.offsetWidth;el.classList.add('flashtok');} function flashTokens(kind){const sp=document.querySelectorAll('#codepre [data-k="'+kind+'"]');if(sp.length){sp.forEach(flashEl);return;}const row=document.querySelector('#legbody tr[data-kind="'+kind+'"]');if(row)flashEl(row.querySelector('.ex'));} @@ -696,10 +699,10 @@ function buildMockFrame(){ buf+=`
${i+1}${cd||' '}
`; }); let html=`
${buf}
`; - html+=`
init.el (Emacs Lisp) L5 git:main
`; - html+=`
*Messages* (Fundamental)
`; - html+=`
I-search: count zzz [no match]
`; - html+=`
https://gnu.org error warning ok
`; + html+=`
init.el (Emacs Lisp) L5 git:main
`; + html+=`
*Messages* (Fundamental)
`; + html+=`
I-search: count zzz [no match]
`; + html+=`
https://gnu.org error warning ok
`; fr.innerHTML=html;fr.style.background=bg;fr.style.color=fg; fr.onclick=(e)=>{const u=e.target.closest('[data-face]');if(u){flashUi(u.dataset.face);return;}const k=e.target.closest('[data-k]');if(k)flashAssign(k.dataset.k);}; } @@ -1040,7 +1043,7 @@ function genericPreview(app){let h='