スクリプト公開
id:sshiに期待してもらったので、はてダラ-howm連携スクリプト公開。
$ ./hw-howm.rb howm_dir target_dir
とやればhowm_dirから再帰的にhowmファイルを探しだしてtarget_dirにYYYY-MM-DD.txtとして格納してくれます。
メモの書き方ですが、メモの一行目に{hw}という文字列を入れて本文中に%%%が行頭となる行を書けば、その行より下が変換対象となります。日付はhowmファイル名のものが使用されますが、{hw}のかわりに{hw:YYYY-MM-DD}を用いると対応する日付のはてダラファイルに変換されます。
こんな感じ
= {hw:2006-06-17} スクリプトテスト [2006-06-18 15:15] >>> ~/howm/2006/06/2006-06-18-095939.howm ここは変換されません。 %%% ここより下が変換対象 *[hatena] test test
これを変換すると2006-06-17.txtというファイルになります。
特徴とか問題点とかいろいろ
- 同じ日付の日記が複数のhowmファイルにあっても問題なし。ただしその場合記事の順番はhowmファイル名順になります。
- deleteには対応してません。YYYY-MM-DD.txtファイルに直接記述してください。ただし一度deleteを書けばファイルを上書きしてもdeleteは消えません。
- -tオプションでtimestampファイルを指定できます。このオプションを指定すると、timestampファイルより新しいhowmファイルのみ変換対象となります。
- その日のタイトルにも対応していません -> deleteと同じ
- 変換後に{hw:YYYY-MM-DD}の日付部分を変えて再度変換すると二重に出力されることになります。以前の日付のYYYY-MM-DD.txtを削除して再度変換するとか、手で編集する必要があります。
- 画像転送に対応してない。
- 異常処理とかまだダメダメ。
以下スクリプト本体です。
#!/usr/bin/ruby -w # # hw-howm.rb -- howmメモをはてダラで扱える形式にする. # require "optparse" require "fileutils" begin opt = OptionParser.new OPTS = {} opt.banner= "usage: #$0 [options] src_dir target_dir" opt.on_tail("-h", "--help", "show this message") {puts opt; exit 0} opt.on("-t", "--timestamp=filename", "timestamp file(default: none)") {|v| OPTS[:t] = v} # touch file path opt.parse!(ARGV) rescue OptionParser::InvalidOption, OptionParser::MissingArgument puts $! puts opt exit 1 end srcdir = ARGV[0] updir = ARGV[1] if !srcdir or !updir puts opt exit 1 end [srcdir, updir].each do |dir| unless FileTest.directory? dir puts "invalid directory: #{dir}" puts opt exit 1 end end touch_mtime = Time.at(0) if OPTS.key?(:t) && FileTest.file?(OPTS[:t]) touch_mtime = File.mtime(OPTS[:t]) end # ファイルの再帰探索 IGNORE_DIR = %w(. ..) def scan_files (path, &block) if FileTest.directory?(path) Dir.foreach(path) do |file| next if IGNORE_DIR.include? file scan_files("#{path}/#{file}", &block) end else block.call(path) end end # メインの処理 scan_files(srcdir) do |path| next unless FileTest.readable?(path) # touchファイルより新しいか next if touch_mtime > File.mtime(path) # howm形式のファイル名か next unless /(\d{4}-\d{2}-\d{2}).*\.howm$/ =~ path date = $1 fio = File.open(path) next if fio.eof? or fio.readline !~ /\{hw(:(\d{4}-\d{2}-\d{2}))?\}/ date = $2 if defined? $2 #日付指定があればそれを使う # 記事格納用ハッシュ content = Hash.new("") # はてダラファイルの先頭部分は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 content[key] += line end elsif FileTest.exist?(uppath) puts "#{uppath} is not file." next end # はてダラファイルがなかったとき # とりあえずファイルの先頭は空行にしておく content["0"] = "\n" unless content.key?("0") # howmファイルの内容をハッシュに格納 filename = File.basename(path) content[filename] = "" fio.each_line do |line| if line =~ /^%%%/ # %%%行より下を格納 content[filename] = fio.readlines.join('') end end # はてダラファイルへ書き込み File.open(uppath, "w+") do |io| io << content["0"] content.keys.sort.each do |key| if key != "0" && content[key] != "" io << "><!--#{key}--><\n" io << content[key] end end end end # touch if OPTS.key?(:t) FileUtils.touch(OPTS[:t]) end exit 0
ライセンスはRubyライセンスで。
バグ報告大歓迎(対応できるか微妙ですが…)