そうだ、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)化できるわけがないのだが