From 630cfddc7060c7019815f8e82f87fb629aefebfa Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Thu, 2 Jul 2026 23:01:54 -0400 Subject: feat(theme-studio): explicit absolute-vs-relative face height kind JSON collapses 2.0 to 2 on save, so a height's number type can't say whether it's a fixed 1/10pt value or a relative multiplier. The face model now carries an explicit heightMode field (abs/rel) through seed, save/load, and export. build-theme.el coerces :height from the kind: abs exports an integer, rel a float, so a relative 2.0 renders as 2.0, never 2. Faces saved before the field existed infer the kind once on load (JS: integer to abs, fractional to rel; Python keeps the authored type, so a float 2.0 seed stays relative) and persist it on the next save. The mode-line seed carries abs explicitly, and WIP.json's eight seeded heights are stamped with their kinds. Regenerating the theme from the stamped WIP.json produces an identical WIP-theme.el, so the round-trip holds. --- scripts/theme-studio/browser-gates.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts/theme-studio/browser-gates.js') diff --git a/scripts/theme-studio/browser-gates.js b/scripts/theme-studio/browser-gates.js index fcdfaff0..1542b0d0 100644 --- a/scripts/theme-studio/browser-gates.js +++ b/scripts/theme-studio/browser-gates.js @@ -58,14 +58,14 @@ function assertPreviewFaces(A, html, faces, minCount, name, required){ // Phase-1 self-test (open with #selftest): seed -> export -> import -> compare. function pkgSelftest(){ const seeded=seedPkgmap(); - seeded['org-mode']['org-level-2']={fg:'#e8bd30',bg:null,weight:null,slant:null,inherit:'org-level-1',height:1.2,source:'user'}; + seeded['org-mode']['org-level-2']={fg:'#e8bd30',bg:null,weight:null,slant:null,inherit:'org-level-1',height:1.2,heightMode:'rel',source:'user'}; const exp=packagesForExport(seeded); const round=seedPkgmap();mergePackagesInto(round,exp); const roundtrip=JSON.stringify(exp)===JSON.stringify(packagesForExport(round)); let oldjson=true;try{const m=seedPkgmap();mergePackagesInto(m,undefined);oldjson=!!(m['org-mode']&&m['org-mode']['org-todo'].source==='default');}catch(e){oldjson=false;} const l2=exp['org-mode']['org-level-2']; const inherited=l2.inherit==='org-level-1'&&l2.source==='user'; - const height=l2.height===1.2 && !('height' in (exp['org-mode']['org-todo'])); + const height=l2.height===1.2 && l2.heightMode==='rel' && !('height' in (exp['org-mode']['org-todo'])) && !('heightMode' in (exp['org-mode']['org-todo'])); const sc=seedPkgmap();sc['org-mode']['org-todo']={fg:null,bg:null,weight:null,slant:null,inherit:null,height:1,source:'cleared'}; const cleared='org-todo' in packagesForExport(sc)['org-mode']; const su=seedPkgmap();mergePackagesInto(su,{'zzz-pkg':{'zzz-face':{fg:'#112233',source:'user'}}}); -- cgit v1.2.3