const patternToPoints = pattern => {
let points = [];
pattern.split("").forEach(glyph => {
if (glyph.match(/[0-9]/)) {
points.pop();
points.push(+glyph);
} else {
points.push(0);
}
});
return points;
};
const mergeBreakpoints = (wordPoints, patternPoints, endIdx) => {
const startIdx = endIdx - patternPoints.length;
for (idx = 0; idx < patternPoints.length; idx++) {
wordPoints[startIdx + idx] = Math.max(
wordPoints[startIdx + idx],
patternPoints[idx]
);
}
};
const hyphenateWord = (word, patterns) => {
if (word.length < 5) {
return word;
}
let breakpoints = new Array(word.length).fill(0);
for (letter = 2; letter <= word.length; letter++) {
const fragment = word.slice(0, letter);
let matches = patterns.general.filter(pattern =>
fragment.match(pattern[0])
);
if (letter == word.length) {
matches.push(
...patterns.final.filter(pattern => fragment.match(pattern[0]))
);
}
for (const matchedPattern of matches) {
mergeBreakpoints(
breakpoints,
patternToPoints(matchedPattern[1]),
letter
);
}
}
breakpoints[0] = 0;
breakpoints[breakpoints.length - 1] = 0;
breakpoints[breakpoints.length - 2] = 0;
const breakpointIndices = breakpoints
.map((el, idx) => (el % 2 ? idx + 1 : 0))
.filter(el => el != 0);
let hyphenated = [];
for (idx = 0; idx <= breakpointIndices.length; idx++) {
if (idx == 0) {
hyphenated.push(word.slice(0, breakpointIndices[idx]));
} else if (idx == breakpointIndices.length) {
hyphenated.push(word.slice(breakpointIndices[idx - 1]));
} else {
hyphenated.push(
word.slice(breakpointIndices[idx - 1], breakpointIndices[idx])
);
}
}
return hyphenated.join("\u00AD");
};