UNPKG

@tanstack/highlight

Version:

Tiny class-based syntax highlighting for documentation.

63 lines (62 loc) • 2.31 kB
export function patternTokenizer(patterns) { return (code) => collectPatternRanges(code, patterns); } export function collectPatternRanges(code, patterns, initial = [], occupied = new Uint8Array(code.length), // Internal lexical passes can supply a fresh owned output array. ranges = [...initial]) { for (const range of initial) occupied.fill(1, range.start, range.end); for (const pattern of patterns) { if (typeof pattern === 'function') { for (const range of pattern(code)) addRange(ranges, occupied, range); continue; } const regex = globalRegex(pattern[0]); const className = pattern[1]; const group = pattern[2] || 0; const previousLastIndex = regex.lastIndex; regex.lastIndex = 0; try { let match; while ((match = regex.exec(code))) { const value = match[group]; if (!value) { if (!match[0]) regex.lastIndex++; continue; } const offset = group ? match[0].length - value.length : 0; const start = match.index + offset; addRange(ranges, occupied, { start, end: start + value.length, className: typeof className === 'function' ? className(match) : className, }); } } finally { regex.lastIndex = previousLastIndex; } } return ranges; } export function offsetRanges(ranges, offset) { return ranges.map((range) => ({ ...range, start: range.start + offset, end: range.end + offset })); } export function addRange(ranges, occupied, range) { if (range.start >= range.end || range.start < 0 || range.end > occupied.length || hasOverlap(occupied, range.start, range.end)) return false; ranges.push(range); occupied.fill(1, range.start, range.end); return true; } function globalRegex(regex) { return regex.global ? regex : new RegExp(regex.source, `${regex.flags}g`); } function hasOverlap(occupied, start, end) { for (let index = start; index < end; index++) if (occupied[index]) return true; return false; }