Skip to content

Commit 5d8cf5d

Browse files
committed
feat!: change codeToThemedTokens options
1 parent b7bd241 commit 5d8cf5d

File tree

5 files changed

+99
-12
lines changed

5 files changed

+99
-12
lines changed

src/bundled/singleton.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { BuiltinLanguages, BuiltinThemes, CodeToHtmlOptions, PlainTextLanguage, RequireKeys } from '../types'
1+
import type { BuiltinLanguages, BuiltinThemes, CodeToHtmlOptions, CodeToThemedTokensOptions, PlainTextLanguage, RequireKeys } from '../types'
22
import { getHighlighter } from './highlighter'
33
import type { Highlighter } from './highlighter'
44

@@ -23,7 +23,7 @@ async function getShikiWithThemeLang(options: { theme: BuiltinThemes; lang: Buil
2323
}
2424

2525
/**
26-
* Shorthand for codeToHtml with auto-loaded theme and language.
26+
* Shorthand for `codeToHtml` with auto-loaded theme and language.
2727
* A singleton highlighter it maintained internally.
2828
*
2929
* Differences from `shiki.codeToHtml()`, this function is async.
@@ -32,3 +32,14 @@ export async function codeToHtml(code: string, options: RequireKeys<CodeToHtmlOp
3232
const shiki = await getShikiWithThemeLang(options)
3333
return shiki.codeToHtml(code, options)
3434
}
35+
36+
/**
37+
* Shorthand for `codeToThemedTokens` with auto-loaded theme and language.
38+
* A singleton highlighter it maintained internally.
39+
*
40+
* Differences from `shiki.codeToThemedTokens()`, this function is async.
41+
*/
42+
export async function codeToThemedTokens(code: string, options: RequireKeys<CodeToThemedTokensOptions<BuiltinLanguages, BuiltinThemes>, 'theme' | 'lang'>) {
43+
const shiki = await getShikiWithThemeLang(options)
44+
return shiki.codeToThemedTokens(code, options)
45+
}

src/core/index.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { CodeToHtmlOptions, LanguageInput, MaybeGetter, ThemeInput } from '../types'
1+
import type { CodeToHtmlOptions, CodeToThemedTokensOptions, LanguageInput, MaybeGetter, ThemeInput } from '../types'
22
import type { OnigurumaLoadOptions } from '../oniguruma'
33
import { createOnigScanner, createOnigString, loadWasm } from '../oniguruma'
44
import { Registry } from './registry'
@@ -55,17 +55,23 @@ export async function getHighlighterCore(options: HighlighterCoreOptions) {
5555

5656
function codeToThemedTokens(
5757
code: string,
58-
lang = 'text',
59-
theme = defaultTheme,
60-
options = { includeExplanation: true },
58+
options: CodeToThemedTokensOptions = {},
6159
) {
60+
const {
61+
lang = 'text',
62+
theme = defaultTheme,
63+
includeExplanation = true,
64+
} = options
65+
6266
if (isPlaintext(lang)) {
6367
const lines = code.split(/\r\n|\r|\n/)
6468
return [...lines.map(line => [{ content: line }])]
6569
}
6670
const _grammar = getLang(lang)
6771
const { _theme, _colorMap } = getTheme(theme)
68-
return tokenizeWithTheme(_theme, _colorMap, code, _grammar, options)
72+
return tokenizeWithTheme(code, _grammar, _theme, _colorMap, {
73+
includeExplanation,
74+
})
6975
}
7076

7177
function getLang(name: string) {
@@ -88,7 +94,8 @@ export async function getHighlighterCore(options: HighlighterCoreOptions) {
8894
}
8995

9096
function codeToHtml(code: string, options: CodeToHtmlOptions = {}): string {
91-
const tokens = codeToThemedTokens(code, options.lang, options.theme, {
97+
const tokens = codeToThemedTokens(code, {
98+
...options,
9299
includeExplanation: false,
93100
})
94101
const { _theme } = getTheme(options.theme)

src/core/themedTokenizer.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import type { FontStyle } from './stackElementMetadata'
1010
import { StackElementMetadata } from './stackElementMetadata'
1111

1212
export function tokenizeWithTheme(
13-
theme: IRawTheme,
14-
colorMap: string[],
1513
fileContents: string,
1614
grammar: IGrammar,
15+
theme: IRawTheme,
16+
colorMap: string[],
1717
options: { includeExplanation?: boolean },
1818
): ThemedToken[][] {
1919
const lines = fileContents.split(/\r\n|\r|\n/)

src/types.ts

+11
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ export interface CodeToHtmlOptions<Languages = string, Themes = string> {
4747
lineOptions?: LineOption[]
4848
}
4949

50+
export interface CodeToThemedTokensOptions<Languages = string, Themes = string> {
51+
lang?: Languages | PlainTextLanguage
52+
theme?: Themes
53+
/**
54+
* Include explanation of why a token is given a color.
55+
*
56+
* @default true
57+
*/
58+
includeExplanation?: boolean
59+
}
60+
5061
export interface LineOption {
5162
/**
5263
* 1-based line number.

test/singleton.test.ts

+60-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,70 @@
11
import { describe, expect, it } from 'vitest'
2-
import { codeToHtml } from '../src'
2+
import { codeToHtml, codeToThemedTokens } from '../src'
33

44
describe('should', () => {
5-
it('works', async () => {
5+
it('codeToHtml', async () => {
66
expect(await codeToHtml('console.log("hello")', { lang: 'js', theme: 'vitesse-light' }))
77
.toMatchInlineSnapshot('"<pre class=\\"shiki vitesse-light\\" style=\\"background-color: #ffffff\\" tabindex=\\"0\\"><code><span class=\\"line\\"><span style=\\"color: #B07D48\\">console</span><span style=\\"color: #999999\\">.</span><span style=\\"color: #59873A\\">log</span><span style=\\"color: #999999\\">(</span><span style=\\"color: #B5695999\\">&quot;</span><span style=\\"color: #B56959\\">hello</span><span style=\\"color: #B5695999\\">&quot;</span><span style=\\"color: #999999\\">)</span></span></code></pre>"')
88

99
expect(await codeToHtml('<div class="foo">bar</div>', { lang: 'html', theme: 'min-dark' }))
1010
.toMatchInlineSnapshot('"<pre class=\\"shiki min-dark\\" style=\\"background-color: #1f1f1f\\" tabindex=\\"0\\"><code><span class=\\"line\\"><span style=\\"color: #B392F0\\">&lt;</span><span style=\\"color: #FFAB70\\">div</span><span style=\\"color: #B392F0\\"> class</span><span style=\\"color: #F97583\\">=</span><span style=\\"color: #FFAB70\\">&quot;foo&quot;</span><span style=\\"color: #B392F0\\">&gt;bar&lt;/</span><span style=\\"color: #FFAB70\\">div</span><span style=\\"color: #B392F0\\">&gt;</span></span></code></pre>"')
1111
})
12+
13+
it('codeToThemedTokens', async () => {
14+
expect(await codeToThemedTokens('console.log("hello")', { lang: 'js', theme: 'vitesse-dark', includeExplanation: false }))
15+
.toMatchInlineSnapshot(`
16+
[
17+
[
18+
{
19+
"color": "#BD976A",
20+
"content": "console",
21+
"explanation": [],
22+
"fontStyle": 0,
23+
},
24+
{
25+
"color": "#666666",
26+
"content": ".",
27+
"explanation": [],
28+
"fontStyle": 0,
29+
},
30+
{
31+
"color": "#80A665",
32+
"content": "log",
33+
"explanation": [],
34+
"fontStyle": 0,
35+
},
36+
{
37+
"color": "#666666",
38+
"content": "(",
39+
"explanation": [],
40+
"fontStyle": 0,
41+
},
42+
{
43+
"color": "#C98A7D99",
44+
"content": "\\"",
45+
"explanation": [],
46+
"fontStyle": 0,
47+
},
48+
{
49+
"color": "#C98A7D",
50+
"content": "hello",
51+
"explanation": [],
52+
"fontStyle": 0,
53+
},
54+
{
55+
"color": "#C98A7D99",
56+
"content": "\\"",
57+
"explanation": [],
58+
"fontStyle": 0,
59+
},
60+
{
61+
"color": "#666666",
62+
"content": ")",
63+
"explanation": [],
64+
"fontStyle": 0,
65+
},
66+
],
67+
]
68+
`)
69+
})
1270
})

0 commit comments

Comments
 (0)