Skip to content

Commit 930dddc

Browse files
committed
feat: allow to swap regex constructor for JavaScript engine
1 parent a71d08c commit 930dddc

File tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed

packages/core/src/engines/javascript.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,31 @@ import type { JavaScriptRegexEngineOptions, PatternScanner, RegexEngine, RegexEn
33

44
const MAX = 4294967295
55

6+
/**
7+
* The default RegExp constructor for JavaScript regex engine.
8+
*/
9+
export function defaultJavaScriptRegexConstructor(pattern: string): RegExp {
10+
return onigurumaToRegexp(
11+
pattern
12+
.replace(/\|\\G(\||\))/g, '$1')
13+
.replace(/(\(|\|)\\G\|/g, '$1')
14+
// YAML specific handling; TODO: move to tm-grammars
15+
.replaceAll('[^\\s[-?:,\\[\\]{}#&*!|>\'"%@`]]', '[^\\s\\-?:,\\[\\]{}#&*!|>\'"%@`]'),
16+
{
17+
flags: 'dgm',
18+
ignoreContiguousAnchors: true,
19+
},
20+
)
21+
}
22+
623
export class JavaScriptScanner implements PatternScanner {
724
regexps: (RegExp | null)[]
825

926
constructor(
1027
public patterns: string[],
1128
public cache: Map<string, RegExp | Error>,
1229
public forgiving: boolean,
30+
public regexConstructor: (pattern: string) => RegExp = defaultJavaScriptRegexConstructor,
1331
) {
1432
this.regexps = patterns.map((p) => {
1533
const cached = cache?.get(p)
@@ -22,17 +40,7 @@ export class JavaScriptScanner implements PatternScanner {
2240
throw cached
2341
}
2442
try {
25-
const regex = onigurumaToRegexp(
26-
p
27-
.replace(/\|\\G(\||\))/g, '$1')
28-
.replace(/(\(|\|)\\G\|/g, '$1')
29-
// YAML specific handling; TODO: move to tm-grammars
30-
.replaceAll('[^\\s[-?:,\\[\\]{}#&*!|>\'"%@`]]', '[^\\s\\-?:,\\[\\]{}#&*!|>\'"%@`]'),
31-
{
32-
flags: 'dgm',
33-
ignoreContiguousAnchors: true,
34-
},
35-
)
43+
const regex = regexConstructor(p)
3644
cache?.set(p, regex)
3745
return regex
3846
}
@@ -126,7 +134,7 @@ export function createJavaScriptRegexEngine(options: JavaScriptRegexEngineOption
126134

127135
return {
128136
createScanner(patterns: string[]) {
129-
return new JavaScriptScanner(patterns, cache, forgiving)
137+
return new JavaScriptScanner(patterns, cache, forgiving, options.regexConstructor)
130138
},
131139
createString(s: string) {
132140
return {

packages/core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export { createShikiInternal, getShikiInternal, setDefaultWasmLoader } from './c
99

1010
// Engines
1111
export { createWasmOnigEngine, loadWasm } from './engines/wasm'
12-
export { createJavaScriptRegexEngine } from './engines/javascript'
12+
export { createJavaScriptRegexEngine, defaultJavaScriptRegexConstructor } from './engines/javascript'
1313

1414
// TextMate Utilities
1515
export { normalizeTheme } from './textmate/normalize-theme'

packages/core/src/types/engines.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,11 @@ export interface JavaScriptRegexEngineOptions {
4141
* Cache for regex patterns.
4242
*/
4343
cache?: Map<string, RegExp | Error>
44+
45+
/**
46+
* Custom pattern to RegExp constructor.
47+
*
48+
* By default `oniguruma-to-js` is used.
49+
*/
50+
regexConstructor?: (pattern: string) => RegExp
4451
}

0 commit comments

Comments
 (0)