FreeMindのデータをインデント付きテキストファイル、もしくは箇条書きhtmlファイルとして出力するRubyスクリプト

会議中、ある人がアイデアマップをWordにしたものと、アイデアマップそのもので要点を説明しているとき、こちらはFreeMindでメモ取り。そこで作成を思い立つ。
RubyXMLを扱うのは初めてで(他の言語でもやったことないですが)、一通り動作したあと、html出力を追加。このときクラスの継承を使うようにしてます。
ただ後から判ったのだけれど、FreeMindから普通にコピー&ペーストでPowerpoint/Wordなりへ持って行けるので、役に立つものでもないですね。

使い方

ruby mm2txt.rb hoge.mm

空白でインデントしたテキストとして標準出力へ

ruby mm2txt.rb -html hoge.mm

<ul>タグを使用した箇条書きhtml文書として標準出力へ

ソース

#! ruby -Ku

require 'rexml/document'
require 'kconv'

INDENT_SIZE = 4

class Base
  attr_reader :fname
  def initialize(filename)
    @filename = File.basename(filename)
    @data  = ""
    begin
      f = open(filename)
      @data = f.read
      f.close
    rescue => e
      puts e.message
    end
  end

  def output
    unless @data.empty?
      doc = REXML::Document.new(@data)
      process_tree(0, doc.elements['//map/node'])
    end
  end
end

# プレーンテキストとして出力
class PlainText < Base
  def process_tree(level, node)
    print "filename: #{@filename}\n" if level == 0
    (level * INDENT_SIZE).times {
      print " "
    }
    print node.attributes['TEXT'].to_s.tosjis, "\n"
    node.elements.each { |e|
      if e.class == REXML::Element && e.name == 'node'
      process_tree(level + 1, e) 
    end
    }
  end
end

# HTMLとして出力(<ul>タグ使用)
class HTMLText < Base
  def process_tree(level, node)
    if level == 0
      print "<html><head><title>#{@filename}</title></head>\n<body>\n"
    end
    indent = ""
    level.times {
      indent += "  "
    }
    print indent + "<ul>\n"
    print indent + "  <li>#{node.attributes['TEXT'].to_s.tosjis}\n"
    node.elements.each { |e|
      if e.class == REXML::Element && e.name == 'node'
        process_tree(level + 1, e) 
      end
    }
    print indent + "</ul>\n"
    if level == 0
      print "</body></html>\n"
    end
  end
end

# usage表示
def usage
  puts "mm2txt version 1.0  dogatana"
  exit
end

# ここからメイン
usage() if ARGV.empty? 

html = ARGV.include?('-html')
ARGV.delete('-html')

ARGV.each { |f|
  text = html ? HTMLText.new(f) : PlainText.new(f)
  text.output
}