Skip to content

Commit bb47a84

Browse files
committedApr 1, 2024·
fix: colorReplacements also for bg and fg, close #641
1 parent f254653 commit bb47a84

File tree

5 files changed

+71
-9
lines changed

5 files changed

+71
-9
lines changed
 

‎packages/core/src/code-to-tokens-ansi.ts

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export function tokenizeAnsiWithTheme(
3939
}
4040

4141
color = applyColorReplacements(color, colorReplacements)
42+
bgColor = applyColorReplacements(bgColor, colorReplacements)
4243

4344
if (token.decorations.has('dim'))
4445
color = dimColor(color)

‎packages/core/src/code-to-tokens-base.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,16 @@ export function tokenizeWithTheme(
9696
continue
9797

9898
const metadata = result.tokens[2 * j + 1]
99-
const foreground = StackElementMetadata.getForeground(metadata)
100-
const foregroundColor = applyColorReplacements(colorMap[foreground], colorReplacements)
99+
const color = applyColorReplacements(
100+
colorMap[StackElementMetadata.getForeground(metadata)],
101+
colorReplacements,
102+
)
101103
const fontStyle: FontStyle = StackElementMetadata.getFontStyle(metadata)
102104

103105
const token: ThemedToken = {
104106
content: line.substring(startIndex, nextStartIndex),
105107
offset: lineOffset + startIndex,
106-
color: foregroundColor,
108+
color,
107109
fontStyle,
108110
}
109111

‎packages/core/src/code-to-tokens.ts

+14-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { codeToTokensBase } from './code-to-tokens-base'
22
import { codeToTokensWithThemes } from './code-to-tokens-themes'
33
import { ShikiError } from './error'
44
import type { CodeToTokensOptions, ShikiInternal, ThemedToken, ThemedTokenWithVariants, TokensResult } from './types'
5-
import { getTokenStyleObject, stringifyTokenStyle } from './utils'
5+
import { applyColorReplacements, getTokenStyleObject, stringifyTokenStyle } from './utils'
66

77
/**
88
* High-level code-to-tokens API.
@@ -24,6 +24,7 @@ export function codeToTokens(
2424
const {
2525
defaultColor = 'light',
2626
cssVariablePrefix = '--shiki-',
27+
colorReplacements,
2728
} = options
2829

2930
const themes = Object.entries(options.themes)
@@ -48,21 +49,29 @@ export function codeToTokens(
4849
tokens = themeTokens
4950
.map(line => line.map(token => mergeToken(token, themesOrder, cssVariablePrefix, defaultColor)))
5051

51-
fg = themes.map((t, idx) => (idx === 0 && defaultColor ? '' : `${cssVariablePrefix + t.color}:`) + (themeRegs[idx].fg || 'inherit')).join(';')
52-
bg = themes.map((t, idx) => (idx === 0 && defaultColor ? '' : `${cssVariablePrefix + t.color}-bg:`) + (themeRegs[idx].bg || 'inherit')).join(';')
52+
fg = themes.map((t, idx) => (idx === 0 && defaultColor
53+
? ''
54+
: `${cssVariablePrefix + t.color}:`) + (applyColorReplacements(themeRegs[idx].fg, colorReplacements) || 'inherit')).join(';')
55+
bg = themes.map((t, idx) => (idx === 0 && defaultColor
56+
? ''
57+
: `${cssVariablePrefix + t.color}-bg:`) + (applyColorReplacements(themeRegs[idx].bg, colorReplacements) || 'inherit')).join(';')
5358
themeName = `shiki-themes ${themeRegs.map(t => t.name).join(' ')}`
5459
rootStyle = defaultColor ? undefined : [fg, bg].join(';')
5560
}
5661
else if ('theme' in options) {
62+
const {
63+
colorReplacements,
64+
} = options
65+
5766
tokens = codeToTokensBase(
5867
internal,
5968
code,
6069
options,
6170
)
6271

6372
const _theme = internal.getTheme(options.theme)
64-
bg = _theme.bg
65-
fg = _theme.fg
73+
bg = applyColorReplacements(_theme.bg, colorReplacements)
74+
fg = applyColorReplacements(_theme.fg, colorReplacements)
6675
themeName = _theme.name
6776
}
6877
else {

‎packages/core/src/utils.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,11 @@ export function splitTokens<
146146
})
147147
}
148148

149-
export function applyColorReplacements(color: string, replacements?: Record<string, string>): string {
149+
export function applyColorReplacements(color: string, replacements?: Record<string, string>): string
150+
export function applyColorReplacements(color?: string | undefined, replacements?: Record<string, string>): string | undefined
151+
export function applyColorReplacements(color?: string, replacements?: Record<string, string>): string | undefined {
152+
if (!color)
153+
return color
150154
return replacements?.[color?.toLowerCase()] || color
151155
}
152156

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { expect, it } from 'vitest'
2+
import { codeToHtml } from '../src'
3+
4+
it('colorReplacements', async () => {
5+
const result = await codeToHtml('console.log("hi")', {
6+
lang: 'js',
7+
themes: {
8+
light: 'vitesse-light',
9+
dark: 'material-theme-palenight',
10+
},
11+
colorReplacements: {
12+
'#393a34': 'var(---replaced-1)',
13+
'#b07d48': 'var(---replaced-2)',
14+
},
15+
})
16+
17+
expect(result).toContain('var(---replaced-1)')
18+
expect(result).toContain('var(---replaced-2)')
19+
20+
expect(result.replace(/>/g, '>\n'))
21+
.toMatchInlineSnapshot(`
22+
"<pre class="shiki shiki-themes vitesse-light material-theme-palenight" style="background-color:#ffffff;--shiki-dark-bg:#292D3E;color:var(---replaced-1);--shiki-dark:#babed8" tabindex="0">
23+
<code>
24+
<span class="line">
25+
<span style="color:var(---replaced-2);--shiki-dark:#BABED8">
26+
console</span>
27+
<span style="color:#999999;--shiki-dark:#89DDFF">
28+
.</span>
29+
<span style="color:#59873A;--shiki-dark:#82AAFF">
30+
log</span>
31+
<span style="color:#999999;--shiki-dark:#BABED8">
32+
(</span>
33+
<span style="color:#B5695999;--shiki-dark:#89DDFF">
34+
"</span>
35+
<span style="color:#B56959;--shiki-dark:#C3E88D">
36+
hi</span>
37+
<span style="color:#B5695999;--shiki-dark:#89DDFF">
38+
"</span>
39+
<span style="color:#999999;--shiki-dark:#BABED8">
40+
)</span>
41+
</span>
42+
</code>
43+
</pre>
44+
"
45+
`)
46+
})

0 commit comments

Comments
 (0)
Please sign in to comment.