> 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/xiang-xi-ji-shi/47-tex-tables-how-tex-calculates-spanned-column-widths.md).

# TeXの表：TeXが列またぎの列幅をどのように計算するか

## この記事の目的

この記事では、〜をどのように $$\mathrm\TeX$$ 表が複数列にまたがる項目（たとえば、表の見出し）を含むときに、表の列幅をどのように計算するかを（たとえば、 $$\mathrm\TeX$$ プリミティブ `\omit` や `\span`）。基本的な [「参照」テーブル](#reference-table) を出発点として、その参照テーブルから派生させたさまざまな例を作成し、複数列にまたがる列を作るために各項目を変更していきます。そうした変更の影響を調べることで、基礎となっているアルゴリズムが $$\mathrm\TeX$$ を使って、またがる列の幅を計算しているのかについての理解を深めることができます。

### 〜を使用する $$\mathrm\TeX$$ 実際の $$\mathrm\LaTeX$$

を調べて説明するには *どのように* $$\mathrm\TeX$$ がまたがる列の幅をどのように決めるかを理解するには、すばらしい $$\mathrm\LaTeX$$ テーブルパッケージをすべて避け、基本的な低レベル（原始的）なテーブル作成コマンドに戻る必要があります。とくに、 `\halign{...}`, `\span` や `\omit`. [既存の $$\mathrm\TeX$$/$$\mathrm\LaTeX$$ テーブルパッケージ](https://ctan.org/topic/table) はもちろん重要な生産性向上ツールであり、 $$\mathrm\LaTeX$$。それらのパッケージは、 $$\mathrm\TeX$$の低レベルな挙動の上に構築された不可欠な「マクロの足場」を提供し、その開発者たちは、基盤にある複雑さを処理してくれる非常にありがたい抽象化と隔離層を提供してくれています。そうしたパッケージの多くは、実に驚くべき複雑な $$\mathrm\TeX$$ プログラミングの成果であり、むき出しの $$\mathrm\TeX$$!

実際のアルゴリズムが $$\mathrm\TeX$$ 複数列にまたがる列幅を計算するために使うアルゴリズムは、 [$$\mathrm\TeX\text{book}$$](https://www.amazon.co.uk/TeXbook-Donald-E-Knuth/dp/0201134489) さらに詳しくは、セクション801（336ページ）を含む印刷版の $$\mathrm\TeX$$のソースコード [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373)。しかし、多くの人にとって（私自身を含め）、クヌースの説明は、時にかなり簡潔で要点が絞られており、細部まで追うのが難しいことがあります。図入りの例はいつも非常に役立ちます。

### はい、表は複雑です

書籍のセクション768（322ページ）で [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373)、クヌースは興味深いコメントをしています：

> 「〜がうまく動くのは、ある種の奇跡だ。 `\halign` や `\valign` それらは〜の制御構造のあまりにも多くを横切っているからだ。 $$\mathrm\TeX$$」によって示されます。

さらに、4巻本の書籍シリーズの第IV巻 [$$\mathrm\TeX\text{ in Practice}$$](https://www.amazon.co.uk/Tex-Practice-Set-Stephan-Bechtolsheim/dp/038797296X/ref=sr_1_11?s=books\&ie=UTF8\&qid=1504256043\&sr=1-11\&keywords=TeX+in+Practice) では、〜で表を作成することに180ページ以上（pp199–379）を割いています $$\mathrm\TeX$$ 使えます。 `\halign` や `\valign`.

したがって、 $$\mathrm\TeX$$ 表は確かに「かなり厄介」だといってよいでしょう。

### 列をまたぐ：\omit、\span、\multispan

述べたように、 $$\mathrm\TeX$$の列幅計算を調べるには「生の」 $$\mathrm\TeX$$を使う必要があります。ここでいうのは、基本コマンドと1つの $$\text{Plain }\mathrm\TeX$$ という `\multispan`を組み合わせたものです。これらのコマンドを例のテーブルを直接示すためには使いません（つまり、すべての $$\mathrm\TeX$$ コードを完全に説明するわけではありません）が、簡単な説明を入れておく価値はあります。

* `\halign`：2つのうちの1つ $$\mathrm\TeX$$ テーブルを作成するための基本コマンド（命令）。もう1つは `\valign` ですが、こちらはそれほど広く使われておらず、この記事では扱いません。
* `\omit`： $$\mathrm\TeX$$ 基本コマンド（命令）で、〜に指示する $$\mathrm\TeX$$ テーブル項目のプレアンブル・テンプレートを無視するよう
* `\span`： $$\mathrm\TeX$$ 隣接する2つのテーブル項目を結合するために使う基本コマンド（命令）。
* `\multispan{n}`プレーンな $$\mathrm\TeX$$ 列をまたぐためのマクロ `n` 。

要するに、列をまたぐには $$\mathrm\TeX$$ 適切な数のテーブルプレアンブルテンプレートを無視し、必要な数のテーブル項目を1つの項目にまとめます。 `\multispan{n}` は、次の連なりに展開されることで動作します `\omit` や `\span` 列をまたぐのに必要なトークン `n` 。たとえば、 `\multispan{3}` は `\omit\span\omit\span\omit`.

## 「参照」テーブルの紹介

以下が参照テーブルで、その後に、構成に使われている要素を説明する注釈付き版を示します：

![{{{alt}}}](/files/239447554c298953c7b19f9f880540f9ea23b963)

参照テーブルを修正していくことで、さまざまな列にまたがる項目を追加したときに、テーブル全体の幅と個々の列の幅がどう変化するかを観察します。この参照テーブルは、生の $$\mathrm\TeX$$ を `\halign{...}` 基本コマンドと、表を組版するために必要ないくつかのカスタムマクロを併用して作成されています。これらのマクロは、例や説明を理解するうえで本質的ではないので、ここでは扱いません。

以下は、参照テーブルの特徴を説明する注釈付き版です：

![{{{alt}}}](/files/7561ece996f33fd10250dc2b24469db0d749284f)

最初の例のテーブル群と初期の参照テーブルでは、すべて `\tabskip=0pt` に設定してあります。これにより $$\mathrm\TeX$$ は列間にいかなる空白も追加しません。実質的には、すべての列が互いに接しています。こうしている理由は、初期の議論とそれに続く計算を簡単にするためです。後でこの記事では、非ゼロの `\tabskip` グルーを再導入して、複数列にまたがる列幅の計算にどのような影響があるかを調べます。

注釈にあるように、すべての非スパンのテーブル項目の先頭（最初の行を除く）に少量の空白（5pt）を加えています。その5ptの空白は、（最初の行を除く）すべての非スパン項目の総幅の一部を構成しており、表を少しだけすっきり見せるために追加したものです。

### テーブル幅についての簡単な注意

この `\halign{...}` コマンドには3つの形式があります：

* `\halign{...}`：テーブルの幅を、 $$\mathrm\TeX$$ が項目のサイズ（および `\tabskip` グルー）に基づいて計算した任意の幅に設定する；
* `\halign to *width* {...}`： $$\mathrm\TeX$$ に、指定した `*width*`;
* `\halign spread *amount*{...}`：計算された幅を `*amount*`.

もう一度 $$\mathrm\TeX$$ を使ってテーブルを組版します `\halign{...}` 組版するために必要なさまざまな計算を行うには、テーブル全体をメモリに読み込まなければなりません。したがって、 `\halign to *width* {...}` で幅を指定していない限り、 $$\mathrm\TeX$$ が処理（組版）を終えるまで最終的な幅はわかりません。 `\halign{...}` によって作られたテーブルの幅を得る1つの方法は、まずテーブルを `\vbox{...}` （たとえば、 `\setbox0=\vbox{\halign{...}}`）の中に組版し、その後、たとえば `\the\wd0` を使って幅を取得することです。

### テーブル項目内で自動改行しない

重要なのは、 $$\mathrm\TeX$$ が `\halign{...}` で作成されたテーブルを組版しているとき、テーブル項目内のテキストは自動的に改行の対象にはならないということです。テーブル項目は *制限付き水平モード*—ちょうど `\hbox`。改行を有効にするには、テーブル項目のテキストを `\vbox{...}` で囲み、さらにその `\hsize` に適切な値を指定する必要があります。 `\vbox{...}`。ただし、 `\noalign{...}` コマンド（ $$\mathrm\TeX$$ 基本コマンド）で、〜の中で使われる `\halign{...}` は〜の対象になります $$\mathrm\TeX$$の改行です。実質的に、その名が示すとおり、 `\noalign{...}` は〜を可能にし $$\mathrm\TeX$$ 、 `\halign{...}` から「抜け出して」テーブルの行の間に内容を置くことを可能にします。通常は、表の行の間に水平罫線を引くために使われます。

### 許可されていないこと：\hbox{...} の中に \halign{...}

できません *直接* 組版することは `\halign{...}` \hbox{...} `\hbox{...}`の中に `\hbox{\halign{...}}` を使おうとすると、かなりわかりにくいエラーが発生します：

```latex
! Missing } inserted.
<inserted text>
                }
<to be read again>
                   \halign
l.1 \hbox{\halign
```

#### このエラーの説明

それを囲む `\hbox{...}` $$\mathrm\TeX$$ は〜の中にあり *制限付き水平モード*すると、 `\halign{...}` これは〜という *垂直モード* コマンドです。たとえば、 `\halign{...}` 段落内で $$\mathrm\TeX$$ は段落を終了し、 `\halign{...}` を処理してから、段落の残りを続けます。

〜の中で使われると `\hbox{...}`、 `\halign{...}` は〜を引き起こし $$\mathrm\TeX$$ 、現在のグループを強制的に閉じようとして垂直モードへ戻ろうとします： $$\mathrm\TeX$$ は「`! Missing }`」と報告し、グルーピングの使い方でミスをしたと判断してエラーを出します。右中括弧（`}`） $$\mathrm\TeX$$ のコードに欠けているわけではなくても、このエラーメッセージは、 `\hbox{...}` が邪魔をしていて、 $$\mathrm\TeX$$ 問題を解決するための適切な対処を「最善の推測」で選んでいることの表れです。

## 複数列にまたがる列を持つ表の例

以下の一連の表図は、表の列にまたがる効果を示すさまざまな例を提供します。長いテーブル項目が、特定の列の幅、ひいては表全体の幅に予期しない結果をもたらしうることを示しています。これから扱う問いは、 $$\mathrm\TeX$$ が、ある表項目が複数の列にまたがるが「幅が大きすぎて収まらない」場合に $$\mathrm\TeX$$ が何をするのか、ということです。上で述べたように、

### は列幅を計算するこの問題に対して確かに特定のアルゴリズムを適用しています。次の例は、そのアルゴリズムの働きを「体感」できるように設計されています。

例表1 `\multispan{2}` を使って、1列目と2列目をまたがせ、テキストが **表の見出し**:

![{{{alt}}}](/files/a1f20487aebb4a831542a1f6ac58882919d8fa6c)

#### 観察

* この表の幅は [参照テーブル](#reference-table): $$327.71722\text{pt}$$.
* 1列目と2列目にまたがる項目の幅は $$81.04953\text{pt}$$ であり、またがっている列の項目の合計幅よりも小さい： $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$

## 例表2

と同様に [は列幅を計算するこの問題に対して確かに特定のアルゴリズムを適用しています。次の例は、そのアルゴリズムの働きを「体感」できるように設計されています。](#example-table-1)、この例でも `\multispan{2}` を使って1列目と2列目をまたがせていますが、ここではテキストが **やや長い表の見出し**.

![{{{alt}}}](/files/0b408f2aa319072680dc9c765822033db07fc9aa)

#### 観察

もしこの例を [参照テーブル](#reference-table) と比べると、次のことがわかります：

* この表の幅は $$327.71722\text{pt}$$ から $$374.37032\text{pt}$$：合計 $$46.6531\text{pt}$$.
* 1列目と2列目にまたがる項目（$$156.28664\text{pt}$$）の幅は、またがっている列の項目の合計幅より大きい： $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$。その差は $$156.28664\text{pt}-109.63355\text{pt} = 46.6531\text{pt}$$ であり、これは表の幅が増えた量と同じです。
* $$\mathrm\TeX$$ は、必要な追加スペースを確保するために2列目の幅を調整しました。後で、 $$\mathrm\TeX$$ が2列目をどれだけ増やす必要があるかをどのように計算するかを見ます。
* 1列目は影響を受けません。1列目と2列目にまたがる項目によって、その幅は変わっていません。

### 例表3

例表1 `\multispan{3}` を使って、テキストが [例表2](#example-table-2): **やや長い表の見出し**.

![{{{alt}}}](/files/23a677d9ae509845b03e0d1cdf6df472c4b9a7ea)

#### 観察

* この表の幅は [参照テーブル](#reference-table): $$327.71722\text{pt}$$.
* と同じ項目で1列目から3列目までをまたがせます$$156.28664\text{pt}$$1列目から3列目にまたがる項目（ $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} = 168.67254\text{pt}$$.
* ）の幅は、それがまたがる3列の項目の合計幅よりも小さい：

列幅のどれにも、1列目から3列目にまたがる項目の影響はありません。

### 少しずつパターンが見えてきましたか？

順不同 [例表3](#example-table-3)と同様に、ここでは `\multispan{3}` を使って1列目から3列目をまたがせますが、今回はかなり長いテキストの項目を使います： **かなり長い、ずっと先まで伸びる表の見出し**.

![{{{alt}}}](/files/2be7373fcd2b409f1e149b51dbcf5fb6ae15dc44)

#### 観察

* と比べると [参照テーブル](#reference-table)、この表の幅は $$327.71722\text{pt}$$ から $$465.95685\text{pt}$$：増加量は $$138.23963\text{pt}$$.
* 1列目から3列目にまたがる項目の幅は $$306.91216\text{pt}$$.
* またがる3列の項目の合計幅は $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} = 168.67254\text{pt}$$.
* 長いまたぎ項目と1列目から3列目の項目との幅の差は $$306.91216\text{pt}-168.67254\text{pt}=138.23962\text{pt}$$。表の幅が増えた量と同じです（小数点以下4桁まで！）。
* 幅が増えたのは3列目だけです。1列目も2列目も影響を受けていません。

#### パターンが現れる

を見てみると [例表2](#example-table-2) や [少しずつパターンが見えてきましたか？](#example-table-4) 、両方の場合で **またがりの最後の列** であることがわかります。そこがその幅を増やして、列をまたぐ長い項目のためのスペースを作っていたのです：

* で [例表2](#example-table-2)：長い項目は1列目と2列目にまたがっていました。2列目が「引き伸ばされ」ました。
* で [少しずつパターンが見えてきましたか？](#example-table-4)：長い項目は1列目から3列目にまたがっていました。3列目が「引き伸ばされ」ました。

#### 3列目の幅：アルゴリズムが見えてくる？

以下の計算を見れば、 $$\mathrm\TeX$$ が何をしているのか、よりはっきりわかります。わかっていることは次のとおりです：

* 1列目から3列目にまたがる長い項目の幅は $$306.91216\text{pt}$$.
* 1列目と2列目の項目の合計幅は $$52.56676\text{pt} + 57.06679\text{pt} = 109.63355\text{pt}$$.

それらの値の差は何でしょうか？ それは $$306.91216\text{pt}-109.63355\text{pt} = 197.2786\text{pt}$$ であり、これは3列目に使われる幅です。これは $$\mathrm\TeX$$.

### 例表5

もっと複雑な例に入る前に、もう1つ「単純な」例を示します。この表には [少しずつパターンが見えてきましたか？](#example-table-4): **かなり長い、ずっと先まで伸びる表の見出し**と同じ長い項目が含まれています。しかし今回は `\multispan{6}` を使うことで、その項目が表全体にまたがれるようにしています。ご覧のとおり、結果として得られる表の幅は依然として [参照テーブル](#reference-table) ($$327.71722\text{pt}$$）と同じであり、そのため、この非常に長い項目によって影響を受けた列はありません。明らかにこれは、項目の幅（$$306.91216\text{pt}$$）が、それがまたがっているすべての項目の合計幅より小さいからです： $$327.71722\text{pt}$$つまり、表の幅です。

![{{{alt}}}](/files/1b4e5416833cd4ad63bc05df412a6c1ac9d5dba3)

### 例表6：やや複雑

ここでは、5列目までまたがる2つの異なる項目の効果を示すために、3つの例表（6(a)〜6(c)）の連続を見ていきます。 [例表6(a)](#example-table-6a) や [例表6(b)](#example-table-6b) いずれも、5列目まで複数列にまたがる単一の項目を含む表を示しています。 [例表6(c)](#example-table-6c) は、両方のまたぎ項目を1つの表にまとめ、次の問いを投げかけます。実際に5列目の幅を決定しているのはどちらの項目で、なぜでしょうか？ その答えは、 $$\mathrm\TeX$$.

#### 例表6(a)

![{{{alt}}}](/files/7651c1666c6eb43a25ec88e494aabc62f4a8ff5a)

**観察**

* と比べると [参照テーブル](#reference-table)、この表の幅は $$327.71722\text{pt}$$ から $$371.11153\text{pt}$$：増加量は $$43.39431\text{pt}$$.
* 3列目から5列目にまたがる項目の幅は $$215.06683\text{pt}$$.
* 3列目から5列目の項目の合計幅は $$59.03899\text{pt} + 52.98344\text{pt} + 59.6501\text{pt} = 171.67253\text{pt}$$.
* 3列目から5列目にまたがる項目の幅と、またぎ項目の幅との差は $$215.06683\text{pt}-171.67253\text{pt}=43.3943\text{pt}$$：表の幅が増えた正確な量（小数点以下4桁まで！）です。

#### 例表6(b)

![{{{alt}}}](/files/3390b0d475a5ca94f70f0aa67375ab7f1d0e8342)

**観察**

* と比べると [参照テーブル](#reference-table)、この表の幅は $$327.71722\text{pt}$$ から $$353.3233\text{pt}$$：増加量は $$25.60608\text{pt}$$.
* 1列目から5列目にまたがる項目の幅は $$306.91216\text{pt}$$.
* 1列目から5列目の項目の合計幅は $$52.56676\text{pt} + 57.06679\text{pt} + 59.03899\text{pt} + 52.98344\text{pt} + 59.6501\text{pt} = 281.30608\text{pt}$$.
* 1列目から5列目にまたがる項目の幅と、またぎ項目の幅との差は $$306.91216\text{pt}-281.30608\text{pt}=25.60608\text{pt}$$: **note** これは *より小さい* という値で [例6(a)](#example-table-6a)、それは $$43.3943\text{pt}$$.

#### 例表6(c)

ここでは、例表 [6(a)](#example-table-6a) や [6(b)](#example-table-6b) の項目を1つの表にまとめます。何が起こるでしょうか？

![{{{alt}}}](/files/0f037ce2d0deaf1ea4c133882aa8714273ce3c4b)

**観察**

* と比べると [参照テーブル](#reference-table)、この表の幅は $$327.71722\text{pt}$$ から $$371.11153\text{pt}$$：増加量は $$43.39431\text{pt}$$。これはちょうど [例表6(a)](#example-table-6a).

#### は何を $$\mathrm\TeX$$ しているのでしょうか？

の結果を理解するには $$\mathrm\TeX$$のアルゴリズムと判断プロセスを理解するには、この項目が

![{{{alt}}}](/files/c8a286f485d01d1d96dd3626738aa9828285c71c)

によってまたがれている項目を超えて広がっています。 $$25.60608\text{pt}$$。しかし、この項目は

![{{{alt}}}](/files/182ca7669083c63e627daffae16e4fa96da6cb96)

またがれている項目をさらに大きく超えて広がっています： $$43.3943\text{pt}$$。したがってその項目が「競争に勝ち」、5列目の幅は **最大値** （この2つの値の$$43.3943\text{pt}$$）。5列目の幅は今や $$59.6501\text{pt} + 43.3943\text{pt} = 103.0444\text{pt}$$ 、3列目から5列目にまたがる項目を収めるために

## 複雑さを少し戻す

これまで議論の複雑さを最小限にするため、 $$\mathrm\TeX$$のアルゴリズムの原理を示すのに比較的単純な例を使ってきました。とくに、 `\tabskip=0pt`を設定しました。実際の「現実世界」の表では、もちろん、さまざまな列にまたがる多くの項目があり、さらに `\tabskip` グルーに非ゼロの値が設定されていることが多いでしょう。そこで、その話題を今あらためて取り上げます。

### \tabskipグルーとまたがり列の幅

表のデザインでは、列の間に空白を加える必要がよくあります。もちろん $$\mathrm\TeX$$ には、 `\tabskip`という基本コマンドによるこの機能があります。このコマンドは、固定または柔軟なグルー（間隔）を次の場所に入れるために使えます：

* 表の前（つまり1列目の左側）；
* 1つ以上の列の間；
* 表の後（つまり最後の列の右側）。

ここで、思い出すための例を示します：

![{{{alt}}}](/files/221acd357ab3e4d6f8c04e69676685defd18d376)

### \tabskipグルーはまたがり列の幅にどう影響するのか？

非ゼロの `\tabskip` グルーにより、またがり項目は、 $$\mathrm\TeX$$ がまたがり内の最後の列の幅を増やすことを考える前に「吸収」できる追加スペースが生まれます。

次の例では、2つのテーブルを使って2列をまたぐ結果を比較します。テーブル間の唯一の違いは `\tabskip` グルーの使い方です。

* 最初の例では、元の「参照」テーブルを使います。ご記憶のとおり、そこでは `\tabskip=0pt`.
* 2番目の例では、元の [参照テーブル](#reference-table) （上で注釈付きで示したもの）の修正版を使います。そこでは `\tabskip=10pt` が表の前後に設定されていますが、さらに重要なのは、列間に `\tabskip=20pt` が設定されていることです。

この *修正版の* 参照テーブルでは、2つのまたぎ列は列幅（および表幅）に影響しませんが、 *元の* [参照テーブル](#reference-table).

### 元の参照テーブル：\tabskip=0pt

ここでは、元の [参照テーブル](#reference-table) と、それから派生した2番目の表（元の [参照テーブル](#reference-table)から作成したもの）を示します。そこには「**より長い表の見出しを試す**」が1列目と2列目にまたがっています。明らかに、図の第2の表の2列目、したがって表全体が、どちらもまたがり列の影響を受けています。

![{{{alt}}}](/files/d962498794df49b9f75bdfb4a86da16d56f95441)

### 修正版の参照テーブル：\tabskip=20pt

ここでは、修正版の参照テーブルと、それから派生した第2の表を示します。こちらにも「**より長い表の見出しを試す**」が1列目と2列目にまたがっています。明らかに、図の第2の表では、2列目の幅も表の幅も、またがり列の影響を受けていません。この場合、列間の `\tabskip` グルー（`20pt`）が、1列目と2列目にまたがる項目のテキストに必要なスペースを「吸収」するのに役立っています：

![{{{alt}}}](/files/0273de6a60cee515362bc702f8a681f434f00c8f)

## の本質 $$\mathrm\TeX$$のアルゴリズム

うまくいけば、上で示したさまざまな例によって、 $$\mathrm\TeX$$ がまたがり項目にどう対応するのか、そして $$\mathrm\TeX$$ 必要なら **最後の** 列の幅を各またがり範囲ごとに調整するのかについての「感覚」が養われたことでしょう。個々の列内の項目幅に加え、非ゼロの `\tabskip` グルーは、 $$\mathrm\TeX$$ が列幅を調整する必要があるかどうかを判断する際に考慮される重要な要素です。覚えておくべき要点は、 $$\mathrm\TeX$$の目標は、 **最後の列** に、それぞれのまたがり範囲内で適切な幅を計算することです。

### 最終テーブルの例：またがり範囲内の最後の列

この最後の例では、再び修正版の参照表を使います（ `\tabskip` 上で述べたグルーの値）を用いて、さまざまな列が罫線によってまたがる別の表を導出します—またがりが見やすいように罫線を使っています。

2つの表は丁寧に揃えてあり、上の表では、5列目より前の列は一切、またがった列の影響を受けていないことが示されています。図の左側にある濃い緑の領域は、両方の表の1列目から4列目が依然として完全に一致していることを示しています。右側には薄い緑の網掛け領域があり、影響を受けているのは5列目と6列目だけであることを示しています。

上の表では、またがりは次のとおりです：

* 1列目から5列目：a にまたがる $$400\text{pt}$$ 罫線;
* 3列目から5列目：a にまたがる $$200\text{pt}$$ 罫線;
* 4列目から6列目：a にまたがる $$250\text{pt}$$ 罫線。

![{{{alt}}}](/files/976ce437e1ff131bfac6ffdf206a8bc5852a394e)

繰り返しになりますが、説明はこうです。列が連続してまたがっている場合、（必要なら）調整されるのは最後の列の幅だけです。途中の列は影響を受けません。ここではそれが1列目から4列目を意味します—もっとも、もちろん1列目から4列目の幅（および途中のグルー）は、5列目と6列目の調整後の幅を計算する際に考慮されます。 `\tabskip` グルー）は、5列目と6列目の調整後の幅を計算するときに考慮されます。

### 手順の説明 $$\mathrm\TeX$$のアルゴリズム

最後に、 *簡略化した* 「$$\mathrm\TeX$$」の思考過程は、またがり項目における列幅を算出する際のものです。説明する $$\mathrm\TeX$$のアルゴリズムを説明するのは必ずしも簡単ではないので、何が起きているかの概要を示すために、少し「簡略化した創作上の自由」を採用します。面倒な細部すべてに興味のある読者は、これを含む印刷版の本の801節（336ページ）を参照してください $$\mathrm\TeX$$のソースコード [$$\mathrm\TeX\text{: The Program}$$](https://www.amazon.co.uk/Computers-Typesetting-Tex-Program-TEX/dp/0201134373).

実際の表は、しばしば `\span` 基本命令（たとえば、 $$\mathrm\LaTeX$$ パッケージ内部などで）を使って、表内に複数のまたがり列のインスタンスを構成します。これに対応するため、データ構造（深い内部では $$\mathrm\TeX$$）は情報（いわゆる *スパンノード*）を保持し、表の項目/列間のリンク（またがり）について知らせます。明らかに、 $$\mathrm\TeX$$ TeX に表の項目/列間のリンク（またがり）を知らせます。明らかに、 $$\mathrm\TeX$$ は、そのアルゴリズムを体系的に適用し、最終計算を行うために表全体を処理する必要があります—すべての列幅、表全体の幅、そして必要なら表で使われたフレキシブルなグルーをどれだけ伸ばしたり縮めたりする必要があるかを決めるためです。 $$\mathrm\TeX$$ は、コマンドを完全に処理し終えるまで最終的な表幅を教えることができないのも、実はさほど驚くことではありません。 `\halign{...}` やるべき仕事が本当にたくさんあるのです！

列幅計算の出発点は1列目です。なぜなら、もちろん1列目の左側（そして *横切って/中へ*）にまたがることはできないからです。 $$\mathrm\TeX$$ は、最大の *自然幅*自然幅 $$w\_1$$を持つ項目を見つけることで、1列目の幅を決め始めます。最大幅を $$w\_{12}$$ 1〜2の幅（1から2への幅）と呼ぶことにしましょう。さらに、 `\tabskip` 1列目と2列目の間のグルーを $$t\_{1}$$—なお、ここで考慮しているのはその *自然幅* グルー `\tabskip` の幅だけであり、ひとまず、それが持つかもしれない伸長成分や収縮成分は無視します。また、2列目にある、またがっていないすべての項目の自然幅の最大値を $$w\_2$$.

ここで注目すべき重要点は、 $$\mathrm\TeX$$ が1列目と *始まる* でまたがり *、* 2列目で終わる項目だけを考慮して列2の幅を計算しようとしているということです。 $$\mathrm\TeX$$ にとって重要なのはテスト $$\max(w\_{2}, w\_{12} - (w\_1+ t\_1))$$です—1列目と2列目にまたがる項目は複数あるかもしれません。細いもの（小さな $$w\_{12}$$）もあれば、とても幅広いもの（大きな $$w\_{12}$$）もあるので、 $$\mathrm\TeX$$ は最も大きな影響を与えるものを探しているのです（したがって $$\max(\text{...})$$）。ここで、 $$w\_{12} -(w\_1+ t\_1)$$ の値は、1列目と2列目にまたがる項目が1列目から2列目へ「はみ出す」量です。なお、 $$\mathrm\TeX$$ は1列目の幅を **や** その `\tabskip` グルー（$$t\_{1}$$）と、1列目と2列目の間の $$\mathrm\TeX$$ が、1〜2列目へのまたがりが列2の幅に影響するかどうかを判断すると、2列目の幅を、（述べたテストを使って）見つけた最大値に設定します。 $$\mathrm\TeX$$ 他のすべての列についても同じようなテストを行いながら、順に処理を続けます。

そして最後に、完全性のために、ここで引用しておくのは $$\mathrm\TeX$$のアルゴリズムの要点です（Knuth のソースコード文書から引用）。 $$\mathrm\TeX$$):

次のように置きます $$w\_{ij}$$ を、列 $$i$$ から $$j$$まで（両端を含む）にまたがるすべての項目の自然幅の最大値とします。最終的な列幅は次の式で定義されます

$$\begin{equation\*} w\_j=\max\_{1\leq i\leq j}\biggl(w\_{ij}-\sum\_{i\leq k< j}(t\_k+w\_k)\biggr) \end{equation\*}$$

ここで $$t\_k$$ は、列間の tabskip グルーの自然幅です $$k$$ や $$k+1$$.

## 付記: Overleaf を使って表を SVG グラフィックスとして作成する

この記事で示した $$\mathrm\TeX$$ 表はすべて、Overleaf プラットフォームで生成された Scalable Vector Graphics (SVG) ファイルです。注釈（矢印と緑の枠）は、SVG グラフィックを Inkscape で開いて追加しました—ただし、注釈の本文は $$\mathrm\TeX$$ 表に添える追加テキストとして組版されており、Inkscape で追加したのは矢印と緑の背景だけです。これをどう実現したかに興味があれば、続けて読んでください。

Overleaf のサーバーは $$\mathrm\TeX \text{ Live}$$ ディストリビューションを使用しており、それに加えて $$\mathrm\TeX$$ベースの組版エンジンに加え、非常に便利な多くの $$\mathrm\TeX$$関連ソフトウェアツールやユーティリティを備えています。その中の1つに [`dvisvgm`](https://dvisvgm.de) と呼ばれるものがあり、その名のとおり $$\mathrm\TeX$$の伝統的な DVI（**D**e**V**ice **I**ndependent）出力ファイル形式を SVG に変換します。その多くの [コマンドラインオプション](https://dvisvgm.de/Manpage/) `dvisvgm` の中には、`-n` または `--no-fonts`）というオプションがあり、これを指定するとすべてのテキストを *パス* に変換します。つまり、SVG グラフィックス中のテキストは、実際のフォントやグリフではなく、線と曲線で描画されます。これにより生成される SVG ファイルのサイズは大きくなるかもしれませんが、SVG グラフィックスは非常に可搬性が高く、どのデバイスでもほぼ確実にうまく動作するようになります。

### では……どうやったのか？

ある [前の記事](https://www.overleaf.com/blog/510-using-luatex-to-run-tools-and-utilities-installed-on-overleafs-servers) Overleaf のサーバーにインストールされているさまざまなソフトウェアツールやユーティリティを実行するために $$\text{Lua}\mathrm\TeX$$ を使う方法については説明しました—これは非常に簡単で便利な手法です。 $$\mathrm\TeX$$ その手法を使って、組版した $$\mathrm\TeX$$ 表の SVG グラフィックスを次のように生成しました。メインの `\halign`文書ファイルの中で、各表を組版するコード（ `.tex` を使って作成）が `ファイルに書き出されました。これは、表のコードを私が` や `と呼んだ一対のコマンドで囲むことで実現しました`。目的の結果を得る方法は他にもたくさんあるはずですが、ここでは私が使ったマクロ定義を示します：

```latex
\def\cc{\catcode`\#=12\relax}
\long\def\scoop#1\endscoop{\global\fulltoks={#1}\egroup}
\def\beginscoop{\global\advance\numfigs by1\relax\bgroup\cc\scoop}
```

使い方は次のとおりです：

```latex
ファイルに書き出されました。これは、表のコードを私が
\halign{...}
と呼んだ一対のコマンドで囲むことで実現しました
```

次の点に注意してください。 `と呼んだ一対のコマンドで囲むことで実現しました` token は、単に `\scoop` マクロ: $$\mathrm\TeX$$ のパラメータを区切る役割を果たすだけです `と呼んだ一対のコマンドで囲むことで実現しました` token は実質的に `を破棄するので、実際には定義する必要はありません（たとえば`).

この $$\mathrm\TeX$$ に含まれるコードは `\halign{...}` に保存されます `toks` レジスタと呼ばれる `\fulltoks`。私が直面したやっかいな点の1つ（ $$\text{Lua}\mathrm\TeX$$では）には、 `#` 文字が `\halign{...}` プリアンブル内で、書き出して `##` ファイルに入れる際に「二重化」されて `.tex` しまうのを防ぐ必要があったことです。これを避けるため、 `\catcode`のトークン値は次のようになります。 `#` 文字を一時的に 12 に設定してから、 $$\mathrm\TeX$$ コード（トークン）を `\fulltoks` トークンレジスタに保存しなければなりませんでした。

次のステップは、 `\fulltoks` に含まれるトークンを書き出して $$\mathrm\TeX$$ ファイルにすることです—私は $$\text{Lua}\mathrm\TeX$$ を使っていたので、これは *極めて* 簡単にできました。というのも $$\text{Lua}\mathrm\TeX$$の素晴らしい Lua API があるからです。簡単に言うと、 `\writefile{...}` というマクロを書きました。これは、ファイルに書き出したいトークンを含むトークンレジスタの名前を引数に取ります（たとえば `\writefile{fulltoks}`）。 `\writefile{...}` マクロの中で、Lua API を使って `\fulltoks` トークンレジスタのテキスト表現を取得しました：

```latex
\def\writefile#1{%
\directlua{
...
...
 local p=tex.toks["#1"]
...
...
}}
```

ここに、 `\writefile{...}` コマンド：

[![{{{alt}}}](/files/0bbdac8ab89799a1eb10823a7c7200561af28865)](https://www.filepicker.io/api/file/ngeDmgRStGWvG044RE1A)

Lua 言語と、LuaTeX が提供する Lua API は $$\text{Lua}\mathrm\TeX$$ プログラミング作業をしばしば簡素化できます $$\mathrm\TeX$$ そして、こうした便利で強力な機能のおかげで私は $$\text{Lua}\mathrm\TeX$$ を 2009 年ごろから使っており—今でも、この本当に素晴らしい $$\mathrm\TeX$$ エンジンの大ファンです。では、この $$\text{Lua}\mathrm\TeX$$ 宣伝はこれで終わりです。

こうして簡単に $$\mathrm\TeX$$ に保存されたコードを得られたので、 `\fulltoks` それに、正しい形式の $$\mathrm\LaTeX$$ ファイルにするための追加コードを少し加えて、ファイルに書き出します。次の手順は次のとおりです：

1. 処理する `.tex` ファイルを $$\text{pdf}\mathrm\LaTeX$$ （DVI モードで）処理して、表を組版し、 `.dvi` 用の `dvisvgm` 処理するために。はい、 $$\text{Lua}\mathrm\TeX$$ を実行するために $$\text{pdf}\mathrm\LaTeX$$—今回も、ある [前の記事](/latex/ja/xiang-xi-ji-shi/52-using-luatex-to-run-tools-and-utilities-installed-on-overleaf-s-servers.md).
2. そして最後に、実行します `dvisvgm` を処理するために `.dvi` ファイルを処理し、組版された $$\mathrm\TeX$$ 表の SVG グラフィックを生成します。
3. 実際の SVG グラフィックを入手するには、Overleaf から ZIP ファイルをダウンロードできます—その際、 **入力ファイルと出力ファイル** オプションに移動します。


---

# 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/xiang-xi-ji-shi/47-tex-tables-how-tex-calculates-spanned-column-widths.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.
