You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
5.1 KiB
137 lines
5.1 KiB
"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
|