Skip to content

Commit

Permalink
feat: allow to swap regex constructor for JavaScript engine
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Sep 4, 2024
1 parent a71d08c commit 930dddc
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 13 deletions.
32 changes: 20 additions & 12 deletions packages/core/src/engines/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,31 @@ import type { JavaScriptRegexEngineOptions, PatternScanner, RegexEngine, RegexEn

const MAX = 4294967295

/**
* The default RegExp constructor for JavaScript regex engine.
*/
export function defaultJavaScriptRegexConstructor(pattern: string): RegExp {
return onigurumaToRegexp(
pattern
.replace(/\|\\G(\||\))/g, '$1')
.replace(/(\(|\|)\\G\|/g, '$1')
// YAML specific handling; TODO: move to tm-grammars
.replaceAll('[^\\s[-?:,\\[\\]{}#&*!|>\'"%@`]]', '[^\\s\\-?:,\\[\\]{}#&*!|>\'"%@`]'),
{
flags: 'dgm',
ignoreContiguousAnchors: true,
},
)
}

export class JavaScriptScanner implements PatternScanner {
regexps: (RegExp | null)[]

constructor(
public patterns: string[],
public cache: Map<string, RegExp | Error>,
public forgiving: boolean,
public regexConstructor: (pattern: string) => RegExp = defaultJavaScriptRegexConstructor,
) {
this.regexps = patterns.map((p) => {
const cached = cache?.get(p)
Expand All @@ -22,17 +40,7 @@ export class JavaScriptScanner implements PatternScanner {
throw cached
}
try {
const regex = onigurumaToRegexp(
p
.replace(/\|\\G(\||\))/g, '$1')
.replace(/(\(|\|)\\G\|/g, '$1')
// YAML specific handling; TODO: move to tm-grammars
.replaceAll('[^\\s[-?:,\\[\\]{}#&*!|>\'"%@`]]', '[^\\s\\-?:,\\[\\]{}#&*!|>\'"%@`]'),
{
flags: 'dgm',
ignoreContiguousAnchors: true,
},
)
const regex = regexConstructor(p)
cache?.set(p, regex)
return regex
}
Expand Down Expand Up @@ -126,7 +134,7 @@ export function createJavaScriptRegexEngine(options: JavaScriptRegexEngineOption

return {
createScanner(patterns: string[]) {
return new JavaScriptScanner(patterns, cache, forgiving)
return new JavaScriptScanner(patterns, cache, forgiving, options.regexConstructor)
},
createString(s: string) {
return {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export { createShikiInternal, getShikiInternal, setDefaultWasmLoader } from './c

// Engines
export { createWasmOnigEngine, loadWasm } from './engines/wasm'
export { createJavaScriptRegexEngine } from './engines/javascript'
export { createJavaScriptRegexEngine, defaultJavaScriptRegexConstructor } from './engines/javascript'

// TextMate Utilities
export { normalizeTheme } from './textmate/normalize-theme'
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/types/engines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,11 @@ export interface JavaScriptRegexEngineOptions {
* Cache for regex patterns.
*/
cache?: Map<string, RegExp | Error>

/**
* Custom pattern to RegExp constructor.
*
* By default `oniguruma-to-js` is used.
*/
regexConstructor?: (pattern: string) => RegExp
}

0 comments on commit 930dddc

Please sign in to comment.