[新活]有道云笔记脑图转Xmind脚本

发布于 2020-04-18  2054 次阅读


GitHub传送门

想法

之前用有道云笔记做了一些脑图,后面发现导出图片和居然要会员,就感觉很不爽。但是这些脑图有点多,感觉很不甘心,于是就花了一点时间写了这个脚本~~(想整活是主要的,不想充会员是次要的(滑稽))

效果

环境

Xmind使用环境:测试使用的是Xmind 2020(Xmind Zen 10.1.2),没有在其他环境内测试过

Python版本为Python 3

原理简述

有道云笔记

有道云的功能相对Xmind来说比较单一。有道云的.mindmap 文件实际上是一个json格式的文件,里面的nodes列表就是节点列表,里面主要存储的内容有:

  • 节点ID(实际上是一个Hash)
  • 节点内容
  • 节点样式(字体等)
  • 父节点ID(parentid)

Xmind

.xmind文件实际上是一个压缩文件,解压后的content.json就是主要记录节点内容的文件,里面有一个固定的框架结构,节点的内容以递归的形式存储在rootTopic下

转换方法

有道云笔记的节点存储形式实际上是一个单向联通图,通过遍历所有节点的方式将其转换为强联通图,最后从根节点开始递归遍历并记录节点,最后写入Xmind文件

使用方法

将有道云中的脑图文件右键另存为input.mindmap到mind.py的同级目录下,运行Python脚本,转换的XMind文件在Output文件夹内(Out.xmind)

源码(PyCharm里不知道为啥打中文注释会编译失败于是就写了英文)(完整使用还需要Template文件夹,请移步Github下载)

import json
import collections
import os
import shutil
import zipfile
#Find the node id in .mindmap file, due to the node in the .mindmap file is unidirectional
def findid(id):
    for node in ydjson["nodes"]:
        if (node["id"]==id):
            return node
    return 0
#Recursively build a node tree
def xmind(ydstruct,xstruct):
    if(ydstruct["id"]!="root"):
        if(not ydstruct["child"]):
            temp = {"id":ydstruct["id"],"title":ydstruct["topic"]}
            xstruct.append(temp)
        else:
            temp = {"id":ydstruct["id"],"title":ydstruct["topic"],"children":{"attached":[]}}
            temp1 = temp["children"]["attached"]
            for children in ydstruct["child"]:
                xmind(findid(children),temp1)
            xstruct.append(temp)
    else:
        temp1 = xstruct["children"]["attached"]
        for children in ydstruct["child"]:
            xmind(findid(children),temp1)
#Transfer the .mindmap file into a dict
with open ('input.mindmap','r', encoding='UTF-8') as ydMind:
    ydcontent = ydMind.read()
#Load the "content.json" in Xmind file, which includes basic config and style in xmind file
with open ('Templates\XmindJsonTemplate.json','r') as xmindtem:
    xmindjson = xmindtem.read()
ydjson = json.loads(ydcontent)
#Xmind is the final "content.json" file's dict pattern
Xmind = json.loads(xmindjson, object_pairs_hook=collections.OrderedDict)
for node in ydjson["nodes"]:
    node["child"] = []
for node in ydjson["nodes"]:
    if(node["id"]!="root"):
        parentid = node ["parentid"]
        parent = findid(parentid)
        parent["child"].append(node["id"])
root = findid("root")
#configure the Xmind file
rootid = root["id"]
rootTopic = Xmind["rootTopic"]
rootTopic["id"] = root["id"]
rootTopic["title"] = root["topic"]
xmind(findid("root"),rootTopic)
output = []
output.append(Xmind)
#Write the json file includes node data into .xmind file
if(os.path.exists('Output')):
    shutil.rmtree('Output')
os.mkdir('Output')
shutil.copyfile("Templates\Mind.xmind","Output\Out.xmind")
with open('Output\content.json','w') as Output:
    Output.write(json.dumps(output))
with zipfile.ZipFile('Output\Out.xmind','a') as tar:
    tar.write('Output\content.json','content.json')

等风来,不如追风去。