Files
ai-coding-skills/skills/atlassian/opencode/scripts/src/adf.ts
T

93 lines
1.9 KiB
TypeScript

const TEXT_NODE = "text";
function textNode(text: string) {
return {
type: TEXT_NODE,
text,
};
}
function paragraphNode(lines: string[]) {
const content: Array<{ type: string; text?: string }> = [];
lines.forEach((line, index) => {
if (index > 0) {
content.push({ type: "hardBreak" });
}
if (line.length > 0) {
content.push(textNode(line));
}
});
return {
type: "paragraph",
...(content.length > 0 ? { content } : {}),
};
}
export function markdownToAdf(input: string) {
const lines = input.replace(/\r\n/g, "\n").split("\n");
const content: Array<Record<string, unknown>> = [];
let index = 0;
while (index < lines.length) {
const current = lines[index]?.trimEnd() ?? "";
if (current.trim().length === 0) {
index += 1;
continue;
}
const heading = current.match(/^(#{1,6})\s+(.*)$/);
if (heading) {
content.push({
type: "heading",
attrs: { level: heading[1].length },
content: [textNode(heading[2])],
});
index += 1;
continue;
}
if (/^[-*]\s+/.test(current)) {
const items: Array<Record<string, unknown>> = [];
while (index < lines.length && /^[-*]\s+/.test(lines[index] ?? "")) {
items.push({
type: "listItem",
content: [
{
type: "paragraph",
content: [textNode((lines[index] ?? "").replace(/^[-*]\s+/, ""))],
},
],
});
index += 1;
}
content.push({
type: "bulletList",
content: items,
});
continue;
}
const paragraphLines: string[] = [];
while (index < lines.length && (lines[index]?.trim().length ?? 0) > 0) {
paragraphLines.push(lines[index] ?? "");
index += 1;
}
content.push(paragraphNode(paragraphLines));
}
return {
type: "doc",
version: 1,
content,
};
}