File size: 1,968 Bytes
adb34c2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 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("<", "<")
.replaceAll(">", ">");
}
function formatInline(value) {
return escapeHtml(value)
.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>")
.replace(/\*(.+?)\*/g, "<em>$1</em>")
.replace(/`(.+?)`/g, "<code>$1</code>");
}
|