groongaなどを使って全文検索システムを作るときは、PDFやオフィス文書などからテキスト情報を抜きだして検索用インデックスを作る必要があります。Windowsでテキストを抽出するソフトウェアとしてはxdoc2txtなどがありますが、ここでは、Linuxサーバ上でテキストを抽出する方法を紹介します。
Linux上でPDFを閲覧する場合は、昔はXpdfでしたが、最近はEvinceやOkularの方がよく使われているようです。どちらもPDFの処理にはXpdfからforkしたPopplerというライブラリを使っています。
popplerにはPDFからテキストを抽出するpdftotextというコマンドが付属しているため、それを利用してPDFからテキストを抽出できます。
% pdftotext hello.pdf hello.txt
これでhello.pdfのテキスト情報がhello.txtに出力されます。
WordやOpenOffice.org Writerで作成した文書はAbiWordでテキスト情報を抽出できます。
AbiWordは通常はGUI付きで起動しますが、オプションを指定することによりフィルタコマンドとしても利用できます。
Word文書からテキストを抽出するコマンドは以下の通りです。
% abiword --to txt --to-name hello.txt hello.doc
OpenDocumentFormatテキスト文書からテキストを抽出する場合も同じオプションです。
% abiword --to txt --to-name hello.txt hello.odt
ExcelやOpenOffice.org Calcで作成したスプレッドシートはGnumericに付属するssconvertでCSVに変換できます。
ExcelスプレッドシートをCSVに変換するコマンドは以下の通りです。
% ssconvert --export-type Gnumeric_stf:stf_csv hello.xls hello.csv
OpenDocumentFormatスプレッドシートをCSVに変換する場合も同じオプションです。
% ssconvert --export-type Gnumeric_stf:stf_csv hello.ods hello.csv
PowerPointやOpenOffice.org Impressで作成したスライドをテキストに変換する方法はいくつかあるのですが、OpenOffice.orgを使う方法を紹介します。OpenOffice.orgを使う方法はWordやExcelの時も使えますが、事前に準備が必要なので、多少面倒です。
OpenOffice.orgを使って変換する方法にはOpenOffice.orgを変換サーバとして使う方法とコマンドとして使う方法がありますが、ここではコマンドとして使う方法を紹介します。コマンドとして使う場合もいろいろやり方がありますが、今回は、まずPDFに変換し、PDFからは上述のPopplerを使って変換することにします。
まず、以下の内容の~/.openoffice.org/3/user/basic/Standard/Export.xbaを作ります。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd"> <script:module xmlns:script="http://openoffice.org/2000/script" script:name="Export" script:language="StarBasic"> sub WritePDF(url as string) dim document as object dim dispatcher as object document = ThisComponent.CurrentController.Frame dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") dim args1(1) as new com.sun.star.beans.PropertyValue args1(0).Name = "URL" args1(0).Value = url args1(1).Name = "FilterName" args1(1).Value = "writer_pdf_Export" dispatcher.executeDispatch(document, ".uno:ExportDirectToPDF", "", 0, args1()) document.close(true) end sub </script:module>
そして、同じディレクトリにある~/.openoffice.org/3/user/basic/Standard/script.xlbに登録して、以下のような内容にします。<library:element>のところを追加しています。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd"> <library:library xmlns:library="http://openoffice.org/2000/library" library:name="Standard" library:readonly="false" library:passwordprotected="false"> <library:element library:name="Export"/> </library:library>
これで準備ができました。以下のようにスライドをPDFに変換できます。
% ooffice -headless hello.ppt 'macro:///Standard.Export.WritePDF("file:///tmp/hello.pdf")'
PowerPointのファイル以外でもWord文書などOpenOffice.orgで開けるファイルを指定すれば、それらもPDFに変換できます。
以前はXがない状態では動かないため、Xvfbなど仮想的なXサーバを使ったものですが、最近のOpenOffice.orgはXがなくても動作するようです。すばらしい。
PDFに変換したら後は上述の方法でテキストを抽出できますね。
Linuxサーバ上でPDFやオフィス文書からテキストを抽出する方法を紹介しました。以前はwvTextやxlhtml、ppthtmlなどを使うことが多かったでしょうが、最近はもっと精度よくテキストを抽出できるようになっているので、ここで紹介したツールも試してみてはいかがでしょうか。
毎年開催規模が大きくなっている日本Ruby会議に今年も参加します。今年も去年と同じくスポンサーと発表者として参加します。
発表タイトルは「るりまサーチの作り方 - Ruby 1.9でgroonga使って全文検索」です。
発表内容はるりまサーチという、Rubyリファレンスマニュアル刷新計画 (通称るりま)の成果物であるRubyのドキュメントを全文検索するWebアプリケーションの関連技術を紹介するというものです。もう少し具体的にいうと以下のような話題になります。
Twitterなどを見てもわかる通り、世界には情報がどんどん増えていきます。そうすると、その中から必要な情報を選ぶことが重要になっていきます。しかし、情報が溢れた世界では人力のみで効率よく情報を選択することは困難です。最近Twitterが提供をはじめた「おすすめユーザー」という機能も、溢れかえった情報の中から必要な情報を見つけることを支援するための機能と言えます。
必要としている人が必要な情報を見つけやすくしたい、そんなアプリケーションを作りたいと考えている人に聞いて欲しい内容です。もしかしたら、groongaが提供する必要な情報を見つけるための機能でそれを実現できるかもしれません。発表日時は最終日8/29(日)の13:30-14:00で、場所は中ホールです。同じ時間帯に、別の場所ではかずひこさんの外国で暮らすRubyistだけど何か質問ある?、TermtterKaigi、MSWin32版Ruby野良ビルダー養成塾などありますが、こちらは30分なので、こちらの発表の時間だけ抜け出すことも考えてみてください。
日本Ruby会議2010で発表する予定の内容を紹介しました。面白そうだと思った方はぜひ参加してみてください。チケットはまだ少し残っているようです。また、チケットを譲りたいという方もいるので、まだチケットを持っていない方は連絡をとってみるのもよいかもしれません。
それでは、日本Ruby会議2010でお会いできることを楽しみにしています。
採用を再開しました。ソフトウェア開発者を2名募集しています。応募条件はプログラミングが好きなことだけです。学歴や年齢などは関係ありません。勤務地は東京都文京区または栃木県小山市になる予定です。詳しくは採用情報を見てください。日本Ruby会議2010の会場にはクリアコードの人が3人はいるはずなので、そのときに声をかけてもらえればその場でも説明します。
注: この記事にライセンスは設定されていません。
早いもので来週末は日本Ruby会議2010です。日本Ruby会議では、たくさんいる(会ったことはないけど名前を知っている)参加者がお互いを認識しやすいように大きな名札をつけることが恒例となっています。
RubyKaigi日記でも名札には名前を大きく書きましょうと呼びかけています。この中で、「あらかじめ太くて大きなフォントで、黒々と印刷してきたものを持参して、名札に貼り付けるのはいかがでしょう。」と提案しています。しかし、自分でデザインするのはわりと面倒なものです。
そこで、kdmsnrさんが名札には名前を大きく書きましょうジェネレータを作りました。これはtwitter IDを指定するだけでRubyKaigi日記で提案されているようなデザインの画像を生成してくれます。
でも、印刷するならPDFの方が嬉しいよね、ということでPDFを出力できるように改造したのが名札には名前を大きく書きましょうジェネレータ改です。
PDFも出力できるようにした他に、フォントを選べたり、細かく調整するためにSVGも出力できるようにしています。それでは、どのように実現しているかを説明します。
描画にはcairo、文字の配置にはPango、画像の読み込みにはGdkPixbufを用いています。どれもLinux、*BSD、Mac OS X、Windowsなど多くの環境で動作するライブラリです。ここでは、cairoとPangoだけ説明します。
cairoは2次元グラフィックを生成するためのライブラリで以下のような特長があります。
ベクトルベースのAPIとなっているということは品質を落とさずに拡大・縮小ができるということです。ジェネレータ改では、実際のサイズの画像とサムネイル画像を生成しますが、このようなことが以下のように描画処理を変更せずに実現できます。
1 2 3 4 5 6 7 8 9 10 |
def render(context) # 実際のサイズの描画 end # 実際のサイズを描画するとき render(context) # 1/3サイズのサムネイルを描画するとき context.scale(1 / 0.3, 1 / 0.3) # 描画処理の前にこれを呼ぶだけでOK render(context) |
描画処理のコードを変更せずに出力先を変えることができると、描画結果はPNGにしてブラウザで確認、印刷するときはPDF、編集する時はSVG、というように用途にあわせたグラフィックのフォーマットを提供することが簡単にできるということです。これは今回のようなWeb上で印刷物を生成する場合はとても便利な機能です。いちいちPDFで確認するのは面倒ですよね。サムネイルで一覧表示する場合もPNG+ブラウザの方が便利です。
cairoの詳しい使い方はRubyist Magazine - cairo: 2 次元画像描画ライブラリを見てください。
Pangoは多言語に対応したテキストの配置を行うライブラリです。フォントの扱いなどテキストの配置に関することを抽象化してくれるので、TTFやOTFなどフォントフォーマットの違いや、フォントファイルをどこに置くかなどをプログラム側で気にする必要がありません。
ジェネレータ改ではインストールされているフォントを列挙したり、できるだけ大きいテキストサイズを自動検出するためにPangoを利用しています。テキストを中央揃えにするのもPangoの機能を利用しています。
システムにインストールされているフォントの一覧は以下のように取得できます。
1 2 3 4 |
font_families = Pango::CairoFontMap.default.families.collect do |family| family.name end p font_families # => ["Mona", "梅明朝S3", "衡山毛筆フォント草書", ...] |
残念ながらPangoを利用するためのまとまった日本語の資料はありません。興味のある人はソースコードを見てください。
名札には名前を大きく書きましょうジェネレータ改をネタにしてcairoとPangoを紹介してみました。cairoとPangoはFirefoxやGTK+などデスクトップで使われることが多いライブラリですが、Webアプリケーションのようにサーバサイドでも有用なライブラリです。ジェネレータ改のように用途にあわせて画像のフォーマットを使い分けたい場合は、cairoとPangoを使ってみてはいかがでしょうか。また、日本Ruby会議2010に参加する人はジェネレータで作った名札を印刷して持っていってはいかがでしょうか。
名札には名前を大きく書きましょうジェネレータ改のソースコードはGitHubにあります。
前作プログラミングRubyのRuby 1.9対応版です。
前作:
プログラミングRuby 第2版 言語編
オーム社
¥ 4,104
プログラミングRuby 第2版 ライブラリ編
オーム社
(no price)
このシリーズはページ数からもわかる通り、Rubyについて細かいところまで網羅しているのが特徴です。例えば、Proc.new
とlambda
の違いはわかりますか?以下のようなクラス定義の書き方による参照解決の違いはわかりますか?
1 2 3 4 5 6 7 8 9 |
module MyLibrary class MyClass # ... end end class MyLibrary::MyClass # ... end |
これまでのシリーズと同様、本書でもそのあたりの細かいところにも触れています。もちろん、1.8と1.9で変わった部分についても触れています。このシリーズでRubyを覚えたという人もわりといるようですが、それはこの網羅性が役に立ったのではないでしょうか。
おそらく、1回読んだだけではすべてを覚えることは無理でしょう。読んで、実際にRubyのコードを書いて、気になったところをまた調べ直す、そのサイクルができるのがこのシリーズです。このシリーズでRubyを覚えた人はこのようなサイクルを使ったのではないでしょうか。先日1.9.2がリリースされ、これから1.8から1.9への移行がより進むと考えられます。そのときに、つまずいたところを本書で調べて理解していくというサイクルに使えるでしょう。
Rubyは(わりと)読みやすいコードを(わりと)書きやすい言語仕様になっています*1が、複雑なこともいろいろできる仕様も多く含まれています。ほとんどの場合は複雑なことはしなくても済むはずですし、そのように書いておく方がよい場合の方が圧倒的に多いです。一度、(わからない部分があったとしても)全体を一通り読んでおいて、Rubyの動作はどうなっているかをざっくりと知っておくとよいでしょう。複雑なことをしそうになったときに、別の方法もあった気がする、と気付けるようになるくらいで十分です。気付けたら本書なりるりまなりで詳しく調べることができます。
本書は分量の多さから言語編とライブラリ編の2編構成になっています。言語編に比べてライブラリ編の内容が手薄になっているので気をつけてください。必ずしもそれぞれのライブラリの最新の情報に追従できているわけではありません。本書をきっかけにしてるりまやWeb上での情報などで補正する必要があるでしょう。
試しにRubyを勉強してみたい、という人には敷居が高いでしょう*2。しかし、Rubyを使いこなそうというくらいの気持ちがあるのであれば、助けになってくれることでしょう。
プログラミングRuby 1.9 −言語編−
オーム社
¥ 4,104
プログラミングRuby 1.9 −ライブラリ編−
オーム社
¥ 4,752