export const fmtDate = (date) => new Date(date).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" }); export const toISODate = (d) => new Date(d).toISOString().split("T")[0]; export const escapeHtml = (s = "") => s.replace(/[&<>"']/g, (ch) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[ch])); export const escapeXml = (s = "") => s.replace(/[<>&'"]/g, (ch) => ({ "<": "<", ">": ">", "&": "&", "'": "'", '"': """ }[ch])); export const fixInternalLinks = (html) => html .replace(/href="\.\//g, 'href="/') .replace(/href="([^"]+)"(?=[^>]*>)/g, (_, href) => href.startsWith("http") || href.startsWith("#") || href.endsWith("/") || href.endsWith(".md") ? `href="${href}"` : `href="${href}/"` ); export const renderAuthorInline = (author = "Apophenia") => { const src = String(author || "Apophenia"); const re = /\[([^\]]+)\]\(([^)]+)\)/g; let out = ""; let last = 0; let match; while ((match = re.exec(src))) { out += escapeHtml(src.slice(last, match.index)); const text = escapeHtml(match[1].trim()); const href = match[2].trim(); const safeHref = /^(https?:\/\/|\/)/.test(href) ? href : "#"; const normalized = safeHref === "#" || safeHref.endsWith("/") || safeHref.startsWith("http") ? safeHref : `${safeHref}/`; out += `${text}`; last = re.lastIndex; } out += escapeHtml(src.slice(last)); return out; };