このアドベントカレンダーでは、先週まで、主にページメディアにおける「PDF」と「XML」の話をしてきました。 この2つ、それぞれ「Webブラウザでのレンダリング」と「HTML」に言い換えると、ウェブメディアの世界観と似ている気がしてこないでしょうか。
実際のところ、ウェブメディアとページメディアって互いに遠い存在ではなく、「平面に文字などを配置することを目的とした構造化文書」という視点に立てば、むしろ兄弟みたいなものです。
「Webブラウザへの表示がHTMLだけで済むわけないだろ、CSSやJavaScriptの役割を知らないのか」という指摘が聞こえてきそうですが、ページメディアにもそれらに相当するものは存在します。 というか、いろいろありすぎて、もはや収拾がついていません。 ページメディアでわりと標準っぽいのは、CSSの役割がXSL-FO、JavaScriptの役割がXSLTという、いわゆるXML組版的な世界観でしょう。
ちょっと話は逸れますが、個人的にこの世界観で面白いなと思うのは、「すべてを同じ構文で済ませよう」とする点です。 XSL-FOでも、XSLTでも、山かっこXML構文が採用されています。 特別なGUIアプリを使わない限り入力も山かっこXML構文なので、おはようからおやすみまですべてがXMLになります。
もっとも、TeXにしても入力から表示制御まですべてを同一の記法で完結させているので、むしろ面白いのは、HTMLとCSSとJavaScriptという異なる記法の技術を当然のように組み合わせているウェブの世界観のほうなのかもしれません。 仕組みを考える側からしても、入力も変換も表示制御もすべてを同じ構文で済ませるほうが、周辺ツールなどを統一的に扱えるので理想的でしょう。 とくにXMLだと構文エラーが機械的に判別しやすく、さらにスキーマを適切に扱えば妥当性検証のようなご利益がもれなくついてくるので、そのような傾向が強いのかもしれません。
ただ、ぼくには、XML組版やTeXのように単一の記法ですべてを完結させる世界観はちょっと馴染めませんでした。 馴染めなかったというよりは、そこまでの腕力がなかっただけともいえます。 そこでウェブメディアにおいてCSSが担っている役割はLaTeX、JavaScriptが担っている役割はSchemeにして、商品としての本を作れていますよというのが、先週の話です。 「ふつうの書籍くらいの規模であればXML組版でなくても構造化文書からの自動組版は十分に可能である」という話だったと思ってもらってもかまいません。 (もちろんこれはXML組版の否定ではなく、たとえばDITAの導入が必要といった具体的な目的意識がある状況であれば、この連載のようなXML組版に対する態度が役に立たないのは言うまでもありません。)
意味の構造、見た目の構造、表示結果
前置きが長くなりましたが、「平面に文字などを配置することを目的とした構造化文書」から実際にコンテンツを平面に配置するまでの流れ的なものを整理しておきます。 いろんなモデル化が考えられると思いますが、ここではまず「意味の木構造」、「見た目の構造」、「表示結果」の3段階で考えます。 これはWebブラウザのモデルに沿ったモデルで、「意味の木構造」は入力されたHTMLもしくはJavaScriptでいじれるDOMツリー、「見た目の構造」はそれにCSSを適用したレンダーツリー、「表示結果」はWebブラウザが表示するレンダリング結果に相当します。 このブログ的には、「意味の木構造」はTeX記法やXML記法の原稿、「見た目の構造」はPDFのドキュメント構造、「表示結果」はPDFビューワーが表示するレンダリング結果です。
XML組版は、これの最初の2つの段階にかかわる要素技術をすべてXMLでやろうというアプローチだといえます。
LaTeX組版の場合、そこまでとんがった使い方をしたがる人は実際には少なく、見た目の構造にはDVIドライバの存在もあったりしてTeX構文でない世界になりますが、このモデルに当てはめるとだいたいXML組版と同じようなノリにはなります。
構造は記法とは別
今日の本題はここからです。 先ほどの3段階モデルには、実際にはその前に「記法」があると考えるのが自然でしょう。
XML組版やLaTeX組版だと記法がXMLやTeXそのものなので意識されにくいんですが、人間が読み書きする記法を「意味の木構造」の生の姿と同一視する必要はないので、ここは区別して考えられるはずです。
ここの同一視を明確に区別して考えると、いろいろ説明がしやすくなります。 たとえば、Re:VIEW(処理系)やSphinxは、Re:VIEW(記法)やreStructuredTextを「記法」としてそれぞれが内部で利用する「意味の木構造」を作り、RubyやPythonで調整しつつLaTeXやHTML/CSSによる「見た目の構造」へと変換し、それらの仕組みによって表示結果を得る仕組み、と説明できます。 CSS組版なんかも同じように説明できるでしょう。
さらに、記法を意味の木構造と区別すれば、ある記法から非標準的な方法で表示結果を得ることもできます。 実際、当社の『プロフェッショナルSSL/TLS』の制作フローでは、記法としては原書と同じXMLを使っていながら、それを標準的なXML組版の流れでなく、LaTeXによる「見た目の構造」へとSchemeで変換することで最終的な表示結果を得ています。
Pandocの構造は構造化文書の構造ではない
「記法」と「構造」、とくにこのモデルでいう「意味の木構造」を明確に区別しようという話は、先週の記事でもときどき触れていました。 なんでこれをそんなに強調しているかというと、この区別をつけないと「構造化文書」の話が「記法」の好き嫌いの話になってしまいやすいからです。 XML組版やTeXは「記法」と「構造」に見た目上の区別があんまりないので、「記法」の好き嫌いで選んでしまうと、他の部分の特性を見失います。 また、部分の特性ばかりを強調すると、「記法」がつらくても我慢して使えみたいな話になり、これはこれであまり健全ではないと思います。
さらに、「記法」と「構造」を混ぜて話すと、HTMLベースの「意味の木構造」に対する「記法」として生まれながら後で「記法」の部分だけが独り立ちしたMarkdownの可能性が見えにくいでしょう。
もうひとつ、この混同を放置したままだと可能性をうまく生かせなくなる技術があると思っていて、それがPandocです。 Pandocの価値の中核は「記法」レベルでの変換であり、変換対象の「記法」がもともと想定している「意味の木構造」より後ろの工程は、Pandocにとってはおまけでしかないからです。
各「記法」が想定している「意味の木構造」の代わりに、Pandocでは独自の抽象データ型を利用します。 その抽象データ型から、さまざまな「意味の木構造」のサブセットが作り出せるようになっています。 そして、この抽象データ型を暗黙に構成するための「記法」として、PandocのMarkdown記法があります。
ちなみに上の図にも示しましたが、このPandocと同じ世界観の仕組みとして、Sphinxがバックエンドで利用しているDocutilsがあります (Docutilsをこのようなモデルに合わせて使ったことがないのですが、『マスタリングDocutils』を読んだ限りでは、たぶんそう)。
もうひとつちなみに、このような「記法から何らかの抽象データ型を暗に読み取り、そこから後段の処理系が自由になるような意味の木構造を生成し、そっちの処理系で表示結果を得る」という戦略は、謎の記法の原稿に対峙するときの基本技でもあります。 そのための武器としてPandocやDocutilsを使ってもいいし、自分でパーサを書いてもいいでしょう。
そんなわけで、構造化文書だからといってXMLやLaTeXのような「意味の木構造」のための従来のフレームに縛られる必要はなく、「記法とそれに対する抽象データ型」でライトウェイトに構造化文書をやっていくのがトレンドになるといいなと考えています。