diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-14 22:11:42 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-14 22:11:42 -0500 |
| commit | 0484e1cf9ea8273f81178c1e16d6299f2c03c513 (patch) | |
| tree | 021510895135c0d4b3d25aa27dd31f6e7ddd6291 /scripts/theme-studio/app.js | |
| parent | ded61fc6bbda1662e9647b207b18ba61a4d0543b (diff) | |
| download | dotemacs-0484e1cf9ea8273f81178c1e16d6299f2c03c513.tar.gz dotemacs-0484e1cf9ea8273f81178c1e16d6299f2c03c513.zip | |
refactor(theme-studio): extract the shared package-preview wrapper
The 20 line-based renderXxxPreview functions each ended with a byte-identical monospace-pre wrapper. They now build their L array and return previewLines(L), so the wrapper lives in one place and can't drift across the family.
Diffstat (limited to 'scripts/theme-studio/app.js')
| -rw-r--r-- | scripts/theme-studio/app.js | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/scripts/theme-studio/app.js b/scripts/theme-studio/app.js index e6951384a..964ec2b2c 100644 --- a/scripts/theme-studio/app.js +++ b/scripts/theme-studio/app.js @@ -518,6 +518,9 @@ function buildPkgTable(){ } function ofs(app,face){const f=PKGMAP[app][face]||{},fg=effFg(pkgEffFg(app,face)),bg=pkgEffBg(app,face);const dec=(f.underline?'underline ':'')+(f.strike?'line-through':'');const bx=boxCss(f.box,bg||MAP['bg']);return `color:${fg};${bg?'background:'+bg+';':''}font-weight:${f.bold?'bold':'normal'};font-style:${f.italic?'italic':'normal'};text-decoration:${dec.trim()||'none'};font-size:${(f.height||1)}em${bx?';box-shadow:'+bx:''}`;} function os(app,face,txt){return `<span data-face="${face}" style="${ofs(app,face)}">${txt}</span>`;} +// Shared wrapper for the line-based package previews: a monospace pre block. +// Each renderer builds its own L array of os(...) lines and returns previewLines(L). +function previewLines(L){return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} function renderOrgPreview(){const a='org-mode',L=[]; L.push(os(a,'org-document-info-keyword','#+TITLE:')+' '+os(a,'org-document-title','Project Notes')); L.push(os(a,'org-document-info-keyword','#+AUTHOR:')+' '+os(a,'org-document-info','Craig Jennings')); @@ -561,7 +564,7 @@ function renderOrgPreview(){const a='org-mode',L=[]; L.push(' '+os(a,'org-agenda-structure-secondary','secondary')+' '+os(a,'org-agenda-structure-filter','filter')+' '+os(a,'org-agenda-restriction-lock','lock')+' '+os(a,'org-agenda-column-dateline','col-date')); L.push(' Filters: '+os(a,'org-agenda-filter-category','cat')+' '+os(a,'org-agenda-filter-tags','tags')+' '+os(a,'org-agenda-filter-effort','effort')+' '+os(a,'org-agenda-filter-regexp','re')); L.push(' '+os(a,'org-mode-line-clock','[0:45]')+' / '+os(a,'org-mode-line-clock-overrun','[OVER]')+' '+os(a,'org-dispatcher-highlight','[d]ispatch')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`; + return previewLines(L); } function renderMagitPreview(){const a='magit',L=[]; L.push(os(a,'magit-header-line',' Magit: dotemacs ')+' '+os(a,'magit-header-line-key','g')+os(a,'magit-header-line-log-select',' refresh')); @@ -612,7 +615,7 @@ function renderMagitPreview(){const a='magit',L=[]; L.push(' '+os(a,'magit-blame-hash','b5b1869f')+' '+os(a,'magit-blame-name','Craig')+' '+os(a,'magit-blame-date','2026-06-08')+' '+os(a,'magit-blame-summary','enlarge picker')+' '+os(a,'magit-blame-highlight','hl')+' '+os(a,'magit-blame-dimmed','dim')); L.push(os(a,'magit-section-heading','Signatures')+os(a,'magit-left-margin',' ')); L.push(' '+os(a,'magit-signature-good','good')+' '+os(a,'magit-signature-bad','bad')+' '+os(a,'magit-signature-untrusted','untrusted')+' '+os(a,'magit-signature-expired','expired')+' '+os(a,'magit-signature-expired-key','expired-key')+' '+os(a,'magit-signature-revoked','revoked')+' '+os(a,'magit-signature-error','error')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderElfeedPreview(){const a='elfeed',L=[]; L.push(os(a,'elfeed-search-filter-face','@6-months-ago +unread')+' '+os(a,'elfeed-search-unread-count-face','3/120')+' '+os(a,'elfeed-search-last-update-face','updated 02:24')); L.push(''); @@ -624,7 +627,7 @@ function renderElfeedPreview(){const a='elfeed',L=[]; L.push(os(a,'elfeed-log-date-face','02:24:02')+' '+os(a,'elfeed-log-warn-level-face','WARN ')+' slow feed: example.com'); L.push(os(a,'elfeed-log-date-face','02:24:03')+' '+os(a,'elfeed-log-error-level-face','ERROR')+' failed: bad.example'); L.push(os(a,'elfeed-log-date-face','02:24:04')+' '+os(a,'elfeed-log-debug-level-face','DEBUG')+' parsed 340 entries'); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderGhostelPreview(){const a='ghostel',L=[]; L.push(os(a,'ghostel-default','craig@host')+' '+os(a,'ghostel-color-green','~/code')+' $ ls'+os(a,'ghostel-fake-cursor',' ')+os(a,'ghostel-fake-cursor-box','[ ]')); L.push(''); @@ -632,7 +635,7 @@ function renderGhostelPreview(){const a='ghostel',L=[]; L.push(os(a,'ghostel-default','bright:')+' '+os(a,'ghostel-color-bright-black','black')+' '+os(a,'ghostel-color-bright-red','red')+' '+os(a,'ghostel-color-bright-green','green')+' '+os(a,'ghostel-color-bright-yellow','yellow')+' '+os(a,'ghostel-color-bright-blue','blue')+' '+os(a,'ghostel-color-bright-magenta','magenta')+' '+os(a,'ghostel-color-bright-cyan','cyan')+' '+os(a,'ghostel-color-bright-white','white')); L.push(''); L.push(os(a,'ghostel-default','default terminal output, 256-color text and a blinking ')+os(a,'ghostel-fake-cursor','cursor')+'.'); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderDashboardPreview(){const a='dashboard',L=[]; L.push(os(a,'dashboard-text-banner',' [ dashboard banner image ]')); L.push(os(a,'dashboard-banner-logo-title','Emacs: The Editor That Saves Your Soul')); @@ -659,7 +662,7 @@ function renderDashboardPreview(){const a='dashboard',L=[]; L.push(' theme-theme.el'); L.push(' todo.org'); L.push(' theme-studio-palette-generator-spec.org'); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderMu4ePreview(){const a='mu4e',L=[]; L.push(os(a,'mu4e-title-face','mu4e')+' '+os(a,'mu4e-context-face','[Personal]')+' '+os(a,'mu4e-ok-face','online')+' '+os(a,'mu4e-warning-face','2 retry')+' '+os(a,'mu4e-modeline-face','12/340')); L.push(''); @@ -681,7 +684,7 @@ function renderMu4ePreview(){const a='mu4e',L=[]; L.push(''); L.push(os(a,'mu4e-compose-header-face','Subject:')+' new mail'); L.push(os(a,'mu4e-compose-separator-face','--text follows this line--')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderLspPreview(){const a='lsp-mode',L=[]; L.push(os(a,'lsp-signature-face','process(')+os(a,'lsp-signature-highlight-function-argument','items: list')+os(a,'lsp-signature-face',') -> None')); L.push(os(a,'lsp-signature-posframe',' docs: iterate over items and process each one ')); @@ -694,13 +697,13 @@ function renderLspPreview(){const a='lsp-mode',L=[]; L.push(' getName() '+os(a,'lsp-details-face','str the cached getter')); L.push(''); L.push(os(a,'lsp-installation-buffer-face','Installing pyright...')+' '+os(a,'lsp-installation-finished-buffer-face','done.')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderGitGutterPreview(){const a='git-gutter',L=[]; L.push(os(a,'git-gutter:added','+')+os(a,'git-gutter:separator','|')+' added line of code'); L.push(os(a,'git-gutter:modified','~')+os(a,'git-gutter:separator','|')+' modified line of code'); L.push(os(a,'git-gutter:deleted','_')+os(a,'git-gutter:separator','|')+' (deleted lines marker)'); L.push(os(a,'git-gutter:unchanged',' ')+os(a,'git-gutter:separator','|')+' '+os(a,'git-gutter:unchanged','unchanged line of code')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderFlycheckPreview(){const a='flycheck',L=[]; L.push(os(a,'flycheck-fringe-error','E')+os(a,'flycheck-fringe-warning','W')+os(a,'flycheck-fringe-info','I')+' x = '+os(a,'flycheck-error','undefined_name')+'('+os(a,'flycheck-warning','unused_arg')+') '+os(a,'flycheck-info','# note')); L.push(' '+os(a,'flycheck-error-delimiter','[')+os(a,'flycheck-delimited-error','err')+os(a,'flycheck-error-delimiter',']')); @@ -709,7 +712,7 @@ function renderFlycheckPreview(){const a='flycheck',L=[]; L.push(os(a,'flycheck-error-list-filename','main.py')+':'+os(a,'flycheck-error-list-line-number','12')+':'+os(a,'flycheck-error-list-column-number','4')+' '+os(a,'flycheck-error-list-error','error')+' '+os(a,'flycheck-error-list-error-message','undefined name x')+' '+os(a,'flycheck-error-list-id','[E0602]')); L.push(os(a,'flycheck-error-list-filename','main.py')+':'+os(a,'flycheck-error-list-line-number','18')+':'+os(a,'flycheck-error-list-column-number','1')+' '+os(a,'flycheck-error-list-warning','warning')+' '+os(a,'flycheck-error-list-error-message','unused import')+' '+os(a,'flycheck-error-list-id-with-explainer','[W0611?]')); L.push(os(a,'flycheck-error-list-highlight','main.py:20 '+os(a,'flycheck-error-list-info','info')+' highlighted row')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderDiredPreview(){const a='dired',L=[]; L.push(os(a,'dired-header','/home/craig/code:')); L.push(' '+os(a,'dired-perm-write','drwxr-xr-x')+' craig 4096 '+os(a,'dired-directory','src/')); @@ -722,7 +725,7 @@ function renderDiredPreview(){const a='dired',L=[]; L.push(' '+os(a,'dired-set-id','-rwsr-xr-x')+' root 900 setuid.bin'); L.push(' '+os(a,'dired-special','prw-r--r--')+' craig 0 fifo.pipe'); L.push(os(a,'dired-warning','! disk space low on /home')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderDirvishPreview(){const a='dirvish',L=[]; L.push(os(a,'dirvish-inactive','~/code')+' '+os(a,'dirvish-free-space','[free 24G]')); L.push(os(a,'dirvish-hl-line',' '+os(a,'dirvish-file-modes','-rw-r--r--')+' '+os(a,'dirvish-file-link-number','1')+' '+os(a,'dirvish-file-user-id','craig')+' '+os(a,'dirvish-file-group-id','staff')+' '+os(a,'dirvish-file-size','4.0K')+' '+os(a,'dirvish-file-time','Jun 8 02:24')+' init.el ')); @@ -734,7 +737,7 @@ function renderDirvishPreview(){const a='dirvish',L=[]; L.push(' '+os(a,'dirvish-media-info-heading','Media')+' '+os(a,'dirvish-media-info-property-key','Dimensions:')+' 1920x1080'); L.push(' proc '+os(a,'dirvish-proc-running','running')+' / '+os(a,'dirvish-proc-finished','finished')+' / '+os(a,'dirvish-proc-failed','failed')); L.push(' narrow '+os(a,'dirvish-narrow-match-face-0','m0')+' '+os(a,'dirvish-narrow-match-face-1','m1')+' '+os(a,'dirvish-narrow-match-face-2','m2')+' '+os(a,'dirvish-narrow-match-face-3','m3')+os(a,'dirvish-narrow-split',' | ')+os(a,'dirvish-emerge-group-title','Group: images')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderCalibredbPreview(){const a='calibredb',L=[]; L.push(os(a,'calibredb-search-header-library-name-face','Calibre')+' '+os(a,'calibredb-search-header-library-path-face','~/books')+' '+os(a,'calibredb-search-header-total-face','412 books')+' '+os(a,'calibredb-search-header-filter-face','tag:scifi')+' '+os(a,'calibredb-search-header-sort-face','sort:date')+' '+os(a,'calibredb-search-header-highlight-face','[*]')); L.push(''); @@ -744,7 +747,7 @@ function renderCalibredbPreview(){const a='calibredb',L=[]; L.push(os(a,'calibredb-title-detailed-view-face','Foundation (detailed)')+' '+os(a,'calibredb-language-face','eng')+' '+os(a,'calibredb-favorite-face','* fav')+' '+os(a,'calibredb-archive-face','archived')); L.push(os(a,'calibredb-ids-face','isbn:0553293354')+' '+os(a,'calibredb-file-face','foundation.epub')+' '+os(a,'calibredb-comment-face','A classic of the genre.')); L.push(os(a,'calibredb-edit-annotation-header-title-face','Annotations')+' '+os(a,'calibredb-highlight-face','highlighted passage')+' '+os(a,'calibredb-current-page-button-face','[page 42]')+' '+os(a,'calibredb-mouse-face','hover row')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderErcPreview(){const a='erc',L=[]; L.push(os(a,'erc-header-line',' #emacs on Libera.Chat 18 users ')); L.push(os(a,'erc-timestamp-face','[10:24]')+' '+os(a,'erc-notice-face','*** alice has joined #emacs')); @@ -756,28 +759,28 @@ function renderErcPreview(){const a='erc',L=[]; L.push(os(a,'erc-command-indicator-face','/help')+' '+os(a,'erc-bold-face','bold')+' '+os(a,'erc-italic-face','italic')+' '+os(a,'erc-underline-face','underline')+' '+os(a,'erc-inverse-face','inverse')+' '+os(a,'erc-spoiler-face','spoiler')); L.push(os(a,'erc-keep-place-indicator-arrow','>')+os(a,'erc-keep-place-indicator-line',' ---- last read ---- ')+os(a,'erc-fill-wrap-merge-indicator-face','+')); L.push(os(a,'erc-prompt-face','craig>')+' '+os(a,'erc-input-face','type a message...')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderOrgdrillPreview(){const a='org-drill',L=[]; L.push('Q: The capital of France is '+os(a,'org-drill-hidden-cloze-face','[...]')+'.'); L.push('A: The capital of France is '+os(a,'org-drill-visible-cloze-face','Paris')+'.'); L.push(' '+os(a,'org-drill-visible-cloze-hint-face','hint: P____')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderOrgnoterPreview(){const a='org-noter',L=[]; L.push('org-noter paper.pdf'); L.push(' page 1 '+os(a,'org-noter-notes-exist-face','[notes]')); L.push(' page 2 '+os(a,'org-noter-no-notes-exist-face','[no notes]')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderSignelPreview(){const a='signel',L=[]; L.push(os(a,'signel-timestamp-face','[10:24]')+' '+os(a,'signel-my-msg-face','Me: hey, are we still on for tonight?')); L.push(os(a,'signel-timestamp-face','[10:25]')+' '+os(a,'signel-other-msg-face','Alice: yes! see you at 7')); L.push(os(a,'signel-error-face','(failed to send -- retrying)')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderPearlPreview(){const a='pearl',L=[]; L.push(os(a,'pearl-preamble-summary','PEARL-42 Fix the broken picker')); L.push('State: '+os(a,'pearl-modified-local','In Progress')+' Priority: '+os(a,'pearl-modified-highlight','High')+' Estimate: '+os(a,'pearl-modified-unknown','?')); L.push(' '+os(a,'pearl-editable-comment','> add a comment (editable)')); L.push(' '+os(a,'pearl-readonly-comment','> created by automation (read-only)')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderShrPreview(){const a='shr',L=[]; L.push(os(a,'shr-text','shr renders nov (EPUB), eww (web), elfeed, and HTML mail.')); L.push(''); @@ -787,7 +790,7 @@ function renderShrPreview(){const a='shr',L=[]; L.push(os(a,'shr-text','Body text flows in shr-text, with a ')+os(a,'shr-link','hyperlink')+os(a,'shr-text',' and a ')+os(a,'shr-selected-link','focused link')+os(a,'shr-text',',')); L.push(os(a,'shr-text','some ')+os(a,'shr-code','inline_code()')+os(a,'shr-text',', a ')+os(a,'shr-mark','highlighted mark')+os(a,'shr-text',', ')+os(a,'shr-strike-through','struck out')+os(a,'shr-text',', a footnote')+os(a,'shr-sup','[1]')+os(a,'shr-text',',')); L.push(os(a,'shr-text','an ')+os(a,'shr-abbreviation','HTML')+os(a,'shr-text',' abbreviation, and an ')+os(a,'shr-sliced-image','[image]')+os(a,'shr-text',' slice.')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderSlackPreview(){const a='slack',L=[]; L.push(os(a,'slack-room-info-title-room-name-face','#general')+' '+os(a,'slack-room-info-title-face','Acme Workspace')); L.push(os(a,'slack-room-info-section-title-face','Topic')+' '+os(a,'slack-room-info-section-label-face','daily standup')+' '+os(a,'slack-room-unread-face','3 unread')); @@ -807,7 +810,7 @@ function renderSlackPreview(){const a='slack',L=[]; L.push('Users: '+os(a,'slack-user-active-face','alice (active)')+' '+os(a,'slack-user-dnd-face','bob (dnd)')+' '+os(a,'slack-profile-image-face','[img]')+' '+os(a,'slack-user-profile-header-face','Profile')+' '+os(a,'slack-user-profile-property-name-face','Title:')+' Dev'); L.push('Search: '+os(a,'slack-search-result-message-header-face','#general')+' '+os(a,'slack-search-result-message-username-face','craig')); L.push('Modeline: '+os(a,'slack-modeline-has-unreads-face','* unreads')+' '+os(a,'slack-modeline-channel-has-unreads-face','#ch')+' '+os(a,'slack-modeline-thread-has-unreads-face','thread')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function renderTelegaPreview(){const a='telega',L=[]; L.push(os(a,'telega-root-heading','Telegram')+' '+os(a,'telega-tracking','[tracking]')+' '+os(a,'telega-unread-unmuted-modeline','5 unread')); L.push(os(a,'telega-has-chatbuf-brackets','[')+os(a,'telega-username','Alice')+os(a,'telega-has-chatbuf-brackets',']')+' '+os(a,'telega-user-online-status','online')+' '+os(a,'telega-unmuted-count','3')+' '+os(a,'telega-mention-count','@2')+os(a,'telega-delim-face',' | ')+os(a,'telega-secret-title','Secret')+' '+os(a,'telega-muted-count','muted')); @@ -826,7 +829,7 @@ function renderTelegaPreview(){const a='telega',L=[]; L.push('Palette '+os(a,'telega-palette-builtin-blue','blue')+' '+os(a,'telega-palette-builtin-green','green')+' '+os(a,'telega-palette-builtin-orange','orange')+' '+os(a,'telega-palette-builtin-purple','purple')); L.push(os(a,'telega-link-preview-sitename','example.com')+' '+os(a,'telega-link-preview-title','Link preview title')); L.push('Webpage '+os(a,'telega-webpage-title','Title')+' '+os(a,'telega-webpage-subtitle','Subtitle')+' '+os(a,'telega-webpage-header','Header')+' '+os(a,'telega-webpage-subheader','Subheader')+' '+os(a,'telega-webpage-outline','outline')+' '+os(a,'telega-webpage-fixed','fixed')+' '+os(a,'telega-webpage-preformatted','pre')+' '+os(a,'telega-webpage-marked','marked')+' '+os(a,'telega-webpage-strike-through','strike')+' '+os(a,'telega-webpage-chat-link','chat-link')); - return `<div style="padding:12px 16px;font:12pt/1.7 monospace;white-space:pre">${L.join('\n')}</div>`;} + return previewLines(L);} function genericPreview(app){let h='<div style="padding:10px 14px;font:12pt/1.8 monospace">';for(const [face,label] of APPS[app].faces)h+=`<div data-face="${face}" style="${ofs(app,face)}">${esc(label)}</div>`;return h+'</div>';} // Bespoke split preview: a focused window beside its auto-dimmed twin, both // showing the language selected at the top of the page (kept in sync via the |
