116 lines
4.0 KiB
TypeScript
116 lines
4.0 KiB
TypeScript
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();
|
|
}
|