Atomのパッケージを作った話。

ついでに、パッケージプロジェクト内で別のプロジェクトを取り込んで使いたい場合に、Gitのサブモジュールを使ってはダメという話。

impress.js

impress.jsというJavaScriptライブラリがある。 HTML5とCSS3とJavaScriptでプレゼン資料を作るためのライブラリで、これを使うと、PowerPointKeynoteといった従来のツールによるものからは一線を画す斬新な資料を作ることができる。

公式のデモを見ればその魅力を堪能できる。

デモを見ると分かるが、Preziに触発されたライブラリだ。 Preziでも非常に新鮮な資料を作れるが、ほぼ有料で、また作成した資料をPreziのサーバに置かなければいけないので、仕事で使う資料作りには使いにくい。 その点impress.jsは、MIT(とGPLv2)で公開されていて自由に無料で使えるのがよい。

ただし、Preziがスライドという概念から大きく脱却しているのに対して、実のところimpress.jsで作れる資料はあくまでスライドベースだ。 従来のものに比べてスライドの並びに制約がなく、スライド間の遷移がダイナミックというだけだ。 impress.jsでもまあ工夫すればPreziのような資料は作れるが。 独自のオーサリングツール/ビューワに依存するPreziに対し、impress.jsは標準的なHTML/CSS/JavaScriptにだけ依存しているので、jQueryなどのWeb技術を活用してスライドを作れるという副次的なメリットはある。

impress.jsは、2012年に最初のバージョンが公開されてからもう4年近く経つが、未だにそれほど広く使われている様子はない。 PowerPointが幅を利かせているせいもあるだろうが、その使い辛さから利用をためらう人が多いのではないだろうか。 impress.jsはあまりドキュメントが充実しているとは言えない。 GitHubに公開されているREADMEには、使い方はソースを見よ、それで分からないなら使うなとある。 さらにソース中には、impress.jsを使うには、HTMLとCSSのスキルに加えてデザイナーのセンスも必要とある。 かなりハードルを上げている。

このハードルをクリアしていたとしても、実際、impress.jsで資料を作るのはPowerPointに比べて10倍は大変だ。 impress.jsはスライド(impress.js用語ではステップ)間の遷移を制御してくれるだけで、各スライドのコンテンツを作るという部分に関してはなんのサポートも提供しない。 テンプレートもなければ、表やグラフを書く機能もなく、アニメーションも作れない。 そういうことをしたければ、自分で別途ライブラリを探して使うなりしないといけない。

ちょっとした図を書くにも、テキストエディタでちまちまHTMLとCSSを書いて、ブラウザで表示して確認して、思った通りになっていなければディベロッパツールでデバッグして、Web UIでも書いていたんだっけという気になってくる。

impressパッケージ

そんな負担を少しでも軽くしたいと思って作ったのがimpressパッケージ

同じ目的のツール(i.e. オーサリングツール)は実は既にいくつかあった。 なかでも、Hovercraft!というのが高機能で便利そう。 ただ、これらはPowerPointほど自在にスライドを作れるまでには至っておらず、結局は仕上げにHTML/CSSを手でいじる作業が必要になる。(と思う。) また、jQueryのプラグイン使ってかっこいいことしたいとか言う場合にも、手でコードを書かなければいけない。

つまりテキストエディタを開かなければいけない。よってAtomを起動することになる。(私は。)

であれば、オーサリングツールもAtomに統合されていた方が便利なんじゃないの? というのがimpressパッケージを作った動機。

まだ機能は少なくて、新規資料プロジェクトの雛形生成、

new_project

ステップをリスト表示するビュー表示、

step_list_view

プレビューができるだけ。

preview


ゆくゆくは、GUIでステップの配置や角度を編集する機能、GUIでステップ内の図を作成する機能を作りたい。 あとできればアニメーションを付ける機能とかも。 Hovercraft!みたいにHTML書かなくてもいいよ、というのを目指すつもりはなくて、あくまでもコーダーのための、コーディングを補助するツールを目指す。

パッケージのサブモジュール

impressパッケージは、新規資料プロジェクトの雛形生成機能などのため、impress.jsプロジェクト(のフォーク)をサブモジュールとしてとりこんでいる。

最初はGitのサブモジュールコマンド(git submodule)を使って取り込んでいて、上手くいっているように見えたが、パブリッシュ後に次のような問題が発生した。 即ち、試しにimpressパッケージをインストールしてみたら、サブモジュールのフォルダの中身がからっぽだった。

これは、AtomのパッケージマネージャがパッケージをGitHub Releasesからダウンロードしてインストールするからだ。サブモジュールの中身はGitHub Releasesに登録されるアーカイブに含まれない。このGitHub Releasesの挙動は、サブモジュールを含むGitプロジェクトをクローンした場合、デフォルトではサブモジュールはクローンされないというGitサブモジュールの仕様に関係しているのかもしれない。

この問題をきっかけにGitサブモジュールについてちょっと調べてみた。 蝙蝠本によると、Git開発チームはあまりサブモジュールコマンドの開発に熱心ではなく真面目に作らなかったらしい。 また、あるブログによればサブモジュールコマンドは大分まえからオワコンらしい。このブログによれば、今は多くの場合git subtreeを使うのがいいとのこと。git subtreeは蝙蝠本にもPro Gitにも載ってないのだが。

git subtreeでプロジェクトを取り込んだ場合、親プロジェクトのクローン時にサブプロジェクトもデフォルトでクローンされる仕様だ。 (というか正しくは、サブモジュールと違って、子プロジェクトが親プロジェクトにマージされているから、一緒にクローンされるというだけ。) これを使ってimpressパッケージを構成しなおしてみたら件の問題が解決した。 因みにやりかたは、impressパッケージプロジェクトのルートにimpress.jsというフォルダを作った後、以下のコマンドを実行しただけ。

# git subtree add --prefix impress.js [email protected]:kaitoy/impress.js.git master --squash


ということで、Atomのパッケージに別のプロジェクトを取り込んで使いたい場合は、git submoduleではなく、git subtreeを使わないといけないという教訓を得た。