anythingでPDFファイルをプレビューしながら高速に選びたい

anything-books.el ?

anythingでPDFファイルをプレビューしながら開くプログラムを作りました。
なぜか大量にPDFがあって、PDFの管理方法に困っていて、たまたまEmacsを使っている人向けです。



画面イメージ

動かした方が受けが良さそうなので、今回はスクリーンキャストを用意してみました。



スクリーンキャスト

インストール

必要なもの:

  • anything-books.el
  • anything.el
  • deferred.el, concurrent.el
  • ImageMagick
  • PDF変換ツール(evince, convert+gsとか)
  • PDFビューアー(AdobeReaderとか)

anything.elはすでに皆さん入っていると思います。まだの人はanything導入のeverything 〜3分で使えるanything.el〜 - http://rubikitch.com/に移転しましたとかWEB+DB Vol.58とかを参考にしてみてください。

anything-books.el, deferred.el, concurrent.el は、auto-install.elで以下の式を評価して入れるか、ダウンロードしてload-pathの場所に置いてください。

;; auto-installを使う場合
(auto-install-from-url "https://github.com/kiwanami/emacs-deferred/raw/master/deferred.el")
(auto-install-from-url "https://github.com/kiwanami/emacs-deferred/raw/master/concurrent.el")
(auto-install-from-url "https://github.com/kiwanami/emacs-anything-books/raw/master/anything-books.el")
;; (2010/11/19 URLの間違いを修正)

ダウンロード

画像変換としてImageMagickを使います。多分Emacs使っているような人は大抵入っているのではないかと思います。

PDFからの画像変換にはいろいろな方法があると思いますが、 Ubuntu なら 汎用ドキュメントビューアー:evince付属の evince-thumbnailer が高速でおすすめです。GhostScript + convert も他のOSでも動作しますので確実です。ただしこちらはかなり遅いです。各自の環境でいろいろ実験してみてください。

PDFビューアーは各自のお好みでどうぞ。

以下、設定例です。

(require 'anything-books)
(setq abks:books-dir "/home/foo/bar/pdf-files") ; PDFファイルのあるディレクトリ(★必須)
(setq abks:open-command "acroread") ; LinuxのAdobeReaderを使う (default)

;; for evince setting (default)
(setq abks:cache-pixel "600")
(setq abks:mkcover-cmd-pdf-postfix nil)
(setq abks:mkcover-cmd '("evince-thumbnailer" "-s" size pdf jpeg))

;; for ImageMagick and GhostScript setting
;; (setq abks:cache-pixel "600x600")
;; (setq abks:mkcover-cmd-pdf-postfix "[0]")
;; (setq abks:mkcover-cmd '("convert" "-resize" size pdf jpeg))

(global-set-key (kbd "M-8") 'anything-books-command) ; キーバインド

結構環境に依存している設定が多いですので、以下の設定をいろいろ調整する必要があるかもしれません。

(setq abks:cmd-copy "cp") ; ファイルコピーのコマンド
(setq abks:copy-by-command t) ; nilにするとEmacsの機能でコピーする(Windowsはnilがいいかも)
(setq abks:preview-temp-dir "/tmp") ; 作業ディレクトリ

Ubuntu 10.10 amd64 / Emacs23.1 でテストしています。あとで Windows でも試してみます。

使い方、動作

普通に起動して選ぶだけです。migemoがあるので検索が楽です。

ファイルはディレクト再帰で取ってきます。数百程度であれば実用的速度で動くとは思います。

プレビューの動作が非同期で動くのでanything自体の動作は軽快です。

プレビューは後からついてくる感じです。初回プレビューはpdfから変換するのでちょっと遅いですが。一度表示すると次からは速いです。非同期動作中はモードラインがアニメーションしたり、プログレスを表示するので、そのあたりもお楽しみいただけるかもしれません。

プレビュー用の画像キャッシュは、PDFのあるフォルダに .cache フォルダを勝手に作って保存します。無かったら作りますのでいつでも消してかまいません。

直近の10個はメモリに画像を持つようにしています。画像は十分縮小していますので多分それほど問題にはならないかなと思いますが、気になる人は abks:preview-image-cache-num の数を減らしてみてください。

プレビュー画面はanythingのウインドウを適当に半分にします。スクリーンキャストでも、このあたりの画面分割の違いが少し見れます。

anythingのプレビューの方法について

プレビューの動作自体は、persisten-actionとして行っています。

毎回persisten-actionを行うために、項目間を移動するときに呼ばれる関数 anything-move-selection-common をアドバイスで引っかけて、 anything-execute-persistent-action 関数を自前で毎回呼んでいます。一応、アドバイスは開始で active 終わったら deactive するようにしています。もしかしたらもっとうまい方法があるかもしれません。

anythingで脇にプレビューを表示させるのはかなりおもしろい使い方だと思っていますので、今後このシリーズでいろいろ作ってみようと思っています。

今後の展開

本のメモを書いたりアクセスしたいので、anything-sourceにhowmとのインタフェースを入れようかと思っています。応用すれば、流行のevernoteやorg-modeでもいけるかもしれません。

concurrent.el

最近のマイブームです。非同期により平行にプログラムが動くようになると、平行プログラムに必要な道具が必要になってきます。例えばconvertやwgetが大量に動かないようにセマフォで制御とか、バッファやスレッド間の通信を行うためにメッセージベースの通信とかデータフロー変数とかです。deferred.elの上に構築しています。

comintとかのプロセス間の通信は deferred.el ではなくて、こちらの非同期メッセージの仕組みを使うか、無限リスト(ストリーム)にするのかなと思っています。

もういくつかアプリを作ってみて、自分の中で確立するものが出来たらまとめる予定です。。。