"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractRangeText = exports.excludeRanges = exports.findMatchingRangesForPatterns = exports.unionRanges = exports.findMatchingRanges = void 0; const GS = __importStar(require("gensequence")); const Text = __importStar(require("./text")); function findMatchingRanges(pattern, text) { if (pattern === '.*') { return [{ startPos: 0, endPos: text.length }]; } const ranges = []; try { const regex = pattern instanceof RegExp ? new RegExp(pattern) : Text.stringToRegExp(pattern, 'gim', 'g'); if (regex) { for (const found of GS.sequenceFromRegExpMatch(regex, text)) { ranges.push({ startPos: found.index, endPos: found.index + found[0].length, text: found[0] }); if (!regex.global) { break; } } } } catch (e) { // ignore any malformed regexp from the user. // console.log(e.message); } return ranges; } exports.findMatchingRanges = findMatchingRanges; function fnSortRanges(a, b) { return a.startPos - b.startPos || a.endPos - b.endPos; } function unionRanges(ranges) { const sortedRanges = ranges.sort(fnSortRanges); const result = sortedRanges.slice(1).reduce((acc, next) => { const last = acc[acc.length - 1]; if (next.startPos > last.endPos) { acc.push(next); } else if (next.endPos > last.endPos) { acc[acc.length - 1] = { startPos: last.startPos, endPos: Math.max(last.endPos, next.endPos), }; } return acc; }, sortedRanges.slice(0, 1)); return result; } exports.unionRanges = unionRanges; function findMatchingRangesForPatterns(patterns, text) { const matchedPatterns = GS.genSequence(patterns).concatMap((pattern) => findMatchingRanges(pattern, text)); return unionRanges(matchedPatterns.toArray()); } exports.findMatchingRangesForPatterns = findMatchingRangesForPatterns; /** * Exclude range b from a */ function excludeRange(a, b) { // non-intersection if (b.endPos <= a.startPos || b.startPos >= a.endPos) { return [a]; } // fully excluded if (b.startPos <= a.startPos && b.endPos >= a.endPos) { return []; } const result = []; if (a.startPos < b.startPos) { result.push({ startPos: a.startPos, endPos: b.startPos }); } if (a.endPos > b.endPos) { result.push({ startPos: b.endPos, endPos: a.endPos }); } return result; } /** * Create a new set of positions that have the excluded position ranges removed. */ function excludeRanges(includeRanges, excludeRanges) { const tInclude = 'i'; const tExclude = 'e'; const sortedRanges = [ ...includeRanges.map((r) => ({ ...r, type: tInclude })), ...excludeRanges.map((r) => ({ ...r, type: tExclude })), ].sort(fnSortRanges); const result = sortedRanges.reduce((acc, range) => { const { ranges, lastExclude } = acc; const lastInclude = ranges.length ? ranges[ranges.length - 1] : undefined; if (range.type === tExclude) { if (!lastInclude || lastInclude.endPos <= range.startPos) { // if the exclude is beyond the current include, save it for later return { ranges, lastExclude: range }; } // we need to split the current include. return { ranges: [...ranges.slice(0, -1), ...excludeRange(ranges[ranges.length - 1], range)], lastExclude: range, }; } // The range is an include, we need to check it against the last exclude if (!lastExclude) { return { ranges: ranges.concat([range]) }; } const nextExclude = lastExclude.endPos > range.endPos ? lastExclude : undefined; return { ranges: [...ranges, ...excludeRange(range, lastExclude)], lastExclude: nextExclude }; }, { ranges: [] }); return result.ranges; } exports.excludeRanges = excludeRanges; function extractRangeText(text, ranges) { return ranges.map(({ startPos, endPos }) => ({ startPos, endPos, text: text.slice(startPos, endPos), })); } exports.extractRangeText = extractRangeText; //# sourceMappingURL=TextRange.js.map