function esc(s: string): string { return s.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """); } export function renderMarkdown(text: string): string { if (!text) return ""; const codeBlocks: string[] = []; let h = text.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => { const i = codeBlocks.length; codeBlocks.push( `
${esc(code.trimEnd())}
` ); return `\x00CB${i}\x00`; }); h = esc(h); h = h.replace(/`([^`]+)`/g, '$1'); h = h.replace(/\*\*([^*]+)\*\*/g, "$1"); h = h.replace(/\*([^*]+)\*/g, "$1"); h = h.replace(/^### (.+)$/gm, '

$1

'); h = h.replace(/^## (.+)$/gm, '

$1

'); h = h.replace(/^# (.+)$/gm, '

$1

'); h = h.replace(/^[*-] (.+)$/gm, '
  • $1
  • '); h = h.replace(/^\d+\. (.+)$/gm, '
  • $1
  • '); h = h.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); h = h.replace(/\n\n/g, "

    "); h = h.replace(/\n/g, "
    "); h = h.replace(/\x00CB(\d+)\x00/g, (_, i) => codeBlocks[+i]); return "

    " + h + "

    "; }