UNPKG

@shikijs/engine-javascript

Version:

Engine for Shiki using JavaScript's native RegExp

76 lines (75 loc) 1.95 kB
//#region src/scanner.ts const MAX = 4294967295; var JavaScriptScanner = class { regexps; constructor(patterns, options = {}) { this.patterns = patterns; this.options = options; const { forgiving = false, cache, regexConstructor } = options; if (!regexConstructor) throw new Error("Option `regexConstructor` is not provided"); this.regexps = patterns.map((p) => { if (typeof p !== "string") return p; const cached = cache?.get(p); if (cached) { if (cached instanceof RegExp) return cached; if (forgiving) return null; throw cached; } try { const regex = regexConstructor(p); cache?.set(p, regex); return regex; } catch (e) { cache?.set(p, e); if (forgiving) return null; throw e; } }); } findNextMatchSync(string, startPosition, _options) { const str = typeof string === "string" ? string : string.content; const pending = []; function toResult(index, match, offset = 0) { return { index, captureIndices: match.indices.map((indice) => { if (indice == null) return { start: MAX, end: MAX, length: 0 }; return { start: indice[0] + offset, end: indice[1] + offset, length: indice[1] - indice[0] }; }) }; } for (let i = 0; i < this.regexps.length; i++) { const regexp = this.regexps[i]; if (!regexp) continue; try { regexp.lastIndex = startPosition; const match = regexp.exec(str); if (!match) continue; if (match.index === startPosition) return toResult(i, match, 0); pending.push([ i, match, 0 ]); } catch (e) { if (this.options.forgiving) continue; throw e; } } if (pending.length) { const minIndex = Math.min(...pending.map((m) => m[1].index)); for (const [i, match, offset] of pending) if (match.index === minIndex) return toResult(i, match, offset); } return null; } }; //#endregion export { JavaScriptScanner as t };