type MarkdownExportFileNameInput = { slug: string; id: number; }; function isAbsoluteOrSpecialUrl(url: string): boolean { return /^(https?:)?\/\//i.test(url) || /^data:/i.test(url); } export function normalizeMarkdownImageUrls(markdown: string, origin: string): string { const normalizedOrigin = origin.replace(/\/+$/, ""); return markdown.replace(/!\[([^\]]*)\]\(([^)\s]+)([^)]*)\)/g, (full, alt, rawUrl, rest) => { if (isAbsoluteOrSpecialUrl(rawUrl)) { return full; } if (!rawUrl.startsWith("/")) { return full; } return `![${alt}](${normalizedOrigin}${rawUrl}${rest})`; }); } export function buildMarkdownExportFileName(input: MarkdownExportFileNameInput): string { const base = input.slug.trim() || `post-${input.id}`; return `${base}.md`; } export function downloadMarkdownFile(filename: string, content: string): void { if (typeof window === "undefined" || typeof document === "undefined") { return; } const blob = new Blob([content], { type: "text/markdown;charset=utf-8" }); const url = URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = filename; anchor.style.display = "none"; document.body.appendChild(anchor); anchor.click(); anchor.remove(); URL.revokeObjectURL(url); }