TABインデントのテキストファイルをFreeMindのファイルへ変換(3)

parentメソッドを使用し、make_tree()の再帰呼び出しを無くすことができ、一件落着。

#! ruby -Ks

require 'rexml/document'
require 'iconv'
require 'CGI'

# インデントつきテキストファイルを読み込む
class TextReader
  def initialize(filename)
    @f.close if @f
    begin
      @f = open(filename)
    rescue => e
      puts e
      return nil
    end
  end

  def read
    return nil unless @f
    while s = @f.gets
      if /^(\t*)[^\t]*$/ =~ s
        line = s.strip
        next if line == ""
        level = $1 ? $1.size : 0
        return [level, line]
      end
    end
    return nil  # EOF
  end
end

def encode_jpnchar(str)
  if str.size == 2
    ustr = Iconv.conv('UTF-16', 'SJIS', str)
    return sprintf("&#x%02x%02x;", ustr[2], ustr[3])
  elsif str.size == 1 && 0xa0 < str[0] && str[0] < 0xe0
    ustr = Iconv.conv('UTF-16', 'SJIS', str)
    return sprintf("&#x%02x%02x;", ustr[2], ustr[3])
  else
    return str
  end
end

def escape(str)
  a = CGI.escapeHTML(str).split(//)
  a.each_with_index { |c, i|
    a[i] = encode_jpnchar(c)
  }
  return a.join
end

#==== ここからメイン
if ARGV.size != 1
  puts "usage: text2mm textfile"
  exit
end

unless txt = TextReader.new(ARGV[0])
  exit
end

doc = REXML::Document.new
map = doc.add_element("map", { "version" => "0.8" })
REXML::Comment.new('this is generated by text2mm by dogatana@gmail.com', map)
root = map.add_element("node", { "TEXT" => "#{escape(File.basename(ARGV[0], '.*'))}"})

level = 0
base = root
while a = txt.read
  case
  when a[0] > level
    (a[0] - level - 1).times {
      child = child.add_element("node", { 'TEXT' => ' '})
    }
    base = child
  when a[0] < level
    (level - a[0]).times {
      base = base.parent
    }
  end
  child = base.add_element("node", { "TEXT" => escape(a[1])})
  level = a[0]
end

doc.write(STDOUT, 2)