MindMap/others_deletable/ai-content-analyzer/markdownToJSON.ts

106 lines
3.3 KiB
TypeScript

// Type definitions - 与Django模型保持一致
interface NodeData {
id: string; // 对应Django的id字段
mindmap?: string; // 对应Django的mindmap外键
is_root: boolean; // 对应Django的is_root字段
parent_id?: string; // 对应Django的parent_id字段
children_count: number; // 对应Django的children_count字段
depth: number; // 对应Django的depth字段
title: string; // 对应Django的title字段
desc: string; // 对应Django的desc字段
created_at?: string; // 对应Django的created_at字段
updated_at?: string; // 对应Django的updated_at字段
deleted: boolean; // 对应Django的deleted字段
children: NodeData[]; // 前端渲染用的子节点数组
}
interface Node {
nodeData: NodeData;
linkData: any;
}
// Helper function to generate unique IDs
function generateId(): string {
return Math.random().toString(36).substr(2, 9);
}
function markdownToJSON(markdown: string): Node {
const lines = markdown.split("\n")
const root: Node = {
nodeData: {
id: "root",
title: lines[0].substring(2),
desc: "",
is_root: true,
parent_id: undefined,
children_count: 0,
depth: 0,
deleted: false,
children: [],
},
linkData: {},
}
let lastNodes: NodeData[] = [root.nodeData]
let listDepth = 0
for (let i = 1; i < lines.length; i++) {
const line = lines[i]
const trimmedLine = line.trim()
const leadingSpaces = line.length - line.trimStart().length
if (trimmedLine.startsWith("#")) {
listDepth = 0 // Reset list depth when encountering a header
let level = trimmedLine.split(" ")[0].length
let node: NodeData = {
id: generateId(),
title: trimmedLine.substring(level + 1).trim(),
desc: "",
is_root: false,
parent_id: lastNodes[lastNodes.length - 2]?.id || undefined,
children_count: 0,
depth: level,
deleted: false,
children: [],
}
while (lastNodes.length >= level) {
lastNodes.pop();
}
lastNodes.push(node);
lastNodes[lastNodes.length - 2].children.push(node);
lastNodes[lastNodes.length - 2].children_count = lastNodes[lastNodes.length - 2].children.length;
} else if (trimmedLine.startsWith("-")) {
const listItemLevel = Math.floor(leadingSpaces / 2) + 1 // 2 spaces per level
listDepth = listItemLevel
let node: NodeData = {
id: generateId(),
title: trimmedLine.substring(1).trim(),
desc: "",
is_root: false,
parent_id: lastNodes[lastNodes.length - 2]?.id || undefined,
children_count: 0,
depth: listItemLevel,
deleted: false,
children: [],
}
while (lastNodes.length >= listItemLevel + 1) {
lastNodes.pop();
}
lastNodes.push(node);
lastNodes[lastNodes.length - 2].children.push(node);
lastNodes[lastNodes.length - 2].children_count = lastNodes[lastNodes.length - 2].children.length;
} else if (trimmedLine.length !== 0) {
lastNodes[lastNodes.length - 1].desc += "\n" + trimmedLine
}
}
return root
}
// Export the function for use in other modules
export { markdownToJSON, Node, NodeData };