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
JavaScript
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==
;