/** * Lightweight text formatter supporting: * - **bold** → * - *italic* → * - [text](url) → * - Auto-linking bare URLs * - Paragraphs (double newline) * * No full markdown parser needed. HTML in input is escaped for security. */ function escapeHtml(str: string): string { return str .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """); } function formatInline(text: string): string { return ( text // [text](url) .replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g, '$1') // **bold** .replace(/\*\*(.+?)\*\*/g, "$1") // *italic* (but not inside URLs/tags) .replace(/(?$1") // bare URLs (not already in href) .replace(/(?)(https?:\/\/[^\s<]+)/g, '$1') ); } export function paragraphSplit(text: string | null | undefined): string { if (text == null) return ""; const escaped = escapeHtml(text); const paragraphs = escaped.split(/\n\n+/).filter((p) => p.trim()); if (paragraphs.length <= 1) { return `

${formatInline(escaped.trim())}

`; } return paragraphs.map((p) => `

${formatInline(p.trim())}

`).join("\n"); }