mind-elixir
Version:
Mind elixir is a free open source mind map core.
171 lines (170 loc) • 4.44 kB
JavaScript
const M = `- Root Node
- Child Node 1
- Child Node 1-1
- Child Node 1-2
- Child Node 1-3
- }:2 Summary of first two nodes
- Child Node 2
- Child Node 2-1 [^id1]
- Child Node 2-2 [^id2]
- Child Node 2-3 {color: #e87a90}
- > [^id1] <-Bidirectional Link-> [^id2]
- Child Node 3
- Child Node 3-1 [^id3]
- Child Node 3-2 [^id4]
- Child Node 3-3 [^id5]
- > [^id3] >-Unidirectional Link-> [^id4]
- > [^id3] <-Unidirectional Link-< [^id5]
- 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
- > [^id1] <-Link position is not restricted, as long as the id can be found during rendering-> [^id8]
`;
function L(i) {
const t = i.split(`
`).filter((e) => e.trim()), d = {
arrowLines: [],
summaryLines: [],
nodeIdMap: /* @__PURE__ */ new Map()
}, n = y(t, 0, -2, d);
if (!n.node)
throw new Error("Failed to parse plaintext: no root node found");
const s = d.arrowLines.map(({ content: e }) => C(e, d)).filter((e) => e !== null), o = d.summaryLines.map(({ content: e, parentChildren: r, parentId: a }) => N(e, r, a)).filter((e) => e !== null);
return {
nodeData: n.node,
arrows: s.length > 0 ? s : void 0,
summaries: o.length > 0 ? o : void 0
};
}
function y(i, t, d, n) {
if (t >= i.length)
return { node: null, nextIndex: t };
const s = i[t], o = I(s);
if (o <= d)
return { node: null, nextIndex: t };
const e = w(s);
if (e.type === "arrow" || e.type === "summary")
return { node: null, nextIndex: t + 1 };
const r = u(), a = {
topic: e.topic,
id: r
};
e.style && (a.style = e.style), e.refId && n.nodeIdMap.set(e.refId, r);
const c = [];
let l = t + 1;
for (; l < i.length; ) {
const m = i[l], p = I(m);
if (p <= o)
break;
if (p === o + 2) {
const f = w(m);
if (f.type === "arrow")
n.arrowLines.push({
content: f.content,
parentChildren: c
}), l++;
else if (f.type === "summary")
n.summaryLines.push({
content: f.content,
parentChildren: c,
parentId: r
// Pass parent node ID
}), l++;
else {
const h = y(i, l, o, n);
h.node && c.push(h.node), l = h.nextIndex;
}
} else
l++;
}
return c.length > 0 && (a.children = c), { node: a, nextIndex: l };
}
function I(i) {
const t = i.match(/^(\s*)/);
return t ? t[1].length : 0;
}
function w(i) {
const d = i.trim().replace(/^-\s*/, "");
if (d.startsWith(">"))
return {
type: "arrow",
topic: "",
content: d.substring(1).trim()
};
if (d.startsWith("}"))
return {
type: "summary",
topic: "",
content: d.substring(1).trim()
};
let n = d, s, o;
const e = n.match(/\[\^(\w+)\]/);
e && (s = e[1], n = n.replace(e[0], "").trim());
const r = n.match(/\{color:\s*(#[0-9a-fA-F]{6})\}/);
return r && (o = { color: r[1] }, n = n.replace(r[0], "").trim()), {
type: "node",
topic: n,
content: n,
refId: s,
style: o
};
}
function C(i, t) {
const d = i.match(/\[\^(\w+)\]\s*<-([^-]*)->\s*\[\^(\w+)\]/);
if (d) {
const o = d[1], e = d[2].trim(), r = d[3];
return {
id: u(),
label: e,
from: t.nodeIdMap.get(o) || o,
to: t.nodeIdMap.get(r) || r,
bidirectional: !0
};
}
const n = i.match(/\[\^(\w+)\]\s*>-([^-]*)->\s*\[\^(\w+)\]/);
if (n) {
const o = n[1], e = n[2].trim(), r = n[3];
return {
id: u(),
label: e,
from: t.nodeIdMap.get(o) || o,
to: t.nodeIdMap.get(r) || r
};
}
const s = i.match(/\[\^(\w+)\]\s*<-([^-]*)-<\s*\[\^(\w+)\]/);
if (s) {
const o = s[3], e = s[2].trim(), r = s[1];
return {
id: u(),
label: e,
from: t.nodeIdMap.get(o) || o,
to: t.nodeIdMap.get(r) || r
};
}
return null;
}
function N(i, t, d) {
const n = i.match(/^:(\d+)\s+(.*)/);
let s, o;
if (n ? (s = parseInt(n[1], 10), o = n[2]) : (s = t.length, o = i.trim()), t.length === 0 || s === 0)
return null;
const e = t.slice(-s), r = t.indexOf(e[0]), a = t.indexOf(e[e.length - 1]);
return {
id: u(),
label: o,
parent: d,
start: r,
end: a
};
}
let g = 0;
function u() {
return `node-${Date.now()}-${g++}`;
}
export {
M as plaintextExample,
L as plaintextToMindElixir
};