hw-howm.rb 0.1.0
微妙に修正。
はてダラファイルにhowmファイル名を"><!--hoge.howm--><"のように埋め込んでたけど、これがよろしくないらしい。RSSにしたとき"<"がゴミとして入ってきてしまう。
たぶんはてな側のバグだとおもうけど、よくよく考えるとpタグ停止記法を使う理由もないのでファイル名埋め込みには"<!-- -->"を使うことにする。
以下本体
#!/usr/bin/ruby -w # # hw-howm.rb -- howmメモをhw.plで扱える形式にする. # require "optparse" require "fileutils" require "find" require "pathname" begin opt = OptionParser.new OPTS = {} opt.banner= "usage: #$0 [options] src" opt.on_tail("-h", "--help", "show this message") {puts opt; exit 0} opt.on("-t", "--timestamp=FILE", "use FILE as timestamp (default: none)") {|v| OPTS[:t] = v} # touch file path opt.on("-g", "--group=GROUP", "assume group name"){|v| OPTS[:g] = v} opt.on("-o", "--outputdir=DIR", "output file in DIR (default: .)"){ |v| OPTS[:o] = v } opt.version = "0.1.0" opt.release = nil opt.parse!(ARGV) rescue OptionParser::InvalidOption, OptionParser::MissingArgument puts $! puts opt exit 1 end if ARGV.size == 0 puts opt exit 1 end updir = OPTS.key?(:o) ? OPTS[:o] : '.' unless FileTest.directory? updir puts "invalid directory: #{dir}" puts opt exit 1 end touch_file = "" if OPTS.key?(:t) && FileTest.file?(OPTS[:t]) touch_file = OPTS[:t] end TOUCH_MTIME = (touch_file == "") ? Time.at(0) : File.mtime(touch_file) ARG_GROUP = OPTS.key?(:g) ? OPTS[:g] : "" IN_NOOP = :IN_NOOP IN_BODY = :IN_BODY IN_DIARY = :IN_DIARY # howmファイルの読み込み def readhowm (path, def_date) status = IN_NOOP howm_content = Hash.new("") date = "" path.each_line do |line| case status when IN_NOOP if line =~ /^= .*\{hw(:(.*))?(?=\})/ date = def_date group = "" if !$2.nil? $2.split(',').each do |str| str.strip! if str =~ /(\d{4}-\d{2}-\d{2})/ date = $1 elsif str =~ /g=(.*)/ group = $1.strip end end end howm_content[date] += "" status = IN_BODY if ARG_GROUP == group end when IN_BODY if line =~ /^=( |$)/ status = IN_NOOP redo end if line =~ /^%%%/ status = IN_DIARY next end when IN_DIARY if line =~ /^=( |$)/ status = IN_NOOP redo end # EOF対策。改行で終らせる。 line += "\n" if line[-1] != ?\n howm_content[date] += line end end return howm_content end def scan_files(array, &block) array.each do |p| path = Pathname.new(p) path.find {|path| block.call(path)} end end # メインの処理 scan_files(ARGV) do |path| next unless path.readable?() # touchファイルより新しいか next if TOUCH_MTIME > path.mtime() # *.howmファイルのみ対象 next unless /\.howm$/ =~ path.to_s filename = path.basename().to_s # ファイル名の先頭がYYYY-MM-DDならその日付を日記日付のデフォルトとして使用 if /^(\d{4}-\d{2}-\d{2}).*\.howm$/ =~ filename def_date = $1 else def_date = path.mtime().strftime("%Y-%m-%d") end # howmファイルの内容をハッシュに読みこみ howm_content = readhowm(path, def_date) howm_content.keys.each do |date| # はてダラファイル記事格納用ハッシュ hatena_content = Hash.new("") # はてダラファイルの先頭部分はhatena_content["0"]に格納 key = "0" # はてダラファイルの内容をハッシュに格納 uppath = "#{updir}/#{date}.txt" if FileTest.file?(uppath) File.foreach(uppath) do |line| if /^<!--(\d{4}-\d{2}-\d{2}.*\.howm)-->$/ =~ line key = $1 next end hatena_content[key] += line end elsif FileTest.exist?(uppath) puts "#{uppath} is not file." next end # はてダラファイルもなく内容が空の場合はファイル出力しない next if !hatena_content.key?("0") and howm_content[date] == "" # はてダラファイルがなかったとき # とりあえずファイルの先頭は空行にしておく hatena_content["0"] = "\n" unless hatena_content.key?("0") if !hatena_content.key?(filename) or hatena_content[filename] != howm_content[date] hatena_content[filename] = howm_content[date] # はてダラファイルへ書き込み File.open(uppath, "w+") do |io| io << hatena_content["0"] hatena_content.keys.sort.each do |key| if key != "0" && hatena_content[key] != "" io << "<!--#{key}-->\n" io << hatena_content[key] end end end end end end # touch if OPTS.key?(:t) FileUtils.touch(OPTS[:t]) end exit 0
マイナーバージョン番号が上ってますがあんまり意味はないです。