1954

Thoughts, stories and ideas.

Introducing literate-intellij-plugin

Background

TLA+のツールセットにはSpecをLaTeXドキュメントとして出力する機能があります。

Example:

最近、この機能を拙作のTLA+ intellij pluginにintegrateできないか考えていました。

公式のTLA+ toolboxやVS Code pluginにはintegrateされていてSpecをPDFとして出力できますが、TeX処理系は同梱されていないため、ユーザーは別途TeX Live等のdistributionをインストールすることになります。

TeX distributionは非常にサイズが大きくインストールする心理障壁が高いので、できればIntelliJのみでLaTeXの描画を完結させたいところです。

少し調べた感じでは、jlatexmathなどのLaTeXの数式描画に特化したライブラリはいくつかあるものの、TeXのコマンドを解釈して組版処理が行えるようなものは、Pure Javaのポータブルなものは無さそうです。

他には面白いプロジェクトとしてTeX Liveをemscriptenでwasmにcompileするtexlive.jsがあります(ブラウザで動かせればWebView経由でpluginに組み込めそう)が、そもそもTeXはとても歴史がある組版システムなのに(他のマークアップ言語と違い)様々な言語による再発明があまり無いことに個人的に興味を引かれました。

これをきっかけにまずTeXについて少し調べました。

TeX

よく知られている通り、TeXはDonald Knuthによって開発された組版システムおよびそのための命令を記述するマークアップ言語です。

TeXファイルを読み込み組版を行ってPDFなどの形式に出力するソフトウェアをTeX engineとよびます。

ただしVanilla TeXはプリミティブな命令しか持たないため、マクロ機構を使って高レベルな命令セットを提供する様々なパッケージが作られ、TeXのエコシステムは発展してきました。

中でもLeslie Lamportによって開発されたLaTeXは、科学論文の作成におけるデファクトスタンダードとなっています。

TLA+のツールによりSpecから生成されるTeXファイルも、TeXではなくLaTeXを対象としたものです。

LaTeXドキュメントをPDFとして出力するプロセスは以下のようになります。

  1. latex.ltxTeXのプリミティブな命令を使った種々のLaTeXマクロ定義を含むファイル)をTeX engineで読み込む
    • すでに読み込んだ状態のメモリダンプ(formatとよばれる)の形でdistributionに含まれているのが一般的なので、通常のユーザーはこのステップを明示的には実行しません
  2. 次に、実際のコンテンツを含むLaTeXドキュメントを読み込む
  3. 組版結果をPDFとして出力する

つまりプリミティブな(といっても300種類以上あるのですが...)TeX命令を処理できるポータブルなengineがあればいいわけで、作れたりしないだろうかという気になってきます。

WEB

現在広く使われているTeX engineにLuaTeXやpdfTeX、XeTeXなどがありますが、pdfTeX・XeTeXについてはソースコードKnuthTeXがベースになっています。(いっぽう、後から知ったのですがLuaTeXはCで再実装されているようです)

KnuthTeXに特徴的なのは、彼の提唱する「literate programming(文芸的プログラミング)」のために彼が開発した(現代においては恐ろしく紛らわしい名前の)WEBとよばれる記法で書かれていることです。

WEBでは、プログラムを「モジュール」の集合として記述し、各モジュールは以下の3つのパートで構成されます。

WEBには、開発された当時(1987年)の状況を伺わせる独特な仕様がいくつかあります。

たとえば各モジュールには名前をつけて他のモジュールから参照できるのですが、「モジュール名の初回の登場以降は、そのモジュール名をPrefixで参照できる」という仕様があります。 (foo-bar module というモジュールがあった場合、2回目以降は(他にfooで始まるmoduleがなければ) fooのみで参照できる)

WEBのマニュアルを見る限り、どうやら「何回も長いモジュール名を打つのが面倒だから」というモチベーションのようですが、エディタのサポートを受けるのが当然の現代では逆にError proneです。

github.com

WEB自体は現在普及しているとは言い難いし、上記のようにいまとなっては理にかなっていない仕様もありますが、対してWEBで書かれたソフトウェアがいまも広く利用されているというのは面白さを感じます。

literate-intellij-plugin

最低限のTeX engineを考えたとき何を実装しなければならないのか、TeXのWEBソースおよびKnuthのThe TeXbookを参照しながら構想を練り始めましたが、ここで、TeXのソースが長大である上に、pluginが無いため自分が愛用するIDEIntelliJ platform)を使ってコードブラウジングができないことが障壁になりました。

「文芸的プログラミング」のための記法であるWEBソースは、Weaveと呼ばれるツールに通すことでコードを含んだ綺麗に整形された完全なドキュメントを得ることができます。

とはいえ、シンタックスハイライトや定義ジャンプといったエディタのサポートなしで「文学」として読み通すには、TeXのソースは自分には複雑すぎる規模です。

そこで結局、Yak ShavingではありますがまずWEBのIntelliJ pluginを作成することにしました。

github.com

いまのところ以下の機能が実装されています。

  • シンタックスハイライト
    • TeXパート、マクロ定義パート、Pascalパートが色分けされます
  • Go to declarations
    • Pascalモジュール(@<...@>)参照から、定義元 (@<...@>=) にジャンプできます

Conclusion

WEBのコードリーディングが捗るようになったものの、所感としてはTeX engineの再発明は簡単ではなさそうです。

とはいえ、オリジナルのTeXの複雑さは当時のハードウェアや言語面の制約から来ている面も多い気がしており、最低限のTeX engineは今作ればシンプルにできたりしないだろうとまだ思っています。

今後も(興味が続けば)進めていきます。