@pie-lib/text-select
Version:
Some react components for text selection
311 lines (267 loc) • 8.41 kB
JavaScript
;
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