Python3で、Freemind形式マインドマップを出力するテストソースを作ってみました。
- ソース
- _createAttr():属性の作成
- addAttribute():Nodeに属性を追加
- getDatetime():日時文字列の取得
- createNode():ノードの作成
- テストコメント以降
- 実際に作ってみて
- 実際に作ってみて
ソース
ソースはこんな感じ。
# coding: utf-8 import xml.dom.minidom as mdom import datetime import re # 属性値の作成 def _createAttr(key, val): attr = dom.createAttribute(key) attr.value = val return attr # Nodeに属性を追加 def addAttribute(attrInfo, node): assert type(attrInfo) != 'dict', 'arg is Not dict' for k, v in attrInfo.items(): assert type(k) != 'str', 'arg.v is Not str @' + k + ', ' + v assert type(v) != 'str', 'arg.v is Not str @' + k + ', ' + v attr = _createAttr(k, v) node.setAttributeNode(attr) # 日時文字列の取得 def getDatetime(): fmt0pd = ( lambda x, y: str(format(x, '0' + str(y) + 'd')) ) t = datetime.datetime.now() year = str(t.year) month = fmt0pd(t.month, 2) day = fmt0pd(t.day, 2) hour = fmt0pd(t.hour, 2) minute = fmt0pd(t.minute, 2) sec = fmt0pd(t.second, 2) ms = fmt0pd(t.microsecond, 6) return year + month + day + hour + minute + sec + ms # ノードの作成 def createNode(text, position=""): # CREATED, ID, MODIFIEDは自動 stIdx = ( lambda t, g: len(t) - g) dt = getDatetime() elm = dom.createElement('node') attr = { "CREATED" : dt[stIdx(dt, 13):len(dt)], "ID" : "ID_" + dt[stIdx(dt, 9):len(dt)], "MODIFIED" : dt[stIdx(dt, 13):len(dt)], "TEXT" : text } if len(position) > 0: attr["POSITION"] = position addAttribute(attr, elm) return elm ########### テスト マインドマップを作ってみる ########## dom = mdom.Document() xmlroot = dom.createElement("map") addAttribute({ "version" : "1.0.1" }, xmlroot) dom.appendChild(xmlroot) root = createNode("ルート") xmlroot.appendChild(root) elm1 = createNode("その1") root.appendChild(elm1) elm2 = createNode("その2") root.appendChild(elm2) # XMLの先頭タグが不要なので削除 mm = re.sub(r'<\?xml version="1.0" \?>\n', '', dom.toprettyxml()) print(mm) with open('test.mm', mode='w', encoding='utf-8') as f: f.write(mm)
PythonでのXML出力については、こちらの記事を参照してください!
関数や処理の詳細を書いていきます。
_createAttr():属性の作成
_createAttr()で、属性の作成を行っています。
属性とは、このようなXMLでいうところの
<tag attr="xxx" />
「attr="xxx"」に当たる箇所です。
この関数の引数に値を渡すことで、属性の設定用データを取得することができます。
ちなみにこの例での属性を取得する場合は、
_createAttr("attr", "xxx")
とコールすればOK!
addAttribute():Nodeに属性を追加
addAttribute()で、引数で渡したノードに、属性を付与することができます。
引数 attrInfoは、辞書型を設定します。
key, valの1セットを順に「_createAttr()」に渡します。
そして取得した属性データを、引数のノードにセットしていきます。
なので辞書型で設定する値を詰めておけば、まとめて属性値をセットすることができます!
getDatetime():日時文字列の取得
現在時刻を「yyyymmddHHMMSSMS」形式の文字列で取得します。
MSは、ミリ秒 6桁です。
桁数が足りない情報については、0パディング*1されます。
createNode():ノードの作成
引数で渡された文字列を表示するノードを作成します。
Freemindのノードを作るうえで最低限必要な要素である
- CREATED
- ID
- MODIFIED
- TEXT
を属性にセットしたノードを作成します。
CREATED, ID, MODIFIEDは、日時から切り出した値をセットしています。
Freemindから出力された結果を見ても、なんの値なのかわからなかったので……
本当はMindmap中でユニークな値とかを設定すべきだと思います……
ですが、とりあえず、ほぼ重複することが無いであろう値を暫定的にセットしています。
表示位置が指定されている場合は、positionも属性に設定します。
テストコメント以降
XML構成の作成
「dom」とか「xmlなんとか」と書かれている箇所は、作成した関数等を駆使して、XMLの構成を作成している箇所です。
ちなみに、このようなXMLを作成しています。
<map version="1.0.1"> <node CREATED="7134817444281" ID="ID_817444281" MODIFIED="7134817444281" TEXT="ルート"> <node CREATED="7134817444281" ID="ID_817444281" MODIFIED="7134817444281" TEXT="その1"/> <node CREATED="7134817445278" ID="ID_817445278" MODIFIED="7134817445278" TEXT="その2"/> </node> </map>
XMLの先頭タグの削除
次に行っているのが、正規表現によるタグの削除です。
xml.dom.minidomは、XMLを作成にめっちゃ便利です。
しかしFreemindを使用するにあたっては、1つ欠点があります。
それは毎回「<?xml ~ ?>」が先頭につくことです。
XMLとしては正解なのですが、「XML形式のナニカ」を作るには邪魔な場合があります。
まさしく、今。
ファイル出力
最後に行っているのが、ファイル出力です。
XMLの先頭タグを削除したものを「test.mm」という名前で保存しています。
実際に作ってみて
正直めっちゃ簡単でした。
思った以上に手軽に作れるな、と。
それもこれもXMLを作るために使用した「xml.dom.minidom」の功績がデカイですね!
今回のことを考えると、
- ある一定のマインドマップを作る
- mmファイルから表示するものを作る
- そもそもマインドマップアプリを作る
なんてことが、思ったより敷居が低いのかも?と思わせてくれます。
(そう感じた「だけ」かもしれない)
もう少しいろいろ遊んでみようと思います。```
XMLの先頭タグの削除
次に行っているのが、正規表現によるタグの削除です。
xml.dom.minidomは、XMLを作成にめっちゃ便利です。
しかしFreemindを使用するにあたっては、1つ欠点があります。
それは毎回「<?xml ~ ?>」が先頭につくことです。
XMLとしては正解なのですが、「XML形式のナニカ」を作るには邪魔な場合があります。
まさしく、今。
ファイル出力
最後に行っているのが、ファイル出力です。
XMLの先頭タグを削除したものを「test.mm」という名前で保存しています。
実際に作ってみて
正直めっちゃ簡単でした。
思った以上に手軽に作れるな、と。
それもこれもXMLを作るために使用した「xml.dom.minidom」の功績がデカイですね!
今回のことを考えると、
- ある一定のマインドマップを作る
- mmファイルから表示するものを作る
- そもそもマインドマップアプリを作る
なんてことが、思ったより敷居が低いのかも?と思わせてくれます。
(そう感じた「だけ」かもしれない)
もう少しいろいろ遊んでみようと思います。
*1:0を左に詰める