Skip to content

Commit 989afdb

Browse files
committedSep 26, 2024··
feat: move createCssVariablesTheme to core
1 parent 50c8e4a commit 989afdb

File tree

4 files changed

+281
-278
lines changed

4 files changed

+281
-278
lines changed
 

‎packages/core/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export { codeToTokens } from './highlight/code-to-tokens'
1616
export { tokenizeAnsiWithTheme } from './highlight/code-to-tokens-ansi'
1717
export { codeToTokensBase, tokenizeWithTheme } from './highlight/code-to-tokens-base'
1818
export { codeToTokensWithThemes } from './highlight/code-to-tokens-themes'
19-
2019
export { normalizeTheme } from './textmate/normalize-theme'
20+
export * from './theme-css-variables'
2121
export { transformerDecorations } from './transformer-decorations'
2222

2323
// Utils and Misc
+276
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
import type { ThemeRegistration } from '@shikijs/types'
2+
3+
export interface CssVariablesThemeOptions {
4+
/**
5+
* Theme name. Need to unique if multiple css variables themes are created
6+
*
7+
* @default 'css-variables'
8+
*/
9+
name?: string
10+
11+
/**
12+
* Prefix for css variables
13+
*
14+
* @default '--shiki-'
15+
*/
16+
variablePrefix?: string
17+
18+
/**
19+
* Default value for css variables, the key is without the prefix
20+
*
21+
* @example `{ 'token-comment': '#888' }` will generate `var(--shiki-token-comment, #888)` for comments
22+
*/
23+
variableDefaults?: Record<string, string>
24+
25+
/**
26+
* Enable font style
27+
*
28+
* @default true
29+
*/
30+
fontStyle?: boolean
31+
}
32+
33+
/**
34+
* A factory function to create a css-variable-based theme
35+
*
36+
* @see https://shiki.style/guide/theme-colors#css-variables-theme
37+
*/
38+
export function createCssVariablesTheme(options: CssVariablesThemeOptions = {}): ThemeRegistration {
39+
const {
40+
name = 'css-variables',
41+
variablePrefix = '--shiki-',
42+
fontStyle = true,
43+
} = options
44+
45+
const variable = (name: string): string => {
46+
if (options.variableDefaults?.[name])
47+
return `var(${variablePrefix}${name}, ${options.variableDefaults[name]})`
48+
return `var(${variablePrefix}${name})`
49+
}
50+
51+
const theme: ThemeRegistration = {
52+
name,
53+
type: 'dark',
54+
colors: {
55+
'editor.foreground': variable('foreground'),
56+
'editor.background': variable('background'),
57+
'terminal.ansiBlack': variable('ansi-black'),
58+
'terminal.ansiRed': variable('ansi-red'),
59+
'terminal.ansiGreen': variable('ansi-green'),
60+
'terminal.ansiYellow': variable('ansi-yellow'),
61+
'terminal.ansiBlue': variable('ansi-blue'),
62+
'terminal.ansiMagenta': variable('ansi-magenta'),
63+
'terminal.ansiCyan': variable('ansi-cyan'),
64+
'terminal.ansiWhite': variable('ansi-white'),
65+
'terminal.ansiBrightBlack': variable('ansi-bright-black'),
66+
'terminal.ansiBrightRed': variable('ansi-bright-red'),
67+
'terminal.ansiBrightGreen': variable('ansi-bright-green'),
68+
'terminal.ansiBrightYellow': variable('ansi-bright-yellow'),
69+
'terminal.ansiBrightBlue': variable('ansi-bright-blue'),
70+
'terminal.ansiBrightMagenta': variable('ansi-bright-magenta'),
71+
'terminal.ansiBrightCyan': variable('ansi-bright-cyan'),
72+
'terminal.ansiBrightWhite': variable('ansi-bright-white'),
73+
},
74+
tokenColors: [
75+
{
76+
scope: [
77+
'keyword.operator.accessor',
78+
'meta.group.braces.round.function.arguments',
79+
'meta.template.expression',
80+
'markup.fenced_code meta.embedded.block',
81+
],
82+
settings: {
83+
foreground: variable('foreground'),
84+
},
85+
},
86+
{
87+
scope: 'emphasis',
88+
settings: {
89+
fontStyle: 'italic',
90+
},
91+
},
92+
{
93+
scope: ['strong', 'markup.heading.markdown', 'markup.bold.markdown'],
94+
settings: {
95+
fontStyle: 'bold',
96+
},
97+
},
98+
{
99+
scope: ['markup.italic.markdown'],
100+
settings: {
101+
fontStyle: 'italic',
102+
},
103+
},
104+
{
105+
scope: 'meta.link.inline.markdown',
106+
settings: {
107+
fontStyle: 'underline',
108+
foreground: variable('token-link'),
109+
},
110+
},
111+
{
112+
scope: ['string', 'markup.fenced_code', 'markup.inline'],
113+
settings: {
114+
foreground: variable('token-string'),
115+
},
116+
},
117+
{
118+
scope: ['comment', 'string.quoted.docstring.multi'],
119+
settings: {
120+
foreground: variable('token-comment'),
121+
},
122+
},
123+
{
124+
scope: [
125+
'constant.numeric',
126+
'constant.language',
127+
'constant.other.placeholder',
128+
'constant.character.format.placeholder',
129+
'variable.language.this',
130+
'variable.other.object',
131+
'variable.other.class',
132+
'variable.other.constant',
133+
'meta.property-name',
134+
'meta.property-value',
135+
'support',
136+
],
137+
settings: {
138+
foreground: variable('token-constant'),
139+
},
140+
},
141+
{
142+
scope: [
143+
'keyword',
144+
'storage.modifier',
145+
'storage.type',
146+
'storage.control.clojure',
147+
'entity.name.function.clojure',
148+
'entity.name.tag.yaml',
149+
'support.function.node',
150+
'support.type.property-name.json',
151+
'punctuation.separator.key-value',
152+
'punctuation.definition.template-expression',
153+
],
154+
settings: {
155+
foreground: variable('token-keyword'),
156+
},
157+
},
158+
{
159+
scope: 'variable.parameter.function',
160+
settings: {
161+
foreground: variable('token-parameter'),
162+
},
163+
},
164+
{
165+
scope: [
166+
'support.function',
167+
'entity.name.type',
168+
'entity.other.inherited-class',
169+
'meta.function-call',
170+
'meta.instance.constructor',
171+
'entity.other.attribute-name',
172+
'entity.name.function',
173+
'constant.keyword.clojure',
174+
],
175+
settings: {
176+
foreground: variable('token-function'),
177+
},
178+
},
179+
{
180+
scope: [
181+
'entity.name.tag',
182+
'string.quoted',
183+
'string.regexp',
184+
'string.interpolated',
185+
'string.template',
186+
'string.unquoted.plain.out.yaml',
187+
'keyword.other.template',
188+
],
189+
settings: {
190+
foreground: variable('token-string-expression'),
191+
},
192+
},
193+
{
194+
scope: [
195+
'punctuation.definition.arguments',
196+
'punctuation.definition.dict',
197+
'punctuation.separator',
198+
'meta.function-call.arguments',
199+
],
200+
settings: {
201+
foreground: variable('token-punctuation'),
202+
},
203+
},
204+
{
205+
// [Custom] Markdown links
206+
scope: [
207+
'markup.underline.link',
208+
'punctuation.definition.metadata.markdown',
209+
],
210+
settings: {
211+
foreground: variable('token-link'),
212+
},
213+
},
214+
{
215+
// [Custom] Markdown list
216+
scope: ['beginning.punctuation.definition.list.markdown'],
217+
settings: {
218+
foreground: variable('token-string'),
219+
},
220+
},
221+
{
222+
// [Custom] Markdown punctuation definition brackets
223+
scope: [
224+
'punctuation.definition.string.begin.markdown',
225+
'punctuation.definition.string.end.markdown',
226+
'string.other.link.title.markdown',
227+
'string.other.link.description.markdown',
228+
],
229+
settings: {
230+
foreground: variable('token-keyword'),
231+
},
232+
},
233+
{
234+
// [Custom] Diff
235+
scope: [
236+
'markup.inserted',
237+
'meta.diff.header.to-file',
238+
'punctuation.definition.inserted',
239+
],
240+
settings: {
241+
foreground: variable('token-inserted'),
242+
},
243+
},
244+
{
245+
scope: [
246+
'markup.deleted',
247+
'meta.diff.header.from-file',
248+
'punctuation.definition.deleted',
249+
],
250+
settings: {
251+
foreground: variable('token-deleted'),
252+
},
253+
},
254+
{
255+
scope: [
256+
'markup.changed',
257+
'punctuation.definition.changed',
258+
],
259+
settings: {
260+
foreground: variable('token-changed'),
261+
},
262+
},
263+
],
264+
}
265+
266+
if (!fontStyle) {
267+
theme.tokenColors = theme.tokenColors?.map((tokenColor) => {
268+
if (tokenColor.settings?.fontStyle)
269+
// @ts-expect-error force delete readonly property
270+
delete tokenColor.settings.fontStyle
271+
return tokenColor
272+
})
273+
}
274+
275+
return theme
276+
}

‎packages/shiki/src/core.ts

-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
export type { CssVariablesThemeOptions } from './theme-css-variables'
2-
3-
export { createCssVariablesTheme } from './theme-css-variables'
41
export * from '@shikijs/core'
+4-274
Original file line numberDiff line numberDiff line change
@@ -1,276 +1,6 @@
1-
import type { ThemeRegistration } from '@shikijs/types'
1+
import { warnDeprecated } from '@shikijs/core'
22

3-
export interface CssVariablesThemeOptions {
4-
/**
5-
* Theme name. Need to unique if multiple css variables themes are created
6-
*
7-
* @default 'css-variables'
8-
*/
9-
name?: string
3+
export { createCssVariablesTheme } from './core'
4+
export type { CssVariablesThemeOptions } from './core'
105

11-
/**
12-
* Prefix for css variables
13-
*
14-
* @default '--shiki-'
15-
*/
16-
variablePrefix?: string
17-
18-
/**
19-
* Default value for css variables, the key is without the prefix
20-
*
21-
* @example `{ 'token-comment': '#888' }` will generate `var(--shiki-token-comment, #888)` for comments
22-
*/
23-
variableDefaults?: Record<string, string>
24-
25-
/**
26-
* Enable font style
27-
*
28-
* @default true
29-
*/
30-
fontStyle?: boolean
31-
}
32-
33-
/**
34-
* A factory function to create a css-variable-based theme
35-
*
36-
* @see https://shiki.style/guide/theme-colors#css-variables-theme
37-
*/
38-
export function createCssVariablesTheme(options: CssVariablesThemeOptions = {}): ThemeRegistration {
39-
const {
40-
name = 'css-variables',
41-
variablePrefix = '--shiki-',
42-
fontStyle = true,
43-
} = options
44-
45-
const variable = (name: string): string => {
46-
if (options.variableDefaults?.[name])
47-
return `var(${variablePrefix}${name}, ${options.variableDefaults[name]})`
48-
return `var(${variablePrefix}${name})`
49-
}
50-
51-
const theme: ThemeRegistration = {
52-
name,
53-
type: 'dark',
54-
colors: {
55-
'editor.foreground': variable('foreground'),
56-
'editor.background': variable('background'),
57-
'terminal.ansiBlack': variable('ansi-black'),
58-
'terminal.ansiRed': variable('ansi-red'),
59-
'terminal.ansiGreen': variable('ansi-green'),
60-
'terminal.ansiYellow': variable('ansi-yellow'),
61-
'terminal.ansiBlue': variable('ansi-blue'),
62-
'terminal.ansiMagenta': variable('ansi-magenta'),
63-
'terminal.ansiCyan': variable('ansi-cyan'),
64-
'terminal.ansiWhite': variable('ansi-white'),
65-
'terminal.ansiBrightBlack': variable('ansi-bright-black'),
66-
'terminal.ansiBrightRed': variable('ansi-bright-red'),
67-
'terminal.ansiBrightGreen': variable('ansi-bright-green'),
68-
'terminal.ansiBrightYellow': variable('ansi-bright-yellow'),
69-
'terminal.ansiBrightBlue': variable('ansi-bright-blue'),
70-
'terminal.ansiBrightMagenta': variable('ansi-bright-magenta'),
71-
'terminal.ansiBrightCyan': variable('ansi-bright-cyan'),
72-
'terminal.ansiBrightWhite': variable('ansi-bright-white'),
73-
},
74-
tokenColors: [
75-
{
76-
scope: [
77-
'keyword.operator.accessor',
78-
'meta.group.braces.round.function.arguments',
79-
'meta.template.expression',
80-
'markup.fenced_code meta.embedded.block',
81-
],
82-
settings: {
83-
foreground: variable('foreground'),
84-
},
85-
},
86-
{
87-
scope: 'emphasis',
88-
settings: {
89-
fontStyle: 'italic',
90-
},
91-
},
92-
{
93-
scope: ['strong', 'markup.heading.markdown', 'markup.bold.markdown'],
94-
settings: {
95-
fontStyle: 'bold',
96-
},
97-
},
98-
{
99-
scope: ['markup.italic.markdown'],
100-
settings: {
101-
fontStyle: 'italic',
102-
},
103-
},
104-
{
105-
scope: 'meta.link.inline.markdown',
106-
settings: {
107-
fontStyle: 'underline',
108-
foreground: variable('token-link'),
109-
},
110-
},
111-
{
112-
scope: ['string', 'markup.fenced_code', 'markup.inline'],
113-
settings: {
114-
foreground: variable('token-string'),
115-
},
116-
},
117-
{
118-
scope: ['comment', 'string.quoted.docstring.multi'],
119-
settings: {
120-
foreground: variable('token-comment'),
121-
},
122-
},
123-
{
124-
scope: [
125-
'constant.numeric',
126-
'constant.language',
127-
'constant.other.placeholder',
128-
'constant.character.format.placeholder',
129-
'variable.language.this',
130-
'variable.other.object',
131-
'variable.other.class',
132-
'variable.other.constant',
133-
'meta.property-name',
134-
'meta.property-value',
135-
'support',
136-
],
137-
settings: {
138-
foreground: variable('token-constant'),
139-
},
140-
},
141-
{
142-
scope: [
143-
'keyword',
144-
'storage.modifier',
145-
'storage.type',
146-
'storage.control.clojure',
147-
'entity.name.function.clojure',
148-
'entity.name.tag.yaml',
149-
'support.function.node',
150-
'support.type.property-name.json',
151-
'punctuation.separator.key-value',
152-
'punctuation.definition.template-expression',
153-
],
154-
settings: {
155-
foreground: variable('token-keyword'),
156-
},
157-
},
158-
{
159-
scope: 'variable.parameter.function',
160-
settings: {
161-
foreground: variable('token-parameter'),
162-
},
163-
},
164-
{
165-
scope: [
166-
'support.function',
167-
'entity.name.type',
168-
'entity.other.inherited-class',
169-
'meta.function-call',
170-
'meta.instance.constructor',
171-
'entity.other.attribute-name',
172-
'entity.name.function',
173-
'constant.keyword.clojure',
174-
],
175-
settings: {
176-
foreground: variable('token-function'),
177-
},
178-
},
179-
{
180-
scope: [
181-
'entity.name.tag',
182-
'string.quoted',
183-
'string.regexp',
184-
'string.interpolated',
185-
'string.template',
186-
'string.unquoted.plain.out.yaml',
187-
'keyword.other.template',
188-
],
189-
settings: {
190-
foreground: variable('token-string-expression'),
191-
},
192-
},
193-
{
194-
scope: [
195-
'punctuation.definition.arguments',
196-
'punctuation.definition.dict',
197-
'punctuation.separator',
198-
'meta.function-call.arguments',
199-
],
200-
settings: {
201-
foreground: variable('token-punctuation'),
202-
},
203-
},
204-
{
205-
// [Custom] Markdown links
206-
scope: [
207-
'markup.underline.link',
208-
'punctuation.definition.metadata.markdown',
209-
],
210-
settings: {
211-
foreground: variable('token-link'),
212-
},
213-
},
214-
{
215-
// [Custom] Markdown list
216-
scope: ['beginning.punctuation.definition.list.markdown'],
217-
settings: {
218-
foreground: variable('token-string'),
219-
},
220-
},
221-
{
222-
// [Custom] Markdown punctuation definition brackets
223-
scope: [
224-
'punctuation.definition.string.begin.markdown',
225-
'punctuation.definition.string.end.markdown',
226-
'string.other.link.title.markdown',
227-
'string.other.link.description.markdown',
228-
],
229-
settings: {
230-
foreground: variable('token-keyword'),
231-
},
232-
},
233-
{
234-
// [Custom] Diff
235-
scope: [
236-
'markup.inserted',
237-
'meta.diff.header.to-file',
238-
'punctuation.definition.inserted',
239-
],
240-
settings: {
241-
foreground: variable('token-inserted'),
242-
},
243-
},
244-
{
245-
scope: [
246-
'markup.deleted',
247-
'meta.diff.header.from-file',
248-
'punctuation.definition.deleted',
249-
],
250-
settings: {
251-
foreground: variable('token-deleted'),
252-
},
253-
},
254-
{
255-
scope: [
256-
'markup.changed',
257-
'punctuation.definition.changed',
258-
],
259-
settings: {
260-
foreground: variable('token-changed'),
261-
},
262-
},
263-
],
264-
}
265-
266-
if (!fontStyle) {
267-
theme.tokenColors = theme.tokenColors?.map((tokenColor) => {
268-
if (tokenColor.settings?.fontStyle)
269-
// @ts-expect-error force delete readonly property
270-
delete tokenColor.settings.fontStyle
271-
return tokenColor
272-
})
273-
}
274-
275-
return theme
276-
}
6+
warnDeprecated('`shiki/theme-css-variables` entry point is deprecated. Use `shiki/core` instead.')

0 commit comments

Comments
 (0)
Please sign in to comment.