//Usage: node simplemind2plantuml.js > output.plantuml //Requires fast-xml-parser and he npm modules const xml = require('fast-xml-parser'); const he = require('he'); const fs = require('fs').promises; function componentToHex(c) { const hex = parseInt(c).toString(16); return hex.length == 1 ? "0" + hex : hex; } function rgbToHex(r, g, b) { return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); } function traverse(root, prefix = '*') { let flags = ''; if(root.style && root.style.fillcolor) { const {r,g,b} = root.style.fillcolor; flags += '['+rgbToHex(r,g,b)+']'; } let text = root.text.replace(/\\N/g, '\n'); if(text.includes('\n')) { text += ';'; flags += ':'; } console.log(prefix + flags, text); root.children.forEach(child => traverse(child, prefix+'*')); } fs.readFile(process.argv[2], 'utf-8').then(data => { const mmdata = xml.parse(data, { attributeNamePrefix: '', ignoreAttributes: false, attrValueProcessor: (val, attrName) => he.decode(val, {isAttributeValue: true}),//default is a=>a }); const mindmap = mmdata['simplemind-mindmaps'].mindmap.topics.topic; const lookup = new Map(); const root = mindmap.find(topic => topic.parent === '-1'); mindmap.forEach(topic => { topic.children = []; lookup.set(topic.id, topic); }); mindmap.forEach(topic => { if(topic.parent === '-1') return; lookup.get(topic.parent).children.push(topic); }); console.log('@startmindmap'); traverse(root); console.log('@endmindmap'); });