PyQtをUbuntuにインストールしマインドマップをHTMLやWikiに変換するツールをつくる

PyQtが面白くなってきたので、Ubuntuにもインストールする

インストール

PyQtを探す

  1. $ apt-cache search pyqt4
  2. python-pyudev - Python bindings for libudevpython-qt4 - Python bindings for Qt4
  3. python-qt4-dbg - Python bindings for Qt4 (debug extensions)python-qt4-dbus - D-Bus Support for PyQt4
  4. python-qt4-dbus-dbg - D-Bus Support for PyQt4 (debug extensions)
  5. :

インストール

  1. $ sudo apt-get install python-qt4
  1. 以上。

使ってみる

インストールがあっけなかったので、自分用のユーティリティを練習がてらGUI化。
普段いろいろなメモや検討、読書の要点などをまとめるのに、Androidの Mindjet というマインドマップアプリを使っている。
 
 
マインドマップは素晴らしいが、後から簡易に見なおしたり、キーワードを拾ったりするために、Wiki や、ブログに まとめておきたい。
ということで、Mindjet で、FreeMind 形式で保存したXMLファイルから、FreeStyleWiki の markdown 記法チックに変換したり、HTMLに変換したりするツールをPyQtでGUI化してみる。
 
できた。この程度なら、すぐできる。素晴らしい!

FreeStyleWiki 書式に変換

 

HTMLに変換

 

HTMLプレビュー

 
以下ソースコード。
かなりやっつけで、ぜんぜん最適化できてないが、自分づかいではこの程度で結構捗るんだよね。
 
  1. # -*- coding:utf-8 -*-
  2. import sys
  3. import os
  4. import glob
  5. import codecs
  6. from xml.dom.minidom import parse
  7. from xml.dom import Node
  8. from xml.sax.saxutils import escape
  9.  
  10.  
  11. from PyQt4 import QtGui as gui
  12. from PyQt4 import QtCore as core
  13.  
  14. class MainWindow(gui.QWidget):
  15. def __init__(self):
  16. super(MainWindow, self).__init__()
  17. self.initUi()
  18. def initUi(self):
  19. grid = gui.QGridLayout()
  20.  
  21. boxFile = gui.QHBoxLayout()
  22. self.txtFile = gui.QLineEdit()
  23. btnFile = gui.QPushButton('...')
  24. btnFile.setMaximumWidth(40)
  25. btnFile.clicked.connect(self.chooseMindMapFile)
  26. boxFile.addWidget(self.txtFile)
  27. boxFile.addWidget(btnFile)
  28. grid.addWidget(gui.QLabel(u'FreeMind ファイル'),1,0)
  29. grid.addLayout(boxFile,1,1)
  30. boxCtrl = gui.QHBoxLayout()
  31.  
  32. rdoGroup = gui.QButtonGroup()
  33. self.rdoFsw = gui.QRadioButton('FreeStyleWiki')
  34. rdoGroup.addButton(self.rdoFsw)
  35. boxCtrl.addWidget(self.rdoFsw)
  36. self.rdoFsw.setChecked(True)
  37. self.rdoHtml = gui.QRadioButton('Html')
  38. rdoGroup.addButton(self.rdoHtml)
  39. boxCtrl.addWidget(self.rdoHtml)
  40.  
  41. self.rdoHtmlPrv = gui.QRadioButton('Html(Preview)')
  42. rdoGroup.addButton(self.rdoHtmlPrv)
  43. boxCtrl.addWidget(self.rdoHtmlPrv)
  44. btnConv = gui.QPushButton(u'変換')
  45. btnConv.setMaximumWidth(200)
  46. btnConv.clicked.connect(self.doConvert)
  47. boxCtrl.addWidget(btnConv)
  48. grid.addLayout(boxCtrl,2,1)
  49. self.txtOut = gui.QPlainTextEdit()
  50. grid.addWidget(gui.QLabel(u'結果'),3,0)
  51. grid.addWidget(self.txtOut,3,1)
  52. self.setLayout(grid)
  53. self.setWindowTitle('FreeMind xml to FreeStyleWiki/Html')
  54. self.show()
  55.  
  56. def chooseMindMapFile(self):
  57. dialog = gui.QFileDialog()
  58. dialog.setFileMode(gui.QFileDialog.AnyFile)
  59. dialog.setFilter('FreeMindMap (*.mm)')
  60. if dialog.exec_():
  61. fileNames = dialog.selectedFiles()
  62. for f in fileNames:
  63. self.txtFile.setText(f)
  64. return
  65. return self.txtFile.setText('')
  66.  
  67. def doConvert(self):
  68. if self.rdoFsw.isChecked():
  69. levelPrefix = wikiLevelPrefix
  70. else:
  71. levelPrefix = htmlLevelPrefix
  72. isHtmlPreview = self.rdoHtmlPrv.isChecked()
  73. convertToWikiFormat(self.txtFile.text(), self.txtOut, levelPrefix, isHtmlPreview)
  74.  
  75. def convertToWikiFormat(mm_file, txt_out, levelPrefix, isHtmlPreview):
  76. txt_out.clear()
  77. dom = parse(open(mm_file,'r'))
  78. level = 0
  79. handleElement(dom.firstChild, level, txt_out, levelPrefix, isHtmlPreview)
  80. txt_out.verticalScrollBar().triggerAction(gui.QAbstractSlider.SliderToMinimum)
  81. def handleElement(element, level, txt_out, levelPrefix, isHtmlPreview):
  82. if element.hasAttribute('TEXT'):
  83. if isHtmlPreview:
  84. txt_out.appendHtml(levelPrefix(level, element.getAttribute('TEXT')) + element.getAttribute('TEXT'))
  85. else:
  86. txt_out.appendPlainText(levelPrefix(level, element.getAttribute('TEXT')) + element.getAttribute('TEXT'))
  87. if element.hasChildNodes():
  88. for node in element.childNodes:
  89. if Node.ELEMENT_NODE == node.nodeType:
  90. handleElement(node, level + 1, txt_out, levelPrefix, isHtmlPreview)
  91.  
  92. def wikiLevelPrefix(level, text):
  93. level_prefix_list = ('', '!!!','!!','!','::','*','**')
  94.  
  95. ret = ''
  96. if len(level_prefix_list) > level:
  97. ret = level_prefix_list[level]
  98. else:
  99. ret = ''.join(['.' for x in range(level - len(level_prefix_list))])
  100. return ret
  101.  
  102. def htmlLevelPrefix(level, text):
  103.  
  104. level_prefix_list = ('h1', 'h1','h2','h3','h4')
  105.  
  106.  
  107. tag = None
  108.  
  109. prefix = ''
  110.  
  111. if len(level_prefix_list) > level:
  112.  
  113. tag = level_prefix_list[level]
  114.  
  115. style = ''
  116.  
  117. else:
  118.  
  119. tag = 'p'
  120.  
  121. style = ' style="padding-left:%dem"' % ((level-3) * 2)
  122.  
  123. prefix = '- '
  124.  
  125. return '<%S%S>%s%s</%S>\r\n' % (tag, style, prefix, escape(text), tag)
  126.  
  127.  
  128. def main():
  129. app = gui.QApplication(sys.argv)
  130. mainWin = MainWindow()
  131. sys.exit(app.exec_())
  132.  
  133. if __name__ == '__main__':
  134. main()

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です