> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/ja/sononotopikku/18-how-overleaf-created-the-tex-primitive-reference-data.md).

# Overleaf が TeX プリミティブ参照データを作成した方法

この記事では、TeXのプリミティブコマンドの2つの相互参照表を作成するために用いられた方法と技法について説明します：

* [TeXエンジン別に列挙したTeXのプリミティブ](/latex/ja/sononotopikku/46-tex-primitives-listed-by-tex-engine.md) および；
* [CJK TeXエンジン別に列挙したTeXのプリミティブ](/latex/ja/sononotopikku/45-tex-primitives-listed-by-cjk-tex-engine.md).

この情報は、より細かな点に関心のある読者向けに提供されていますが、相互参照表そのものを使うための前提条件ではありません。読者それぞれのニーズに応えるため、非常に短い要約版と、問題をより深く掘り下げたい人向けの詳しい説明の両方を用意しています。

## 短い要約/概要版

相互参照表を作成するため、Overleafは9つのTeXエンジンのソースコードを処理して、それぞれがサポートするプリミティブの一覧を抽出しました。その結果、9つのテキストファイル（TeXエンジンごとに1ファイル）が作成されました。その9組のプリミティブを組み合わせて「マスター一覧」を作成しました。これは実質的に、個々のプリミティブ集合の和集合であり、各種エンジンにまたがる約1000個の一意なプリミティブが得られました。各エンジンについて、そのプリミティブ一覧をマスターファイル（全コマンドの集合）と相互参照し、その約1000個のコマンドのうちどれをサポートしているかを判定しました。その比較結果を次の2つの表にまとめています：

* [TeXプリミティブの相互参照データ](/latex/ja/sononotopikku/46-tex-primitives-listed-by-tex-engine.md)
* [TeXプリミティブの相互参照データ（CJKエンジン向け）](/latex/ja/sononotopikku/45-tex-primitives-listed-by-cjk-tex-engine.md)

## 「ソフトウェアをビルドする」101：それはどういう意味？

この記事の残りでは、「TeXエンジンをビルドする」という概念に触れます。これは、プログラマでない人や、CやC++のようなコンパイル型言語で開発しない人にはなじみがないかもしれません。ここでいうソフトウェアのビルド、つまりTeXエンジンのビルドとは、構成要素であるソースコードファイル—プログラムの開発に使われるプログラミング言語で書かれたファイル—から、実行可能なTeXプログラムを作成するプロセスです。

## 完全版：詳細をご覧になりたい方はこちら...

TeXベースの組版エンジンはどれも、TeX言語の「方言」、つまり各エンジンの組版機能を制御し、マクロ—ユーザー定義のコマンド列—を作る/定義するための構成要素を提供するプリミティブコマンドの特定の集合をサポートしています。LaTeX用であれ、plain TeX用であれ、その他のマクロパッケージ用であれ、すべてのマクロは最終的にはプリミティブコマンドから構成されています—ただし、TeXプリミティブの「岩盤層」に到達するまでには、さらに多くのマクロ層をかなり深く掘り下げる必要があるかもしれません。プリミティブコマンドの参照データを作成するために解析した9つのTeXエンジンの集合は、もちろん多くのコマンドを共有していますが、各TeXエンジンには、その「版」に固有の機能をサポートするために開発者が追加した独自のプリミティブコマンドもあります。

TeXエンジンのプリミティブコマンドは、実行可能なTeXソフトウェアに組み込まれています。プリミティブはユーザーが作るマクロではなく、各エンジンの組版動作を制御するための基本的で不可分な、原子的な命令です。したがって、どのTeXエンジンがサポートするプリミティブコマンドの決定版一覧を作る最も確実な方法は、実行可能なTeXプログラムがそこから生成（コンパイル）される実際のソースコードを調べ、そこに定義されているプリミティブの一覧を抽出することです。簡単そうに聞こえますよね？ しかし、TeXの40年にわたる開発の歴史のため、LuaTeXを除くTeXエンジンのソースコードファイルを探索/調査するのは、特に簡単ではありません。その複雑さの原因は、Knuthが元のTeXソースコードを書く際に用いたツール、プログラミング言語（Pascal）、そして方法論（文学的プログラミング）にあります。そこから、最終的には他のすべてのエンジンが派生しています。

LuaTeXについては例外であることに注意します。というのも、そのコアエンジンコードは、下で詳述するPascalやその他の旧来の複雑さ（Web2C）の使用を取り除くためにCで書き直されたからです。そのため、LuaTeXのソースコード自体はかなり大きいものの、その「パッケージ化」や配布のされ方は、他のTeXエンジンと比べてはるかに理解しやすくなっています。その結果、ソースコードからのビルドのワークフロー/ प्रक्रियाに基づくと、TeXエンジンは2つのカテゴリにまとめると便利です：

1. LuaTeX：独自の（より आधुनिकな）ビルドプロセス
2. その他すべてのエンジン：旧来の（Web2C）ビルドプロセス

## 旧来コードの文脈：なぜ（ほとんどの）TeXエンジンのビルドは複雑なのか

以下で見るように、Knuthは元のTeXソースコードを、 `tex.web` という単一の巨大ファイルとして公開しました。これは7年ごとに更新され、残っているバグを修正し続けています—新機能が追加されることは一切なく、純粋にバグ修正だけが行われます。

TeXのソースコードの拡張子（`.web`）はあまりなじみがないでしょうし、Knuthはどの言語でTeXを書いたのだろうと思うかもしれません。答えはPascalですが、 `.web` この拡張子には少し説明が必要です。Knuthは [文学的プログラミング](https://en.wikipedia.org/wiki/Literate_programming) と呼ぶプログラミング手法を開発しました。これは、プログラムのソースコードと文書をまとめて1つの複合ファイル（コード＋文書）として拡張子 `.web`で公開するものです。そのファイル形式はWEBファイルと呼ばれます。WEBファイルについては下で少し詳しく説明します。

### 新しいTeXエンジンの作成：Knuthの条件

Knuthは長年にわたり、自身のTeXソースコード（`tex.web`）をすべての人に無償で公開してきましたが、彼には当然の権利として、重要な条件もありました。それは、自身の（`tex.web`）ソースコードを直接編集/変更して、プログラム名を「TeX」として再配布してはならない、というものです。ソースコードには次のように書かれています：

```
% このプログラムの著作権 (C) は1982年 D. E. Knuth にあり、すべての権利は留保されています。
% このファイルの複製は、(1) あなたが D. E. Knuth である場合、または
% (2) コピーに一切の変更を加えない場合にのみ許可されます。（WEBシステムでは
% 補助ファイルを通じた変更が可能です。マスターファイルはそのまま保持されるべきです。）
```

さらに：

```
このプログラムが変更された場合、その結果得られたシステムを
`\TeX'」と呼んではなりません。公式名称`\TeX'単独は、
互いに完全に互換なソフトウェアシステムに対してのみ予約されています。
「\. {TRIP} テスト」と呼ばれる特別なテストスイートは、
ある実装が
`\TeX'と呼ばれるに値するかどうかを判断するのに役立ちます［cf.~Stanford Computer Science report CS1027,
1984年11月］。
```

要するに、マスターTeXソースコードを編集して変更版を配布し、それを `tex.web`と呼び続けるようなことはしないでください。もし変更を加えたい、たとえば新しいプリミティブなどを追加したいのであれば、その変更は「補助ファイルを通じた変更」として行い、「TeX」の派生物であるあなたのプログラムには、「TeX」とは区別できる名前を付けなければなりません。なお、組版された形での（$$\mathrm\TeX$$）、これはアメリカ数学会の商標です。

### 旧来の継承

Javaベースの2つの取り組みのように、現代的なプログラミング言語や方法論を使ってTeXを完全に書き直そうとする試みは長年にわたり行われてきました。たとえば [New Typesetting System](https://en.wikipedia.org/wiki/New_Typesetting_System) や [εχTEX](http://www.extex.org/) や、ほかにもたとえば [Clojureによるもの](https://www.infoq.com/news/2015/01/implementing-tex-in-clojure)などがありますが、どれも完全には成功していません。TeXをさらに発展させるためのプロジェクトや取り組みの歴史は興味深い موضوعであり、読者は [UK TeX FAQを訪れて](https://texfaq.org/FAQ-enginedev) さらに情報を得ることができます。

e-TeX、pdfTeX、XeTeXその他のエンジンのように成功を収めた非LuaTeX系の取り組みは、 *直接その上に* 築かれてきました。つまり、Knuthの元のコードを取り出し、「変更を適用」して、新しいプリミティブの追加、PDF出力の生成、UTF-8テキスト入力のサポートなど、追加機能を備えた新しいエンジンを派生させてきたのです。この手法は目覚ましい成功につながった一方で、派生エンジンは、Knuthが40年前に作った旧来コードと開発技法を引き継ぐことにもなります。

ここでの重要なポイントは、LuaTeXを除けば、Knuthの元のソースコードから派生したほとんどのTeXエンジンは、単一の巨大ファイル（通常は `tex.web`）を取り出し、そのファイルに変更を加えることで、さらに別の単一の巨大ファイル、すなわち新エンジンのコアソースコードを含むファイルを生成する、という形で作られていることです。上級読者は、続く [pdfTeXとXeTeXに関する注記](#aside-xetex-and-pdftex).

### TeXの追加の歴史/背景

TeXが誕生した瞬間は [1977年3月30日としてKnuthの日記に記録されている](/latex/ja/xiang-xi-ji-shi/55-what-s-in-a-name-a-guide-to-the-many-flavours-of-tex.md#the-genesis-of-tex-a-brief-history)、つまり今から40年以上前です。内部的には、TeXは非常に複雑なプログラムであり、そのソースコードをKnuthは並々ならぬ努力を払って [極めて詳細に文書化しました](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373)。そのためにKnuthは [文学的プログラミング](https://en.wikipedia.org/wiki/Literate_programming) と呼ぶプログラミングスタイルを開発し、 `.web` プログラムのソースコードと文書をまとめて、拡張子 `tex.web`の複合ファイルとして公開しました（WEBファイルと呼ばれます）。KnuthはTeXソフトウェアを書くためのプログラミング言語としてPascalを選び、当然ながら、最終的な文書にはTeXの組版言語を用いました。したがって、KnuthのTeXのマスターソースコードは、

という1つの巨大ファイルとして公開されています。これは、Pascalソースコードと、文書用のTeX組版コードが混在したものです。 `tex.web`のようなツールで [WEAVE](http://tug.org/texinfohtml/web2c.html#weave-invocation) を使ってWEBファイルを処理すると、文書として組版できる `.tex` ファイルが得られます。Pascalのソースコードを抽出するには、 [TANGLE](http://tug.org/texinfohtml/web2c.html#tangle-invocation) という別のユーティリティを使い、拡張子 `.p` のPascalソースコードを含むファイルを出力します。

執筆時点（2019年初頭）で、KnuthのTeXの最新版は2014年1月付けの3.14159265です。繰り返しますが、KnuthのTeXソースコードは、約25,000行のTeX/Pascalコードを含むたった1つのファイルに収められています！

### PascalからCへ

TeX誕生から40年以上が経ち、Pascalは流行遅れとなり、今日では、元のPascalソースコードからTeXをビルドしようと考える人は、いてもごく少数でしょう。KnuthのPascal使用を回避するため、 [Web2C](http://tug.org/texinfohtml/web2c.html) と呼ばれるワークフローが（1987年ごろに）設計されました。これは、TeXのPascalソースコードを機械的に（つまりソフトウェアで）対応するCコードへ変換し、そのCコードを使ってTeXをコンパイルし、実行可能プログラムを作成するものです。うまく動作しますが、唯一の欠点は、機械生成されたCソースコードは人が気軽に読むことを想定していないことです。それは *極めて* 冗長で、ほとんど解読不能であり、人間ではなくコンパイラ向けに作られています—以下は、TeXのPascalソースから生成されたCコードの小さな断片を示すスクリーンショットです：

![](/files/2063032a6a6c774dc2c23e3a9fbf94f027663007)

### もう1つのKnuth流：WEB変更ファイル

前述のとおり、Knuthの元のソースコードの上に構築するには「変更を適用」する、あるいはKnuthの言葉で言えば「補助ファイルを通じた変更」を行います。しかし、これは実際にはどういう意味なのでしょうか？ そこで登場するのが *変更ファイル機構*.

### 変更ファイル：新しいTeXエンジンを作る仕組み

KnuthのTeXを何らかの形で拡張したい、つまりKnuthの元の成果の上に積み上げたい開発者は、通常、TeXのまったく新しい「版」を作るか、あるいは *拡張* を提供して、それを任意のTeXエンジンに追加できるようにしたいと考えます。拡張の例としては [SyncTeX](https://github.com/jlaurens/synctex) や [EncTeX](https://ctan.org/pkg/enctex?lang=en)があります—たとえばSyncTeXは非常に便利な拡張で、現在ではすべてのTeXエンジンに含まれています。EncTeXの必要性は、Unicode対応TeXエンジンの進化によって大部分が不要になりましたが、EncTeXはpdfTeXに組み込まれている点に注意してください。

TeXの新しい「版」（つまりKnuthの元のTeXの派生版）を作るのであれ、拡張を作るのであれ、開発者はKnuthの元のソースコードを出発点にして、新しいTeXエンジン（あるいはアドイン拡張）を作るために必要な修正を適用します。ただし前述のとおり、TeXの挙動を変更したい人は、そうした変更/修正を *直接* Knuthの元のソースコードを編集することで行ってはなりません。開発者は、いわゆるWEB *変更ファイル機構*を使う必要があります。KnuthのTeXを修正するコードはWEB「言語」で書かれ、 *変更ファイル*と呼ばれる1つ以上のコードファイルに保存され、その後 *統合されます* 。この統合作業によって、新しい複合WEBファイルが作成され、そこには新規/変更されたTeXベースソフトウェアの *コア* ソースコードが含まれるようになります。 *変更ファイルは* しばしば拡張子 `.ch` を持ちますが、実際には開発者が望む任意の拡張子を付けられます。

#### 変更ファイルはどう使う/適用するの？

今日では、変更ファイルを適用して「マスター」WEBファイルを修正する最も簡単な方法は、 [TIE](https://ctan.org/pkg/tie)と呼ばれるユーティリティプログラムを使うことです。たとえば、KnuthのTeXに新しいプリミティブを2つほど追加したり、既存の（標準の）TeXプリミティブの動作を変更したいとします。その場合は、WEBシステムの文学的プログラミングを使ってコードを（Pascalで！）書き、たとえば `myprim.ch`というファイルに保存します。次のステップは、そのコードを（ `myprim.ch`）Knuthのマスターソースファイルと `tex.web` 結合して、 `mytex.web`と呼ぶことにする新しい複合WEBファイルを作成することです。これを行うには、次のようにTIEプログラムを実行するだけです：

```
tie -m mytex.web tex.web myprim.ch
```

結合が成功すると、新しいWEBファイル `mytex.web`が生成され、Knuthのマスターソースファイル `tex.web` は要件どおり完全に変更されないままとなります。

では、あなたの加えた変更を気に入った別の人が、その上に自分の変更を追加したいと考えたとします。あなたは、自分が変更したTeX版（`mytex.web`）を配布する代わりに、変更ファイルだけを公開/共有することにします。 `myprim.ch`。あなたの成果の上に構築したい人は、たとえば `moreprim.ch` という自分の変更ファイルを作成して共有できるようになります。さらに、複数の変更ファイルの両方を利用したい人は、 *両方の* 変更ファイルをKnuthの元のものに統合して、たとえば `newmytex.web`:

```
tie -m newmytex.web tex.web myprim.ch moreprim.ch
```

### 実際のTeXシステム：複数の変更ファイル

上のTIEの説明は、実際に多くのTeXエンジンが構築される方法に非常に近いものです。すなわち、Knuthの `tex.web` を出発点にして、一連の変更ファイルを追加し、そのエンジン用のWEBソースファイルを生成します。各TeXエンジンには固有の変更ファイル群があり、それらは厳密な順序で適用/処理（統合）しなければなりません。順序を間違えると、連続する各変更ファイルは前の変更ファイルによって導入された変更に依存しているため、統合作業は失敗します。

以下は、複数の変更ファイルをKnuthの `tex.web` に適用して `ktex.web`を生成するTIEの実行例です—これは、KnuthのTeXに対する変更を含み、Web2Cプロセスを通じてCに変換する準備（適切な状態）を整えた複合WEBファイルです。あわせて次の点にも注意してください：

* `tex.ch` は非常に大きな変更ファイルで、多くのことの中でTeXをKpathseaを使うように変更しています；
* SyncTeX拡張は複数の変更ファイルを通じて追加されます。

```
tie -m ktex.web tex.web tex.ch enctex.ch synctex-def.ch0 synctex-mem.ch0 synctex-mem.ch2 synctex-rec.ch0 synctex-rec.ch1 synctex-rec.ch2 tex-binpool.ch
これがTIE、CWEB版2.4です。
著作権 (c) 1989,1992 THD/ITI。すべての権利は留保されています。
(tex.web)
(tex.ch)
(enctex.ch)
(synctex-def.ch0)
(synctex-mem.ch0)
(synctex-mem.ch2)
(synctex-rec.ch0)
(synctex-rec.ch1)
(synctex-rec.ch2)
(tex-binpool.ch)
....500....1000....1500....2000....2500....3000....3500....4000....4500
....5000....5500....6000....6500....7000....7500....8000....8500....9000
....9500....10000....10500....11000....11500....12000....12500....13000
....13500....14000....14500....15000....15500....16000....16500....17000
....17500....18000....18500....19000....19500....20000....20500....21000
....21500....22000....22500....23000....23500....24000....24500....
（エラーは見つかりませんでした。）
```

#### 補足：XeTeXとpdfTeX

完全性のために述べておくと、pdfTeXとXeTeXのビルドプロセスは、実際にはKnuthの `tex.web`から始まるわけではありません；代わりに、 `pdftex.web` や `xetex.web` というファイルからそれぞれ始まります。おそらく、変更が非常に大きいため、Knuthの元のコードに加えられた非常に重要な修正をすでに含むWEBファイルを共有/公開する方が理にかなっているのでしょう。

### 例：e-upTeX

日本のTeXコミュニティは、日本語組版の複雑さに対応するためのTeXエンジンをいくつか開発してきました：

* **pTeX**：KnuthのTeXエンジンを拡張し、日本語組版をサポートするようにしたもの；
* **e-pTeX**：e-TeXとpTeXの組み合わせ（さらにpdfTeXで導入された若干のプリミティブを追加）；
* **upTeX**：pTeXのUnicode対応版に、CJK（中国語、日本語、韓国語）の扱いを改善する拡張を加えたもの；
* **e-upTeX**：e-TeXとupTeXの組み合わせ（統合）。

#### e-upTeXの複合ソースファイルの生成

e-upTeX（SyncTeX付き）の複合WEBソースファイルを作るには、Knuthの `tex.web` から始めますが、 **26** 個別の変更ファイルを次の順序で適用して、そこからプリミティブコマンドの一覧を抽出できる単一の複合ファイルを生成する必要があります：

```
etex.ch, tex.ch0, tex.ch, tex.ech, etex.ch0,
ptex-base.ch, uptex-m.ch, euptex.ch0, eptex.ech,
etex.ch1, euptex.ch1, synctex-def.ch0, synctex-ep-mem.ch0,
synctex-mem.ch0, synctex-e-mem.ch0, synctex-ep-mem.ch1,
synctex-p-rec.ch0, synctex-rec.ch0, synctex-rec.ch1,
synctex-e-rec.ch0, synctex-p-rec.ch1, fam256.ch,
pdfstrcmp-eup-pre.ch, pdfutils.ch, pdfstrcmp-eup-post.ch,
tex-binpool.ch
```

#### 変更ファイルの適用：どのファイルを、どの順序で？

前述のとおり、変更ファイルは厳密な順序で適用/処理することが極めて重要ですが、必要なファイルがどれで、どの順序で処理すべきかはどうやって知るのでしょうか？ 幸い、その重要な情報はTeX Live配布物に含まれるファイル内に記録されており、TeX Liveのソースコードを調べることで、各TeXエンジンのビルド要件を規定するルールが明らかになりました。これらのルールに従って、Overleafは各TeXエンジンの複合WEBソースコードファイルを再構成し、後続のデータ処理のためにプリミティブの一覧を抽出することができました。

## そして最後に：プリミティブの一覧をどう抽出するのか？

複合WEBファイルが作成されれば、正規表現を用いてプリミティブ一覧を抽出する作業は簡単です。というのも、すべてのプリミティブコマンドは `primitive(...)`という単一のPascal関数を使って定義（「登録」）されているからです。Knuthの `tex.web` ソースコードから取った実例をいくつか示します：

```
primitive("lineskip",assign_glue,glue_base+line_skip_code)
primitive("baselineskip",assign_glue,glue_base+baseline_skip_code)
primitive("parskip",assign_glue,glue_base+par_skip_code)
primitive("abovedisplayskip",assign_glue,glue_base+above_display_skip_code)
primitive("belowdisplayskip",assign_glue,glue_base+below_display_skip_code)
primitive("abovedisplayshortskip",assign_glue,glue_base+above_display_short_skip_code)
...
...
```

ご覧のとおり、 `primitive(...)` この関数は正規表現によるテキスト処理に非常に適しています。登録されるプリミティブの名前は引用符（`"..."`）内にあり、各プリミティブの動作を分類する追加データも付いています（ここでは詳細には触れません）。各エンジンのプリミティブ一覧を抽出した後、そのデータはLuaスクリプトで処理され、表形式の結果を含むHTMLが生成されました。

### LuaTeXに戻ると

LuaTeXが他の8つのTeXエンジンとまったく同じビルドプロセスを使っていないことは、すでに述べました。Web2Cプロセス、PascalからCへの変換、そして変更ファイル機構をざっと見たところで、LuaTeXがどこで異なるのかを説明できます。LuaTeXの開発者は、PascalをCに変換する面倒なプロセスを取りやめることにしたのです— [LuaTeXリファレンスマニュアル](http://www.pragma-ade.com/general/manuals/luatex):

> にあるように、

...コンパイル基盤はweb2cであり、そのまま使い続けていますが、PascalからCへのステップはありません。

LuaTeXのコアエンジンはCで書き直されており、その結果、そのビルドプロセスは多少標準的になり、確かにずっと便利になっています。1つの有用な結果として、LuaTeXがサポートするプリミティブは別個のCソースファイルにきれいに切り出されており、それらへアクセス/一覧化する作業がかなり楽になりました。 [CWEB](https://en.wikipedia.org/wiki/CWEB)と呼ばれる、PascalではなくCに基づくKnuthの文学的プログラミング手法の派生版を使うソースコードファイルもあることに、厳密には触れておくべきでしょう。

### WEBファイルだけではない：他のソースコードも必要

LuaTeXを除くどのTeXエンジンでも複合WEBソースファイルを生成した後、Pascalソースコードを抽出してCコードに変換する必要がありますが、それで全てというわけではありません。WEBソース（Pascal⮕C）から生成されたCコードに加えて、ほとんどのTeXエンジンは、通常Cで書かれた追加の補助ソースコードファイル（ライブラリ）も必要とします。たとえば [Kpathsea](https://www.tug.org/kpathsea/)などです。補助ソースファイル（ライブラリ）は、WEB（Pascal）で書く必要がない、あるいは書けない機能を実装します。TeX向けにWEB「言語」で書くものは、Pascal言語を使わなければならず、その後に抽出されて機械生成されたCへ変換されます。そもそもその変換が不要なら、最初からCやC++で単純に書けばよいのです。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/ja/sononotopikku/18-how-overleaf-created-the-tex-primitive-reference-data.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
