Skip to content

Commit 45ab19a

Browse files
committed
fix(core): allow langAlias to special languages, close #1164
1 parent c39ff79 commit 45ab19a

File tree

7 files changed

+60
-13
lines changed

7 files changed

+60
-13
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { ShikiError } from '../../../types/src/error'
2+
3+
export function resolveLangAlias(name: string, alias?: Record<string, string>): string {
4+
if (!alias)
5+
return name
6+
if (alias[name]) {
7+
const resolved = new Set<string>([name])
8+
while (alias[name]) {
9+
name = alias[name]
10+
if (resolved.has(name))
11+
throw new ShikiError(`Circular alias \`${Array.from(resolved).join(' -> ')} -> ${name}\``)
12+
resolved.add(name)
13+
}
14+
}
15+
return name
16+
}

packages/core/src/constructors/bundle-factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ export function createBundledHighlighter<BundledLangs extends string, BundledThe
6262
): Promise<HighlighterGeneric<BundledLangs, BundledThemes>> {
6363
function resolveLang(lang: LanguageInput | BundledLangs | SpecialLanguage): LanguageInput {
6464
if (typeof lang === 'string') {
65+
lang = (options.langAlias?.[lang] || lang) as LanguageInput | BundledLangs | SpecialLanguage
6566
if (isSpecialLang(lang))
6667
return []
67-
lang = (options.langAlias?.[lang] || lang) as LanguageInput | BundledLangs | SpecialLanguage
6868
const bundle = bundledLanguages[lang as BundledLangs]
6969
if (!bundle)
7070
throw new ShikiError(`Language \`${lang}\` is not included in this bundle. You may want to load it from external source.`)

packages/core/src/constructors/internal-sync.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import type {
1111
ThemeRegistrationAny,
1212
ThemeRegistrationResolved,
1313
} from '@shikijs/types'
14-
1514
import { ShikiError } from '../../../types/src/error'
1615
import { resolveLangs, resolveThemes } from '../textmate/getters-resolve'
1716
import { normalizeTheme } from '../textmate/normalize-theme'
1817
import { Registry } from '../textmate/registry'
1918
import { Resolver } from '../textmate/resolver'
19+
import { resolveLangAlias as _resolveLangAlias } from './_alias'
2020

2121
let instancesCount = 0
2222

@@ -43,6 +43,10 @@ export function createShikiInternalSync(options: HighlighterCoreOptions<true>):
4343

4444
let _lastTheme: string | ThemeRegistrationAny
4545

46+
function resolveLangAlias(name: string): string {
47+
return _resolveLangAlias(name, options.langAlias)
48+
}
49+
4650
function getLanguage(name: string | LanguageRegistration): Grammar {
4751
ensureNotDisposed()
4852
const _lang = _registry.getGrammar(typeof name === 'string' ? name : name.name)
@@ -128,6 +132,7 @@ export function createShikiInternalSync(options: HighlighterCoreOptions<true>):
128132
getLanguage,
129133
getLoadedThemes,
130134
getLoadedLanguages,
135+
resolveLangAlias,
131136
loadLanguage,
132137
loadLanguageSync,
133138
loadTheme,

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ export function codeToTokensBase(
3434
options: CodeToTokensBaseOptions = {},
3535
): ThemedToken[][] {
3636
const {
37-
lang = 'text',
3837
theme: themeName = internal.getLoadedThemes()[0],
3938
} = options
4039

40+
const lang = internal.resolveLangAlias(options.lang || 'text')
41+
4142
if (isPlainLang(lang) || isNoneTheme(themeName))
4243
return splitLines(code).map(line => [{ content: line[0], offset: line[1] }])
4344

@@ -46,7 +47,7 @@ export function codeToTokensBase(
4647
if (lang === 'ansi')
4748
return tokenizeAnsiWithTheme(theme, code, options)
4849

49-
const _grammar = internal.getLanguage(lang)
50+
const _grammar = internal.getLanguage(options.lang || 'text')
5051

5152
if (options.grammarState) {
5253
if (options.grammarState.lang !== _grammar.name) {

packages/core/src/textmate/registry.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { IGrammarConfiguration, IRawTheme } from '@shikijs/vscode-textmate'
88
import type { Resolver } from './resolver'
99
import { Registry as TextMateRegistry, Theme as TextMateTheme } from '@shikijs/vscode-textmate'
1010
import { ShikiError } from '../../../types/src/error'
11+
import { resolveLangAlias } from '../constructors/_alias'
1112
import { normalizeTheme } from './normalize-theme'
1213

1314
export class Registry extends TextMateRegistry {
@@ -71,15 +72,7 @@ export class Registry extends TextMateRegistry {
7172
}
7273

7374
public getGrammar(name: string): Grammar | undefined {
74-
if (this._alias[name]) {
75-
const resolved = new Set<string>([name])
76-
while (this._alias[name]) {
77-
name = this._alias[name]
78-
if (resolved.has(name))
79-
throw new ShikiError(`Circular alias \`${Array.from(resolved).join(' -> ')} -> ${name}\``)
80-
resolved.add(name)
81-
}
82-
}
75+
name = resolveLangAlias(name, this._alias)
8376
return this._resolvedGrammars.get(name)
8477
}
8578

packages/core/test/core.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,34 @@ describe('should', () => {
132132
const code = shiki.codeToHtml('const a: Foo = 1', { lang: 'js', theme: 'nord' })
133133
expect(code).toMatchInlineSnapshot(`"<pre class="shiki nord" style="background-color:#2e3440ff;color:#d8dee9ff" tabindex="0"><code><span class="line"><span style="color:#81A1C1">const</span><span style="color:#D8DEE9"> a</span><span style="color:#81A1C1">:</span><span style="color:#8FBCBB"> Foo</span><span style="color:#81A1C1"> =</span><span style="color:#B48EAD"> 1</span></span></code></pre>"`)
134134
})
135+
136+
it('works with alias and special langs', async () => {
137+
using shiki = await createHighlighterCore({
138+
langAlias: {
139+
lang1: 'text',
140+
lang2: 'ansi',
141+
lang3: 'lang4',
142+
lang4: 'lang5',
143+
lang5: 'ansi',
144+
},
145+
engine: createJavaScriptRegexEngine(),
146+
})
147+
148+
await shiki.loadTheme(nord)
149+
150+
const original1 = shiki.codeToHtml('console.log("Hi")', { lang: 'text', theme: 'nord' })
151+
const code1 = shiki.codeToHtml('console.log("Hi")', { lang: 'lang1', theme: 'nord' })
152+
expect(code1).toBe(original1)
153+
154+
const ansiCode = 'colored foregroundcolored backgroundbold textdimmed textunderlined textreversed textstrikethrough textunderlined + strikethrough text'
155+
const original2 = shiki.codeToHtml(ansiCode, { lang: 'ansi', theme: 'nord' })
156+
const code2 = shiki.codeToHtml(ansiCode, { lang: 'lang2', theme: 'nord' })
157+
expect(code2).toBe(original2)
158+
159+
// nested alias
160+
const code3 = shiki.codeToHtml(ansiCode, { lang: 'lang3', theme: 'nord' })
161+
expect(code3).toBe(original2)
162+
})
135163
})
136164

137165
describe('errors', () => {

packages/types/src/highlighter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ export interface ShikiInternal<BundledLangKeys extends string = never, BundledTh
6060
colorMap: string[]
6161
}
6262

63+
/**
64+
* Resolve a language alias
65+
*/
66+
resolveLangAlias: (lang: string) => string
6367
/**
6468
* Get the names of loaded languages
6569
*

0 commit comments

Comments
 (0)