はじめに
問題を解決するため、記事を書くことにしました
本記事の対象読者は「TeX言語のキホンを既に習得している人」とします。
TeX言語においてキーワードとは何か
TeX言語における「キーワード」と聞くと、\def
とか\expandafter
とかの“プリミティブ”を思い浮かべる人もいるかもしれません。しかしキーワードはプリミティブとは別の概念です。実際、TeX言語のプリミティブは(一般の言語における)“キーワード”のように「特定の名前と不可分に結びついている」わけではありません。\let
を使えば「\expandafter
の制御綴が\expandafter
のプリミティブと対応しない」状況は容易に作り出せます1。
\let\ARE\expandafter % 制御綴 \ARE がプリミティブ \expandafter をもつ😲
\let\expandafter\noexpand % 制御綴 \expandafrer がプリミティブ \expandafter をもたない😲
% ↓要するに"\expandafter\noexpand\csname..."を実行している
\edef\macro{\ARE\expandafter\csname empty\endcsname}
\show\macro %==>'\empty'
それではTeX言語における「キーワード」とは何でしょうか。TeXbookによると、以下のようなものが「キーワード(keyword)」と呼ばれています。
% ↓この'to'がキーワード
\hbox to 0pt{\TeX\hss}
% ↓この'at'がキーワード
\font\fA=cmr10 at 12.5pt
つまり「プリミティブの構文の中で固定して現れる、英字からなる文字列」がキーワードです。なるほど、これは\let
などの機能を用いて別の文字列に代替させることは不可能2ですね。
キーワードに関する構文規則
基本的に、TeX言語のキーワードは「プリミティブの構文の中でそれが出現する(可能性のある)位置」で出現した場合にのみキーワードと見なされ、それ以外の位置で同じ単語を書いてもキーワードとは扱われません(文字として版面に出力される)。つまりキーワードは“予約語”ではないということです。
% \parskip はグルー値パラメタなので右辺はグルー値,
% よって"plus"はキーワードになる.
\parskip = 12pt plus 6pt
% \parindent は寸法値パラメタなので右辺は寸法値,
% よって"plus"はキーワードにならず版面に出力される.
\parindent = 12pt plus 6pt
その他に、TeX言語のキーワードには以下のような規則があります。
- ASCII英字のみからなる。
- 大文字小文字は区別されない。例えば
by
はBY
やbY
と書いてもよい3。 - 暗黙文字トークン4は使用不可。
- 文字トークンのカテゴリコードは何でもよい5。ただしアクティブ文字トークンはその意味の方に従う。
- キーワードの前後の区切りは不要である。
% ↓"8"の後には"true", "pt", "plus"の3つのキーワードが続く
\parskip = 8trueptplus1fil
% ↓"1"の後には"fil", "l", "l"の3つのキーワードが続く
\vskip 0pt plus 1filll
% 異様なカテゴリコード設定😱
\catcode`\p=3 \catcode`\T=2
% ↓これでもキーワード"pt"と見なされる
\jot=8pT
% "T"をアクティブにする
\catcode`\T=13 \def T{c}
% ↓これは"pc"と見なされる
\jot=1pT
% ↓この場合"T"は暗黙文字トークンなのでダメ
\let T=t \jot=1pT %==> エラー "Illegal unit of measure"
一覧表
元祖TeXの範囲でのキーワードの一覧は以下の通りです。
単語 | 説明 | 使用例 |
---|---|---|
at |
フォント定義:サイズ | cmr10 at 13pt |
bp |
単位:ビッグポイント | \parskip=6bp |
by |
算術演算命令:オペランド | \divide\ovx by 2 |
cc |
単位:シセロ | \hsize=7cc |
cm |
単位:センチメートル | \vsize=14.8cm |
dd |
単位:ディドーポイント | \kern2dd |
depth |
罫命令:深さの引数 | \vrule depth 0pt |
em |
単位:全角 | \parindent=2em |
ex |
単位:エックスハイト | \raise 1ex |
fil |
単位:1次無限 | 0pt plus 0.5fil |
height |
罫命令:高さの引数 | \hrule height1pt |
in |
単位:インチ | \hoffset=-1in |
l |
無限の次数を上げる | 0pt plus 2fill |
minus |
グルー:縮小量 | 6pt minus 3pt |
mm |
単位:ミリメートル | \hsize=160mm |
mu |
単位:数式単位 | \mkern -4mu |
pc |
単位:パイカ | \hsize=6pc |
plus |
グルー:伸長量 | 20pt plus 1fil |
pt |
単位:ポイント | \leftskip=0pt |
scaled |
フォント定義:拡大率 | cmr12 scaled 1200 |
sp |
単位:スケールドポイント | \ifdim\ovx<1sp |
spread |
ボックス命令:追加量 | \hbox spread 2em |
to |
ボックス命令:寸法 | \hbox to 0pt |
true |
単位への拡大の不適用 | \hsize=5truein |
width |
罫命令:幅の引数 | \vrule width 1em |
詳細
以下では、キーワードのそれぞれについてその用途と構文を詳しく解説していきます。
構文説明の中では以下の記法を用います。
-
[A]
は「Aが省略可能である」ことを表します。[ ]
自体は書きません6。 -
(A | B)
は「AまたはB」を表します。
また、使用例のコードの動作は「plain TeXで@
のカテゴリコードが11の状態」を仮定します。
絶対的な長さの単位(pt・mm・bp等)
説明
絶対的な長さの単位(絶対単位)は寸法値を記述するのに使われます。
% 以下のものは寸法値となる
(«整数» | «小数表記») [true] «絶対単位»
TeXで使える絶対単位の一覧です。
単位 | 意味 | TeXでの定義 |
---|---|---|
pt |
ポイント(point) | |
in |
インチ(inch) | 1in=(7227/100)pt |
pc |
パイカ(pica) | 1pc=12pt |
cm |
センチメートル | 1cm=(7227/254)pt |
mm |
ミリメートル | 1mm=(7227/2540)pt |
bp |
ビッグポイント(big point) | 1bp=(7227/7200)pt |
dd |
ディドーポイント(Didot point) | 1dd=(1238/1157)pt |
cc |
シセロ(Cicero) | 1cc=(14856/1157)pt |
sp |
スケールドポイント(scaled point) | 1sp=(1/65536)pt |
- TeXにおける
pt
(ポイント)は「アメリカンポイント」のことを指します。これは米国の印刷業界で使われてきた単位で、TeXでは「1pt=(1/72.27)in」と定義されています。アメリカンポイントの上位の単位がpc
(パイカ)で「1pc=12pt」です。 - 現代のDTP業界で使われている「ポイント」はアメリカンポイントを利便性のために少し修正したもので「1ポイント=(1/72)in」と定義されています。TeXではこの「ポイント」のことを
bp
「ビッグポイント」と呼んでいます。 -
dd
(ディドーポイント)はフランスの印刷業界で使われた単位です。その上位単位がcc
(シセロ)で「1cc=12dd」です。 -
sp
(スケールドポイント)はTeXが扱える最小の長さです。TeXの内部では寸法値はsp単位の整数として表されています7。
使用例
% 段落の行長を160mmにする
\hsize=160mm
% 12pt=1pc なので等しい
\dimen@=12pt
\message{\ifdim \dimen@=1pc YES\else NO\fi} %==>"YES"
% "\tw@"は内部値の整数, "2.0"は小数表記
\message{\ifdim \tw@ pt=2.0pt YES\else NO\fi} %==>"YES"
% 0.42cm=783162sp, 4.2mm=783164sp なので等しくない
\message{\ifdim 0.42cm=4.2mm YES\else NO\fi} %==>"NO"
% 寸法→整数のキャストの例(12pt=786432sp)
\count@=\dimen@ \message{\the\count@} %==>"786432"
フォント相対的な長さの単位(em・ex)
説明
em・ex(フォント相対単位)は寸法値を記述するのに使われます。
% 以下のものは寸法値となる
(«整数» | «小数表記») «フォント相対単位»
これらの単位は現在有効なフォント(\font
の値)の特定のパラメタの値に等しい長さと定められています。
フォント相対単位は現在のフォントを基準にして決まるので元々mag値の影響を受けません。従って、フォント相対単位にはtrue
は付きません。
-
em
は現在フォントの\fontdimen6
に等しい長さで、フォントの全角幅(em)を表します。 -
ex
は現在フォントの\fontdimen5
に等しい長さで、フォントのエックスハイト(x-height)を表します。エックスハイトは英小文字のa・c・x・zなどの(基準となる)高さを表します。
使用例
% 段落の行長を40全角にする
\hsize=40em
% "x"と"y"の間に"いい感じ"に長めの線を引く
x\raise 0.5ex\hbox{\vrule width 3em height .4pt}y
% cmr7(\sevenrm)の全角幅の値
\sevenrm \dimen@=1em \message{\the\dimen@} %==>"7.97224pt"
% 全角幅(\fontdimen6)の値を書き換える
\fontdimen6\font=42pt
\dimen@=1em \message{\the\dimen@} %==>"42.0pt"
at
説明
フォント定義命令(\font
)においてフォントサイズを指定します。
% フォントサイズを«寸法»に指定する
\font\制御綴 = «TFM名» [at «寸法»]
フォントサイズの既定値(at
やscaled
を指定しない場合)についてはscaled
の項目を参照してください。
使用例
% \fA のサイズは12pt(cmr12のデザインサイズ)
\font\fA=cmr12
% \fB のサイズは13bp
\font\fB=cmr12 at 13bp
by
説明
算術演算命令(\advance
・\multiply
・divide
)におけるオペランドを表します。
% «変数» ← «変数» + «値»
\advance «変数» [by] «値»
% «変数» ← «変数» × «整数»
\multiply «変数» [by] «整数»
% «変数» ← «変数» ÷ «整数»
\divide «変数» [by] «整数»
ここで«変数»
とはレジスタやパラメタのことです。\advance
において«値»
は«変数»
と同じ型である(と見なせる10)必要があります。
キーワードby
は省略可能です。なので「原則書かない」という方針の人もいます。
使用例
% 42+12 を計算する
\count@=42
\advance \count@ by 12
% "by"は省略可能
\advance\count@12
\dimen@=10mm
\skip@=4pt plus 2fil
% \count@ ← \count@ − 12 (減算)
\advance \count@ by -12
% \dimen@ ← \dimen@ + 20mm (寸法)
\advance \dimen@ by 20mm
% \hsize ← \hsize − 2×\dA
\advance \hsize by -2\dA
% \count@ ← \count@ × 3
\multiply \count@ by \thr@@ (\thr@@=3)
% \dimen@ ← \dimen@ × (−\count@)
\multiply \dimen@ by -\count@
% \skip@ ← \skip@ × 2 (グルー値, 8pt plus 4fil となる)
\multiply \skip@ by 2
% \thinmuskip ← \thinmuskip ÷ 2 (数式グルー値)
\divide \thinmuskip by 2
depth
説明
罫を出力する命令(\hrule
・\vrule
)において罫の深さを指定します。
\hrule [width «幅»] [height «高さ»] [depth «深さ»]
\vrule [width «幅»] [height «高さ»] [depth «深さ»]
depth
引数の既定値は、\hrule
では0pt、\vrule
では「その罫を囲むボックスの深さ」となります。
使用例
% 高さ8pt, 深さ4ptの"支柱"(幅ゼロの罫)
\vrule width 0pt height 8pt depth 4pt
fil
説明
グルー値表記の中の伸縮量(つまりplus
やminus
の引数)において無限長を表す単位です。fil
そのものは1次の無限を表し、直後にキーワードl
を続けることでより高次の無限を表します。
% 以下のものは伸縮量となる
(«整数» | «小数表記») fil [l [l]]
% もっと解りやすく書くと以下の通り
(«整数» | «小数表記») fil % 1次の無限
(«整数» | «小数表記») fill % 2次の無限
(«整数» | «小数表記») filll % 3次の無限
※「実はl
がキーワードである」という件についてはl
の項目を参照してください。
使用例
\skip@=0pt plus 10000pt minus 5000pt
% 有限長10000ptは888filより"無限に小さい"ので無視される.
\advance \skip@ by 2pt plus 888fil
\showthe\skip@ %==>"2.0pt plus 888.0fil minus 5000.0pt"
% 888filは0.001fillより"無限に小さい"ので無視される.
\advance \skip@ by 2pt plus 0.001fill minus 1filll
\showthe\skip@ %==>"4.0pt plus 0.001fill minus 1.0filll"
height
説明
罫を出力する命令(\hrule
・\vrule
)において罫の高さを指定します。
\hrule [width «幅»] [height «高さ»] [depth «深さ»]
\vrule [width «幅»] [height «高さ»] [depth «深さ»]
height
引数の既定値は、\hrule
では0.4pt、\vrule
では「その罫を囲むボックスの高さ」となります。
使用例
% 太さが0.8ptの行幅いっぱいの横罫線を出力する
% (※ \hrule は垂直モードでのみ使用可能)
\hrule height 0.8bp
l
説明
キーワードfil
の直後に続けて無限長の次数を1つ上げます。最大の次数は3次なので最大2つまで付けられます。
% 以下のものは伸縮量となる
(«整数» | «小数表記») fil [l [l]]
% もっと解りやすく書くと以下の通り
(«整数» | «小数表記») fil % 1次の無限
(«整数» | «小数表記») fill % 2次の無限
(«整数» | «小数表記») filll % 3次の無限
fill
やfilll
は一見すると単一のキーワードに見えますが、実は複数のキーワードの連なりです。このためfil l l
のように間に空白が含まれていても認識されます。
以下の例は予想外の結果をもたらします。
\hbox to10em{First\hskip 0pt plus 1fil Last}
1fil
の後にあるL
の文字はキーワードと見なされるため、このコードは
\hbox to10em{First\hskip 0pt plus 1fill ast}
と書いたのと同等になりL
の文字は出力されません。
使用例
% (※plainの既定値で \parfillskip=0pt plus 1fil)
% "A"は行の中央に置かれる
\hskip 0pt plus 1fil A\par
% "A"は行の右端に置かれる (1filは1fillより"無限に小さい"ので)
\hskip 0pt plus 1fill A\par
minus
説明
グルー値・数式グルー値の表記において縮小量を表します。
% 以下はグルー値表記であり, minusの引数が縮小量を表す.
«寸法» [plus «寸法»] [minus «寸法»]
% 以下は数式グルー値表記であり, minusの引数が縮小量を表す.
«mu寸法» [plus «mu寸法»] [minus «mu寸法»]
minus
引数の既定値は0ptです。
使用例
% この \hskip は80ptまで縮むので結局70ptはみ出す
\hbox to 10pt{\hskip 100pt minus 20pt}
%==> 警告 "Overfull \hbox (70.0pt too wide)"
% (外部垂直モード中で)
% "無限に縮むページ"はダメ🙃
\vskip 0pt minus 1fil\par
%==>エラー "Infinite glue shrinkage found"
mu
説明
数式グルーの長さを表すのに使われる唯一の単位です。数式グルー値はグルー値と同様に自然長・伸長量・縮小量の3つの要素からなりますが、それぞれの量(ここでは仮に“mu寸法”と呼称します)は寸法ではなくmu単位の数値で表されます11。
% 以下のものは"mu寸法"
(«整数» | «小数表記») mu
mu
は現在の数式ファミリ2のフォントの\fontdimen6
(全角幅)の1/18に等しい長さを表します。ここで「現在の」というのは数式スタイルの状態も含みます。つまり添字中の1muは\scriptfont2
に基づいていて、これは通常の1mu(これは\textfont2
に基づく)より(普通は)小さくなります。
“mu寸法”はTeX言語の文法上では寸法とは別のデータ型として扱われ、両者の間で算術演算や比較を行うことはできません。“mu寸法”が実際に寸法に“換算”されるのは実際に組版処理が行われる段階12に至ってからになります。
使用例
% "mu寸法"と寸法は比較できない
\dimen@=1em \advance\dimen@ by -18mu
%==> エラー "Illegal unit of measure (pt inserted)"
% (plainの初期状態で)
\scriptspace=0pt % 添字の余分空きを消す
% これで1muに相当する寸法がわかる
\setbox0\hbox{$\mskip 1mu$}
\showthe\wd0 %==>"9.55554pt" (通常の1mu)
\setbox0\hbox{$^{\mskip 1mu}$}
\showthe\wd0 %==>"0.45525pt" (添字の1mu)
plus
説明
グルー値・数式グルー値の表記において伸長量を表します。
% 以下はグルー値表記であり, plusの引数が伸長量を表す.
«寸法» [plus «寸法»] [minus «寸法»]
% 以下は数式グルー値表記であり, plusの引数が伸長量を表す.
«mu寸法» [plus «mu寸法»] [minus «mu寸法»]
plus
引数の既定値は0ptです。
使用例
% 100ptまで伸長するとグルーの伸長量が70ptとなり,
% 伸長倍率が7倍に増大してしまうので例の警告が出る🙃
\hbox to 100pt{\hskip 30pt plus 10pt}
%==> 警告 "Underfull \hbox (badness 10000)"
scaled
フォント定義命令(\font
)においてフォントサイズのデザインサイズに対する拡大率を指定します。拡大率は千分率の整数(1000が1倍を表す)で表します。
% フォントサイズをデザインサイズの«整数»/1000倍に指定する
\font\制御綴 = «TFM名» [scaled «整数»]
scaled
引数の既定値は1000(1倍)です。つまり、at
やscaled
を指定しない場合はフォントサイズはデザインサイズに等しくなります。デザインサイズはTFMがもつパラメタの一つで、例えばcmr17のデザインサイズは17.28ptとなっています。
使用例
% \fA のサイズは12pt(cmr12のデザインサイズ)
\font\fA=cmr12
% \fB のサイズは18pt(デザインサイズの1500/1000倍)
\font\fB=cmr12 scaled 1500
spread
説明
ボックスを生成する命令(\hbox
・\vbox
・\vtop
・\vcenter
)において、ボックスの長さ(\hbox
では幅、\vbox
・\vtop
・\vcenter
では高さ)を「自然長から指定値だけ増やした値」に設定します。つまり、ボックス内のグルーは伸縮量が(全て合わせて)指定値になるように調整されます。
※「ボックスの高さ」についてはto
の項目を参照してください。
\hbox [spread «寸法»] {«テキスト»}
\vbox [spread «寸法»] {«テキスト»}
\vtop [spread «寸法»] {«テキスト»}
\vcenter [spread «寸法»] {«テキスト»}
spread
引数の既定値は0ptです。つまりspread
もto
もない場合はボックスは自然長で組まれます。
使用例
% この \hskip の伸長量が30pt(全体で40pt)になる.
\hbox spread 30pt{\hskip 10pt plus 1fil}
% この場合も同じで \hskip の伸長量が30ptになる.
% (※自然長が"AB"と"CD"の幅だけ増えただけだから.)
\hbox spread 30pt{AB\hskip 10pt plus 1fil CD}
to
説明
ボックスを生成する命令(\hbox
・\vbox
・\vtop
・\vcenter
)において、ボックスの長さ(\hbox
では幅、\vbox
・\vtop
・\vcenter
では“ボックスの高さ”)を指定します。ボックス内のグルーが指定値を満たすように伸縮することになります。
垂直ボックス命令の場合の“ボックスの高さ”というのは「仮に\vbox
として組んだ場合のボックスの高さに相当する寸法」のことを指します。つまり「ボックスの縦幅全体から“一番下にあるもの”の深さを差し引いた値」です。\vbox
の場合は指定値がそのまま実際のボックスの高さになりますが、\vtop
・\vcenter
の場合はそれぞれの要件を満たすように高さと深さが再配分されます。
\hbox [to «寸法»] {«テキスト»}
\vbox [to «寸法»] {«テキスト»}
\vtop [to «寸法»] {«テキスト»}
\vcenter [to «寸法»] {«テキスト»}
to
引数の既定値は「ボックスの自然長」です。つまりspread
もto
もない場合はボックスは自然長で組まれます。
使用例
% この \hskip は30ptまで伸長される(伸長量は20pt).
\hbox to 30pt{\hskip 10pt plus 1fil}
% (垂直ボックスの例; plainの初期状態で)
\def\thing{\hrule width 100pt height 30pt depth 20pt}
% このボックスは高さが80pt, 深さが20pt.
\vbox{\thing\thing}
% "高さ"が200pt(縦幅が220pt)になるようにグルーが120pt伸長する.
% このボックスは高さが200pt, 深さが20pt.
\vbox to 200pt{\thing\vfill\thing}
% これも縦幅が220ptになるようにグルーが120pt伸長する.
% このボックスは高さが30pt, 深さが190pt.
\vbox to 200pt{\thing\vfill\thing}
% これも同様で, やはりグルーが120pt伸長する.
% math axisの高さ(=\fontdimen22\tensy)が2.5ptであり
% \vcenter のボックスはそこを中心に220ptの縦幅をもつため,
% 高さが112.5pt, 深さが107.5ptとなる. (外側の \hbox も同じ.)
\hbox{$\vcenter to 200pt{\thing\vfill\thing}$}
true
説明
絶対単位の前に付いて、その単位が版面拡大の影響を受けない“真正の単位”であることを示します。例えば、版面拡大が有効である(mag値が1000でない)場合には、1pt
(TeX内部の“1pt”)の表す物理的な長さは1ptになりません(版面拡大率が乗算される)が、この場合でも1truept
の表す物理的な長さは1ptになります。
% 以下のものは寸法値となる
(«整数» | «小数表記») [true] «絶対単位»
使用例
% 版面を2倍に拡大する
\mag=2000
% "5pt"は2倍に拡大されて"物理的に10pt"になり, 一方で"10truept"は
% そのまま"物理的に10pt"なので2つの寸法は等しい.
% (※実際には"10truept"がTeX内部で5ptとして扱われている.)
\message{\ifdim 10truept=5pt YES\else NO\fi} %==>"YES"
width
説明
罫を出力する命令(\hrule
・\vrule
)において罫の幅を指定します。
\hrule [width «幅»] [height «高さ»] [depth «深さ»]
\vrule [width «幅»] [height «高さ»] [depth «深さ»]
width
引数の既定値は、\hrule
では「その罫を囲むボックスの幅」、\hrule
では0.4ptとなります。
使用例
% "A"と"B"の間に3emの横線を引く(太さは0.4pt)
A\vrule width 3em B
まとめ
ワタシハ TeXキーワード チョットデキル
-
つまりTeX言語のプリミティブは「JavaScriptの
parseInt
関数やDate
オブジェクト」と同様に「初期状態でたまたまその“グローバル変数”に結びついている」に過ぎないわけです。 ↩ -
もちろんマクロを使えば「ソースファイル上の文字列」は別のものにできますが、プリミティブを実行する際には結局正しいキーワードに展開されて読み込まれるわけです。 ↩
-
なお、ここでの「大文字と小文字の対応」は単純にASCIIの規定に従います。つまり、
\lccode
・\uccode
には影響されません。 ↩ -
意味が文字トークンになっている代入可能トークンのことを「暗黙文字トークン」と呼びます。例えば
\let\bgroup={
を実行した後の\bgroup
は暗黙文字トークンです。 ↩ -
ただし飽くまで文字トークンのカテゴリコードなので、トークンにならないカテゴリコード(9や14等)は含みません。 ↩
-
ちなみに、TeX言語のプリミティブの構文の中で
[ ] ( ) |
の記号が使われることはありません。 ↩ -
例えば
\count255=\dimen0
のように「寸法から整数へのキャスト」を行うと、寸法値は「sp単位の整数値」に変換されます。 ↩ -
全角幅のことを“em”と呼ぶのは「多くのフォントにおいて文字“M”の横幅が全角幅に大体等しい」ことに由来します。「“M”の横幅」自体のことを指すのではないことに注意してください。 ↩
-
『The TeXbook』には“ems are simply arbitrary units that come with a font”とだけ書かれていて、Knuthがemについてどういう考えを持っていたのかは不明です。もちろん「“M”の横幅」という扱いではありません。 ↩
-
例えば
\advance \count255 by \dimen0
では、オペランドの\dimen0
は寸法から数値へのキャストされます。 ↩ -
ただし数式グルー値の伸長量・縮小量も無限長にすることが可能でその場合の単位にはグルー値と同様に
fil
とl
を用います。 ↩ -
『TeX by Topic』の“4プロセッサモデル”における「ビジュアルプロセッサ」に相当します。 ↩