feed

2015年04月04日, 編集履歴

OS XのEPUB用Spotlight/Quick Lookプラグインを作り直した

 OS XのEPUB用Spotlight/Quick Lookプラグインを作り直した。

 システム要件はとりあえずOS X 10.10以上。

 上記のバイナリィダウンロードのページからZIPをダウンロード・解凍し、所定のパスへ配置することでインストール。Spotlightプラグイン(EPUB.mdimporter)は、

Quick Lookプラグイン(EPUB.qlgenerator)は、

 プラグイン同梱版のMurasakiをインストールしている場合は、そちらが優先される可能性がある。そのときはFinderからMurasakiを選択して、コンテキストメニューの「パッケージの内容を表示」で中身を開いて、パッケージ内のLibraryフォルダを削除もしくはリネームする。

 プラグインをシステムに認識させるには、Macを再起動すると手数としては手っ取り早い。CLIが使えるならば、

$ mdimport -r /path/to/EPUB.mdimport
$ qlmanage -r

を実行する。

 この新しいプラグインをいつMurasakiに同梱するかは未定である。

 これまでMurasakiに同梱していたものと比べて、変更点は以下の通り。

Spotlightプラグイン

 EPUB仕様のヴァージョン文字列(2.0とか3.0)をメタデータとして収集し、検索対象になった。メタデータの内部項目名は「com_genjiapp_Murasaki_mdimporter_EPUB_EPUBVersion」で、表示名は「EPUB Version」および「EPUB バージョン」。たとえばターミナルで

$ mdfind "com_genjiapp_Murasaki_mdimporter_EPUB_EPUBVersion = '3.0'"

とすれば、EPUB仕様のヴァージョンが3.0のもののみが検索できる。FinderウィンドウからのSpotlight検索ならGUIで条件指定可能。

 Finderの「情報を見る」ウィンドウにEPUBのメタデータが表示されるようになった。

 「情報を見る」ウィンドウでのプレヴューは表紙画像のみ。

Quick Lookプラグイン

 各コンテントドキュメント(EPUB内部のXHTML)で指定されたスタイルをできるだけ保ちつつ、以前のものより表示品質を上げた(つもり)。コンテントドキュメントとしてXHTMLではなく画像ファイルが直接指定されているEPUBのプレヴューもできるようになった。

 Spotlight検索からのQuick Lookプレヴューは以下のような感じ。Spotlight検索でEPUBだけを対象にしたい場合は、以下の画像のようにkind:epubという条件を加えると良い。

 赤線による強調は画像処理による。画像のようにEPUB内の単語でSpotlight検索できていることが解る。

style要素のscoped属性

 Quick Lookでファイルをプレヴューさせる場合、プラグインはファイルの内容を取得・加工し、標準的な形式(画像やPDF、HTMLなど)にしてシステムに伝える必要がある。以前のものも今回のものも、EPUB内のコンテントドキュメント(多くの場合複数のXHTML)をひとつのHTMLにまとめ、システムに渡している。
 各コンテントドキュメントをひとつにまとめる処理は以下のような感じになる。

  1. EPUBのspineで指定された読み順にしたがいコンテントドキュメントを読み込む
  2. コンテントドキュメントの内容を抜き出し、div要素に詰め込む
  3. 抽出されたdivをひとつのHTMLに順に並べる

 ここで問題になるのが、各コンテントドキュメントで指定されているスタイルである。通常複数あるXHTMLコンテントドキュメントをひとつのHTMLにまとめているので、各コンテントドキュメントで指定されているスタイルが全体に影響を与えてしまう。(たとえば、本来ならば表紙ページにだけ適用されるべきスタイルがプレヴューされるHTML全体に適用される)。スタイル指定の記述を省くとまったくスタイルが当たっていない状態になるか、こちらで用意するスタイルを画一的に適用することになる。

 そこで有望視しているのが、HTML 5で追加されたstyle要素のscoped属性である。style要素にscoped属性を付けることで、そのstyle要素の親コンテナだけにスタイルを適用させることが可能になる。たとえば、

<p>...</p>
<div>
  <style scoped="scoped"> p { color: red; } </style>
  <p>...</p>
</div>

とすれば、div内のp要素だけにスタイルを適用できるようになる。
 残念ながらWebKit(HTML形式のプレヴューではWebKitが用いられる)は現在scoped属性に対応していない(確認した中ではFirefoxが対応している)が、今回のQuick Lookプラグインは各コンテントドキュメントのスタイル指定にscoped属性を付けるようにした。

 コンテントドキュメントの内容を抜き出す際、指定されているスタイル(style要素の内容とリンクされているCSSファイルの内容)をscoped属性を付けたstyle要素に入れていっしょにdivに詰め込むようにした。そうやってひとつにまとめられたHTMLは以下のような形になる。

<html>
  <body>
    <div>
      <style scoped="scoped">コンテントドキュメント1のスタイル</style>
      ...コンテントドキュメント1の内容...
    </div>

    <div>
      <style scoped="scoped">コンテントドキュメント2のスタイル</style>
      ...コンテントドキュメント2の内容...
    </div>

    <div>
      <style scoped="scoped">コンテントドキュメント3のスタイル</style>
      ...コンテントドキュメント3の内容...
    </div>
      
  </body>
</html>

 WebKitがscoped属性に対応していない現在では、各スタイル指定は各コンテントドキュメントの範囲を超えて全体に影響を及ぼす。その結果、表示に問題が出る可能性はあるが、EPUBの性質とリーディングシステムとの関係上、個別のコンテントドキュメントにあまり複雑なスタイルを当てることはあまりないはずで、これによる影響は少ないと思われる(少なくとも文字もののリフロー型では。固定レイアウト型は対象外)。
 それよりも、まったくスタイルが適用されなかったり、あるいは画一的なスタイル指定ではなく、個別のEPUBごとの雰囲気を再現する方針をとっている。将来、WebKitがscoped属性に対応すれば、スタイルの適用範囲が各コンテントドキュメントの範囲に限定されるようになるはずである。

2015年02月13日, 編集履歴

iTunesで再生中の曲にレート付けするウィジェットを作った

 OS X 10.10 Yosemiteから搭載された機能拡張(通知センターの「今日」ペインで動作する機能拡張を「ウィジェット」と呼ぶ)を用いて、iTunesで再生中の曲にレート付けをするウィジェットを作ってみた。ソースはGenjiApp/iTunes-Rating-Widgetで公開する。

Scripting Bridge

 iTunesからの情報取得や操作にはScripting Bridgeを用いた。Scripting BridgeはAppleScriptで操作可能なアプリケーションに対して、AppleScriptを用いずにObjective-Cからの操作を行うフレームワークである。

iTunesArtworkオブジェクトの謎

 Scripting Bridgeを用いてiTunesの曲情報を取得すると、アートワークはiTunesArtworkオブジェクトとして得られる(クラス名等の接頭辞iTunesは自分で設定可能)。このオブジェクトにはNSImage型のdataというプロパティがある。通常これを用いればCocoa環境で使いやすい画像オブジェクトが得られるはずである。
 アートワークがJPEG形式の場合、dataプロパティは問題なくNSImageが返すが、PNG形式だった場合、NSAppleEventDescriptorオブジェクトが返ってくるという謎の挙動を示す。仕方がないので、iTunesArtworkが持つ画像の生データrawDataプロパティを用いてNSImageを生成した。

com.apple.iTunes.playerInfoノーティフィケーション

 iTunesの再生・一時停止・曲送り・曲戻し操作の際には通知名「com.apple.iTunes.playerInfo」で通知が飛ぶ。これをNSDistributedNotificationCenterで捕まえて情報の更新を行った。

NSLevelIndicatorCellのハイライト

 NSLevelIndicatorを使うとiTunesのような星を用いたレート付けのGUIが作れる。しかし素のままで使うと、値が0のときに表示が何もなくなって解りづらい。レート付けの操作中、つまりハイライト時にはドットが表示されるので、NSLevelIndicatorCellをサブクラス化し、- (BOOL)isHighlightedが常にYESを返すようにしておいた。

コンテナアプリケーション

 機能拡張はそれ単体では開発・配布を行うことができず、主となるアプリケーションが必要になる。これをコンテナアプリケーションと呼び、コンテナアプリケーションに内包する形で機能拡張を開発・配布することになる。
 今回はそれは主眼ではないので、適当にシステム環境設定の機能拡張ペインを開くだけのものにした。システム環境設定の各ペインの実体は「/System/Library/PreferencePanes/」以下にあるので、目的のペインのURLを作成し、NSWorkspaceopenURL:メソッドで開いてやれば良い。

2015年01月06日, 編集履歴

Murasaki ver. 2.2.4をリリースしました

 OS X用EPUBリーダMurasakiのver. 2.2.4をリリースしました(アプリ紹介ページMac App Store)。

 ver. 2.2.4は、

です。この問題はTwitterアカウント宛にご報告いただきました。ありがとうございます。

2014年12月19日, 編集履歴

Mailto Interceptor ver. 1.2.2をリリースしました

 mailto:リンク等によるメールアプリケーションの即時起動を抑制するユーティリティMailto Interceptorをver. 1.2.2にヴァージョンアップしました。

 ver. 1.2.2の変更点は、

です。どうぞよろしくお願いします。

2014年12月13日, 編集履歴

Murasaki ver. 2.2.3をリリースしました

 OS X用EPUBリーダMurasakiのver. 2.2.3をリリースしました(アプリ紹介ページMac App Store)。

 ver. 2.2.3はバグ修正版です。修正箇所は、

です。この問題はコンタクトフォームよりご報告いただきました。ありがとうございます。