import { transformText } from "./formatter"; function stripUnsupportedMarkdown(text: string): string { return text .replace(/!\[[^\]]*\]\([^)]+\)/g, "") .replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1 ($2)") .replace(/~~(.+?)~~/g, "$1") .replace(/`(.+?)`/g, "$1"); } function applyInlineMarkdown(text: string): string { return text.replace( /\*\*\*(.+?)\*\*\*|\*\*(.+?)\*\*|_(.+?)_/g, (_match: string, boldItalic: string | undefined, bold: string | undefined, italic: string | undefined) => { if (boldItalic !== undefined) return transformText(boldItalic, "bold-italic"); if (bold !== undefined) return transformText(bold, "bold"); return transformText(italic!, "italic"); } ); } export function markdownToLinkedIn(text: string): string { const processed = stripUnsupportedMarkdown(text); const lines = processed.split("\n"); const output: string[] = []; let pendingBlanks = 0; let skipNextBlanks = false; let inListContext = false; for (const line of lines) { if (line.trim() === "") { if (!skipNextBlanks) pendingBlanks++; continue; } skipNextBlanks = false; if (line.startsWith("# ")) { for (let i = 0; i < pendingBlanks; i++) output.push(""); pendingBlanks = 0; inListContext = false; const headingText = line.slice(2).toUpperCase(); output.push(transformText(applyInlineMarkdown(headingText), "bold") + " "); skipNextBlanks = true; continue; } if (line.startsWith("## ")) { for (let i = 0; i < pendingBlanks; i++) output.push(""); pendingBlanks = 0; inListContext = false; const headingText = line.slice(3); output.push(transformText(applyInlineMarkdown(headingText), "bold") + " "); skipNextBlanks = true; continue; } const hMatch = line.match(/^#{3,6}\s/); if (hMatch) { for (let i = 0; i < pendingBlanks; i++) output.push(""); pendingBlanks = 0; inListContext = false; const headingText = line.slice(hMatch[0].length); output.push(transformText(applyInlineMarkdown(headingText), "bold") + " "); skipNextBlanks = true; continue; } if (line.startsWith("> ")) { for (let i = 0; i < pendingBlanks; i++) output.push(""); pendingBlanks = 0; inListContext = false; output.push(transformText(applyInlineMarkdown(line.slice(2)), "italic")); continue; } if (line.startsWith("- ") || line.startsWith("* ")) { if (!inListContext) { for (let i = 0; i < pendingBlanks; i++) output.push(""); } pendingBlanks = 0; output.push("— " + applyInlineMarkdown(line.slice(2)) + " "); inListContext = true; continue; } const orderedMatch = line.match(/^(\d+)[.)]\s+(.+)/); if (orderedMatch) { if (!inListContext) { for (let i = 0; i < pendingBlanks; i++) output.push(""); } pendingBlanks = 0; const num = orderedMatch[1]!; const content = orderedMatch[2]!; output.push(`${num}/ ${applyInlineMarkdown(content)} `); inListContext = true; continue; } if (/^-{3,}$/.test(line.trim()) || /^\*{3,}$/.test(line.trim())) { for (let i = 0; i < pendingBlanks; i++) output.push(""); pendingBlanks = 0; inListContext = false; output.push(""); continue; } for (let i = 0; i < pendingBlanks; i++) output.push(""); pendingBlanks = 0; inListContext = false; output.push(applyInlineMarkdown(line)); } return output.join("\n").replace(/[ \u00A0]\./g, ".").trimEnd(); }