UNPKG

mind-elixir

Version:

Mind elixir is a free open source mind map core.

229 lines (227 loc) 6.58 kB
class x { node; children = []; // slots[i] represents elements that appear *before* children[i] // slots[children.length] represents elements that appear *after* all children slots; constructor(e) { this.node = e; const s = e.children?.length ?? 0; this.slots = Array.from({ length: s + 1 }, () => []); } } function j(a) { const { nodeData: e, arrows: s = [], summaries: n = [] } = a, o = /* @__PURE__ */ new Map(); function r(t) { const d = new x(t); return o.set(t.id, d), t.children && (d.children = t.children.map(r)), d; } const i = r(e), l = [], g = /* @__PURE__ */ new Set(); for (const t of s) { g.add(t.from), g.add(t.to); const d = t.metadata, u = d?.parentId, p = d?.index ?? 1 / 0; if (!u) { l.push(t); continue; } const w = o.get(u); if (w) { const y = Math.min(p, w.children.length); w.slots[y].push({ type: "arrow", arrow: t }); } else l.push(t); } for (const t of n) { const d = o.get(t.parent); if (d) { const u = Math.min(t.end + 1, d.children.length); d.slots[u].push({ type: "summary", summary: t }); } } function h(t) { return o.get(t)?.node.metadata?.refId ?? t; } const f = []; function c(t, d) { const u = " ".repeat(d), p = " ".repeat(d + 1), w = t.node.metadata, y = [t.node.topic], M = w?.refId ?? (g.has(t.node.id) ? t.node.id : void 0); M && y.push(`[^${M}]`), t.node.style && Object.keys(t.node.style).length > 0 && y.push(JSON.stringify(t.node.style)), f.push(`${u}- ${y.join(" ")}`); for (let I = 0; I <= t.children.length; I++) { for (const C of t.slots[I]) if (C.type === "arrow") { const m = C.arrow, $ = m.bidirectional ? `<-${m.label ?? ""}->` : `>-${m.label ?? ""}->`; f.push(`${p}- > [^${h(m.from)}] ${$} [^${h(m.to)}]`); } else if (C.type === "summary") { const m = C.summary, $ = m.end - m.start + 1, b = $ === t.children.length ? "" : `:${$} `; f.push(`${p}- }${b}${m.label}`); } I < t.children.length && c(t.children[I], d + 1); } } c(i, 0); for (const t of l) { const d = t.bidirectional ? `<-${t.label ?? ""}->` : `>-${t.label ?? ""}->`; f.push(`- > [^${h(t.from)}] ${d} [^${h(t.to)}]`); } return f.join(` `) + ` `; } function N() { return ((/* @__PURE__ */ new Date()).getTime().toString(16) + Math.random().toString(16).substring(2)).substring(2, 18); } const k = `- Root Node - Child Node 1 - Child Node 1-1 {"color": "#e87a90", "fontSize": "18px"} - Child Node 1-2 - Child Node 1-3 - }:2 Summary of first two nodes - Child Node 2 - Child Node 2-1 [^node-2-1] - Child Node 2-2 [^id2] - Child Node 2-3 - > [^node-2-1] <-Bidirectional Link-> [^id2] - Child Node 3 - Child Node 3-1 [^id3] - Child Node 3-2 [^id4] - Child Node 3-3 [^id5] {"fontFamily": "Arial", "fontWeight": "bold"} - > [^id3] >-Unidirectional Link-> [^id4] - Child Node 4 - Child Node 4-1 [^id6] - Child Node 4-2 [^id7] - Child Node 4-3 [^id8] - } Summary of all previous nodes - Child Node 4-4 - > [^node-2-1] <-Link position is not restricted, as long as the id can be found during rendering-> [^id8] `; function v(a, e = "Root") { const s = a.split(` `).filter((h) => h.trim()); if (s.length === 0) throw new Error("Failed to parse plaintext: no root node found"); const n = { arrowLines: [], nodeIdMap: /* @__PURE__ */ new Map() }, o = [], r = [], i = []; for (const h of s) { const f = S(h), c = T(h); for (; r.length > 0 && r[r.length - 1].indent >= f; ) r.pop(); const t = r.length > 0 ? r[r.length - 1].node : null, d = t ? t.children ??= [] : i; if (c.type === "arrow") { n.arrowLines.push({ content: c.content, parentId: t?.id ?? null, index: d.length }); continue; } if (c.type === "summary") { const w = O(c.content, d, t?.id ?? ""); w && o.push(w); continue; } const u = N(), p = { topic: c.topic, id: u }; c.style && (p.style = c.style), c.refId && (n.nodeIdMap.set(c.refId, u), p.metadata = { refId: c.refId }), d.push(p), r.push({ indent: f, node: p }); } if (i.length === 0) throw new Error("Failed to parse plaintext: no root node found"); let l; i.length === 1 ? l = i[0] : l = { topic: e, id: N(), children: i }; const g = n.arrowLines.map(({ content: h, parentId: f, index: c }) => { const t = R(h, n); return t && (t.metadata = { parentId: f, index: c }), t; }).filter((h) => h !== null); return { nodeData: l, arrows: g.length > 0 ? g : void 0, summaries: o.length > 0 ? o : void 0 }; } function S(a) { const e = a.match(/^(\s*)/); return e ? e[1].length : 0; } function L(a) { try { const e = a.trim().startsWith("{") ? a : `{${a}}`; return JSON.parse(e); } catch { return {}; } } function T(a) { const s = a.trim().replace(/^-\s*/, ""); if (s.startsWith(">")) return { type: "arrow", topic: "", content: s.substring(1).trim() }; if (s.startsWith("}")) return { type: "summary", topic: "", content: s.substring(1).trim() }; let n = s, o, r; const i = n.match(/\[\^([\w-]+)\]/); i && (o = i[1], n = n.replace(i[0], "").trim()); const l = n.match(/\{([^}]+)\}/); return l && (r = L(l[1]), n = n.replace(l[0], "").trim()), { type: "node", topic: n, content: n, refId: o, style: r }; } function R(a, e) { const s = a.match(/\[\^([\w-]+)\]\s*<-([^-]*)->\s*\[\^([\w-]+)\]/); if (s) { const o = s[1], r = s[2].trim(), i = s[3]; return { id: N(), label: r, from: e.nodeIdMap.get(o) || o, to: e.nodeIdMap.get(i) || i, bidirectional: !0 }; } const n = a.match(/\[\^([\w-]+)\]\s*>-([^-]*)->\s*\[\^([\w-]+)\]/); if (n) { const o = n[1], r = n[2].trim(), i = n[3]; return { id: N(), label: r, from: e.nodeIdMap.get(o) || o, to: e.nodeIdMap.get(i) || i }; } return null; } function O(a, e, s) { const n = a.match(/^:(\d+)\s+(.*)/); let o, r; if (n ? (o = parseInt(n[1], 10), r = n[2]) : (o = e.length, r = a.trim()), e.length === 0 || o === 0) return null; const i = e.slice(-o), l = e.indexOf(i[0]), g = e.indexOf(i[i.length - 1]); return { id: N(), label: r, parent: s, start: l, end: g }; } export { j as mindElixirToPlaintext, k as plaintextExample, v as plaintextToMindElixir };