2013年7月16日火曜日

Kyoto.pm 05に参加してきました


このエントリーをはてなブックマークに追加
人生初の遠距離pm参加をノリできめて発表してきました。
ツイッターアカウントは知ってるけど話したことはない、って人が多くて来てよかったなーと思いました。

いつも通り、全体的なことは他の人が書くだろー、ってことで自分の話をすると、
EPUB::Parserってモジュールを書いたので、それについて書いた動機と、それの設計などをざっくり言った感じです。
僕的にはコードの設計を教えて欲しいなって気持ちだったんですが、発表って形式でいきなり出しても難しい感じでした。

余談ですが、EPUB::Filterというモジュールも書こうとしてて、
EPUB::Parserのスクリプトが返す{ "title" : "タイトル" } ってjsonを書き換えて、Filterのスクリプトに食わすとEPUBの中身が書き変わるというものです。
けど、Filterって銘打つならHTML::Filterっぽくせにゃいかんのかなー、そこまでは、、、って感じです。

発表資料: EPUBのパーサーとビルダー

作成動機
  • 電子書籍をweb上で作成、販売するサイトを運用
  • 出版社から頂くデータがEPUB3化
  • EPUB3仕様に完全対応した既存モジュールがない
  • 都度アップデートする必要があるなら得意なPerl製モジュールでないとキツい
発表動機
  • 設計やメソッド名について意見が欲しい
  • パーサーの話が主
EPUB::Parser
github
  • サイトで提供しているインポート機能のために作成
  • 現在EPUB3のみ対応
  • インポート時に必要となるデータの整形を吸収(パスの書き換え等)
  • XML::LibXMLを使用
  • ドキュメント追加中

EPUB::Parser設計
  • ファイル毎にクラス化しており、複数ファイルを参照する必要がある場合は責務を逸脱しないよう別の名前空間を用意(EPUB::Parser::ManagerとEPUB::Parser::Fileに分割)
  • 単一ファイルの中にもmanifestやspineなど重要な役割をもつノードがあるのでそれぞれクラス化(EPUB::Parser::File::**::Context::**)

 EPUB
 ├── Parser
 │   ├── File
 │   │   ├── Container.pm # META-INF/container.xml用クラス
 │   │   ├── Document.pm # 本文ファイル用
 │   │   ├── Navi
 │   │   │   ├── Context
 │   │   │   │   └── Toc.pm
 │   │   │   └── Context.pm
 │   │   ├── Navi.pm
 │   │   ├── OPF
 │   │   │   ├── Context
 │   │   │   │   ├── Guide.pm
 │   │   │   │   ├── Manifest.pm
 │   │   │   │   ├── Metadata.pm
 │   │   │   │   └── Spine.pm
 │   │   │   └── Context.pm
 │   │   ├── OPF.pm
 │   │   ├── Parser #各ファイル用パーサー. xpathのネームスペース設定とコンテキスト切り替えを行う
 │   │   │   ├── Container.pm
 │   │   │   ├── Document.pm
 │   │   │   ├── Navi.pm
 │   │   │   └── OPF.pm
 │   │   └── Parser.pm # 各ファイル用パーサーの親で、find,singleメソッドを持っている
 │   ├── Manager
 │   │   └── Pages.pm
 │   └── Util
 │       ├── Archive.pm         # zip内データをイテレータで返す
 │       ├── AttributePacker.pm # 任意の属性値を主キーとしたデータ構造を返す
 │       ├── Context.pm  # EPUB::Parser::File::**::Contextの共通メソッドエクスポート用.
 │       │               # 安易にUtilに置いてしまった
 │       ├── EpubLoad.pm
 │       └── ShortcutMethod.pm # EPUB::Parserにメソッドエクスポート
 └── Parser.pm
  • データ構造を作成するメソッド命名が難しい。ノードの任意の属性値を主キーとして、データ構造を返す処理など。
  • テストはsubtest名に完全なメソッド名を書いてgrepで特定できるようにしている
  • 面倒くさいと言われたのでショートカットメソッドを作った。$self->opf->metadata->titleが$self->titleに。しかしショートカットメソッドは作り出すとキリがなく、EPUB/Parser.pmが本質と関係ないコードで肥大化するので、EPUB/Parser/Util/ShortcutMethod.pmからエクスポートすることにした。
EPUB3::Builder(cpan化の予定無し)
github
  • 入力xhtmlのbody部をepub3用のテンプレートに流し込む
  • メタデータ等の作成
  • naviファイルは全ページ列挙してるだけ
  • テストでxmlを比較するにはXML::Compareを使った

jsでグラフ生成をためしてみたい
http://code.shutterstock.com/rickshaw/


0 件のコメント:

コメントを投稿