2009年10月4日日曜日

Emacs + Lookup で Wikipedia辞書を手軽に持ち歩く

Wikipedia の記事データをノートパソコンに入れ、どこでも気軽に素早く引けるようにしたい、という要望は結構、多いかと思います。ここでは、そんな方法の一つを紹介したいと思います。

Wikipedia の全記事データは、wikipedia.org の 公式サイト から圧縮XMLファイルとして、自由にダウンロードできます。

しかし、これをオフラインで読むために、自分のノートパソコンに Wikipedia サーバを構築する作業は、非常に多くの手間と時間を要します。MySQLサーバへの記事の読み込みだけで4・5日かかる場合 も珍しくありません。また数十Gbyteという膨大なHDDを消費します。これでは頻繁に記事データを更新する気力も失せてしまいます。

Wikipedia を辞書標準フォーマットEPwingに変換するツール等もあります。しかしこれらを使ったとしても、作業には半日ほどの時間かかり、また辞書サイズも4Gbyteを超えてしまい、さらにEPwingは日本独自の仕様であるため、JIS X 0208以外の文字が扱えない等の問題がありました。

ここでは、配布されている圧縮Wikipedia記事データをそのまま、解凍せずに手軽に検索して読む方法を紹介します。基本的なアイデアは記事 "Building a (fast) Wikipedia offline reader" に基づいています。

配布圧縮データをそのまま使う利点は、ディスク消費容量の少なさと、導入の容易さです。容量としては、配布圧縮データ+インデックスで、元ファイルの1.3〜 1.6倍程度(2009年10月時点の日本語版Wikipediaで1.3Gbyte, 英語版で8.5Gbyte)の容量しか必要としません。またセットアップも日本語版Wikipediaで1時間程度、英語版でも半日から1日程度(マシンの性能 に依存します)で完了するため、記事を最新版に更新するのも容易です。

この方式は、配布されている圧縮Wikipedia記事データ(日本語版の場合は jawiki-latest-pages-articles.xml.bz2 で、2009年10月時点でおよそ1Gbyteの容量がある)が、"bzip2" 形式で圧縮されていることを利用します。"bzip2" はブロックソート処理を行う都合上、約1Mbyte単位の独立したブロックの並びで構成されています。圧縮ファイルをブロック単位に分割してハードディス クにおいてしまえば、容量はほとんど変わらずに、Wikipediaの記事に対してランダムアクセスに近いことができます。

bzip2 ファイルを分割には "bzip2recover" を利用します。2009年10月時点の jawiki-latest-pages-articles.xml.bz2 を分割すると、およそ5,000近いファイルが生成されます。この分割ファイル群の総容量は、オリジナルとほぼ変わりません。分割後はオリジナルファイルは消去します。この作業は10数分程度でできます。

次に、分割 され、ランダムアクセスできるようになった Wikipedia の記事データに対して、インデックスを作成します。Wikipedia XML ファイルでは、項目タイトルは <title> .... </title> タグで囲まれています。このタイトルを(日本語版では)形態素解析に基づいて分解すると、検索性が高いインデックスを作ることができます。

この作業を高速に行うためのツールとして、"MeCab"と"Xapian" を使用します。この両者の組み合わせで、日本語版Wikipediaならば1時間程度でインデックスが作成できます。(英語版のWikipediaの場合、空白で単語を区切ってインデックス化する作業はおよそ1日ほどかかりました。)

Wikipediaの記事本文は、XMLファイルのtext タグ中にMediaWiki フォーマットで格納されています。MediaWikiフォーマットの記事を自分のノートパソコンで閲覧するには、ノートパソコンにApache Webサーバと、PHPで書かれたMediaWiki/HTML変換ツールを用意しなくてはなりません(上述のWebサイトはこの方法の説明がありま す)。ただ、この方式は処理が重く、テキストベースでさくさくと気軽に記事を読みたいという場合にはあまり向いていません。

MediaWiki (Wikipedia)もwikiの一種類であるため、その書式を plain text に変換するのは難しくありません。ただし MediaWiki をテキスト化するならば、「表組」と「数式」をどのように扱うかが問題になります。Wikipediaでは(しばしば複雑な)表が多用されるため、この 表示をおろそかにする訳にはいきませんし、また理系のリファレンスとしてWikipediaを使う場合、数式をきちんと表示するのは必須です。

「表組」をプレーンテキストに変換するツールとしては、HTMLのテーブルを奇麗に整形、テキスト化する "w3m"が有名です。Mediawikiの表組は容易にHTMLのテーブルに変換できますので、まずMeidaWikiの表をHTML化し、さらにそのHTMLをw3mに食わせることで、MediaWikiの表はプレーテキストにできます。

数式は基本的にはプレーンテキスト化は無理なので、これだけは画像化せざるを得ません。MediaWikiでは、数式は math タグで囲まれたLaTeX形式(のサブセット)で書かれています。この数式を解釈し、そのまま画像化する手軽なツールとして、MediaWikiのツールの一部である texvc がありますので、数式はこれで画像化し、それをテキストに埋め込むようにします。

以上の作業を、ひとまとめに行い、Emacsのバッファで気軽にWikipediaを引くためのツールを、Emacs 辞書検索ソフトウェア、"lookup" の中に組み込んでみました。Wikipediaをノートパソコンで気軽に持ち運びたい、という人はこのツールを検討してみるのはいかがでしょうか。

ただ、本ツールはまだ作り立てなので、CVSサーバからチェックアウトして試用することしかできません(使い方メモが、ndwikipedia.el ファイルのコメント部分にあります)。

本ツールは、Emacs, MeCab、Xapian、MediaWiki (texvc)、w3m、LaTex、bzip2, ruby などを組み合わせています。元サイトの中の人も言っていましたが、多様なツールを組み合わせれば、このような比較的複雑なシステムも簡単に構築できるの が、オープンソースソフトウェアの一つの魅力なのではないかな、と思います。


(数式のみ画像化して貼付けたサンプル画面)


(W3Mを使って、MediaWikiの表組をテキスト化して表示したサンプル画面)

2008年11月7日金曜日

去る10月に、北アルプスの「下の廊下」を歩いてみた。

この歩道は戦前の日本電力株式会社によって整備されたため、「日電歩道」とも呼ばれている。

日本電力は戦後、GHQにより他の様々な会社と統合されて「関西電力」となったが、未だに名前だけは残っている。

積雪のため、一年のうち10月の一ヶ月しか歩くことができない、幻の歩道だが、紅葉と黒部渓谷の絶壁の織りなす風景は絶景。

ただしこの歩道、「けが人がでない歩道」とも呼ばれている。道を踏み外したら、怪我どころではなく確実に死ぬことから。

日電歩道は「焦熱隧道」(黒部第三ダム)、「黒部の太陽」(黒部第四ダム)にも若干、記述がある。数多くの人がここで命を失っている。

毎年、わずか一ヶ月のためにこの歩道を整備してくれる関西電力に感謝。






2008年7月26日土曜日

変貌著しい清亮寺の周辺






Google Earth で東京の変貌を視ていると楽しいのだが、この箇所はとりわけ苦笑してしまった。
かつて、田んぼの真ん中にあった寺は、今や東西南北を川と鉄道で囲まれてしまっている。

100年4世代の間に、この寺はこの周囲の変化をどのように見ていたんだろうか・・・

2008年7月16日水曜日

新しい文字が生まれる時。


 新しい文字が生まれる瞬間とはこんなものなのだろうか。
 薄田泣菫の「白羊宮」を読んでいるとき、このような表記に出くわした。
「イモリ」は漢語では「蠑螈」と書く。

 おそらく版元は何らかの理由で「螈」を作字せざるを得ないとき、「源」の右側と「虫偏」を組み合わせようとしたのではないか。
 しかし、原の字は左下に払いが伸びるので、左上の「さんずい」の名残が残り、結果として、虫偏に「源」という字が作られてしまった・・・そういう想像をしている。

 この詩集は金尾文淵堂による初版以来、幾つかの叢書に再録されているので、
各々がこの字をどのように取り扱ったのか、追跡してみるのも面白いかも知れない。

2008年7月8日火曜日

ポータブルで高速な.emacs.elの書き方



ネットを巡回していると、「ポータブルな .emacs.el の書き方(意訳)」という記事がありましたが、ここではさらに、「ポータブルでかつ高速起動する.emacs.el」の書き方を紹介したいと思います。
すなわち、.emacs.elで拡張ライブラリを設定するときには、

(require 'ライブラリ名)
(add-hook 'xxxx 'yyyy)
....
(setq xxxx 設定値)
....
という記法で書くことが多いのですが、これを以下のような記法で統一します。

(when (locate-library "ライブラリ名")
(autoload '関数名 "ライブラリ名" "関数の簡単な説明")
(autoload 'xxxx "....")
(add-hook 'xxxx 'yyyy)
....
(eval-after-load 'ライブラリ名
'(progn
(setq xxxx 設定値)
....)))
このように書くことで、以下のメリットがあります。

  • 指定されたライブラリが入っていないEmacs環境でも ".emacs.el" はエラーを起こさない。

  • 指定されたライブラリが入っていても、そのライブラリが必要とされるまで、読み込まれない。

この記法を活用すれば、ライブラリは使用するまで読み込まれないので、滅多に利用しないライブラリも安心して ".emacs.el" に組み込めることができます。なお、interactiveな関数(M-x xxxx で起動するタイプ)については、autoloadの第四引数をtにすることで、たとえライブラリが読み込まれなくても M-x xxxxで実行することができるようになります。
また、ライブラリを読み込む前に設定すべき事柄(フック関数など)は、eval-after-load の後には置かないように注意しましょう。

2008年7月5日土曜日

近代書誌データベースの画像を一度に取得する



薄田泣菫の「白羊宮」を読みたくなったので、ネットで検索したら青空文庫にはなく、近代書誌データベースにあることがわかりました。
ところがこの近代書誌データベース、1ページ1ページのダウンロードが遅い上に、画像サイズが800x600と小さく、各ページ毎にサイズを直して表示しなおすのが非常に手間暇かかります。
仕方がないので、ちょっとWebページの中身を拝見させてもらったら、白羊宮の画像に関しては以下のことがわかりました。

  1. 一度に表示できる最大のサイズは、1520x1004ドット。(これ以上いくら設定でサイズを大きくしても見ることができない。)

  2. この画像はある特定のURLを送って、サーバ側で「画像を生成」させて、その後で取得しなければならない。


そういうわけで、下記のようなスクリプトを作成し、一括して1520x1004ドットの全ページのJPEGを取得するようにしてみました。結果は良好で、現在はこうやって取得したJPEGファイルをzipで固めてビューワーで読んでいます。また、他の文献もいくつか、同様の方法で取得できることがわかりました。
(安易な乱用を防ぐため、スクリプトの一部は伏せ字にしていますが、ページの中身を調べればおそらくはすぐにわかるでしょう。)

#!/bin/sh
# 近代書誌データベースの画像を、1600x1200(1520x1004)で取得します。
# usage: command doc-id max-page
# 実行前のチェック項目
# (1) ページ数
# (2) 画像サイズ:ファイルの末尾が760-502/a-1520-1000.jpgとなっている場合は、1520x1004 が最大サイズ。これ以外の場合は、実験してみて下記の値を調整する。
count=0
while [ $count -le $2 ];
do
echo "Now processing $1-`printf \"%04d\"` $count"
curl "http://image.nijl.ac.jp/XXXX(伏せ字)XXXX/$1-`printf \"%04d\" $count`.jp2&file=kindai.html&dy=1200&dx=1600" &gt; /dev/null
curl "http://image.nijl.ac.jp/XXXX(伏せ字)XXXX/$1-`printf \"%04d\" $count`.dir/02-0/1520-1004/a-1520-1004.jpg" -o $1-`printf "%04d" $count`.jpg
count=`expr $count + 1`
done

実行例(白羊宮のJPEGファイル172枚取得)は以下の通りです。

% sh getNDLDoc.sh CKMR-00075 172


2008年7月2日水曜日

Emacs g-clientでブログを編集する。

このブログはできるだけg-clientでやろうかと思います。
まずインストールとセットアップ。".emacs"に以下を追加。

(when (locate-library "g")
(autoload 'gblogger-sign-in "g" "Resets client so you can start with a different userid." t)
(autoload 'gblogger-blog "g" "Retrieve and display feed of feeds after authenticating." t)
(eval-after-load 'g
'(progn
(setq g-user-email "XXXXXX@gmail.com")
;;(setq gcal-user-email "XXXXX@gmail.com")
;;(setq gblogger-user-email "XXXXX@gmail.com")
;;(setq browse-url-browser-function 'w3m-browse-url))
(setq browse-url-browser-function 'browse-url-firefox))))

次に、"M-x gblogger-blog" を実行。ブラウザに一連のリンクが表示されます。これがキーになります。たとえば、新しいブログを投稿したい場合は、"M-x gblogger-new-entry" を実行しますが、その後に聞いてくる "Post URL:"には、このリンクの該当するブログの[PostLink]のリンクをコピーして貼り付けます。

編集したい場合は、まず"M-x gblogger-atom-display" を実行して、"Feed:"に対しては、[feedLink]のリンクをコピーして表示。そして編集したいブログに対して、"M-x gblogger-edit-entry" を実行して、[Edit]のリンクを入力。

日本語でも編集しやすいよう、auto-fill-modeは無効にして、あと <br /> の文字列は改行に置換した方が良いでしょう。

うーん・・現時点では今ひとつ使いにくい(英語圏の人用のカスタマイズが入ってるみたい)のですが、なれればこっちの方がいいのかな…?