UNPKG

string-punctuation-tokenizer

Version:

Small library that provides functions to tokenize a string into an array of words with or without punctuation

117 lines (87 loc) 14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.selectionArray = exports.selectionsToRanges = exports.spliceStringOnRanges = void 0; var _occurrences = require("./occurrences"); /** * Splice string into array of ranges, flagging what is selected * @param {String} string - string. * @param {Array} ranges - array of ranges [[int,int],...] * @return {Array} - array of objects [obj,...] */ var spliceStringOnRanges = function spliceStringOnRanges(string, ranges) { var selectionArray = []; // response var remainingString = string; // shift the range since the loop is destructive by working on the remainingString and not original string var rangeShift = 0; // start the range shift at the first character ranges.forEach(function (range) { var firstCharacterPosition = range[0] - rangeShift; // original range start - the rangeShift var beforeSelection = remainingString.slice(0, firstCharacterPosition); // save all the text before the selection if (beforeSelection) { // only add to the array if string isn't empty selectionArray.push({ text: beforeSelection, selected: false }); } var shiftedRangeStart = range[0] - rangeShift; // range start - the rangeShift var shiftedRangeEnd = range[1] + 1 - rangeShift; // range end - rangeShift + 1 to include last character var selection = remainingString.slice(shiftedRangeStart, shiftedRangeEnd); // save the text in the selection var stringBeforeRange = string.slice(0, range[0]); var occurrence = (0, _occurrences.occurrencesInString)(stringBeforeRange, selection) + 1; var occurrences = (0, _occurrences.occurrencesInString)(string, selection); var selectionObject = { text: selection, selected: true, occurrence: occurrence, occurrences: occurrences }; selectionArray.push(selectionObject); // add the selection to the response array // next iteration is using remaining string var lastCharacterPosition = range[1] - rangeShift + 1; // original range end position - the rangeShift + 1 to not include the last range character in the remaining string remainingString = remainingString.slice(lastCharacterPosition); // update the remainingString to after the range // shift the range up to last char of substring (before+sub) rangeShift += beforeSelection.length; // adjust the rangeShift by the length prior to the selection rangeShift += selection.length; // adjust the rangeShift by the length of the selection itself }); if (remainingString) { // only add to the array if string isn't empty selectionArray.push({ text: remainingString, selected: false }); } return selectionArray; }; /** * Converts ranges to array of selection objects * @param {String} string - text used to get the ranges of * @param {Array} selections - array of selections [obj,...] * @return {Array} - array of range objects */ exports.spliceStringOnRanges = spliceStringOnRanges; var selectionsToRanges = function selectionsToRanges(string, selections) { var ranges = []; // response selections.forEach(function (selection) { if (string && string.includes(selection.text)) { // conditions to prevent errors var splitArray = string.split(selection.text); // split the string to get the text between occurrences var beforeSelection = splitArray.slice(0, selection.occurrence); beforeSelection = beforeSelection.join(selection.text); // get the text before the selection to handle multiple occurrences var start = beforeSelection.length; // the start position happens at the length of the string that comes before it var end = start + selection.text.length - 1; // the end position happens at the end of the selection text, but length doesn't account for 0 based position start var range = [start, end]; // new range ranges.push(range); // add the new range } }); return ranges; }; exports.selectionsToRanges = selectionsToRanges; var selectionArray = function selectionArray(string, selections) { var selectionArray = []; var ranges = selectionsToRanges(string, selections); selectionArray = spliceStringOnRanges(string, ranges); return selectionArray; }; exports.selectionArray = selectionArray; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9zZWxlY3Rpb25IZWxwZXJzLmpzIl0sIm5hbWVzIjpbInNwbGljZVN0cmluZ09uUmFuZ2VzIiwic3RyaW5nIiwicmFuZ2VzIiwic2VsZWN0aW9uQXJyYXkiLCJyZW1haW5pbmdTdHJpbmciLCJyYW5nZVNoaWZ0IiwiZm9yRWFjaCIsInJhbmdlIiwiZmlyc3RDaGFyYWN0ZXJQb3NpdGlvbiIsImJlZm9yZVNlbGVjdGlvbiIsInNsaWNlIiwicHVzaCIsInRleHQiLCJzZWxlY3RlZCIsInNoaWZ0ZWRSYW5nZVN0YXJ0Iiwic2hpZnRlZFJhbmdlRW5kIiwic2VsZWN0aW9uIiwic3RyaW5nQmVmb3JlUmFuZ2UiLCJvY2N1cnJlbmNlIiwib2NjdXJyZW5jZXMiLCJzZWxlY3Rpb25PYmplY3QiLCJsYXN0Q2hhcmFjdGVyUG9zaXRpb24iLCJsZW5ndGgiLCJzZWxlY3Rpb25zVG9SYW5nZXMiLCJzZWxlY3Rpb25zIiwiaW5jbHVkZXMiLCJzcGxpdEFycmF5Iiwic3BsaXQiLCJqb2luIiwic3RhcnQiLCJlbmQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7Ozs7O0FBTU8sSUFBTUEsb0JBQW9CLEdBQUcsU0FBdkJBLG9CQUF1QixDQUFDQyxNQUFELEVBQVNDLE1BQVQsRUFBb0I7QUFDdEQsTUFBSUMsY0FBYyxHQUFHLEVBQXJCLENBRHNELENBQzdCOztBQUN6QixNQUFJQyxlQUFlLEdBQUdILE1BQXRCLENBRnNELENBR3REOztBQUNBLE1BQUlJLFVBQVUsR0FBRyxDQUFqQixDQUpzRCxDQUlsQzs7QUFDcEJILEVBQUFBLE1BQU0sQ0FBQ0ksT0FBUCxDQUFlLFVBQVNDLEtBQVQsRUFBZ0I7QUFDN0IsUUFBTUMsc0JBQXNCLEdBQUdELEtBQUssQ0FBQyxDQUFELENBQUwsR0FBU0YsVUFBeEMsQ0FENkIsQ0FDdUI7O0FBQ3BELFFBQU1JLGVBQWUsR0FBR0wsZUFBZSxDQUFDTSxLQUFoQixDQUFzQixDQUF0QixFQUF5QkYsc0JBQXpCLENBQXhCLENB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R0FBRyxHQUFHRCxLQUFLLEdBQUdiLFNBQVMsQ0FBQ0osSUFBVixDQUFlVSxNQUF2QixHQUFnQyxDQUE1QyxDQUw2QyxDQUtFOztBQUMvQyxVQUFNZixLQUFLLEdBQUcsQ0FBQ3NCLEtBQUQsRUFBUUMsR0FBUixDQUFkLENBTjZDLENBTWpCOztBQUM1QjVCLE1BQUFBLE1BQU0sQ0FBQ1MsSUFBUCxDQUFZSixLQUFaLEVBUDZDLENBT3pCO0FBQ3JCO0FBQ0YsR0FWRDtBQVdGLFNBQU9MLE1BQVA7QUFDRCxDQWRNOzs7O0FBZ0JBLElBQU1DLGNBQWMsR0FBRyx3QkFBQ0YsTUFBRCxFQUFTdUIsVUFBVCxFQUF3QjtBQUNwRCxNQUFJckIsY0FBYyxHQUFHLEVBQXJCO0FBQ0EsTUFBSUQsTUFBTSxHQUFHcUIsa0JBQWtCLENBQUN0QixNQUFELEVBQVN1QixVQUFULENBQS9CO0FBQ0FyQixFQUFBQSxjQUFjLEdBQUdILG9CQUFvQixDQUFDQyxNQUFELEVBQVNDLE1BQVQsQ0FBckM7QUFDQSxTQUFPQyxjQUFQO0FBQ0QsQ0FMTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7b2NjdXJyZW5jZXNJblN0cmluZ30gZnJvbSAnLi9vY2N1cnJlbmNlcyc7XG4vKipcbiAqIFNwbGljZSBzdHJpbmcgaW50byBhcnJheSBvZiByYW5nZXMsIGZsYWdnaW5nIHdoYXQgaXMgc2VsZWN0ZWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgLSBzdHJpbmcuXG4gKiBAcGFyYW0ge0FycmF5fSByYW5nZXMgLSBhcnJheSBvZiByYW5nZXMgW1tpbnQsaW50XSwuLi5dXG4gKiBAcmV0dXJuIHtBcnJheX0gLSBhcnJheSBvZiBvYmplY3RzIFtvYmosLi4uXVxuICovXG5leHBvcnQgY29uc3Qgc3BsaWNlU3RyaW5nT25SYW5nZXMgPSAoc3RyaW5nLCByYW5nZXMpID0+IHtcbiAgbGV0IHNlbGVjdGlvbkFycmF5ID0gW107IC8vIHJlc3BvbnNlXG4gIGxldCByZW1haW5pbmdTdHJpbmcgPSBzdHJpbmc7XG4gIC8vIHNoaWZ0IHRoZSByYW5nZSBzaW5jZSB0aGUgbG9vcCBpcyBkZXN0cnVjdGl2ZSBieSB3b3JraW5nIG9uIHRoZSByZW1haW5pbmdTdHJpbmcgYW5kIG5vdCBvcmlnaW5hbCBzdHJpbmdcbiAgbGV0IHJhbmdlU2hpZnQgPSAwOyAvLyBzdGFydCB0aGUgcmFuZ2Ugc2hpZnQgYXQgdGhlIGZpcnN0IGNoYXJhY3RlclxuICByYW5nZXMuZm9yRWFjaChmdW5jdGlvbihyYW5nZSkge1xuICAgIGNvbnN0IGZpcnN0Q2hhcmFjdGVyUG9zaXRpb24gPSByYW5nZVswXS1yYW5nZVNoaWZ0OyAvLyBvcmlnaW5hbCByYW5nZSBzdGFydCAtIHRoZSByYW5nZVNoaWZ0XG4gICAgY29uc3QgYmVmb3JlU2VsZWN0aW9uID0gcmVtYWluaW5nU3RyaW5nLnNsaWNlKDAsIGZpcnN0Q2hhcmFjdGVyUG9zaXRpb24pOyAvLyBzYXZlIGFsbCB0aGUgdGV4dCBiZWZvcmUgdGhlIHNlbGVjdGlvblxuICAgIGlmIChiZWZvcmVTZWxlY3Rpb24pIHsgLy8gb25seSBhZGQgdG8gdGhlIGFycmF5IGlmIHN0cmluZyBpc24ndCBlbXB0eVxuICAgICAgc2VsZWN0aW9uQXJyYXkucHVzaCh7dGV4dDogYmVmb3JlU2VsZWN0aW9uLCBzZWxlY3RlZDogZmFsc2V9KTtcbiAgICB9XG4gICAgY29uc3Qgc2hpZnRlZFJhbmdlU3RhcnQgPSByYW5nZVswXS1yYW5nZVNoaWZ0OyAvLyByYW5nZSBzdGFydCAtIHRoZSByYW5nZVNoaWZ0XG4gICAgY29uc3Qgc2hpZnRlZFJhbmdlRW5kID0gcmFuZ2VbMV0rMS1yYW5nZVNoaWZ0OyAvLyByYW5nZSBlbmQgLSByYW5nZVNoaWZ0ICsgMSB0byBpbmNsdWRlIGxhc3QgY2hhcmFjdGVyXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gcmVtYWluaW5nU3RyaW5nLnNsaWNlKHNoaWZ0ZWRSYW5nZVN0YXJ0LCBzaGlmdGVkUmFuZ2VFbmQpOyAvLyBzYXZlIHRoZSB0ZXh0IGluIHRoZSBzZWxlY3Rpb25cbiAgICBjb25zdCBzdHJpbmdCZWZvcmVSYW5nZSA9IHN0cmluZy5zbGljZSgwLCByYW5nZVswXSk7XG4gICAgY29uc3Qgb2NjdXJyZW5jZSA9IG9jY3VycmVuY2VzSW5TdHJpbmcoc3RyaW5nQmVmb3JlUmFuZ2UsIHNlbGVjdGlvbikgKyAxO1xuICAgIGNvbnN0IG9jY3VycmVuY2VzID0gb2NjdXJyZW5jZXNJblN0cmluZyhzdHJpbmcsIHNlbGVjdGlvbik7XG4gICAgY29uc3Qgc2VsZWN0aW9uT2JqZWN0ID0ge1xuICAgICAgdGV4dDogc2VsZWN0aW9uLFxuICAgICAgc2VsZWN0ZWQ6IHRydWUsXG4gICAgICBvY2N1cnJlbmNlOiBvY2N1cnJlbmNlLFxuICAgICAgb2NjdXJyZW5jZXM6IG9jY3VycmVuY2VzLFxuICAgIH07XG4gICAgc2VsZWN0aW9uQXJyYXkucHVzaChzZWxlY3Rpb25PYmplY3QpOyAvLyBhZGQgdGhlIHNlbGVjdGlvbiB0byB0aGUgcmVzcG9uc2UgYXJyYXlcbiAgICAvLyBuZXh0IGl0ZXJhdGlvbiBpcyB1c2luZyByZW1haW5pbmcgc3RyaW5nXG4gICAgY29uc3QgbGFzdENoYXJhY3RlclBvc2l0aW9uID0gcmFuZ2VbMV0tcmFuZ2VTaGlmdCsxOyAvLyBvcmlnaW5hbCByYW5nZSBlbmQgcG9zaXRpb24gLSB0aGUgcmFuZ2VTaGlmdCArIDEgdG8gbm90IGluY2x1ZGUgdGhlIGxhc3QgcmFuZ2UgY2hhcmFjdGVyIGluIHRoZSByZW1haW5pbmcgc3RyaW5nXG4gICAgcmVtYWluaW5nU3RyaW5nID0gcmVtYWluaW5nU3RyaW5nLnNsaWNlKGxhc3RDaGFyYWN0ZXJQb3NpdGlvbik7IC8vIHVwZGF0ZSB0aGUgcmVtYWluaW5nU3RyaW5nIHRvIGFmdGVyIHRoZSByYW5nZVxuICAgIC8vIHNoaWZ0IHRoZSByYW5nZSB1cCB0byBsYXN0IGNoYXIgb2Ygc3Vic3RyaW5nIChiZWZvcmUrc3ViKVxuICAgIHJhbmdlU2hpZnQgKz0gYmVmb3JlU2VsZWN0aW9uLmxlbmd0aDsgLy8gYWRqdXN0IHRoZSByYW5nZVNoaWZ0IGJ5IHRoZSBsZW5ndGggcHJpb3IgdG8gdGhlIHNlbGVjdGlvblxuICAgIHJhbmdlU2hpZnQgKz0gc2VsZWN0aW9uLmxlbmd0aDsgLy8gYWRqdXN0IHRoZSByYW5nZVNoaWZ0IGJ5IHRoZSBsZW5ndGggb2YgdGhlIHNlbGVjdGlvbiBpdHNlbGZcbiAgfSk7XG4gIGlmIChyZW1haW5pbmdTdHJpbmcpIHsgLy8gb25seSBhZGQgdG8gdGhlIGFycmF5IGlmIHN0cmluZyBpc24ndCBlbXB0eVxuICAgIHNlbGVjdGlvbkFycmF5LnB1c2goe3RleHQ6IHJlbWFpbmluZ1N0cmluZywgc2VsZWN0ZWQ6IGZhbHNlfSk7XG4gIH1cbiAgcmV0dXJuIHNlbGVjdGlvbkFycmF5O1xufTtcbi8qKlxuICogQ29udmVydHMgcmFuZ2VzIHRvIGFycmF5IG9mIHNlbGVjdGlvbiBvYmplY3RzXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIC0gdGV4dCB1c2VkIHRvIGdldCB0aGUgcmFuZ2VzIG9mXG4gKiBAcGFyYW0ge0FycmF5fSBzZWxlY3Rpb25zIC0gYXJyYXkgb2Ygc2VsZWN0aW9ucyBbb2JqLC4uLl1cbiAqIEByZXR1cm4ge0FycmF5fSAtIGFycmF5IG9mIHJhbmdlIG9iamVjdHNcbiAqL1xuZXhwb3J0IGNvbnN0IHNlbGVjdGlvbnNUb1JhbmdlcyA9IChzdHJpbmcsIHNlbGVjdGlvbnMpID0+IHtcbiAgbGV0IHJhbmdlcyA9IFtdOyAvLyByZXNwb25zZVxuICAgIHNlbGVjdGlvbnMuZm9yRWFjaCggKHNlbGVjdGlvbikgPT4ge1xuICAgICAgaWYgKHN0cmluZyAmJiBzdHJpbmcuaW5jbHVkZXMoc2VsZWN0aW9uLnRleHQpKSB7IC8vIGNvbmRpdGlvbnMgdG8gcHJldmVudCBlcnJvcnNcbiAgICAgICAgY29uc3Qgc3BsaXRBcnJheSA9IHN0cmluZy5zcGxpdChzZWxlY3Rpb24udGV4dCk7IC8vIHNwbGl0IHRoZSBzdHJpbmcgdG8gZ2V0IHRoZSB0ZXh0IGJldHdlZW4gb2NjdXJyZW5jZXNcbiAgICAgICAgbGV0IGJlZm9yZVNlbGVjdGlvbiA9IHNwbGl0QXJyYXkuc2xpY2UoMCwgc2VsZWN0aW9uLm9jY3VycmVuY2UpO1xuICAgICAgICBiZWZvcmVTZWxlY3Rpb24gPSBiZWZvcmVTZWxlY3Rpb24uam9pbihzZWxlY3Rpb24udGV4dCk7IC8vIGdldCB0aGUgdGV4dCBiZWZvcmUgdGhlIHNlbGVjdGlvbiB0byBoYW5kbGUgbXVsdGlwbGUgb2NjdXJyZW5jZXNcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBiZWZvcmVTZWxlY3Rpb24ubGVuZ3RoOyAvLyB0aGUgc3RhcnQgcG9zaXRpb24gaGFwcGVucyBhdCB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdGhhdCBjb21lcyBiZWZvcmUgaXRcbiAgICAgICAgY29uc3QgZW5kID0gc3RhcnQgKyBzZWxlY3Rpb24udGV4dC5sZW5ndGggLSAxOyAvLyB0aGUgZW5kIHBvc2l0aW9uIGhhcHBlbnMgYXQgdGhlIGVuZCBvZiB0aGUgc2VsZWN0aW9uIHRleHQsIGJ1dCBsZW5ndGggZG9lc24ndCBhY2NvdW50IGZvciAwIGJhc2VkIHBvc2l0aW9uIHN0YXJ0XG4gICAgICAgIGNvbnN0IHJhbmdlID0gW3N0YXJ0LCBlbmRdOyAvLyBuZXcgcmFuZ2VcbiAgICAgICAgcmFuZ2VzLnB1c2gocmFuZ2UpOyAvLyBhZGQgdGhlIG5ldyByYW5nZVxuICAgICAgfVxuICAgIH0pO1xuICByZXR1cm4gcmFuZ2VzO1xufTtcblxuZXhwb3J0IGNvbnN0IHNlbGVjdGlvbkFycmF5ID0gKHN0cmluZywgc2VsZWN0aW9ucykgPT4ge1xuICBsZXQgc2VsZWN0aW9uQXJyYXkgPSBbXTtcbiAgbGV0IHJhbmdlcyA9IHNlbGVjdGlvbnNUb1JhbmdlcyhzdHJpbmcsIHNlbGVjdGlvbnMpO1xuICBzZWxlY3Rpb25BcnJheSA9IHNwbGljZVN0cmluZ09uUmFuZ2VzKHN0cmluZywgcmFuZ2VzKTtcbiAgcmV0dXJuIHNlbGVjdGlvbkFycmF5O1xufTtcbiJdfQ==