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

HAHAHA
私はついにRubyをマスターしたぞ!
今回作ったサンプルプログラムは、まさしく、傑作だ。

#!/usr/bin/ruby
# Epub文字数カウンタ

require "rubygems"
require "zipruby"
require "rexml/document"
require "htmlentities"

$some_error = nil

# HTMLEntities.new.decode(" ") == " " はfalseになる
# こいつが返すのはC2A0という2バイトのUTF-8半角空白である
IgnoreCharacters = "\0\s\t\r\n" + HTMLEntities.new.decode(" ")

AcceptEntrySuffix = [".xhtml", ".html"]

# エレメント内のテキストの文字数を再帰的に計算する関数
def count(element)
    cnt = 0

    # 最初にCGI.unescapeHTMLを使ったが、
    #  が置換できなかったのでHTMLEntitiesを使ってみた
    element.texts.each {|text|
        HTMLEntities.new.decode(text).split(//).each {|c|
            unless IgnoreCharacters.split(//).any? {|l| l == c} then
                cnt += 1
            end
        }
    }

    element.elements.each {|child| cnt += count(child)}
    return cnt
end

# 1つのZIPエントリーを処理してテキスト文字数を返す関数
def process(archive)
    buf = ""

    archive.read do |chunk|
        buf << chunk
    end

    # 丸ごとパースしようとすると、
    # XHTMLの定義部でパースエラーになるので、body部だけ拾ってくる
    unless /<body.*<\/body>/m =~ buf then
        $stderr.puts "parse error. (#{archive.name})"
        $some_error = true
        return nil
    end

    buf = $&
    doc = REXML::Document.new buf
    return count doc.root
end

# 総文字数を記憶する変数
letter_cnt = 0

# 処理したファイル数を記憶する変数
epub_cnt = 0

# プログラム引数で指定されたEPUBファイルを全部カウントする
ARGV.select {|path| /.+\.epub\Z/ =~ path && File.exist?(path)}.each {|file|
    Zip::Archive.open(file) do |ar|
        ar.each do |f|
            if AcceptEntrySuffix.any? {|ext| File.extname(f.name) == ext}
                letter_cnt += process(f)
            end
        end
    end
    
    epub_cnt += 1
}

if 0 >= epub_cnt then
    $stderr.puts "epub not found."
    exit 1
end

if $some_error then
    $stderr.puts "ended up with some errors."
    exit 1
end

puts letter_cnt

この100行にも満たない、小さなスクリプトがいったい何の役に立つのか、わからない人もいるだろう。このスクリプトを使えば、EPUB文書のタグや改行を除いた、純粋な文字数をカウントできるのだ。これを使って、自分の作成したメモのうち、きちんと電子化したものについての総文字数を計測できる。その値は即ち、私のコンピュータに関する知識のうち、形式知を表すものだ。私は日々の習慣と、このツールによって、自身の知識量を定量的に測る物差しを得たのである。

まぁ、もっとも

すべての知識を電子(Epub)化できるわけがないのだが