mm2nested_lists#

Dieses Notebook: Eine kleine Utility, die eine Freeplane-Mindmap in eine nested list überführt, und als JSON-Datei ‘rausschreibt.

Konventionen:

  • Ein Knoten, der keine Kindknoten hat, wird durch den Text des Knotens selbst repräsentiert

  • Ein Knoten, der Kindknoten hat, wird repräsentiert durch eine Liste,

    • die als erstes Element den Knotentext selbst aufweist

    • und deren weitere Listenelemente die Kindknoten sind.

Beispiel#

Aufbau der Mindmap: Die Mindmap test.mm hat die Root-Node mit dem Text test und die Kindknoten (mit dem Text) a, b und c. Knoten b hat selbst wieder die Kindknoten ba und bb:

  • test

    • a

    • b

      • ba

      • bb

    • c

Die Ergebnis-Liste soll etwa so aussehen:

['test', 'a', ['b', 'ba', 'bb'], 'c']

Code#

mm_path = "./test.mm"
# https://lxml.de/
from lxml import etree

# https://pypi.org/project/markdownify/
# pip install markdownify
from markdownify import markdownify
parser = etree.XMLParser(remove_blank_text=True)
etree_tree = etree.parse(mm_path, parser)
etree_startnode = etree_tree.getroot().find("node")
def walk(current):
    """Returns a nested list representation of a freeplane mindmap.
    rich content nodes are translated to markdown nodes."""
    
    
    # Liste aller "node"-Kinder des aktuellen Knotens
    # (andere XML-Elemente sind uninteressant)
    children = current.findall('node')
    
    
    if len(children) == 0:
        # der aktuelle Knoten hat keine Kinder:
        # einfach den Knotentext selbst zurückgeben
        
        # nachschauen: ist current ein rich content Knoten mit html text?
        rich_content = current.find('richcontent[@TYPE="NODE"]')
        if rich_content is not None:
            # html Knoteninhalt als Markdown zurückliefern
            return markdownify(etree.tostring(rich_content, encoding="utf8"), heading_style="ATX")
        else:
            # Knotentext ist Plaintext im Attribut @TEXT
            return current.get("TEXT")
    
    else:
        # der aktuelle Knoten *hat* Kinder:
        # Wir geben eine Liste zurück, deren erstes Element der aktuelle Knoten selbst ist:
        return_list = [ current.get("TEXT") ]
        
        # und die weiteren Kinder dieses Knotens seine Kinder:
        for child in children:
            return_list.append(walk(child))
            
        # wir geben den durch eine Liste repräsentierten Teilbaum zurück
        return return_list
mm_nested_list = walk(etree_startnode)
mm_nested_list
['test', 'a', ['b', 'ba', 'bb'], 'c']

JSON#

Wir schreiben das Ergebnis als JSON-Datei ‘raus:

import json
mm_json_object = json.dumps(mm_nested_list, indent=2)
with open(mm_path+'.json', 'w') as outfile:
    outfile.write(mm_json_object)

Ergebnis: Im gleichen Verzeichnis wie unsere Mindmap ./test.mm liegt jetzt die JSON-Datei test.mm.json.