golden-luckyの日記

ツイッターより長くなるやつ

QUICとHTTP/3時代のインターネット解説書はどうあるべきだろう

OSI参照モデルTCP/IPモデル

かつてぼくたちは、7つのレイヤに分かれたOSI参照モデルという姿でコンピュータネットワークを学び、その7層のモデルにそって各種のプロトコルを理解しようとしていました。 だから、「SONET/SDH上のATM回線でIPパケットをやり取りする」という構想をきけば、「つまり、SONET/SDHがレイヤ1で、ATMがレイヤ2で、IPがレイヤ3なのだな」という枠組みを頭に描いていました。

と同時に、OSIのレイヤとはいったい……、というアンビバレントな想いにさいなまれることもよくありました。 「SONET/SDHがレイヤ1っていうけど、これレイヤ2の話も含まれてるような気がする」とか、逆に、「ATMってレイヤ2とされるけど、レイヤ1の話も含まれているような」とか。

それでもまだ、このへんの低レイヤのネットワーク技術は、OSI参照モデルの各層になんとなく合致しているような雰囲気がありました。 本当に混乱するのは、レイヤ5以上です。 ぼくの稼業はネットワーク技術の解説書を作ったりすることなんですが、レイヤ4を下位層として利用するさまざまな技術に対し、誰もが納得するようなOSI参照モデルの階層を与えるという仕事は、いつだって絶望的でした。 それでもなお、現在のようにすべてがインターネットになる以前は、OSI参照モデルの枠組みで理解すると都合がよいプロトコルスタックもありました。 OSI参照モデルに立脚した技術解説を与えることは、インターネットの時代になっても十分に意義があることだと自分を思い込ませながら、解説書を作っていました。

そうこうするうちに、コンピュータネットワークの世界は、事実上インターネットと互換な技術ばかりになります。 それらインターネットを前提に開発された技術は、OSI参照モデルに準拠して開発されたわけではありません。 OSI参照モデルのレイヤという枠組みで、それらの技術をすっきり説明することは、ますます絶望的になりました。

実際のところ、そうしたインターネット前提の技術(長いので以降ではインターネット技術と総称します)をうまく説明するだけなら、OSI参照モデルのすべてのレイヤについて語る必要はありません。 インターネット技術の中核となるのは、パケットをずっと先まで転送するための「IP」と、転送されるパケットをさらに上位のアプリケーションに結び付ける「トランスポート」です。 この2つのレイヤと、その上下のレイヤの合計4つだけを見れば、インターネット技術について語るには十分でしょう。 このようなモデルを、ここでは「TCP/IPモデル」と呼ぶことにします。

(IP、トランスポート、その上下のレイヤという4つの層にゆるく分けてインターネット技術を説明するモデルは、インターネットに接続する端末の技術要件を整理したRFC 1122にまとめられています。 RFC 1122では、この説明モデルの名前を特に定めていませんが、一ヶ所だけ「インターネットモデル」という言い方をしているので、ひょっとすると「TCP/IPモデル」よりも「インターネットモデル」と呼ぶほうが正確かもしれません。 しかし、この記事では、このモデルをモデルたらしめている部分を担うIPとTCPというプロトコルを強調したいので、「TCP/IPモデル」と呼ぶことにします。)

なぜいまでもOSI参照モデルによる説明が多いか

ここまでのおさらい。

  1. かつてOSI参照モデルというものが論じられ、ネットワーク技術の解説でもそれに沿ったアプローチが採用された
  2. ネットワーク技術の多くがインターネット技術と同義になっていくなかで、その技術の理解を促すのにOSI参照モデルは最適とはいえず、TCP/IPモデルと呼ぶべきモデルが考えられた

しかし、インターネット技術の解説においてTCP/IPモデルはあまり採用されていないように見えます。 むしろ、旧来のOSI参照モデルに照らしてインターネットを支える各種のプロトコルを説明していくスタイルの解説書のほうが優勢でしょう。

なぜ、インターネット技術の解説でも、OSI参照モデルが依然として採用され続けているのでしょうか?  解説のアプローチをTCP/IPモデルに移行できない根本的な理由があるのでしょうか?

理由の1つとして考えられるのは、「レイヤ2ネットワーク」とか「レイヤ3スイッチ」のようなOSI参照モデル由来の用語がそれなりに普及しているという現状でしょう。 これらの用語について説明するには、「2」とか「3」といった数字が何を意味するのかを解き明かす必要があり、そのためにはOSI参照モデルについてまったく紹介しないわけにはいきません。

そしてもう1つ、私見ではこちらのほうが理由として大きいと想像しているのですが、説明方法を変更するリスクを負いたくないという解説側の思惑があるような気がしています。 現代のネットワーク技術について説明するには、レイヤという概念がとても便利です。 なにせ、前述したRFC 1122でも、「きっちりレイヤを分けたモデルでインターネット技術を考えることは、それが仕様であれ実装であれ不完全(な理解しかもたらさない)」と明言しつつ、要件の整理には4レイヤからなるTCP/IPモデルを採用しています。

データをカプセル化し、あるプロトコルが提供する機能を別のプロトコルから呼び出して使うという抽象的なインターフェースを理解するには、プロトコルが層になったモデルで考えるのが手っ取り早いでしょう。 その概念を教えるためのアプローチとして、長年にわたり採用されてきたのが、OSI参照モデルです。 レイヤという、だいぶ説明がめんどくさい概念について、いままでの解説と同じ枠組みをそのまま再利用したいという要求があったことは想像に難くありません。

都合がいいことに、インターネット技術の中核となっているIPとトランスポートは、それぞれOSI参照モデルにおけるレイヤ3とレイヤ4にだいたい対応していました。 そのため、OSI参照モデルについて説明した部分は従来のまま、「このうちのレイヤ3がIP、レイヤ4がトランスポートです」という感じに説明を済ませることができます。 インターネット技術について解説するにあたり、OSI参照モデルを破棄する必要は特になかったのです。

こうして、技術理解にとって最適な枠組みはOSI参照モデルからTCP/IPモデルに変わったにもかかわらず、その解説ではOSI参照モデルが採用され続けるという状況が続きました。 OSI参照モデルの7つのレイヤをすべて意識し、そのすべてに個々のインターネット技術を対応させないといけない状況は、こんな具合にして形成されるに至ったのだと思われます。

QUICは、TCP/IPモデルのトランスポートとはいえるが、OSI参照モデルのレイヤ4とはいいにくい

ここからが本題です。

いま、TCP/IPモデルにおけるトランスポートを担う新しいプロトコルとして、QUICが標準化されつつあります。 このQUICの役割を解説するにあたって、ぼくらはいよいよ、OSI参照モデルというネットワーク技術の解説方法を手放すべきではないでしょうか。

これは、これからはOSI参照モデルではなくTCP/IPモデルを使ってレイヤの考え方を解説すべきという話ではありません。 むしろ、金科玉条のモデルはないという事実を受け入れて、もっと別の説明の仕方を考えないと、どう説明しても無理が生じる(場合によっては間違いと指摘されかねない)状況に陥るだろう、その好例がQUICではないか、という私見です。

QUICは、OSI参照モデルに押し込めればレイヤ4にあたりますが、たとえばTCPの代わりにQUICをそのまま使えるわけではなく、同じレイヤ4のプロトコルであるUDPが必要です。 OSI参照モデルにのっとった解説だと、この時点でもうすっきりしません。 UDPでレイヤ4の機能を実現しているのだから、QUICはレイヤ5、あるいはレイヤ6になるのでは?  実際、そういう側面もあります。 OSI参照モデルにのっとった解説では、TLSの機能をレイヤ5とかレイヤ6に分類することがありますが、QUICにはTLSで実現していた機能も含まれています。 そう考えると、QUICのことをレイヤ4のプロトコルとして考えるのは間違っているようにも感じられます。

では、いっそのことQUICをレイヤ5からレイヤ6を統合したプロトコルと説明するのはどうでしょうか?  それはそれで、QUICをTCP/IPモデルにおけるトランスポートプロトコルとみなす説明と矛盾しそうです。 トランスポートプロトコルだといえるけど、OSI参照モデルの枠組みで説明しようとするとレイヤ5や6に区分されてしまう、そういう役割にQUICという名前が与えられた、というのが実態に近い気がします。

そもそも、なんでこんな、従来のモデルにおけるレイヤ分けに合致しないプロトコルが誕生したのでしょうか?  この疑問について考えることが、おそらく、これからのネットワーク技術の解説の仕方を考えることになると思います。

ぼくの現在の考えを先に言ってしまうと、OSI参照モデルであれインターネットモデルであれ、既存のレイヤのモデルを頭に思い浮かべてそれに沿ってQUICを説明しようとすると、たぶん破綻します。 プラトンイデア的な理想のレイヤのモデルはありません。 ぼく自身、そういう理想のレイヤの存在を暗に前提していて、そのうちの1つのレイヤを担うプロトコルとして開発された技術という視点でQUICをとらえようとした結果、上記のようにわけがわからなくなっていました。

それなら、そういう視点を捨ててネットワーク技術のトレンドからQUICの意義を素直に考えて、そのうえで来るべきネットワーク技術の教科書の姿を思い描いてみようというのが、この記事で言いたいことです。

HTTP/QUICモデル

QUICのことを、TCP/IPモデルに当てはめると、トランスポートを担うプロトコルとされます。 しかし同時に、QUICは、TCP/IPモデルにおけるトランスポートとしてUDPを使います。 この2つの事実は、きっちりレイヤ分割されたモデルの世界観に照らして考えると、どうにも矛盾しているような気がします。 しかしこれは錯覚で、実際には上下2つの観点から冷静に技術トレンドとして考えるとすっきり説明がつきます。

まず上から考えましょう。 現在のインターネットを支配しているサービスはウェブです。そして、そのウェブを担うプロトコルHTTPです。 HTTPは、従来はトランスポートとしてTCPを利用しています。

HTTPの未来について考えている人たちは、ここで、トランスポートとしてTCPを使わずにHTTPをやる方法はないかと考えました。 なんでそんなことを考え始めたかというと、TCPのやり方をハックして接続を確立するまでの手間を減らしたり輻輳制御や再送処理をいじったり並列に接続を張って多重化したりしたいけど、TCPの機能はOSに組み込まれていて簡単には変更できないから。 で、そういう仕掛けをHTTPに組み込んだ魔改造HTTPの開発に着手しました。 この魔改造HTTPには、必然的に従来のTCPで提供されていた機能も含まれます。 そこで、この魔改造HTTPを開発したGoogleは、これを「トランスポートの機能を提供する新しいプロトコル」として発表しました。 これがQUICです。 Googleは、以前にも魔改造HTTPを作ってインターネットで運用し、HTTP/2として標準化までもっていきましたが、こちらは最初からTCPを利用するプロトコルとして開発されました。)

ここで問題になるのが、このGoogle魔改造HTTPであるQUICをどうやってインターネットに載せるかです。 トランスポートなので、可能ならIPv6の上に直接載せたいくらいだけど、そんな通信を許してくれるように世界中の通信機器を変更することはできません。 そこで、既存の中間機器すべてで既に対応済みであろうUDPを使うことにしました。 これにより、途中の機器ではUDPポート80や443を通ってやりとりされるパケットとして、この魔改造HTTPをいまのインターネットにそのままのっけることが可能になりました。 これが、QUICを下からみた場合の実体です。 要するに、UDPを使うことはQUICにとって本質的な要請ではなく、たまたま運用上都合がよかったからです。 なんでこれをわざわざ強調するかというと、QUICが登場したころの記事では「UDPなので速い」という論調の解説が多くあり、ぼくもつい最近まではそれを真に受けていたからです。

さらに、このGoogleが実装した魔改造HTTPとしてのQUICは、IETFで標準化されるにあたり、本来のHTTPっぽい部分は分けて考えられるようになりました。 QUICのうち、このHTTPよりの部分だけを指すときには、「HTTP over QUIC」という表現が使われるようになります。 この部分には、その後、「HTTP/3」という正式名称がつきます。

こんなふうに、現在標準化が進められているQUICを見ると、最初から汎用のトランスポート技術として開発されてきたわけではなく、HTTP中心の世界観からの要請で出発していることがわかります。 実際、QUICの最初の標準は、HTTP/3に特化したものに限定することが合意されているようです。 QUICをTCP/IPモデルでトランスポートとしてすっきり説明できないのは、こう考えると当然であるように思えます。 むしろQUIC(とHTTP/3)について解説するときは、HTTP/QUICモデルという、TCP/IPモデルとはまた別の見方をしたほうがいいのではないかと思えるくらいです。

QUICをどう解説するか

さて、本記事的に肝心なのはここからです。 TCP/IPを中心にした世界観から、HTTP側の要請で従来のTCPのさまざまな機能を提供しようという世界観になりつつある中で、インターネットの仕組みをどう解説するか。 ぼくはQUICもHTTP/3も具体的な仕様に熟知しているわけではないので、解説そのものは書けませんが、どういう構成にするのがいいかなという妄想ならできます。

おそらく、まず必要になるのは、TLSの仕組みと世界観をしっかり説明することでしょう。 なぜなら、QUICによるHTTP通信は、すべてTLSの仕組みが組み込まれた暗号通信だから。 ここでいうTLSの仕組みの理解には、接続の確立手順や暗号の合意のためのネゴシエーション手順の説明だけでなく、証明書を利用したインターネット信頼モデルの理解も必要です。

とはいえ、この部分については、「なにはともあれ『プロフェッショナルSSL/TLS』を読みましょう」でいい気もします。 『プロフェッショナルSSL/TLS』を読むと、認証付き暗号(AEAD)の考え方がわかるので、さらによい。 QUICでは、ほとんどのパケットはAEADで保護されるし、トークンの相互認証を使ったステートレスな接続終了とかもあるので、AEADを理解させないとたぶん概略すら説明できない気がします。

プロフェッショナルSSL/TLS(紙書籍+電子書籍)www.lambdanote.com

で、そのうえで、まずはHTTPの説明なんだろうなあ。 HTTPの部分については、とりあえず渋川さんの『Real World HTTP』があるし、これが改訂されれば当面は十分そう。 あるいは、ウェブ屋さん向けにコンピュータシステムの低レイヤの話を説明するという『Goならわかるシステムプログラミング』という本があります。 ふつうのコンピュータシステムの本だとTCP/IPやソケットの話が入るところで、この本ではHTTPの話を厚めにしています。 上に書いたようなQUICの背景をふまえると、ウェブ開発者にとってのHTTP/3は、ネイティブアプリのプログラマーにとってのTCPのような位置づけになるわけで、システムプログラミングと冠した『Goならわかるシステムプログラミング』でHTTPを扱うのはまったくもって自然だったのだなあ(たぶんあとづけ)。

Goならわかるシステムプログラミング(紙書籍)www.lambdanote.com

さらに、ネットワーク技術の解説書としては、再送制御とか輻輳制御の話もQUICとは独立に解説してあげないと意味がなさそう。 QUICそのものとは別なので、汎用の専門的な解説書がほしいところです(計画進行中)。

もちろん、QUICの下はIPv6です(繰り返しになりますがUDPは本質じゃないよ)。 IPv6については『プロフェッショナルIPv6』があるので安心ですね!

プロフェッショナルIPv6(紙書籍+電子書籍)www.lambdanote.com

そんな感じで、これからQUICとHTTP/3が本格的に普及してくると、インターネット技術の教科書にも大胆な構成変更が求められるようになるかもしれません。 具体的には、トップダウンでこんな構成にするのはどうですかね。

第1章 ウェブの概要
第2章 HTTP
第3章 インターネットの信頼モデルと認証付き暗号
第4章 QUICとその一部としてのTLS
第5章 トランスポートの信頼性に関するさまざまな技術
第6章 IPv6の概要

興味がある専門家の方からのご連絡をお待ちしています!(一部の章だけでもいいよ!)

TeXのフォントまわりについては、以下の3点が意識して語られるといいなと思う。

  1. TeXのフォント環境の理解は難しい。なぜなら、フォントに関する深い知見はもちろん、今となっては古臭いTeXディレクトリに関する知識も必要だから
  2. 今となってはどうしようもない古臭い設計を、TeX Liveが現代的なインターフェースでラップしてくれているので、ぼくらは古臭いTeXの知識がなくても日本語PDFが作れる
  3. 古臭い設計を捨て、現代的なOSのフォント環境で動かすことを前提に開発されている新しいTeXもある(LuaTeXやXeTeX)

1については、特効薬がない。TeX Wikiに書いてある部分もあるけど、たとえばTEXMFLOCALが何かとかを知るには、まずKpathseaについて知る必要がある。つまり、texdoc Kpathsea とかする。Webブラウザで見るなら Kpathsea: A library for path searching にある。これを読むと、TeXディレクトリ構成、すなわち、TeXの実行に必要なファイルの配置場所、そこにPATH的なものを通す方法などがわかる。PATH的なものが通っている場所から必要なファイルの存在を確認するためのコマンド kpsewhich についてもわかる。TeXはあくまでもこのKpathsea経由でファイルを探すので、Kpathseaについて知らないとTeX関連の環境整備は何もできない。しかし、Kpathseaのマニュアルを読んでも、最初は何が書いてあるのかさっぱりわからないんだ。とくにフォントは、さまざまなツールで扱いが異なるし、フォントの種類によっても扱いが異なる。そもそも、フォントの実体ファイルをKpathseaから見えるようにしただけでは、TeX組版で使うことはできない。だから、Kpathseaのマニュアルは、折にふれ何度も眺めることになる。というわけで、1については、特効薬がない。

それでも日本語のPDFをぼくらがTeXで作れてしまうのは、TeX Liveのおかげである。もちろん、だからといってTeX Liveが完璧なツールというわけでもないけど、TeXでフォントがどう扱われるかを完璧に知らなくても済むというだけで、だいぶありがたい。かつてAppleのOS上のTeXで利用することが流行し、現在ではAppleによって古いTeXから見にいくのが困難な状態にされてしまったヒラギノを引き続きmacOSで使えるようにするパッチも、TeX Liveの本体とは別に毎度作られている。いろいろな事情や思惑があって大々的には配布されていないようだけど、OSSなので、プロプラなシステムに対応するためのパッチをどういう形で公開するかに文句はいえないと思う。

で、3です。いつまでも古臭い設計を引きずるのはいやだという勢力があって、そういう方向での進化も続いている。具体的にはLuaTeXやXeTeXというプロジェクトで、これらはTeXの旧来のフォント利用方法ではなくシステムフォントを使うことを前提にして開発されている。これらで日本語を問題なく使えるようにするプロジェクトも進んでいて、ある意味ではすでに十分実用的になっている。もちろん後方互換性は気にしないで開発されているので、匿名の誰かがTeX Wikiにまとめた情報だけで今までと同じように使い始められるようなものでもないけれど、「macOSでどうしてもシステムフォントをTeXで使いたい」という目的には、むしろそっちの道を模索して開発に貢献する道のほうが適切なのではないかなと最近では考えている。

%.texという名前のファイルをLaTeXで処理する方法

ふつう、コマンドの引数にファイル名を指定すれば、そのコマンドの実行プロセスに標準入力経由でファイルの中身が渡されると思いますよね。 ところがplatexとかpdftexなどのコマンドは、引数として指定されたものを、すべてTeXトークンであるかのように読み始めます。

ただし、そうやって読み始めるとき、「先頭の文字が \ でない場合だけは、その前に \input がついているとみなす」というルールがあります。 このルールのおかげで、たとえば次のようにコマンドを実行すると…

$ pdftex foo.tex

次のように実行したのと同じことになります。

$ pdftex \\input foo.tex

これはつまり、次のような1行だけを中身として持つファイルをpdftexコマンドに指定して実行したのと同じことです。

\input{foo}

したがって、もし次のようにすれば…

$ pdftex %.tex

次のような1行だけを中身として持つファイルを実行したのと同じことになります。

\input{%}

これらは、事実上同じというレベルでなく、完全に同じです。 なのでpdftexコマンドは、エラーを吐くでもなく、単に \input{ の続きをユーザが入力してくれるのを待ち続けます。

$ pdflatex %.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode

*

この動作の裏をかけば、次のような手順で、%.tex という名前のソースをTeX(以降はpdflatexを例にします)で処理することはできなくはなさそう?

1. `%.tex` の1行めに `\catcode`\%=14` と追記する

\catcode`\%=14
\documentclass{standalone}
\begin{document}
foo
\end{document}

2. pdflatex実行時にファイル名の前に ``\\relax\\catcode\`\\%=12\\input`` と指定する

$ pdflatex \\relax\\catcode\`\\%=12\\input %.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
LaTeX2e <2018-04-01> patch level 5
(./%.tex
(/usr/local/texlive/2018/texmf-dist/tex/latex/standalone/standalone.cls
Document Class: standalone 2018/03/26 v1.3a Class to compile TeX sub-files stan
 dalone
(中略)
Output written on %.pdf (1 page, 8374 bytes).
Transcript written on %.log.

どうしても % を含むファイルをTeXで実行したい場合は、「1をsedにやらせてから2をやる」みたいなシェルスクリプトを書くことになるのかなあ。

2018年でもEPSファイルをTeXで使う

はじめに

みなさん、EPSファイル、使ってますか?

近年、(La)TeXの文書作成においては、「EPSファイルを使うな」というマナーが確立しています。 マナーにはデフォルトで抗っていくということで、この記事では、現代的なLaTeX環境におけるEPSファイルの可能性を探りたいと思います。

もちろん、「EPSファイルを使うな」は、実際にはマナーではありません。 技術的な根拠があるベストプラクティスのひとつです。 したがって、この記事の真の目的は、以下の2点だといえます。

  1. ベストプラクティスをマナーへと貶めないために技術的な背景を知る
  2. 条件があえばEPSファイルにもまだまだ使い道があることを示す

コンピュータサイエンスには、"All problems in computer science can be solved by another level of indirection"(「コンピュータ科学のあらゆる問題は、別の階層を挟むことで解決できる」)という格言があります (David WheelerまたはButler Lampson)。 上記の2では、MetaPostというアプリケーションをindirectionとして、EPSファイルをTeXが直接扱える形式として利用する道を示したいと思います。

この記事について

この記事は、TeX Conf 2018にてLT発表した「2018年でもTeXでEPSを使う」で話す予定だった内容のメモを文章として清書し、「TeX & LaTeX Advent Calendar 2018」の4日目の記事としてまとめたものです。

こうして文章にしてみると、この記事を原稿として読むだけでも5分で終わらなそうな話だった。。

目次

(La)TeX文書においてEPSはどう扱われるか

LaTeXで画像を挿入したいとき、もっとも歴史があるのは、EPSファイルを\includegraphicsする方法でしょう。 EPS形式で用意した画像を取り込むという手法は、LaTeX以前からTeXのエコシステムでは一般的だったようで、plain TeXにもepsf.styという仕組みがあります。 epsf.styのマニュアルでは開発履歴も触れられており、それを見ると、かなり初期のころにクヌース自身が手を入れていたようです(参考)。

ここで注意が必要なんですが、TeXそのものには、一般のEPSファイルを解釈する仕組みがありません。 \includegraphicsを提供するgraphicxパッケージやepsf.styの仕事は、「最終的な印刷を担うデバイス」へとEPSファイルを丸投げするだけです。

では、「最終的な印刷を担うデバイス」は、どうやって丸投げされるEPSファイルを画像にする、つまり、紙に印刷したり、PDFに変換したり、あるいはベクター画像としてレンダリングしたりするのでしょうか? そもそも、「最終的な印刷を担うデバイス」とは何なのでしょうか?

昔ながらのTeXであれば、原稿はDVIへとコンパイルされます。したがって、最終的な印刷を担うデバイスは、「DVIウェア」などと総称されるソフトウェアです。

DVIウェアがdvipsであれば、原稿で指定されていたEPSファイルの中身は、出力されるPostScriptにそのまま埋め込まれます。 それをGhostscriptやAdobe Distiller、あるいはPostScriptプリンタに渡すことで、それらのPostScript処理系が最終的な画像を生成します。

DVIウェアがdvipdfmxであれば、EPSファイルを最終的な画像にするのは、一般にはGhostscriptというPostScript処理系の仕事です。 これは、dvipdfmxの設定ファイル(dvipdfmx.cfg)に、「一般的なEPSファイルがあったらGhostscriptを起動してPDFに変換する」という内容の処理がデフォルトで記述されているからです。

DVIウェアには、XdviやWindvi、あるいはdviout、あるいはEvinceのような、DVIをそのまま画面上でプレビューするものも多々あります。 これらのほとんども、PostScript処理系を自前でもっているわけではなく、外部のGhostscriptを呼び出してEPSファイルを何らかの形式の画像に変換して描画しています。

いずれの場合も、「一般的なEPSファイルを最終的な画像にするにはPostScript処理系が必要」という点がポイントです。 これは、EPSファイルが、そもそもは一枚絵のために規定されたPostScriptのコーディング規約(DSC、Document Structring Conventionといいます)に基づくものであることを考えれば、当然だといえます。 PostScript処理系がないと、TeXのエコシステムは一般のEPSファイルを画像として再現できないというわけです。

そして、ここでいうPostScript処理系は、事実上Ghostscript一択です。 プロプラエタリなソフトウェアを利用せずに、PostScriptをベースとした技術を利用しようと思ったら、現状ではGhostscriptに頼らざるをえず、TeXもその例外ではないのです。

f:id:golden-lucky:20181204121414p:plain:w400
TeXエンジンはEPSを処理できない

「EPSファイルを使うな」の意味

前節で見たように、PDFが出力となるようなTeXのエコシステムでは、一般にはTeXのソースでEPSファイルが出てくるたびに外部のPostScript処理系(事実上Ghostscriptであることが多い)が走ります。 常識的に考えてこれは効率が悪い。

そもそも、現在もっとも広く利用されているTeX組版エンジンであるpdfTeXは、ネイティブでPDFの取り込みに対応しています(参考)。 日本語環境ではdvipdfmxがよく利用されていますが、これもネイティブでPDFの取り込みに対応しています(参考)。 そのため、EPSファイルとして用意した画像をそのつどGhostscriptを呼び出して処理するのは完全な無駄であり、最初からGhostscriptでPDFに変換しておけば十分なのです。

これが、いま「EPSファイルを(La)TeX文書に取り込むときの画像に使うな」という主張の背景にある事情です。

pdfTeXやdvipdfmxがネイティブに扱えるEPS

EPSファイルが現代的なTeXのエコシステムにおいて扱いにくい代物であるのは紛れもない現実です。 PDFならTeXエンジンがネイティブで扱えるのに、そこでEPSファイルを使い続ければ、Ghostscriptという厄介なアプリケーションが作業フローに関与してしまいます。

とはいえ、長らくTeXにおけるデフォルトの画像形式であったEPSファイルを利用しなければならないドキュメントもあるでしょう。 アプリケーションがEPSしか出力してくれない場合もあります。 あらかじめGhostscriptでPDFにしておけばいいとも言えますが、管理しているファイルがPDFでは扱いにくいという事情もありえます。 なにしろEPSの中身はPostScriptであり、PostScriptを知っていればテキストエディタで直接編集できます。 テキストファイルなので、バージョン管理にも都合がいい。

はたして、Ghostscriptを起動せず、TeXのエコシステムでPostScriptを直接処理することは不可能なのでしょうか?

実は、TeXのエコシステムで直接処理できるようなEPSファイルがあります。 そのようなEPSファイルであれば、画像としてTeXの文書中で取り込んでも、処理中にGhostscriptが呼び出されることはありません。 EPSファイル中のPostScriptを、pdfTeXやdvipdfmxが、直接解釈して画像にしてくれるのです。

そのようなEPSファイルは、Purified EPSと呼ばれています。純化されたEPSというわけです。 具体的には、MetaPostというアプリケーションによって生成されたEPSだけがPurified EPSになります(参考)。

重要かつややこしい箇所なので、MetaPostとPurified EPSについてもう少し詳しく見ておきましょう。

MetaPostは、ベクター画像を生成するためのプログラミング言語です。 MetaPostについては、2018年のTeX & LaTeXアドベントカレンダーの北川さんの記事(参照)がとても参考になります。 たとえば、ここにラムダノートという出版社のロゴマークがありますが…

f:id:golden-lucky:20181204151846p:plain
ラムダノートのロゴ

このロゴは、こんな感じのMetaPostソースで再現できます。

prologues := 1;

beginfig(1);
drawoptions (withcolor (0.6,0.6,0.6));
linecap := butt;
linejoin := mitered;
fill (26.867201,14.046900)..controls (26.914101,11.453100) and (27.386700,8.511720)..(26.027300,6.519530)
    ..controls (23.898399,3.402340) and (19.093800,1.851560)..(15.031300,1.777340)
    ..controls (8.378910,1.660160) and (2.886720,6.957030)..(2.765630,13.613300)
    ..controls (2.644530,20.269501) and (7.945310,25.761700)..(14.597700,25.878901)
    ..controls (21.253901,26.000000) and (26.746099,20.703100)..(26.867201,14.046900)
    --cycle;
drawoptions (withcolor (0,0,0));
fill (111.976997,17.812500)..controls (110.969002,18.261700) and (109.785004,17.804701)..(109.339996,16.796900)
    --(109.188004,16.445299)..controls (109.188004,16.445299) and (109.140999,16.339800)..(109.046997,16.132799)
    ..controls (108.941002,15.929700) and (108.875000,15.621100)..(108.612999,15.234400)

(つづく)

なお、MetaPostによく似た名前のアプリケーションとして、クヌースが作ったフォント開発のための言語および処理系のMetaFontがあります。 名前がよく似ていることからわかるとおり、MetaPostはMetaFontに影響を受けていますが、もっとずっと新しい時代に別の人が作った別のアプリケーションです。 実際、MetaFontはPostScriptに埋め込めるビットマップフォントを生成するのに対し、MetaPostはPostScriptをEPSファイルとして生成します(MetaPostのPostはPostScriptのPostです)。

MetaPostの処理系は mpost というコマンドです。 上記のMetaPostのソースファイルlogo.mpmpostコマンドに指定して次のように実行すると、EPSファイルが生成されます。

$ mpost logo.mp
This is MetaPost, version 2.00 (TeX Live 2018) (kpathsea version 6.3.0)
(/usr/local/texlive/2018/texmf-dist/metapost/base/mpost.mp
(/usr/local/texlive/2018/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.005) ) (./logo.mp [1{psfonts.map}] )
1 output file written: logo.1
Transcript written on logo.log.

$ ls
logo.mp    logo.1    logo.log

拡張子が.epsのファイルがありませんが、logo.1というのがMetaPostによって生成されたEPSファイルです。 中身を見ると、以下のように、お馴染みのPostScriptコマンドとPostScriptコメント(%%のスタイルは正確にはDSCコメントといいます)がならんだEPSファイルであることがわかります。

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 -1 114 94
%%HiResBoundingBox: 0.00034 -0.00009 113.16754 93.72906
%%Creator: MetaPost 2.00
%%CreationDate: 2018.12.04:1520
%%Pages: 1
%%BeginProlog
%%EndProlog
%%Page: 1 1
 0.6 0.6 0.6 setrgbcolor
newpath 26.8672 14.0469 moveto
26.91411 11.4531 27.3867 8.51172 26.0273 6.51953 curveto
23.89839 3.40234 19.0938 1.85156 15.0313 1.77734 curveto
8.3789 1.66016 2.88672 6.95703 2.76563 13.6133 curveto
2.64453 20.2695 7.94531 25.7617 14.5977 25.8789 curveto
21.2539 26 26.7461 20.7031 26.8672 14.0469 curveto
 closepath fill
 0 0 0 setrgbcolor
newpath 111.97699 17.8125 moveto
110.96901 18.2617 109.785 17.8047 109.34 16.7969 curveto
109.188 16.4453 lineto
109.188 16.4453 109.141 16.3398 109.047 16.1328 curveto

(つづく)

この「MetaPostが生成したEPS」こそが、Purified EPSの正体です。 残念ながらPurified EPSの明確な仕様はよくわからないのですが、MetaPostのマニュアルで「Purified EPS」と名づけられていることから、「MetaPostが生成したEPSがPurified EPS」だと考えて問題ないでしょう。

PostScriptとして見れば、Purified EPSはフルのEPSから機能を削り取ったDSCであり、EPSファイルのサブセットといえます。 したがって、通常のEPSと同じように扱えます。

さらに特筆すべき特徴として、Purified EPSは、pdfTeX(およびLuaTeX)やdvipdfmxに完全な処理系が実装されています。 これが何を意味するかというと、「TeXエンジンにPostScriptの処理系が実装されていないのでEPSファイルは使うべきではない」というベストプラクティスが、Purified EPSには適用されないのです。 Purified EPSは、むしろTeXのエコシステムで積極的に使ってよい形式であるとさえいえます。

f:id:golden-lucky:20181204123124p:plain:w400
EPSがMetaPost由来であれば、TeXエンジンが直接処理できる

ちなみに、dvipdfmxに至っては、その名称に反し、(DVIではなく)生のPurified EPSを受け取ってPDFに変換するオプションまで用意されています。

$ dvipdfmx -M logo.1  # dvipdfmxに、DVIファイルではなくEPSファイル(ただしPurified)を渡せる!
logo.1 -> logo.1.pdf

4105 bytes written

ここまでのまとめ

ここまでの話をまとめましょう。

  1. 一般のEPSファイルは、完全なPostScriptの処理系を持たないTeXのエコシステムでは直接扱えないので、必要な場合には外部アプリケーションであるGhostscriptをそのつど起動して処理を投げている
  2. あらかじめEPSファイルをPDFにしておけば、現代的なTeXのエコシステムはPDFを直接扱えるので、そのつどGhostscriptが起動されることはなくなる(これが現在のTeXワークフローの主流)
  3. しかし、テキストファイルであるEPSファイルには、PDFにない利点もある
  4. ところで、MetaPostが生成するEPS(Purified EPS)でれば、現代的なTeXのエコシステムに完全な処理系が内蔵されている

このように状況を整理すると、そのつどGhostscriptが起動されるというハンデを負わずに、テキストファイルとしての扱いやすさだけを享受できる、そんな作業フローの可能性があることに気づきます。 そう、一般のEPSファイルを、可能な場合にはPurified EPSに変換してしまえばいいのです。

一般のEPSをPurified EPSに変換する

ずばり、purifyepsというツールがあります。その名のとおり、EPSファイルをpurifyしてくれるユーティリティです。 TeX Liveに入っているので、ふつうにTeX環境をインストールしていれば利用可能です(参考)。

このpurifyeps、実態は、pstoeditmpostという別々のツールを順番に呼び出すだけのPerlスクリプトです。 前段のpstoeditが、EPSファイルをMetaPostのソースファイルに変換してくれます。 後段のmpostは、MetaPostの処理系そのものです。 前段のpstoeditで生成されたMetaPostのソースファイルを、後段のmpostにかけて、Purified EPSが出力されるという寸法です。

f:id:golden-lucky:20181204123553p:plain:w500
purifyepsにより通常のEPSをMetaPost由来にできる場合がある

purifyepsを使うには、pstoeditにフォントマップを指定して、もとのEPSファイルで使われているフォントをmpostが知っているフォント名に置き換えてあげる必要があります。 これはmpost.fmpとして、かなり長大なファイルがpstoeditに付随してくるはずです。 しかし、このデフォルトのmpost.fmpに登録されていないフォントがEPSファイルで使われていたり、対応するtfmを自分の環境に持っていなかったりすると、変換がコケます。 その場合は、エラーメッセージをもとに、PostScriptフォント名と対応するtfm名からなる行をmpost.fmpに追記してあげれば、とりあえず通ります。 対応するtfm名は、ぶっちゃけなんでもいいので、とりあえずcmr10でも指定しておいて変換を通してみましょう。

あと、ちょっと罠があって、素のpurifyepsだとGhostscriptが意味不明なエラーを吐き出す可能性があります。 これは、pstoeditでGhostscriptのDELAYBINDオプションが暗に指定されているからです。 DELAYBINDは、PostScriptのbindコマンドの動作をちょっと変えることで、標準ライブラリのコマンド名を上書きしているような場合でも問題なく扱えるようにするためのGhostscript独自の仕掛けです(参考)。 しかし、Adobe Distillerが隠し持っているinternaldict辞書を操作するsuperexecというコマンドがsystemdictにあったのを取り除いたときに、副作用があるので取り除かれてしまいました(参考)。 結果として、Adobe Illustratorなどで生成されたEPSの多くは、素のpstoedit(したがってpurifyeps)で変換しようとすると意味不明なPostScriptエラーを吐き出して終了するわけです。

pstoeditは、DELAYBINDを無効にするGhostscriptの-dNOBINDオプションを有効にするために、-nbというオプションを指定してあげます。 しかし、これをpurifyepsから実現する手段はありません。 そのため、purifyepsのソースでpstoeditを呼び出している箇所に直接-nbオプションを書き加えるしかなさそうです。 以下のようにpstoeditを呼び出している箇所があるはずなので、そこに-nbオプションを追記しましょう。

(省略)

# Utilize pstoedit to convert from EPS to MetaPost.
my $mpfile = $tempbase . ".mp";
executeCommand "pstoedit -ssp -mergetext -f mpost -fontmap \"$fontmap\" \"$infile\" \"$mpfile\""; 

(省略)

Perlスクリプトなので、パスが通っているディレクトリにあるpurifyepsというファイルを直接いじってしまえば目的は達成されます。

Purified EPSをTeXに書き換える

こうして変換できたPurified EPSは、\includegraphicで読み込んでも、Ghostscriptが起動することもなくpdfTeX/LuaTeXやdvipdfmxだけでPDFの画像になります。 変換前の一般のEPSファイルを読み込んだときに比べて、爆速で処理が終わります。

ここで満足してもいいんですが、ここでさらに、Purified EPSをTeXソースそのものに変換できないか考えてみましょう。

なんでそんなことを考えるかというと、画像を外部ファイルではなくTeXソースで持っていることには、次のようなメリットが考えられるからです。

  • 本文と同じスキームで図中のフォントを扱える(数式日本語も)
  • 図中の長文を組版してもらえる(数式日本語も)
  • 図中で脚注や相互参照や索引が使える

つまり、メリットしかない。 補足しておくと、実はここまでの話はすべて図中のフォントがASCIIであることを前提としていて、EPSファイル中で日本語が使われているとpurifyepsが日本語をアウトライン化してしまうのでした。 もしTeXソースにできてしまえば、日本語が使えるように設定したTeXで処理するだけで図中に日本語を埋め込めます。

幸い、最近のTeXには、PGFという高度なベクター画像のための仕組みがあります。 PGFは、人間が書くときにはTikZという独自のインターフェースを使うのですが、PGFそのものはかなりPostScriptに近いシンタックスであり、いかにも直接変換できそうな雰囲気がします(参考)。 これを利用すれば、Purified EPSをTeXのマクロにできそうです。

同じことを考える人はいるもので、すでにeps2pgfというJava製の変換ツールを作っている人が過去にいました(参考)。 現在はSourceforgeにポストされているもののソースもない状態で、メンテもされてなさそうなんですが、とりあえずダウンロードして使ってみるとそれなりに満足のいく結果が得られました。

$ java -jar eps2pgf.jar logo.1 -o logo.tex

結果として生成されるTeXファイルは、 pgfpicture 環境にPGFのコマンドが並んだこんな状態です。

% Created by Eps2pgf 0.7.0 (build on 2008-08-24) on Tue Dec 04 15:38:00 JST 2018
\begin{pgfpicture}
\pgfpathmoveto{\pgfqpoint{0cm}{-0cm}}
\pgfpathlineto{\pgfqpoint{3.992cm}{-0cm}}
\pgfpathlineto{\pgfqpoint{3.992cm}{3.307cm}}
\pgfpathlineto{\pgfqpoint{0cm}{3.307cm}}
\pgfpathclose
\pgfusepath{clip}
\definecolor{eps2pgf_color}{rgb}{0.6,0.6,0.6}\pgfsetstrokecolor{eps2pgf_color}\pgfsetfillcolor{eps2pgf_color}
\pgfpathmoveto{\pgfqpoint{0.948cm}{0.496cm}}
\pgfpathcurveto{\pgfqpoint{0.949cm}{0.404cm}}{\pgfqpoint{0.966cm}{0.3cm}}{\pgfqpoint{0.918cm}{0.23cm}}
\pgfpathcurveto{\pgfqpoint{0.843cm}{0.12cm}}{\pgfqpoint{0.674cm}{0.065cm}}{\pgfqpoint{0.53cm}{0.063cm}}
\pgfpathcurveto{\pgfqpoint{0.296cm}{0.059cm}}{\pgfqpoint{0.102cm}{0.245cm}}{\pgfqpoint{0.098cm}{0.48cm}}
\pgfpathcurveto{\pgfqpoint{0.093cm}{0.715cm}}{\pgfqpoint{0.28cm}{0.909cm}}{\pgfqpoint{0.515cm}{0.913cm}}
\pgfpathcurveto{\pgfqpoint{0.75cm}{0.917cm}}{\pgfqpoint{0.944cm}{0.73cm}}{\pgfqpoint{0.948cm}{0.496cm}}
\pgfpathclose
\pgfusepath{fill}
\definecolor{eps2pgf_color}{rgb}{0,0,0}\pgfsetstrokecolor{eps2pgf_color}\pgfsetfillcolor{eps2pgf_color}
\pgfpathmoveto{\pgfqpoint{3.95cm}{0.628cm}}
\pgfpathcurveto{\pgfqpoint{3.915cm}{0.644cm}}{\pgfqpoint{3.873cm}{0.628cm}}{\pgfqpoint{3.857cm}{0.593cm}}

(つづく)

これはもう完全にTeXなので、uplatexでもpdflatexでも好きなものでPDFにすればいいでしょう。 もちろん、ふつうにTeXソースとして編集できるので、LaTeXのパッケージの機能もフルに使えます。

% Created by Eps2pgf 0.7.0 (build on 2008-08-24) on Tue Dec 04 15:38:00 JST 2018
\begin{pgfpicture}
\pgfpathmoveto{\pgfqpoint{0cm}{-0cm}}
\pgfpathlineto{\pgfqpoint{4cm}{-0cm}}
\pgfpathlineto{\pgfqpoint{4cm}{4.0cm}}
\pgfpathlineto{\pgfqpoint{0cm}{4.0cm}}
\pgfpathclose
\pgfusepath{clip}
% 追記
\pgftext[x=2cm,y=3.7cm,rotate=0]{%
  \fontsize{12}{12}\selectfont\parbox{4cm}{\centering ラムダノート}}
\pgftext[x=2.12cm,y=2.5cm,rotate=-65]{%
  \fontsize{18}{10}\selectfont\scsnowman[hat=true,muffler=red,arms=true]}
\pgftext[x=3.73cm,y=0.95cm,rotate=80]{%
  \fontsize{18}{10}\selectfont\scsnowman[hat=true,muffler=red,arms=true]}
% ここまで追記
\definecolor{eps2pgf_color}{rgb}{0.6,0.6,0.6}\pgfsetstrokecolor{eps2pgf_color}\pgfsetfillcolor{eps2pgf_color}
\pgfpathmoveto{\pgfqpoint{0.948cm}{0.496cm}}
\pgfpathcurveto{\pgfqpoint{0.949cm}{0.404cm}}{\pgfqpoint{0.966cm}{0.3cm}}{\pgfqpoint{0.918cm}{0.23cm}}
\pgfpathcurveto{\pgfqpoint{0.843cm}{0.12cm}}{\pgfqpoint{0.674cm}{0.065cm}}{\pgfqpoint{0.53cm}{0.063cm}}
\pgfpathcurveto{\pgfqpoint{0.296cm}{0.059cm}}{\pgfqpoint{0.102cm}{0.245cm}}{\pgfqpoint{0.098cm}{0.48cm}}
\pgfpathcurveto{\pgfqpoint{0.093cm}{0.715cm}}{\pgfqpoint{0.28cm}{0.909cm}}{\pgfqpoint{0.515cm}{0.913cm}}
\pgfpathcurveto{\pgfqpoint{0.75cm}{0.917cm}}{\pgfqpoint{0.944cm}{0.73cm}}{\pgfqpoint{0.948cm}{0.496cm}}
\pgfpathclose
\pgfusepath{fill}
\definecolor{eps2pgf_color}{rgb}{0,0,0}\pgfsetstrokecolor{eps2pgf_color}\pgfsetfillcolor{eps2pgf_color}
\pgfpathmoveto{\pgfqpoint{3.95cm}{0.628cm}}
\pgfpathcurveto{\pgfqpoint{3.915cm}{0.644cm}}{\pgfqpoint{3.873cm}{0.628cm}}{\pgfqpoint{3.857cm}{0.593cm}}

(つづく)

f:id:golden-lucky:20181204161246p:plain
ラムダノートのロゴ with ☃

以上で、PostScriptをある程度読めてベジエを手で調整する気力とフォントの位置を微調整する忍耐力がある人にとっては、実に快適なテキストベースの図環境が得られることがわかりました。

f:id:golden-lucky:20181204123556p:plain:w600
EPSをMetaPost経由でTeXソースにする

まとめ

MetaPost、そのまま作図のためのツールとして使うにはハードルが高いんですが、画像編集ソフトで生成したEPSファイルを本稿の手法でTeXにするための中間形式としては魅力がありますね。

ただし、その変換パスにも、pstoeditという形でGhostscriptが関与します。TeXはGhostscriptから離れては生きていけないのです。

ところでラムダノートという会社では、「古いEPSを活用してドキュメントを作りたい」といったお仕事も、こんな感じでわりと効率よく引き受けることが可能です。 著者や原文のソースにあるメタ情報をフル活用したい、バージョン管理したい、ミスが怖いので人力で変換したくない、といったドキュメント関連のお悩みがありましたら、下記のフォームよりご連絡ください。

www.lambdanote.com

出版社を作って3年が経ちました

ラムダノートという出版社を作って3年が経ちました。

https://cdn.shopify.com/s/files/1/1634/7169/files/132x320_240x.png

www.lambdanote.com

この12月から、会社としては第4期に突入です。 3年もすれば中学生は高校生になるわけで、それなりに感慨があります。 そこで、pyspaアドベントカレンダーという場を借りて、ちょっとふりかえりをしてみることにしました。

本の紹介はよくやるけど、会社の紹介はあまり積極的にやってないので、そのつもりで書いたものです。

第1期(2015年12月-2016年11月)

出版社なので本を作って売りたいわけですが、本は自然には生えてきません。 前の会社に在職中から独立に向けた準備を進めるような計画性があればよかったのですが、本当になにも準備しないまま音楽性の違いで辞めたので、起業した最初の年は当然ながらラインナップがゼロでした。 そんな状態でも起業に踏み切れたのは、時雨堂の@volantusが凄腕の会計事務所を紹介してくれて、さらに出資までしてくれたおかげです。

第1期は、自社で出す本を企画したり、直販サイトを作ったり、そういう夢ベースで駆動していた時期でした。 種まき以前の、開墾の時期だった気がします。

幸い、書籍制作のお手伝いをもらったり、Webメディアの記事編集をやらせてもらったり、ドキュメント技術のコンサルティングっぽいことをさせてもらったりしたことで、アルバイト程度の現金収入がありました。 しかし、ぼく自身の給料がゼロだったこともあり(貯金と退職金、それに起業に伴う再就職手当で食いつないでいた)、現金は減っているのに会社としては黒字となり、税金だけは納めることになりました。つらい。

第2期(2016年12月-2017年11月)

この期の第2四半期に、ラムダノートからはじめての書籍を発行しました! 『プロフェッショナルSSL/TLS』『RubyでつくるRuby』です。 さらに第4四半期には、もう二冊、『定理証明手習い』『Goならわかるシステムプログラミング』を発行しました。

ラムダノートは、第2期にして、ようやく名実ともに出版社になれたことになります。

とはいえ、出版社になったからといって発行する本が自動的に書店に並ぶわけではありません。 書店で本が買える状態にするには、全国の書店へとつながっている流通網を使う必要があります。 しかし、出版社だからといって、この流通網を無条件で使えるわけではないのです。

全国どこでも、書店にいけば本や雑誌が買えるというのは、よくよく考えれば奇跡のような仕組みです。 既存の出版社の社員として本を作っていたときは、この奇跡のような流通網の存在を前提にして収益性を考えていました。

ところが、ぽっとでの新規出版社には、この既存の流通網は使えません。 正確に言うと、使いたいと言って交渉することは可能だけど、かなり不利な条件になります。

出版社としては、売り出す本の中身に対してかなり強い自信を持っています。 しかし、本の中身というやつは、流通網を運用している側にとって評価軸ではありません(異論はあるかもしれないけど、そもそも何万冊という新刊の中身をすべて評価するのは無理なので評価軸にはなりようがない)。 だから、既存の流通網を使いたければ、基本的には先方の条件に従うしかないのです。

そんなわけでラムダノートでは、既存の流通網も少し使わせてもらいつつ、自分たちが主体になって最終的な読者まで本を届けることに挑戦することにしました。 具体的には、Webベースの直販で商売を立ち上げることを目指しました。

直販サービスを自分たちで作ったことで、既存の流通網だけではケアできないような売り方、たとえば電子版も同じ価格で一緒に提供するとか、そうやって提供した電子版をバージョンアップしていくとか、そういうことも可能になりました。

もちろん、全国の書店で気楽に買えないということは、潜在的な読者の方々に不便をかける道を選んだともいえます。 発売開始直後に、得体のしれない出版社のWebサイトにクレジットカード番号を入力して注文していただいた何百人もの方々には感謝の気持ちしかありません。 本当にありがとうございました(これからもよろしくお願いします)。 ラムダノートの本は、今でもこの直販サイトを中心に発売しています。

www.lambdanote.com

個人的には、この第2期は、約1年半ぶりに給料を手にできた時期でもあります(学生バイトみたいな月給ですが(いまだに))。

会社としては、いろいろ経費がかかるようになったこともあって、けっこうな赤字で第2期を終えました。

第3期(2017年12月-2018年11月)

前期に引き続き、書籍を3タイトル発行しました。 『数式組版』『プロフェッショナルIPv6』『みんなのデータ構造』です。 特に『プロフェッショナルIPv6』は、前期に打ち立てたクラウドファンディングの成果物を形にできて、本当によかった。 事前にお金をもらってから本をつくるの、メンタルにかなりこたえますね……。

タイトルが全部で7つに増えたことで、毎月の現金収入は前期に比べると少しずつ安定してきました。 その一方、やはりタイトルが増えたことで、管理コストも増えました。 前期から一緒に経営と本づくりに参加してくれている@ctakaoがいなかったら、ぼく一人では間違いなくオーバーフローしていたはずです。

なんでそんなに管理コストが増えたのか。

物理的な商品を作って売るには、倉庫と配送はもちろん、内部的な見えないコストがけっこうかかるものなんですね。 既存の書籍流通網に依存していないので、商品のハンドリングにかかるコストの割合は一般的な出版社より低いはずですが、それでも最近ではアマゾン・マーケットプレイス経由での購入がけっこう増えていたりして、これは配送料なども考慮すると30%がアマゾンに持っていかれるので、一冊あたりの利益率は直販に比べるとかなり目減りします。

この販売にかかる見えないコストは、当社の根本的な方針にも影響します。 実は当社の印税率は、書下ろしの紙版書籍では15%であり、わりと高めの設定です(翻訳の場合は原著者と原書出版社に支払うロイヤリティからの差分相当になるのでこれより低くなります)。 この印税率が可能な理由は主に2つあって、そのひとつが直販メインであることで販売コストが抑制できているからなのです。 著者の取り分を維持するためにも、販売戦略はこれからいろいろ工夫していきたいところです。

ちなみに、著者の取り分を比較的多くできるもうひとつの理由は、バージョン管理と自動組版のおかげで書籍制作にかかる直接のコストが一般の出版社より低く抑えられていることにあります。 とはいえ、データ入稿後は他の出版社と同じか、それよりも費用がかかるので、重版するラインナップが増えてくると利益を圧迫してきたりします。 このへんは、1回の刷数や重刷のタイミング、それから電子版をうまく回してやりくりしてがんばっていこうと考えています。

結局、第3期は総売上は去年よりだいぶ増えたけど経費も増え、ほぼ収支が均衡する状態で終わりました。 PEAKSさんやエン・ジャパンさんをはじめ他のメディアのお手伝いをしたり、ドキュメント技術の相談を受けたりしながら、その利益を本づくりに突っ込んできた感じです。 前期の終わりに時雨堂さんから増資を受けたのは本当に助かりました。

最終的な決算はこれからですが、前期の赤字もあるので、手元の現金はまだまだ心もとないぞ……。

第4期(2018年12月-)

というわけで、今日から第4期の営業開始です。今期もラムダノートをよろしくお願いいたします。

制作中の本、執筆を依頼している本がいくつかあるので、その発行に向けてがんばりながら、単発の本じゃない形で濃い技術情報をお届けする新企画も動かしていたりします。すでに相談済みの皆様におかれましては原稿のほうにぼちぼち本気を出していただきたく!

逆に、こちらのアクションがきちんと取れていない方々もおり、本当に申し訳ありません。 すべて私の脳がいろいろな意味で追い付いていないことが原因です。 何かのタイミングで何かがリンクして何かへと結実する予定ですが、催促やリマインダを気兼ねなく飛ばしてもらえるとうれしいです。

既刊の7冊の改訂や販売促進も控えています。特に売れ筋の『プロフェッショナルIPv6』『Goならわかるシステムプログラミング』『プロフェッショナルSSL/TLS』は、将来のバージョンアップに向けて準備を始めています(SSL/TLS本は原著の改訂待ちです)。

他の4冊も、これから教科書などで需要が高まってくる本ばかりだと考えているので、採用を検討されている先生は info@lambdanote.com までご連絡ください。 特に『みんなのデータ構造』『RubyでつくるRuby』は、当社の本としては価格も安く(『みんなのデータ構造』の紙版はなんと1900円!)、学部生向けにぴったりの教科書だと思います!

www.lambdanote.com

ホワイトチョコを挟んだやつ三銃士

ホワイトチョコを挟んだやつ三銃士を連れて来たよ。

SDIM0190-2

ホワイトチョコを挟んだやつ三銃士?

SDIM0199

北の専門家、白い恋人。うっす、よろしく。

SDIM0197

ヨックモックの専門家、ドゥーブルショコラブラン。がんばります、よろしく。

SDIM0195

ルマンド、ルーベラなどブルボンの専門家、ブランチュール。よっす、どうも。

SDIM0194

TeX Conf 2018が札幌で開催された結果、ホワイトチョコをラング・ド・シャに挟んだお菓子が我が家に3つ揃いました。

白い恋人、とにかくでかい。ホワイトチョコも分厚い。ホワイトチョコ好きとしてはテンションがあがります。 その一方で、ラング・ド・シャは他の2点に比べると、ややざらざらしています。ISO 400のTri-Xともいうべき食感。 このラング・ド・シャの食感に合わせると、これだけ体積が大きいホワイトチョコが必要なのかもしれない。 ホワイトチョコだけ食べたい一品です。

SDIM0218

ヨックモックは、細長いクッキーのシガールで有名ですが、ラング・ド・シャとチョコレートを組み合わせたシリーズこそ本領。 とくにクリスマスシーズンにしか手に入らない、ホワイトチョコを挟んだラング・ド・シャの全面をさらにホワイトチョコでコーティングしたやつがすごい。 しかし今回は、他の2点と条件を合わせるために、秘蔵されていた春先限定商品のドゥーブルショコラブランを開封しました。 ラング・ド・シャのパリッと感と、カカオの風味が少し残るホワイトチョコで、バランスのとれた風味を実現しています。 ホワイトチョコだけ食べたい一品です。

SDIM0219

最後は、ブルボンのブランチュール。あまりスーパーで安売りされない、ブルボンの裏大王。 ぼくは箱買いしています。 主食なので、いまさら他の2点と比べるまでもないのですが、とにかくコストパフォーマンスが圧倒的。 価格のみならず、白い恋人クラスの厚さを誇るホワイトチョコにそれほど主張しないラング・ド・シャという構成で、ホワイトチョコ好きを狙い撃ちする完成度です。 ホワイトチョコだけ食べたい一品です。

SDIM0220

どれもホワイトチョコだけ食べたい。

SDIM0222

「そういえば前職でこの話を業務ブログに書いてたな」と思った話があって、検索したところ、ひっかからない。トップページからリンクをたどっても見当たらない。いやな予感がしてもうちょっと調べたら、過去の記事がぜんぶ、しれっとなかったことになっていた!

幸い、Internet Archivesではまだ残っていたので、自分が書いた文章のうちあとで参照したくなるやつを拾っておいた。『すごいHaskell』のサイン会の写真とか、たぶん日本のコンピュータサイエンス史にとって貴重なはず。