このエントリは、TeX & LaTeX Advent Calendar 2013 の参加記事です。 前の記事は k16shikano さんの『Learn You The TeX for Great Good! 「第3章 マクロ初級講座」』、 次の記事は、neruko3114 さんの『私とTeX』です。
私は、ここ8年ほど、OmniOutlinerというアウトラインプロセッサを使ってTeXで各種原稿を作成しています。 今日は、その背景と、今使ってるワークフローを説明してみようと思います。 ドキュメント保存するだけで、自動生成されたPDFのプレビューも更新されるようにできます。
TeX好き + アウトラインプロセッサ好き + OmniOutliner 好き、という組み合わせ故の、かなりオカシイワークフローですが、もしかすると誰かの役に立つかもしれません。
長いですが、背景をちょっと説明させてください。 いや、単に、誰かに話したいけれど、話す相手が居なかった話なので。。(笑)
TeX使って長いのですが(ASCII TeXの初期のころから、ぐらい)、論文のような長めの文章を書くようになったのは比較的最近です。 それより前は、長い文章は、あまり書いてませんでした。 一方、仕様書や報告書を書いたり、見積・請求・納品等の文書の生成や、ウェブ上で作ったサービスでのPDFの自動生成のバックエンドに使うのなど、TeXを道具として使うのは常套手段でした。
TeXは道具として散々使っていて分かっていたつもりだったのですが、論文を書くようになった当初、TeXを使って長い文書を書くのがかったるいなぁと思った事がありました。
自分が感じていた問題点の一つは、TeXのソース自身は単なるテキストファイルで ( 無論、それはとても価値があることなわけですが )、こう、整形されていない文字が並んでいるソースファイルだけを見ても、全体の印象を想像するのが、ちょっとムズカシイという点でした。
テキストエディタで書いている以上、どうしても避けられない点ではあります。
アウトラインプロセッサという類のソフトがあり、これまた、かなり昔からあります(歴史については、最後の方を参照)。 文書を木構造に整理して整理しながら書けるもの、といえば良いでしょうか。 さらに、枝を開いたり閉じたりを任意にできるので、作業したい部分(枝)だけを出して、集中することができます。
無論、使っている人もいらっしゃると思いますが、使ってるという人の話をあまり聞かないので、実は、使われていないんではないかという印象を勝手に持っています。モッタイナイ話です。 Microsoft Wordにもアウトラインモードはあるのですが、使ってないんじゃないでしょうか。 Emacsにもアウトラインモードがあるのですが、Emacsに指が慣れきっている私にとっても、どうもアレは馴染めない感じです。 一度、アウトラインプロセッサのアプリケーションを使い始めると、単なるテキストエディタで文章書くのが辛くなります。
ただ、アウトラインプロセッサには欠点があって、どうしても文章がツリー構造の箇条書きになってしまうのです。 印刷したときの「見た目」が、どうも芳しくない。 なにか、私にとっては、文章は整形されて四角くなっているものであり、段付けの文書は「生煮え」状態だと、脳ミソが訴えるのです。 結果、どうも、読む気が起きません。
また、アウトラインプロセッサでの出力を印刷して人にみせても、なぜか、読んでもらえる気がしないのです。
さらに、アウトラインプロセッサを使える環境にあるかどうかは結構重要な点です。
専用ソフトをつかっているため、文書を共有する人がいる場合、アプリを揃えて使う必要がありますが、
アウトラインプロセッサのアプリケーションは、だれもが使うようなものではありませんから、ファイルを行き来させて使うような方法はムズカシイのです。
アウトラインプロセッサに親しんでいるせいで、TeXのソースをEmacs等のテキストエディタで書き進めるのが苦痛でした。 特に論文のような構造を持った文書を書くときは、アウトラインプロセッサのような仕掛けを武器に、議論の構造を練り上げたいわけです。
一方、アウトラインプロセッサの文書をそのまま印字して読むのは苦痛です。 良くも悪くもTeXで鍛えられたせいで、適当にフォーマットされた文書を読むのにとても抵抗がありますし、人に見せるのにも抵抗があります。
こんな形で、ムズムズしていたのですが、 論文を書くようになったのと同時期に、しばらく離れていたMacintoshを再び使うようになりました。 また、書く文書は、かなり私的なものが大半となったので、専用アプリを使っても問題ありませんでした。 そこで、MacOS X用の、OmniOutlinerを見付けて使うようになりました。
そしてある日、愛用しているOmniOutlinerのファイルがgzip圧縮されたXML書式であることに気づきました。
それならば、OmniOutlinerの出力ファイルを加工してTeXファイルを生成すれば、結構便利に使えるのではないかと思ったのです。
こうして生まれたのがoo2texというスクリプトでした(未公開)。
OmniOutliner の .oo3
拡張子を持つファイルを読み込んで、TeXのソースとして出力します。
このスクリプトは、フォント指定や色等といった文字のスタイルが、保存されるファイルのXMLの属性に反映されることを利用して、OmniOutlinerで表現された文字スタイルからTeXのマクロに展開する機能を持っていました。
たとえば、ボールドの文字列にしていれば、{\bf ..}
と置き換えたり、ハイライトされている文字は、TeXの出力でもulemパッケージの書式でハイライトするといった形です。
また、最近よく用いられているMarkdown形式に近い形で、\section
や \subsection
といったヘッダを指定する機能も合わせて持っていました。
一部をTeXに対する出力の対象から外したり、デバッグ用のコメントを欄外に印刷したりといった機能も持っていました。
このスクリプトは、その後5年ほどメンテナンスし続け、最終的に博士論文を仕上げるまで使いました。
左がOmniOutlinerの画面、右がPDF ビューア (Skim)です。
ところが、最初から覚悟はしていたのですが、細かい機能を入れすぎたせいで、自分で使うのはともかく、人に使ってもらうのが極めて難しくなってしまいました。
自分でメンテナンスするにしろ、後方互換性を捨てるかどうかでどうしても迷いが出てきました。
一方、自分が一番やりたいことは、実は、アウトラインプロセッサでTeXのソースを書くことができれば達成でき、複雑なスタイルのマッピング機能が無くても充分に実用になるのではないかと気づきました。
こうした事情から、思い切って機能を単純化した oo2md2tex
を作りました。
oo2md2tex
は oo2text
, md2tex
, ja-ten-maru-normalize
という3個のスクリプトから構成されます。Rubyで書いています。それぞれ、非常に単純なものです。
一つ目のスクリプトは、OmniOutlinerのファイル(拡張子 *.oo3
)を読み込み、内容を、そのままの順序で、テキストファイルで出力するものです。
二つ目のプログラムは、Markdown形式のファイルから TeX への変換を行うものです。ただし、ごくごく単純な事しかできません。
三つめのスクリプトは「、。」「,.」の正規化をするスクリプトです。
make
を使っているのであれば、通常の.tex
ファイルをPDFに変換するスクリプトに少し追加するだけで、OmniOutliner で書いたソースをTeXに変換し、さらにPDFへと自動的に変換できます。
Makefileとサンプルデータは、 oo2md2tex/sample にあります。
oo2md2tex
に、二つのツールを組み合わせると、TeXShopに負けない快適な環境が出来上がります。以下のツールを組み合わせて使うと良好です。
アジャイル系やテストドリブン開発などをしてる人にはお馴染みですが、指定したディレクトリのファイルが変更になった時に、特定のコマンドを実行するツールがあります。 例としては、古くは watchr、最近の流行はGuard でしょう。
ファイルが書き換わった場合に、それを検知して自動的に読み直してくれるタイプのビューアを使います。 私が使っている限りでは、Skimがうまくつかえています。
今まではWatchr
を使っていましたが、メンテされない状態が続いているので、Guardに乗り換えしようとしてます。
今回、Guard
を使って例を示したかったのですが、.oo3
ファイルの変更をうまく検知してくれないので、その部分については涙をのんで省略します。
博士論文を書いていたときは、Macにディスプレイ二枚付け、一枚のディスプレイでPDFをプレビュー、片方で資料見ながら編集という形で作業を進めていました。 OmniOutlinerでセーブすると即座にPDFが出て結果が見られますし、ある種のPDF表示プログラムを使っていると、自動で読み込まれて同じ場所が表示されて、大変良好です
(ここにスクリーンスナップショットを貼るつもりだったのですが、最近作ったツールで、再録になってはいても、まだ、公開されていない論文ばかりなので、作業環境は↑の博士論文のものから想像してください:D ごめんなさい。)
ただ、若干問題があります。TeXがエラーで止まってしまった場合、PDFが一旦削除されてしまいます。このあと、正しくPDFが生成されても、Skimはこれを認識してくれません。この場合は開き直す必要があります。 あと、TeXShopなどのように、エラーが出た場合に、ソースを参照するのが困難です。これについては、AppleScript利用する仕掛けが作れるかとも思うのですが、ちょっと難しそうですね。
そんなわけで、長々とお付き合いいただきありがとうございました。 アウトラインプロセッサというもののアイディアや、その歴史については、Dave Winerのサイトに詳しい記事があるので( Outliners & Programming )、オススメです。 使ったことがないなら是非試して下さい。 なお、今回のユースケースとは全く無関係ですが、Dave Winerは、最近、Webベースのアウトラインプロセッサ ( Little Outliner ) に取り組んでいて、中々興味深いです。
蛇足ですが、この記事は、Jekyllを使って用意しているということで、Markdown形式です。 そんなわけで、こんな形で作業をしているのです。
左がOmniOutliner、右上はMarkedというMarkdownプレビューア、右下はSafariです。 これについては、Guard が使えるようになったときにでも。
あと、追伸。なんでTeX Advent Calendarに参加する気になったというと、TUG 2013 Japanに参加したからです(TUG = TeX User’s Group)。
まさかTUGのミーティングが行われる日が来るとはね。関係者の皆様に大感謝です。