mirror of
https://github.com/Boof2015/prism.git
synced 2026-08-12 05:10:51 +02:00
make optional overrides in the template actually optional
This commit is contained in:
+50
-33
@@ -824,6 +824,16 @@ function serializeSection<T extends SectionTokenMap>(
|
||||
return lines
|
||||
}
|
||||
|
||||
function commentExampleTokens(lines: string[]): string[] {
|
||||
return lines.map((line) => {
|
||||
const trimmed = line.trim()
|
||||
if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith(';') || /^\[.+\]$/.test(trimmed)) {
|
||||
return line
|
||||
}
|
||||
return `# ${line}`
|
||||
})
|
||||
}
|
||||
|
||||
export function serializeThemeFile(theme: PrismTheme): string {
|
||||
const normalized = normalizeTheme(theme, theme.name)
|
||||
const sections: string[] = [
|
||||
@@ -871,78 +881,84 @@ export function createTemplateThemeFile(): string {
|
||||
`text = ${toThemeChannels(base.app.text ?? 'rgb(255, 255, 255)')}`,
|
||||
'',
|
||||
'# Optional palette extras:',
|
||||
`text_muted = ${toThemeChannels(base.app.textMuted ?? 'rgba(255, 255, 255, 0.42)')}`,
|
||||
`success = ${toThemeChannels(base.app.success ?? DEFAULT_SUCCESS)}`,
|
||||
`warning = ${toThemeChannels(base.app.warning ?? DEFAULT_WARNING)}`,
|
||||
`danger = ${toThemeChannels(base.app.danger ?? DEFAULT_DANGER)}`,
|
||||
...commentExampleTokens([
|
||||
`text_muted = ${toThemeChannels(base.app.textMuted ?? 'rgba(255, 255, 255, 0.42)')}`,
|
||||
`success = ${toThemeChannels(base.app.success ?? DEFAULT_SUCCESS)}`,
|
||||
`warning = ${toThemeChannels(base.app.warning ?? DEFAULT_WARNING)}`,
|
||||
`danger = ${toThemeChannels(base.app.danger ?? DEFAULT_DANGER)}`,
|
||||
]),
|
||||
'',
|
||||
'# Optional shell overrides:',
|
||||
`toolbar_bg = ${toThemeChannels(withAlpha(base.app.surfaceAlt ?? 'rgba(4, 8, 12, 0.98)', 0.78))}`,
|
||||
`settings_bg_top = ${toThemeChannels(base.app.surface ?? 'rgba(8, 11, 16, 0.92)')}`,
|
||||
`settings_bg_bottom = ${toThemeChannels(base.app.surfaceAlt ?? 'rgba(4, 8, 12, 0.98)')}`,
|
||||
`bottom_bar_bg = ${toThemeChannels(withAlpha(base.app.surfaceAlt ?? 'rgba(4, 8, 12, 0.98)', 0.98))}`,
|
||||
...commentExampleTokens([
|
||||
`toolbar_bg = ${toThemeChannels(withAlpha(base.app.surfaceAlt ?? 'rgba(4, 8, 12, 0.98)', 0.78))}`,
|
||||
`settings_bg_top = ${toThemeChannels(base.app.surface ?? 'rgba(8, 11, 16, 0.92)')}`,
|
||||
`settings_bg_bottom = ${toThemeChannels(base.app.surfaceAlt ?? 'rgba(4, 8, 12, 0.98)')}`,
|
||||
`bottom_bar_bg = ${toThemeChannels(withAlpha(base.app.surfaceAlt ?? 'rgba(4, 8, 12, 0.98)', 0.98))}`,
|
||||
]),
|
||||
]
|
||||
|
||||
const controlsSection = serializeSection('Controls', {
|
||||
const controlsSection = commentExampleTokens(serializeSection('Controls', {
|
||||
...base.controls,
|
||||
flatControls: 'false',
|
||||
}, CONTROLS_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
controlsSection.splice(1, 0, '# Entire section optional. Remove tokens or the whole section to use Prism defaults.')
|
||||
}, CONTROLS_SCHEMA as SectionSchema<Record<string, string | undefined>>))
|
||||
controlsSection.splice(1, 0, '# Entire section optional. Uncomment tokens here only if you want to override Prism defaults.')
|
||||
|
||||
const scopesSection = serializeSection('Scopes', { ...base.scopes }, SCOPES_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
scopesSection.splice(1, 0, '# Entire section optional. Remove tokens or the whole section to use Prism defaults.')
|
||||
const scopesSection = commentExampleTokens(
|
||||
serializeSection('Scopes', { ...base.scopes }, SCOPES_SCHEMA as SectionSchema<Record<string, string | undefined>>),
|
||||
)
|
||||
scopesSection.splice(1, 0, '# Entire section optional. Uncomment tokens here only if you want to override Prism defaults.')
|
||||
|
||||
const spectrumSection = serializeSection('Spectrum', {
|
||||
const spectrumSection = commentExampleTokens(serializeSection('Spectrum', {
|
||||
...base.spectrum,
|
||||
background: resolved.spectrum.background,
|
||||
guides: resolved.spectrum.guides,
|
||||
labels: resolved.spectrum.labels,
|
||||
heatBase: resolved.spectrum.heatBase,
|
||||
}, SPECTRUM_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
}, SPECTRUM_SCHEMA as SectionSchema<Record<string, string | undefined>>))
|
||||
|
||||
const oscilloscopeSection = serializeSection('Oscilloscope', {
|
||||
const oscilloscopeSection = commentExampleTokens(serializeSection('Oscilloscope', {
|
||||
...base.oscilloscope,
|
||||
background: resolved.oscilloscope.background,
|
||||
guides: resolved.oscilloscope.guides,
|
||||
}, OSCILLOSCOPE_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
}, OSCILLOSCOPE_SCHEMA as SectionSchema<Record<string, string | undefined>>))
|
||||
|
||||
const vectorscopeSection = serializeSection('Vectorscope', {
|
||||
const vectorscopeSection = commentExampleTokens(serializeSection('Vectorscope', {
|
||||
...base.vectorscope,
|
||||
background: resolved.vectorscope.background,
|
||||
guides: resolved.vectorscope.guides,
|
||||
labels: resolved.vectorscope.labels,
|
||||
}, VECTORSCOPE_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
}, VECTORSCOPE_SCHEMA as SectionSchema<Record<string, string | undefined>>))
|
||||
|
||||
const spectrogramSection = serializeSection('Spectrogram', {
|
||||
const spectrogramSection = commentExampleTokens(serializeSection('Spectrogram', {
|
||||
...base.spectrogram,
|
||||
background: resolved.spectrogram.background,
|
||||
}, SPECTROGRAM_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
}, SPECTROGRAM_SCHEMA as SectionSchema<Record<string, string | undefined>>))
|
||||
|
||||
const vumeterSection = serializeSection('VUMeter', {
|
||||
const vumeterSection = commentExampleTokens(serializeSection('VUMeter', {
|
||||
...base.vumeter,
|
||||
background: resolved.vumeter.background,
|
||||
scale: resolved.vumeter.scale,
|
||||
labels: resolved.vumeter.labels,
|
||||
}, VUMETER_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
}, VUMETER_SCHEMA as SectionSchema<Record<string, string | undefined>>))
|
||||
|
||||
const lufsmeterSection = serializeSection('LUFSMeter', {
|
||||
const lufsmeterSection = commentExampleTokens(serializeSection('LUFSMeter', {
|
||||
...base.lufsmeter,
|
||||
background: resolved.lufsmeter.background,
|
||||
scale: resolved.lufsmeter.scale,
|
||||
labels: resolved.lufsmeter.labels,
|
||||
}, LUFSMETER_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
}, LUFSMETER_SCHEMA as SectionSchema<Record<string, string | undefined>>))
|
||||
|
||||
const waveformSection = serializeSection('Waveform', {
|
||||
const waveformSection = commentExampleTokens(serializeSection('Waveform', {
|
||||
...base.waveform,
|
||||
background: resolved.waveform.background,
|
||||
guides: resolved.waveform.guides,
|
||||
}, WAVEFORM_SCHEMA as SectionSchema<Record<string, string | undefined>>)
|
||||
}, WAVEFORM_SCHEMA as SectionSchema<Record<string, string | undefined>>))
|
||||
|
||||
const nowPlayingSection = serializeSection(
|
||||
const nowPlayingSection = commentExampleTokens(serializeSection(
|
||||
'Now Playing',
|
||||
{ ...base.nowPlaying },
|
||||
NOW_PLAYING_SCHEMA as SectionSchema<Record<string, string | undefined>>,
|
||||
)
|
||||
))
|
||||
|
||||
return `# Prism theme template
|
||||
#
|
||||
@@ -950,13 +966,14 @@ export function createTemplateThemeFile(): string {
|
||||
# CSS colors like #hex, rgb(), and rgba() also work
|
||||
#
|
||||
# Start with [App].
|
||||
# Everything else below is optional and can be removed to inherit defaults.
|
||||
# Everything else below is optional and starts commented out.
|
||||
# Uncomment the tokens you want to customize and leave the rest commented to inherit defaults.
|
||||
#
|
||||
# [Controls] and [Scopes] are shared override groups.
|
||||
# Module sections show the full set of supported tokens for each module.
|
||||
#
|
||||
# Remove any token to let Prism inherit or derive it.
|
||||
# Remove an entire section if that area should use Prism's defaults.
|
||||
# Comment out any optional token to let Prism inherit or derive it.
|
||||
# Leave an entire optional section commented if that area should use Prism's defaults.
|
||||
#
|
||||
${[
|
||||
themeSection.join('\n'),
|
||||
@@ -964,7 +981,7 @@ ${[
|
||||
controlsSection.join('\n'),
|
||||
scopesSection.join('\n'),
|
||||
'# Module sections below are optional overrides.',
|
||||
'# Keep the tokens you want to customize and delete the rest.',
|
||||
'# Uncomment the tokens you want to customize and leave the rest as examples.',
|
||||
spectrumSection.join('\n'),
|
||||
oscilloscopeSection.join('\n'),
|
||||
vectorscopeSection.join('\n'),
|
||||
|
||||
@@ -206,21 +206,40 @@ test('createTemplateThemeFile presents a simplified recommended theme layout', (
|
||||
const parsed = parseThemeFileContent(template, 'Template Theme')
|
||||
|
||||
assert.match(template, /# Start with \[App\]\./)
|
||||
assert.match(template, /# Everything else below is optional and can be removed to inherit defaults\./)
|
||||
assert.match(template, /# Everything else below is optional and starts commented out\./)
|
||||
assert.match(template, /# Uncomment the tokens you want to customize and leave the rest commented to inherit defaults\./)
|
||||
assert.match(template, /# \[Controls\] and \[Scopes\] are shared override groups\./)
|
||||
assert.match(template, /# Module sections show the full set of supported tokens for each module\./)
|
||||
assert.match(template, /# Remove any token to let Prism inherit or derive it\./)
|
||||
assert.match(template, /# Remove an entire section if that area should use Prism's defaults\./)
|
||||
assert.match(template, /# Comment out any optional token to let Prism inherit or derive it\./)
|
||||
assert.match(template, /# Leave an entire optional section commented if that area should use Prism's defaults\./)
|
||||
assert.match(template, /# Optional palette extras:/)
|
||||
assert.match(template, /# Optional shell overrides:/)
|
||||
assert.match(template, /^\[Controls\]$/m)
|
||||
assert.match(template, /^\[Scopes\]$/m)
|
||||
assert.match(template, /^\[Spectrum\]$/m)
|
||||
assert.match(template, /^flat_controls = false$/m)
|
||||
assert.match(template, /^toolbar_bg = 4, 8, 12, 199$/m)
|
||||
assert.match(template, /^# flat_controls = false$/m)
|
||||
assert.match(template, /^# toolbar_bg = 4, 8, 12, 199$/m)
|
||||
assert.equal(parsed.app.accent, 'rgb(56, 189, 248)')
|
||||
assert.equal(parsed.app.textMuted, 'rgba(255, 255, 255, 0.42)')
|
||||
assert.equal(parsed.controls.flatControls, 'false')
|
||||
assert.equal(parsed.app.textMuted, undefined)
|
||||
assert.equal(parsed.controls.flatControls, undefined)
|
||||
assert.equal(parsed.spectrum.line, undefined)
|
||||
assert.equal(parsed.nowPlaying.background, undefined)
|
||||
})
|
||||
|
||||
test('parsed template keeps module colors and backgrounds derived from starter app tokens', () => {
|
||||
const parsed = parseThemeFileContent(createTemplateThemeFile(), 'Template Theme')
|
||||
parsed.app.accent = 'rgb(74, 222, 128)'
|
||||
parsed.app.background = 'rgb(3, 7, 18)'
|
||||
|
||||
const resolved = resolveTheme(parsed)
|
||||
|
||||
assert.equal(resolved.spectrum.line, 'rgb(74, 222, 128)')
|
||||
assert.equal(resolved.oscilloscope.line, 'rgb(74, 222, 128)')
|
||||
assert.equal(resolved.vectorscope.trace, 'rgb(74, 222, 128)')
|
||||
assert.equal(resolved.waveform.line, 'rgb(74, 222, 128)')
|
||||
assert.equal(resolved.interface.scopeBackground, 'rgb(3, 7, 18)')
|
||||
assert.equal(resolved.spectrum.background, 'rgb(3, 7, 18)')
|
||||
assert.equal(resolved.nowPlaying.background, 'rgb(3, 7, 18)')
|
||||
})
|
||||
|
||||
test('resolveTheme exposes now playing button tokens and derived button states', () => {
|
||||
@@ -287,6 +306,7 @@ test('library seeds default themes and template file', async () => {
|
||||
assert.match(templateContent, /\[App\]/)
|
||||
assert.match(templateContent, /^\[Controls\]$/m)
|
||||
assert.match(templateContent, /^\[Scopes\]$/m)
|
||||
assert.match(templateContent, /^# flat_controls = false$/m)
|
||||
} finally {
|
||||
await harness.cleanup()
|
||||
}
|
||||
@@ -352,6 +372,7 @@ test('library refreshes the managed template when its generated layout changes',
|
||||
assert.match(templateContent, /# Start with \[App\]\./)
|
||||
assert.match(templateContent, /^\[Controls\]$/m)
|
||||
assert.match(templateContent, /^\[Spectrum\]$/m)
|
||||
assert.match(templateContent, /^# flat_controls = false$/m)
|
||||
} finally {
|
||||
await harness.cleanup()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user