そうだ、Rubyをやろう(3日目)

私は、日々のメモはなるべく電子化するようにしている。
例えば、用語メモ、人物メモ、開発日記などがある。
これらのメモの内容はすぐに忘れてしまうので、時々意識して振り返ることがある。iPhoneに入れておいて、電車の中や、ラーメン二郎に並んでいるときや、寝る前に、気が向いたらメモの内容を確認したりするのだ。

このメモたちは、単なるテキストファイルだ。
メモを取るのにいちいち時間をかけていられない。
しかし、閲覧するときのことを考えると、できれば電子書籍にしておきたい。

そこで、せっかくRubyを学習していることだし、まずはローカルの人物メモのテキストファイルをEpub形式に変換するスクリプトを書いてみることにした。

私の人物メモのフォーマットはこうだ。

Aaron Swartz
http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%BC%E3%83%AD%E3%83%B3%E3%83%BB%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%84
アーロン・スワーツ
14歳にしてRSSの審議会メンバーになった天才プログラマ。
ソフトウェアに関する論文の自由を求めて、MIT内からJSTORにアクセスして、
多数の論文データをダウンロードした。
これにより、懲役35年を求刑され、公判開始の前月に自殺した。
2013年1月11日没満26歳。


Bill Gates
http://ja.wikipedia.org/wiki/%E3%83%93%E3%83%AB%E3%83%BB%E3%82%B2%E3%82%A4%E3%83%84
ビル・ゲイツ
マイクロソフト社の創業者、現会長。
Basic, MS-DOS, Windowsの開発はあまりに有名。

...

--
ここから先は追記メモ

最初の行に正式な名前、次の行にwikiへのリンク(オプション)、次の行にカタカナ名、その次の行からが簡単なメモで、空行2つで次の人物へと移る。人物の並びはABC順になっている。最後に2つのハイフンと改行に続いて、ファイルの末尾までが自由なメモ欄となっている。


さてさて。
私は今回、モジュールってやつを使ってみたいんだ。

require "rubygems"
require "rexml/document"

module Txt2Epub
    def create_document
        out_doc = REXML::Document.new
        out_doc.add REXML::XMLDecl.new(version="1.0", encoding="utf-8", standalone="no")
        doc_type = REXML::DocType.new  %(html PUBLIC '-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd')
        out_doc.add doc_type
        return out_doc
    end

    def create_html(titleText, styleSheet)
        html = REXML::Element.new "html"
        html.add_attribute("xmlns", "http://www.w3.org/1999/xhtml")
        html.add_attribute("xml:lang", "ja")
        html.add_attribute("xmlns:xml", "http://www.w3.org/XML/1998/namespace")
        head = REXML::Element.new "head"
        title = REXML::Element.new "title"
        title.add_text titleText
        head.add title
        link = REXML::Element.new "link"
        link.add_attribute("href", "../Styles/" + styleSheet)
        head.add link
        html.add head
        return html
    end

    def write_xhtml(outDoc, outFileName)
        File.open(outFileName, "w") do |outfile|
            outDoc.write(outfile, 0)
        end
    end
end


うーん・・・
なんか、こういうことじゃないような気がするんだけども。
とりあえず、「人物メモ」以外でも使えそうなモジュール関数を作ってみた。
そして、この素晴らしいモジュールを使って、ローカルのテキストファイルをEPUBに変換するRubyスクリプトを書くのだ。

# ローカルメモEPUB化ツール
# -人物メモ編
require "rexml/document"
require "Txt2Epub_module"
include Txt2Epub

# コマンドライン処理
if ARGV.length < 3 then
    puts "USAGE:Txt2Epub_p <in-file-name> <out-file-name> <picture_dir_path>"
    exit 1
end

in_file_name = ARGV[0]
out_file_name = ARGV[1]
picture_dir_path = ARGV[2]

out_doc = Txt2Epub.create_document
html = Txt2Epub.create_html "人物", "persons.css"
body = REXML::Element.new "body"

# テキストメモファイル読み込み
File.open(in_file_name) {|f|
    while line = f.gets
        line = line.strip

        if line.empty? then
            next
        end

        # 追記コメントチェック
        if line.start_with?("--") then
            break
        end

        # 名前取得
        head = REXML::Element.new "h3"
        name = line
        name_j = nil
        desc = ""
        url = f.gets

        unless url then
            break
        end

        unless url = url.strip then
            next
        end
        
        if url.start_with?("http://") then
            anchor = REXML::Element.new "a"
            anchor.add_attribute "href", url
            anchor.add_text name
            head.add anchor
            body.add head
        else
            name_j = url
            head.add_text name
            body.add head
        end

        head = nil

        # 写真取得
        paragraph = REXML::Element.new "p"
        image_path = File.join picture_dir_path, name + ".jpg"
        image_path = File.expand_path image_path

        if File.exists?(image_path) then
            img =  REXML::Element.new "img"
            img.add_attribute "alt", name
            img.add_attribute "src", "../Images/" + name + ".jpg"
            paragraph.add img
            body.add paragraph
        end


        # 日本語名取得
        paragraph = REXML::Element.new "p"

        if name_j then
            paragraph.add_text name_j
            body.add paragraph
        else
            unless name_j = f.gets
                break
            end
            
            name_j = name_j.strip

            if name_j.empty? then
                next
            end

            paragraph.add_text name_j
            body.add paragraph
        end

        # 説明文取得
        while line = f.gets 
            line = line.strip

            if line.empty? then
                break
            end

            desc += line
        end

        # ボディに追加
        paragraph = REXML::Element.new "p"
        paragraph.add_text desc
        body.add paragraph
        paragraph = REXML::Element.new "p"
        paragraph.add REXML::Element.new "br"
        body.add paragraph
    end

    # 追記コメントを取得
    body.add REXML::Element.new "hr"
    head = REXML::Element.new "h3"
    head.add_text "*メモ*"
    body.add head
    
    unless f.eof? then
        paragraph = nil
        title = nil
        desc = nil

        while line = f.gets
            line = line.strip

            # 空行に遭遇したら
            if line.empty? then
                unless title then
                    next
                end

                # コメント段落を追加して改行して次へ
                paragraph = REXML::Element.new "p"
                paragraph.add_text title
                paragraph.add REXML::Element.new "br"

                if desc then
                    paragraph.add_text desc
                end

                body.add paragraph
                paragraph = REXML::Element.new "p"
                paragraph.add REXML::Element.new "br"
                body.add paragraph

                paragraph = nil
                title = nil
                desc = nil
                next
            end

            # 最初の行はタイトル行
            unless title then
                title = line
            # タイトルが既に存在するなら説明文
            else
                unless desc then
                    desc = ""
                end

                desc += line
            end
        end

        # 最終行の処理
        if title then
            paragraph = REXML::Element.new "p"
            paragraph.add_text title
            paragraph.add REXML::Element.new "br"

            if desc then
                paragraph.add_text desc
            end

            body.add paragraph
            paragraph = REXML::Element.new "p"
            paragraph.add REXML::Element.new "br"
            body.add paragraph

            paragraph = nil
            title = nil
            desc = nil
        end
    end
}

html.add body
out_doc.add html
Txt2Epub.write_xhtml out_doc, out_file_name

みんなぁ〜;;


もうだめだ〜

ぐちゃぐちゃになってきちゃった;;;



まぁ、今日のところはこれくらいにしといてやろう。
.xhtmlを出力するところまではできたので、後はSigilを使って画像とスタイルシートをつけてやれば良いだろう。

こうして完成した私のオリジナル電子書籍Adobe Digital Editions(笑)で開いてみた。
ちなみに、私の個人日記の多くはAdobeとPDFの悪口で埋め尽くされているので、ここにはUPできない。


うむ、なかなかいいじゃないか。

これで落ち込んだ時、いつでもマリッサの笑顔で癒されることができるようになった。