mirror of
https://github.com/paperclipai/paperclip
synced 2026-03-25 11:21:48 +00:00
48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
const FENCE_RE = /^\s*(`{3,}|~{3,})/;
|
|
const SPACE_ENTITY_RE = / /gi;
|
|
const ESCAPED_UNORDERED_LIST_RE = /^(\s{0,3})\\([*+-])([ \t]+)/;
|
|
|
|
/**
|
|
* Normalize markdown artifacts emitted by rich-text serialization so
|
|
* plain markdown list syntax remains usable in Paperclip editors.
|
|
*/
|
|
export function normalizeMarkdownArtifacts(markdown: string): string {
|
|
if (!markdown) return markdown;
|
|
|
|
const lines = markdown.split(/\r?\n/);
|
|
let inFence = false;
|
|
let fenceMarker: "`" | "~" | null = null;
|
|
let fenceLength = 0;
|
|
let changed = false;
|
|
|
|
const normalized = lines.map((line) => {
|
|
const fenceMatch = FENCE_RE.exec(line);
|
|
if (fenceMatch) {
|
|
const marker = fenceMatch[1];
|
|
if (!inFence) {
|
|
inFence = true;
|
|
fenceMarker = marker[0] as "`" | "~";
|
|
fenceLength = marker.length;
|
|
} else if (marker[0] === fenceMarker && marker.length >= fenceLength) {
|
|
inFence = false;
|
|
fenceMarker = null;
|
|
fenceLength = 0;
|
|
}
|
|
return line;
|
|
}
|
|
|
|
if (inFence) return line;
|
|
|
|
let next = line;
|
|
if (next.includes(" ")) {
|
|
next = next.replace(SPACE_ENTITY_RE, " ");
|
|
}
|
|
const unescaped = next.replace(ESCAPED_UNORDERED_LIST_RE, "$1$2$3");
|
|
if (unescaped !== line) changed = true;
|
|
return unescaped;
|
|
});
|
|
|
|
if (!changed) return markdown;
|
|
return normalized.join("\n");
|
|
}
|