display = (cfg) => {
let pNum = config(cfg, "numberParagraphs") ? 1 : 0;
let htmlStr = config(cfg, "paraTag") + (pNum > 0 ? `*${pNum}.* ` : ``);
let dictionary, phrases;
if (config(cfg, "produceDictionary")) {
dictionary = new Map();
phrases = new Set();
} else {
dictionary = undefined;
phrases = undefined;
}
let kpermutations;
let unhosted = [];
let unhostedSyls = [];
let hostIdx = 0;
let lastpNum = 0;
let tkObj = { idx: 0, guestToken: "To Begin" };
loop_through_guestTokens: for (let guestToken of config(cfg, "guest")) {
let pStr = "";
if (pNum == lastpNum) {
pStr = "";
} else {
lastpNum = pNum;
pStr = pNum + ". ";
}
console.log(pStr, `${guestToken}`);
if (!config(cfg, "useSubsequentHosts")) {
hostIdx = 0;
}
if (guestToken === `\n`) {
htmlStr += config(cfg, "paraTag") + (pNum > 0 ? `*${++pNum}.* ` : ``); // using * for <em> tags
continue loop_through_guestTokens;
}
// sharedCaps terms (shared proper names) are always 'found'
if (sharedCaps.has(guestToken)) {
tkObj = {};
tkObj.idx = searchFromExact(guestToken, hostTokens, hostIdx);
tkObj.guestToken = guestToken;
if (tkObj.idx > -1) {
// only bump hostIdx if we actually found the shared PN
tkObj.hostToken = hostTokens[tkObj.idx];
hostIdx = (tkObj.idx + 1) % hostTokens.length;
} else {
tkObj.hostToken = "[shared PN not in host]";
}
tkObj.displayStr =
`${config(cfg, "htagOpen")}` +
guestToken +
`${config(cfg, "htagClose")}`;
tkObj.caps = -1;
htmlStr += guestSpc(tkObj.displayStr);
report("shrdPN", [tkObj], dictionary);
continue loop_through_guestTokens;
} else tkObj = undefined;
// single letter tokens:
if (guestToken.length === 1 && config(cfg, "exactMatches")) {
let idx = searchFrom(guestToken, hostTokens, hostIdx, true);
if (idx > -1) {
tkObj = {};
tkObj.idx = idx;
tkObj.guestToken = guestToken;
tkObj.hostToken = hostTokens[tkObj.idx];
tkObj.displayStr =
`${config(cfg, "htagOpen")}` +
guestToken +
`${config(cfg, "htagClose")}`;
tkObj.caps = -1;
htmlStr += guestSpc(tkObj.displayStr);
report("oneLtr", [tkObj], dictionary);
hostIdx = (idx + 1) % hostTokens.length;
continue loop_through_guestTokens;
} else tkObj = undefined;
}
// uppercase treatment
let caps = -1;
if (/[A-ZÉ]/.test(guestToken)) {
if (guestToken === guestToken.toUpperCase() && guestToken.length > 1) {
// these are all caps guestTokens, flagged with caps = 99 and changed to lower case
caps = 99;
} else if (guestToken.length > 0) {
// if a guestToken is in sharedCaps and it's not empty:
if (guestToken[0] !== guestToken[0].toLowerCase()) {
// i.e. capitalized words, including "I", flagged with caps = 1 and toLowerCase()
caps = 0;
}
// French cases of "l’<oneCap>..."
if (
guestToken.length > 2 &&
guestToken[2] !== guestToken[2].toLowerCase()
) {
// capitalized after "l’"
caps = 2;
}
}
guestToken = guestToken.toLowerCase();
}
// end uppercase treatment
if (!config(cfg, "alwaysSplit") || guestToken.length < 2) {
// search hostTokens for first token containing all of the guestToken
tkObj = conTokenFor(guestToken, caps, hostIdx);
// tkObj will be undefined if not found
if (tkObj) {
htmlStr += guestSpc(tkObj.displayStr);
hostIdx = (tkObj.idx + 1) % hostTokens.length;
report("allFnd", [tkObj], dictionary);
continue loop_through_guestTokens;
}
} else tkObj = undefined;
// entire guestToken is not in any hostToken
// single-letter words should have been found
if (guestToken.length < 2) {
unhosted.push(guestToken);
console.log(`Single-letter token, ${guestToken} unfound at: ${hostIdx}`);
continue loop_through_guestTokens;
}
// try hyphenated tokens first
// capture caps parameter (which is -1 on first match)
let tempCaps = caps;
let partsArray = [];
let guestSyls = config(cfg, "sylls").hyphenate(guestToken);
// special cases
if (guestToken === "de rigueur") guestSyls = ["de", "ri", "gueur"];
if (guestToken === "à la") guestSyls = ["à", "la"];
if (guestToken === "in extremis") guestSyls = ["in", "ex", "trem", "is"];
if (guestToken === "en route") guestSyls = ["en", "route"];
if (config(cfg, "sylls") === hyphen) {
if (
guestSyls.filter((s) => s.includes("k") || s.includes("w")).length > 0
) {
// TODO ???
// console.log(pNum + ": " + guestSyls);
}
}
if (guestSyls.length > 1) {
let displayStr = "";
let foundAll = true;
// let oneCap = guestObj.oneCap;
for (let sylIdx = 0; sylIdx < guestSyls.length; sylIdx++) {
let guestToken = guestSyls[sylIdx];
tkObj = conTokenFor(guestToken, caps, hostIdx);
if (!tkObj) {
foundAll = false;
unhostedSyls.push(guestSyls[sylIdx]);
// capture caps parameter (which becomes -1 on first match)
caps = tempCaps;
partsArray = [];
} else {
partsArray.push(tkObj);
hostIdx = (tkObj.idx + 1) % hostTokens.length;
caps = tkObj.caps;
displayStr += tkObj.displayStr + " ";
}
}
if (foundAll) {
htmlStr += guestSpc(displayStr);
report("Hyph> ", partsArray, dictionary, phrases, tkObj.idx);
continue loop_through_guestTokens;
} else tkObj = undefined;
}
// new (better) code for generating any number of split subTokens
for (let k = 1; k < config(cfg, "maxKsplits") + 1; ++k) {
if (guestToken.length < k + 1) {
unhosted.push(guestToken);
continue loop_through_guestTokens;
}
// generates array of all for k splits from 1 to cfg.maxKsplits
kpermutations = permutedSplits(guestToken, k);
// console.log(pNum + ". kpermutations: " + kpermutations);
for (let idx = 0; idx < kpermutations.length; ++idx) {
guestSyls = kpermutations[idx].slice();
// checking that the slice yields two strings:
if (guestSyls.length > 1) {
let displayStr = "";
let foundAll = true;
partsArray = [];
// capture caps parameter (which becomes -1 on first match)
caps = tempCaps;
for (let sylIdx = 0; sylIdx < guestSyls.length; sylIdx++) {
let guestToken = guestSyls[sylIdx];
tkObj = conTokenFor(guestToken, caps, hostIdx);
if (!tkObj) {
foundAll = false;
caps = tempCaps;
partsArray = [];
} else {
partsArray.push(tkObj);
hostIdx = (tkObj.idx + 1) % hostTokens.length;
caps = tkObj.caps;
displayStr += tkObj.displayStr + " ";
}
} // end syls loop
if (foundAll) {
htmlStr += guestSpc(displayStr);
report("kPerm> ", partsArray, dictionary, phrases, tkObj.idx);
continue loop_through_guestTokens;
} else tkObj = undefined;
} // at least one syllable
} // end permutations loop
}
unhosted.push(guestToken);
}
// collecting guestToken's that have not been hosted
unhosted = new Set(unhosted);
unhostedSyls = new Set(unhostedSyls);
let sortedDictionary = undefined;
if (dictionary) {
sortedDictionary = new Map();
// sorting is based on the previous sorted liConcordance
for (const [key, value] of liConcordance) {
sortedDictionary.set(key, dictionary.get(key));
}
}
return { htmlStr, unhosted, unhostedSyls, sortedDictionary, phrases };
}