2017-03-18 08:35:17 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const anyIntersection = require("./anyIntersection");
|
|
|
|
const fill = require("./fill");
|
|
|
|
|
2017-04-04 04:36:03 +00:00
|
|
|
// Merge text part information within a styling fragment
|
2017-03-18 08:35:17 +00:00
|
|
|
function assign(textPart, fragment) {
|
|
|
|
const fragStart = fragment.start;
|
|
|
|
const start = Math.max(fragment.start, textPart.start);
|
|
|
|
const end = Math.min(fragment.end, textPart.end);
|
|
|
|
|
2017-11-27 23:44:05 +00:00
|
|
|
return Object.assign({}, fragment, {
|
2017-03-18 08:35:17 +00:00
|
|
|
start: start,
|
|
|
|
end: end,
|
2017-11-15 06:35:15 +00:00
|
|
|
text: fragment.text.slice(start - fragStart, end - fragStart),
|
2017-03-18 08:35:17 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-04-04 04:36:03 +00:00
|
|
|
// Merge the style fragments withing the text parts, taking into account
|
|
|
|
// boundaries and text sections that have not matched to links or channels.
|
|
|
|
// For example, given a string "foobar" where "foo" and "bar" have been
|
|
|
|
// identified as parts (channels, links, etc.) and "fo", "ob" and "ar" have 3
|
|
|
|
// different styles, the first resulting part will contain fragments "fo" and
|
|
|
|
// "o", and the second resulting part will contain "b" and "ar". "o" and "b"
|
|
|
|
// fragments will contain duplicate styling attributes.
|
2017-03-18 08:35:17 +00:00
|
|
|
function merge(textParts, styleFragments) {
|
2017-04-04 04:36:03 +00:00
|
|
|
// Re-build the overall text (without control codes) from the style fragments
|
|
|
|
const cleanText = styleFragments.reduce((acc, frag) => acc + frag.text, "");
|
2017-03-18 08:35:17 +00:00
|
|
|
|
2017-04-04 04:36:03 +00:00
|
|
|
// Every section of the original text that has not been captured in a "part"
|
|
|
|
// is filled with "text" parts, dummy objects with start/end but no extra
|
|
|
|
// metadata.
|
2017-03-18 08:35:17 +00:00
|
|
|
const allParts = textParts
|
|
|
|
.concat(fill(textParts, cleanText))
|
|
|
|
.sort((a, b) => a.start - b.start);
|
|
|
|
|
2017-04-04 04:36:03 +00:00
|
|
|
// Distribute the style fragments within the text parts
|
2017-04-08 12:34:31 +00:00
|
|
|
return allParts.map((textPart) => {
|
2017-03-18 08:35:17 +00:00
|
|
|
textPart.fragments = styleFragments
|
2017-04-08 12:34:31 +00:00
|
|
|
.filter((fragment) => anyIntersection(textPart, fragment))
|
|
|
|
.map((fragment) => assign(textPart, fragment));
|
2017-03-18 08:35:17 +00:00
|
|
|
|
|
|
|
return textPart;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = merge;
|