oapix / public /chatclient /richText.js
woiceatus's picture
imrpove ui for chatclient
adb34c2
export function renderRichText(container, text) {
container.innerHTML = "";
const lines = String(text).replaceAll("\r\n", "\n").split("\n");
let list = null;
let codeLines = null;
let paragraph = [];
const flushParagraph = () => {
if (paragraph.length === 0) {
return;
}
const element = document.createElement("p");
element.innerHTML = formatInline(paragraph.join(" "));
container.appendChild(element);
paragraph = [];
};
const flushList = () => {
if (list) {
container.appendChild(list);
list = null;
}
};
const flushCode = () => {
if (!codeLines) {
return;
}
const pre = document.createElement("pre");
pre.textContent = codeLines.join("\n");
container.appendChild(pre);
codeLines = null;
};
for (const line of lines) {
if (line.startsWith("```")) {
flushParagraph();
flushList();
if (codeLines) {
flushCode();
} else {
codeLines = [];
}
continue;
}
if (codeLines) {
codeLines.push(line);
continue;
}
const listMatch = line.match(/^\s*[-*]\s+(.+)$/);
if (listMatch) {
flushParagraph();
if (!list) {
list = document.createElement("ul");
}
const item = document.createElement("li");
item.innerHTML = formatInline(listMatch[1]);
list.appendChild(item);
continue;
}
if (!line.trim()) {
flushParagraph();
flushList();
continue;
}
flushList();
paragraph.push(line.trim());
}
flushParagraph();
flushList();
flushCode();
}
export function escapeHtml(value) {
return String(value)
.replaceAll("&", "&")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");
}
function formatInline(value) {
return escapeHtml(value)
.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>")
.replace(/\*(.+?)\*/g, "<em>$1</em>")
.replace(/`(.+?)`/g, "<code>$1</code>");
}