1
0
Fork 0
tsgames/src/games/storywriter/utils/highlight.ts

63 lines
2.3 KiB
TypeScript

export const highlight = (message: string, keepMarkup = true): string => {
let resultHTML = '';
const replaceRegex = /(\*\*?|"|```|`)/ig;
const splitToken = '___SPLIT_AWOORWA___';
const preparedMessage = message.replace(replaceRegex, `${splitToken}$1${splitToken}`);
const parts = preparedMessage.split(splitToken);
const stack: string[] = [];
let inCodeBlock = false;
for (const part of parts) {
const isClose = stack.at(-1) === part;
const keepPart = keepMarkup || part === '"';
if (inCodeBlock) {
if (part === '```' && isClose) {
inCodeBlock = false;
stack.pop();
resultHTML += `${keepPart ? part : ''}</span>`;
} else {
resultHTML += part;
}
continue;
}
if (isClose) {
stack.pop();
if (part === '*' || part === '**' || part === '"' || part === '`' || part === '```') {
resultHTML += `${keepPart ? part : ''}</span>`;
}
} else {
if (part === '*') {
stack.push(part);
resultHTML += `<span style="font-style:italic;color:var(--italicColor)">${keepPart ? part : ''}`;
} else if (part === '**') {
stack.push(part);
resultHTML += `<span style="font-weight:bold">${keepPart ? part : ''}`;
} else if (part === '"') {
stack.push(part);
resultHTML += `<span style="color:var(--quoteColor)">"`;
} else if (part === '```') {
stack.push(part);
inCodeBlock = true;
resultHTML += `<span style="font-family:monospace;background:var(--codeBg);padding:0.5em;display:block;border-radius:var(--radius)">`;
} else if (part === '`') {
stack.push(part);
resultHTML += `<span style="font-family:monospace;background:var(--codeBg);padding:0.1em 0.3em;border-radius:0.2em">`;
} else {
resultHTML += part;
}
}
}
while (stack.length) {
const part = stack.pop();
if (part === '*' || part === '**' || part === '"' || part === '`' || part === '```') {
resultHTML += `</span>`;
}
}
return resultHTML;
}