106 lines
3.3 KiB
TypeScript
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 }; |