論文リストのデータ形式
論文のサーベイや発表論文の情報を掲載するにあたり ymatsuo.com で用いられているデータ形式を用いている.その形式は以下のようなものである.
上記に用いられているタグはクラス名が同じであればタグ名は異っても問題ない(と思う).ただし,論文データを構成する "author", "title" などは,"paper" をクラス名にもつタグの子ノードである必要がある.
RubyによるRSSデータの出力
プログラムの作成方針としては,HTMLファイル内にある "paper" をクラス名にもつタグを探し,その子ノードを論文の情報を構成する要素であることを前提としている.
新しいサーベイ情報を追加するなど,RSSデータを更新する場合は,既存のRSSデータ(XMLファイル)とHTMLファイル内の論文情報とを比較して,追加もしくは更新されたデータの変更を行う.ただし,RSSの要素の粒度は,上記の論文データ形式に比べて荒いために,RSSの要素のタイトル情報を,title+publication, サマリー情報で,author+publication+descriptionを保存し,それぞれが異れば更新or追加されたと見なしている.これは,国際会議と雑誌とで同タイトルで公開されている場合などを想定した措置である.
HTMLファイルの読み込み
HTMLファイルを読み込むにあたり,まず問題になるのは文字コードの問題がある.ファイルもメタタグを信じる.文字コードを判別するなどいろんな方法を試したが,あらゆるケースに追いて確実に対応できる方法が密からかなったため,多少強引ではあるが,nkf を使ってファイルの文字コード強引に変えるという方法をとった.
# 入力ファイルを nkf を使って文字コードを utf-8 に変換 inputFilename = ARGV.shift # 元データ HTMLファイル名 day = Time.now datestring = day.strftime("%y%m%d-%H%M%S") # tmpファイル用 datetime を取得 tmpfilename = "tmp_SPRSS#{datestring}.txt" tmpfile = open(tmpfilename,"w") File.open(inputFilename) { |file| while line = file.gets tmpfile.print NKF.nkf("-sjis",line) # エンコードを sjis に変換 end } tmpfile.close
直接 UTF8に変換しないで,SJISに変換しているのは文字化けが起きる場合があるのでSJISにしてある.EUCでも良かった気もするが確証はない.
当然,作成した tmp ファイルは,処理の一番最後で削除する.
File.delete(tmpfilename) # tmp ファイル
HTMLファイルの処理
HTMLファイルを処理するにあたり,hypricot を利用している.これは,ruby が動作する環境にて,rubygems を用いてインストールしてある必要がある.なお,そのプロセスの説明は,検索エンジンで探せばみつかるので,ここでは省く.
先に SJIS に変換したtmpファイルを読み込み hpricot を使ってデータの処理を行う.
htmldata = Hpricot(File.read(tmpfile)) (htmldata/".paper").each do |p| # class名が "paper" であるタグのリストを作成 paper = Hash.new # 論文データの抽出 p_title = "\"#{p.at("[@class='title']").inner_text.sub(/\[\d+?\]/,"").sub(/^\s+/,"").sub(/\s+$/,"")}\"" p_title += ":\t#{p.at("[@class='publication']").inner_text}" p_desc = "Author: #{p.at("[@class='author']").inner_text}
" p_desc += "Publication: #{p.at("[@class='publication']").inner_text}
" p_desc += p.at("[@class='description']").inner_text tag = p.at("[@class='link']") p_link = nil tag.search("a") { |ele| p_link = ele['href'] } unless tag == nil if $ifencode == 'EUC' # 文字コード処理の名残り p_title = Uconv.euctou8(p_title) p_desc = Uconv.euctou8(p_desc) p_link = Uconv.euctou8(p_link) elsif $ifencode == 'SJIS' p_title = Uconv.sjistou8(p_title) p_desc = Uconv.sjistou8(p_desc) p_link = Uconv.sjistou8(p_link) end paper['title'] = p_title paper['desc'] = p_desc paper['link'] = p_link paper['date'] = fstat.mtime paperList.push(paper) # 論文データの保存
RSSデータの出力
RSSの出力は,ruby の標準ライブラリに入っているので ruby が動作する環境であれば問題なく利用できるはず.
def mkRSS(rssuri,name,description,link, paperList) rss = RSS::Maker.make("2.0") do |maker| maker.channel.title = name maker.channel.description = description maker.channel.link = link maker.items.do_sort = true maker.encoding = "UTF-8" # RSSの文字コード paperList.each do |paper| # 論文データの登録 maker.items.new_item do |item| item.title = paper['title'] item.link = paper['link'] unless paper['link'] == nil item.description = paper['desc'] item.date = paper['date'] end end end end
登録したRSSのデータは .to_s で文字に変換できるので,それをファイルなりに出力すればよい.
データの更新
既存のRSSファイルを更新するには,既存のファイルを読み込み,そこにあるデータと元データとの比較が必要である.よって,rss ライブラリでは,データの読み込みにも対応しているのでそれを利用した.
def readRSS(fname) feed = nil begin feed = RSS::Parser.parse(File.read(fname),false) rescue RSS::Error STDERR.puts "#{fname}はRSS 0.9x/1.0/2.0, Atom 1.0のいずれでもありません。" if feed == nil end return feed end
次に読み込んだRSSデータを,一旦文字データとして配列に格納する.この作業をするのは,読み込んだ RSSフィードのデータを上書きしようとしたが,文字データとして出力する時に反映させることができなかったので,お手軽な対処として,もう一度 RSSのフィードを作成することにしたためである.ただし,この時に,RSSの各アイテム部分の更新時間の情報を,追加・更新されたアイテムに関しては実行した時間,それ以外は,既存のデータの時間にしてある.
papers.each do |paper| flagp = false rss.items.each do |item| if item.title == paper['title'] if item.description != paper['desc'] item.description = paper['desc'] item.date = paper['date'] end flagp = true end if item.description == paper['desc'] if item.title != paper['title'] item.title = paper['title'] item.date = paper['date'] end flagp = true end end next if flagp item = RSS::RDF::Item.new item.title = paper['title'] item.link = paper['link'] unless paper['link'] == nil item.description = paper['desc'] item.date = paper['date'] rss.items << item end return rss
プログラム
論文リストのRSS出力プログラム
- SPRSS.rb
- 新規のRSSの出力の場合
% ./SPRSS.rb [元HTMLファイル名] "RSSタイトル" "RSS説明" "RSSタイトルにリンクするURL" > [出力ファイル名]
新規のRSSを出力したあとは,元データとなる HTMLファイルにメタ情報を追加する必要がある.
- 既存のRSSの更新の場合
% ./SPRSS.rb -update [元HTMLファイル名] [既存RSSファイル名]