UNPKG

mind-elixir

Version:

Mind elixir is a free open source mind map core.

222 lines (221 loc) 6.99 kB
//#region src/utils/mindElixirToPlaintext.ts var e = class { node; children = []; slots; constructor(e) { this.node = e; let t = e.children?.length ?? 0; this.slots = Array.from({ length: t + 1 }, () => []); } }; function t(t) { let { nodeData: n, arrows: r = [], summaries: i = [] } = t, a = /* @__PURE__ */ new Map(); function o(t) { let n = new e(t); return a.set(t.id, n), t.children && (n.children = t.children.map(o)), n; } let s = o(n), c = [], l = /* @__PURE__ */ new Set(); for (let e of r) { l.add(e.from), l.add(e.to); let t = e.metadata, n = t?.parentId, r = t?.index ?? Infinity; if (!n) { c.push(e); continue; } let i = a.get(n); if (i) { let t = Math.min(r, i.children.length); i.slots[t].push({ type: "arrow", arrow: e }); } else c.push(e); } for (let e of i) { let t = a.get(e.parent); if (t) { let n = Math.min(e.end + 1, t.children.length); t.slots[n].push({ type: "summary", summary: e }); } } function u(e) { return a.get(e)?.node.metadata?.refId ?? e; } let d = []; function f(e, t) { let n = " ".repeat(t), r = " ".repeat(t + 1), i = e.node.metadata, a = [e.node.topic], o = i?.refId ?? (l.has(e.node.id) ? e.node.id : void 0); o && a.push(`[^${o}]`), e.node.style && Object.keys(e.node.style).length > 0 && a.push(JSON.stringify(e.node.style)), d.push(`${n}- ${a.join(" ")}`); for (let n = 0; n <= e.children.length; n++) { for (let t of e.slots[n]) if (t.type === "arrow") { let e = t.arrow, n = e.bidirectional ? `<-${e.label ?? ""}->` : `>-${e.label ?? ""}->`, i = e.delta1 ? ` (${e.delta1.x},${e.delta1.y})` : "", a = e.delta2 ? ` (${e.delta2.x},${e.delta2.y})` : ""; d.push(`${r}- > [^${u(e.from)}]${i} ${n}${a} [^${u(e.to)}]`); } else if (t.type === "summary") { let n = t.summary, i = n.end - n.start + 1, a = i === e.children.length ? "" : `:${i} `; d.push(`${r}- }${a}${n.label}`); } n < e.children.length && f(e.children[n], t + 1); } } f(s, 0); for (let e of c) { let t = e.bidirectional ? `<-${e.label ?? ""}->` : `>-${e.label ?? ""}->`, n = e.delta1 ? ` (${e.delta1.x},${e.delta1.y})` : "", r = e.delta2 ? ` (${e.delta2.x},${e.delta2.y})` : ""; d.push(`- > [^${u(e.from)}]${n} ${t}${r} [^${u(e.to)}]`); } return d.join("\n") + "\n"; } //#endregion //#region src/utils/index.ts function n() { return Date.now().toString(36) + Math.random().toString(36).substring(2, 8); } //#endregion //#region src/utils/plaintextToMindElixir.ts var r = "- Root Node\n - Child Node 1\n - Child Node 1-1 {\"color\": \"#e87a90\", \"fontSize\": \"18px\"}\n - Child Node 1-2\n - Child Node 1-3\n - }:2 Summary of first two nodes\n - Child Node 2\n - Child Node 2-1 [^node-2-1]\n - Child Node 2-2 [^id2]\n - Child Node 2-3\n - > [^node-2-1] <-Bidirectional Link-> [^id2]\n - Child Node 3\n - Child Node 3-1 [^id3]\n - Child Node 3-2 [^id4]\n - Child Node 3-3 [^id5] {\"fontFamily\": \"Arial\", \"fontWeight\": \"bold\"}\n - > [^id3] >-Unidirectional Link-> [^id4]\n - Child Node 4\n - Child Node 4-1 [^id6]\n - Child Node 4-2 [^id7]\n - Child Node 4-3 [^id8]\n - } Summary of all previous nodes\n - Child Node 4-4\n- > [^node-2-1] <-Link position is not restricted, as long as the id can be found during rendering-> [^id8]\n\n"; function i(e, t = "Root") { let r = e.split("\n").filter((e) => e.trim()); if (r.length === 0) throw Error("Failed to parse plaintext: no root node found"); let i = { arrowLines: [], nodeIdMap: /* @__PURE__ */ new Map() }, o = [], u = [], d = []; for (let e of r) { let t = a(e), r = s(e); for (; u.length > 0 && u[u.length - 1].indent >= t;) u.pop(); let c = u.length > 0 ? u[u.length - 1].node : null, f = c ? c.children ??= [] : d; if (r.type === "arrow") { i.arrowLines.push({ content: r.content, parentId: c?.id ?? null, index: f.length }); continue; } if (r.type === "summary") { let e = l(r.content, f, c?.id ?? ""); e && o.push(e); continue; } let p = n(), m = { topic: r.topic, id: p }; r.style && (m.style = r.style), r.refId && (i.nodeIdMap.set(r.refId, p), m.metadata = { refId: r.refId }), f.push(m), u.push({ indent: t, node: m }); } if (d.length === 0) throw Error("Failed to parse plaintext: no root node found"); let f; f = d.length === 1 ? d[0] : { topic: t, id: n(), children: d }; let p = i.arrowLines.map(({ content: e, parentId: t, index: n }) => { let r = c(e, i); return r && (r.metadata = { parentId: t, index: n }), r; }).filter((e) => e !== null); return { nodeData: f, arrows: p.length > 0 ? p : void 0, summaries: o.length > 0 ? o : void 0 }; } function a(e) { let t = e.match(/^(\s*)/); return t ? t[1].length : 0; } function o(e) { try { return JSON.parse(e); } catch { return console.warn(`[plaintext] Invalid node style (must be valid JSON), ignored: ${e}`), null; } } function s(e) { let t = e.trim().replace(/^-\s*/, ""); if (t.startsWith(">")) return { type: "arrow", topic: "", content: t.substring(1).trim() }; if (t.startsWith("}")) return { type: "summary", topic: "", content: t.substring(1).trim() }; let n = t, r, i, a = n.match(/\s*(\{[^}]+\})\s*$/); if (a) { let e = o(a[1]); e && (i = e, n = n.substring(0, n.length - a[0].length).trim()); } let s = n.match(/\s*\[\^([\w-]+)\]\s*$/); return s && (r = s[1], n = n.substring(0, n.length - s[0].length).trim()), { type: "node", topic: n, content: n, refId: r, style: i }; } function c(e, t) { let r = e.match(/\[\^([\w-]+)\](?:\s*\(([\d.-]+),([\d.-]+)\))?\s*<-([^-]*)->(?:\s*\(([\d.-]+),([\d.-]+)\))?\s*\[\^([\w-]+)\]/); if (r) { let e = r[1], i = r[2], a = r[3], o = r[4].trim(), s = r[5], c = r[6], l = r[7]; return { id: n(), label: o, from: t.nodeIdMap.get(e) || e, to: t.nodeIdMap.get(l) || l, delta1: i && a ? { x: Number(i), y: Number(a) } : void 0, delta2: s && c ? { x: Number(s), y: Number(c) } : void 0, bidirectional: !0 }; } let i = e.match(/\[\^([\w-]+)\](?:\s*\(([\d.-]+),([\d.-]+)\))?\s*>-([^-]*)->(?:\s*\(([\d.-]+),([\d.-]+)\))?\s*\[\^([\w-]+)\]/); if (i) { let e = i[1], r = i[2], a = i[3], o = i[4].trim(), s = i[5], c = i[6], l = i[7]; return { id: n(), label: o, from: t.nodeIdMap.get(e) || e, to: t.nodeIdMap.get(l) || l, delta1: r && a ? { x: Number(r), y: Number(a) } : void 0, delta2: s && c ? { x: Number(s), y: Number(c) } : void 0 }; } return null; } function l(e, t, r) { let i = e.match(/^:(\d+)\s+(.*)/), a, o; if (i ? (a = parseInt(i[1], 10), o = i[2]) : (a = t.length, o = e.trim()), t.length === 0 || a === 0) return null; let s = t.slice(-a), c = t.indexOf(s[0]), l = t.indexOf(s[s.length - 1]); return { id: n(), label: o, parent: r, start: c, end: l }; } //#endregion export { t as mindElixirToPlaintext, r as plaintextExample, i as plaintextToMindElixir };