UNPKG

@pie-lib/text-select

Version:

Some react components for text selection

311 lines (267 loc) 8.41 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.words = exports.sort = exports.sentences = exports.paragraphs = exports.normalize = exports.intersection = exports.handleSentence = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _compact = _interopRequireDefault(require("lodash/compact")); var _parseEnglish = _interopRequireDefault(require("@pie-framework/parse-english")); var _clone = _interopRequireDefault(require("lodash/clone")); var g = function g(str, node) { if (node.children) { return node.children.reduce(g, str); } else if (node.value) { return str + node.value; } else { return str; } }; var getParagraph = function getParagraph(p) { return g('', p); }; var getSentence = function getSentence(s) { return g('', s); }; var getWord = function getWord(w) { return g('', w); }; var paragraphs = function paragraphs(text) { var tree = new _parseEnglish["default"]().parse(text); var out = tree.children.reduce(function (acc, child) { if (child.type === 'ParagraphNode') { var paragraph = { text: getParagraph(child), start: child.position.start.offset, end: child.position.end.offset }; return acc.concat([paragraph]); } else { return acc; } }, []); return out; }; exports.paragraphs = paragraphs; var handleSentence = function handleSentence(child, acc) { var sentenceChilds = []; // we parse the children of the sentence var newAcc = child.children.reduce(function (acc, child) { // if we find a whitespace node that's \n, we end the sentence if (child.type === 'WhiteSpaceNode' && child.value === '\n') { if (sentenceChilds.length) { var firstWord = sentenceChilds[0]; // we create a sentence starting from the first word until the new line var sentence = { text: sentenceChilds.map(function (d) { return getSentence(d); }).join(''), start: firstWord.position.start.offset, end: child.position.start.offset }; // we remove all the elements from the array sentenceChilds.splice(0, sentenceChilds.length); return acc.concat([sentence]); } } else { // otherwise we add it to the array that contains the child forming a sentence sentenceChilds.push(child); } return acc; }, acc); // we treat the case when no \n character is found at the end // so we create a sentence from the last words or white spaces found if (sentenceChilds.length) { var firstWord = sentenceChilds[0]; var lastWord = sentenceChilds[sentenceChilds.length - 1]; var sentence = { text: sentenceChilds.map(function (d) { return getSentence(d); }).join(''), start: firstWord.position.start.offset, end: lastWord.position.end.offset }; newAcc = newAcc.concat([sentence]); sentenceChilds.splice(0, sentenceChilds.length); } return newAcc; }; exports.handleSentence = handleSentence; var sentences = function sentences(text) { var tree = new _parseEnglish["default"]().parse(text); var out = tree.children.reduce(function (acc, child) { if (child.type === 'ParagraphNode') { return child.children.reduce(function (acc, child) { if (child.type === 'SentenceNode') { var newAcc = handleSentence(child, acc); return newAcc || acc; } else { return acc; } }, acc); } else { return acc; } }, []); return out; }; exports.sentences = sentences; var words = function words(text) { var tree = new _parseEnglish["default"]().parse(text); var out = tree.children.reduce(function (acc, child) { if (child.type === 'ParagraphNode') { return child.children.reduce(function (acc, child) { if (child.type === 'SentenceNode') { return child.children.reduce(function (acc, child) { if (child.type === 'WordNode') { var node = { text: getWord(child), start: child.position.start.offset, end: child.position.end.offset }; return acc.concat([node]); } else { return acc; } }, acc); } else { return acc; } }, acc); } else { return acc; } }, []); return out; }; exports.words = words; var Intersection = /*#__PURE__*/function () { function Intersection(results) { (0, _classCallCheck2["default"])(this, Intersection); this.results = results; } (0, _createClass2["default"])(Intersection, [{ key: "hasOverlap", get: function get() { return this.results.filter(function (r) { return r.type === 'overlap'; }).length > 0; } }, { key: "surroundedTokens", get: function get() { return this.results.filter(function (r) { return r.type === 'within-selection'; }).map(function (t) { return t.token; }); } }]); return Intersection; }(); /** * get intersection info for the selection in relation to tokens. * @param {{start: number, end: number}} selection * @param {{start: number, end: number}[]} tokens * @return {tokens: [], type: 'overlap|no-overlap|contains'} */ var intersection = function intersection(selection, tokens) { var start = selection.start, end = selection.end; var startsWithin = function startsWithin(t) { return start >= t.start && start < t.end; }; var endsWithin = function endsWithin(t) { return end > t.start && end <= t.end; }; var mapped = tokens.map(function (t) { if (start === t.start && end === t.end) { return { token: t, type: 'exact-fit' }; } else if (start <= t.start && end >= t.end) { return { token: t, type: 'within-selection' }; } else if (startsWithin(t) || endsWithin(t)) { return { token: t, type: 'overlap' }; } }); return new Intersection((0, _compact["default"])(mapped)); }; exports.intersection = intersection; var sort = function sort(tokens) { if (!Array.isArray(tokens)) { return tokens; } else { var out = (0, _clone["default"])(tokens); out.sort(function (a, b) { var s = a.start < b.start ? -1 : a.start > b.start ? 1 : 0; var e = a.end < b.end ? -1 : a.end > b.end ? 1 : 0; if (s === -1 && e !== -1) { throw new Error("sort does not support intersecting tokens. a: ".concat(a.start, "-").concat(a.end, ", b: ").concat(b.start, "-").concat(b.end)); } return s; }); return out; } }; exports.sort = sort; var normalize = function normalize(textToNormalize, tokens) { // making sure text provided is a string var text = textToNormalize || ''; if (!Array.isArray(tokens) || tokens.length === 0) { return [{ text: text, start: 0, end: text.length }]; } var out = sort(tokens).reduce(function (acc, t, index, outer) { var tokens = []; var lastIndex = acc.lastIndex; if (t.start === lastIndex) { tokens = [{ text: text.substring(lastIndex, t.end), start: lastIndex, end: t.end, predefined: true, correct: t.correct, isMissing: t.isMissing }]; } else if (lastIndex < t.start) { tokens = [{ text: text.substring(lastIndex, t.start), start: lastIndex, end: t.start }, { text: text.substring(t.start, t.end), start: t.start, end: t.end, predefined: true, correct: t.correct, isMissing: t.isMissing }]; } if (index === outer.length - 1 && t.end < text.length) { var last = { text: text.substring(t.end), start: t.end, end: text.length }; tokens.push(last); } return { lastIndex: tokens.length ? tokens[tokens.length - 1].end : lastIndex, result: acc.result.concat(tokens) }; }, { result: [], lastIndex: 0 }); return out.result; }; exports.normalize = normalize; //# sourceMappingURL=builder.js.map