カウンタと長さ

LaTeX には、値を覚えておける二種類の「レジスタ(記憶場所)」があります。整数を入れる カウンタ と、寸法を入れる 長さ です。章・図・式の番号はカウンタで数えられ、余白やボックスの幅は長さで測られます。このページでは、自前のカウンタや長さを 定義して操作する プログラミングの基本を扱います。単位そのものや \hspace\vspace といった空白命令は別ページ(下記リンク)に譲り、ここでは「数える・測る・記憶する」しくみに集中します。

カウンタ — 整数のレジスタ

カウンタ は整数を一つ覚えておく入れ物です。LaTeX は文書を読み進めながら、章が始まれば chapter を、図を置けば figure を 1 ずつ進め、その番号を見出しやキャプションに刷り込みます。これらはあらかじめ用意された 標準カウンタ で、自分で新しいカウンタを作ることもできます。

新しいカウンタは **\newcounter{foo} で作ります。作られた直後の値は 0。名前は文字だけ(バックスラッシュは付けない)で、既存の名前とは重ねられません。さらに大切なのが省略可能な親指定 \newcounter{foo}[⟨parent⟩]** です。こうすると fooparent の従属カウンタになり、**parent が一つ進むたびに foo は自動的に 0 へ戻ります**。節が変わると小節番号が振り出しに戻る、あの挙動はこのしくみによるものです。

値を変えるには三つの命令があります。**\setcounter{foo}{3}** は foo を 3 に 代入 し、**\addtocounter{foo}{2} は現在値に 2 を 加え(負の数を渡せば減らせます)、\stepcounter{foo}** は 1 だけ増やします。\stepcounter には大事な副作用があり、その親カウンタとして登録されている従属カウンタをすべて 0 にリセット します。なお \setcounter\addtocounter の代入は 大域的(グローバル) で、グループ({ } や環境)を抜けても元には戻りません。

\stepcounter によく似た **\refstepcounter{foo} は、1 増やして子をリセットするところまでは同じですが、加えて その時点で foo を「現在の参照先」に設定** します。つまり直後に置いた \label{…} は、foo の表示値(後述の \thefoo)を指すようになり、\ref でその番号を呼び出せます。LaTeX が sectionequationfigure を進めるとき内部で使っているのはこの \refstepcounter で、だからこそ見出しや式に \label を付けると正しい番号が参照できるのです。番号を内部的に動かすだけなら \stepcounter、参照可能な「番号付きの何か」を作るなら \refstepcounter を使います。

latex
\newcounter{trial}            % trial を作成(初期値 0)
\setcounter{trial}{5}         % trial = 5
\addtocounter{trial}{-2}      % trial = 3
\stepcounter{trial}           % trial = 4(子カウンタがあれば 0 に)

カウンタの「数」を取り出す — \value

カウンタの中身を TeX が計算に使える数 として取り出すのが **\value{foo}** です。これは \setcounter\addtocounter の値の位置や、条件判定 \ifnum、さらには寸法計算(\value{foo}\parindent のように)など、LaTeX が整数を期待する場所 で使えます。たとえば「barfoo と同じ値にそろえる」なら次のように書きます。

latex
\setcounter{bar}{\value{foo}}        % bar に foo の現在値を代入
\addtocounter{bar}{\value{foo}}      % bar に foo の値をさらに加える

ここが初心者のつまずきどころですが、**\value は表示用ではありません**。本文に番号を「刷る」には、次節の \arabic などの表示命令や \thefoo を使います。\value は計算のための 生の数値、表示命令は人が読む 文字列 ——この区別を押さえておくと混乱しません。

カウンタを表示する — \the と書式命令

すべてのカウンタには、その値を 文字列に変換して出力 するための表示命令が一式あります。どの記法で刷るかを選べます。

命令出力範囲・備考
\arabicアラビア数字(1, 2, 3 …)最も一般的。負の値も可
\roman小文字のローマ数字(i, ii, iii …)1 未満は無出力
\Roman大文字のローマ数字(I, II, III …)1 未満は無出力
\alph小文字(a, b, c …)1〜26。範囲外はエラー
\Alph大文字(A, B, C …)1〜26。範囲外はエラー
\fnsymbol脚注記号(∗ † ‡ § ¶ ‖ …)1〜9。数式モード用

\alph\Alph はアルファベット 26 文字に対応するので、値が 1 未満か 26 を超えると「Counter too large」エラーになります。\fnsymbol** は 9 個の脚注記号(アスタリスク・短剣符・二重短剣符・節記号・段落記号・並行記号・二重アスタリスク・二重短剣符・二重二重短剣符)を順に出し、有効範囲は 1〜9。数式モードで動くため、本文では $\fnsymbol{footnote}$ のように囲うか、\thefootnote 経由で使います。

これらの命令は引数にカウンタ名をとります(\arabic{page} のように)。しかし実際の組版で番号を刷っているのは、各カウンタに自動で用意される **\thefoo** という専用マクロです。section には \thesectionfigure には \thefigure、といった具合。**この \the…\renewcommand で再定義すれば、番号の書式をまるごと変えられます**。たとえば節番号をローマ数字にしたいなら次の一行です。

latex
\renewcommand{\thesection}{\Roman{section}}   % 1, 2, 3 → I, II, III
% 図番号を「節.通し番号」に:図 2.3 のように
\renewcommand{\thefigure}{\thesection.\arabic{figure}}

二つ目の例のように、\the… の定義に別のカウンタの表示を混ぜると「2.3」のような複合番号が作れます。これが効くのは、図カウンタが節カウンタを親(リセット元)に持つよう設定されているからで、番号の 見た目 と、いつ 0 に戻るかという 連動 は別々に決められる、という設計が見てとれます。

標準カウンタと番号の深さ

LaTeX があらかじめ用意し、文書中で自動的に動かしているカウンタには次のものがあります。これらも \setcounter などで自由に操作できます(章番号を途中から振り直す、付録で図番号を A.1 にする、など)。

  • 見出し系: partchaptersectionsubsectionsubsubsectionparagraphsubparagraph(クラスにより使えるものが異なる)
  • フロート・式: figuretableequation
  • 脚注: footnotempfootnote(minipage 内の脚注)
  • 箇条書き: enumienumiienumiiienumivenumerate のネスト 4 段ぶん)
  • ページ: page
  • 制御用: secnumdepth(どの深さの見出しまで番号を振るか)・tocdepth(どの深さまで目次に載せるか)

最後の二つは少し毛色が違い、番号やリストの「深さ」を整数で握るスイッチ です。見出しコマンドにはレベル番号があり(section は 1、subsection は 2…)、そのレベルが secnumdepth の値 以下 なら番号が振られます。標準では 2 程度なので、\setcounter{secnumdepth}{1} とすれば小節以下は番号なしに、\setcounter{tocdepth}{1} なら目次を節までに絞れます。カウンタが単なる数え上げだけでなく、組版の挙動を制御する 設定値 にもなっている好例です。

長さ — 寸法のレジスタ

もう一方の 長さ(length) は、12pt2cm のような 寸法を一つ覚えておく レジスタです。カウンタが整数なのに対し、長さは単位付きの寸法を保持し、伸び縮みの遊び(plusminus)も持てます。同じ寸法を文書のあちこちで使うなら、数値を直書きするより長さに名前を付けておくほうが保守が楽になります。

新しい長さは **\newlength{\mylen} で宣言します。カウンタと違い、引数は バックスラッシュ付きの命令名**(\mylen)で、初期値は 0pt。値の操作は **\setlength{\mylen}{2em}(代入)と \addtolength{\mylen}{-3pt}**(加算、負値で減算)の二つが基本です。一度作れば、\hspace{\mylen} のように 寸法が必要な場所 ならどこでも使えます。

\textwidth(本文の幅)や \baselineskip(行送り)のような 既存の長さ も、そのまま計算に使えます。係数を前に付けるだけで 0.8\textwidth(本文幅の 8 割)のように倍率を指定でき、長さどうしの加減もできます。より複雑な四則演算、とりわけ 割り算 が要るなら **calc パッケージ** を読み込みます。すると \setlength{\x}{\textwidth/3}(本文幅の 1/3)のように、寸法を整数で割る式がそのまま書けます。

calc には注意点が一つ。寸法を 実数倍 したいときは整数の割り算とは書き方が違い、\real{} を挟みます(例:\widthof{語} * \real{0.68})。また、式の型をそろえる必要があり、2cm + 4(寸法に裸の整数)は不可で、2cm + 4pt のように両辺を寸法にします。

document.tex
\usepackage{calc}
\newlength{\thirdcol}
\setlength{\thirdcol}{\textwidth/3}     % 本文幅の 1/3
\addtolength{\thirdcol}{-1em}            % そこから 1em 引く

組まれた文字を測る — \settowidth ほか

長さの操作で特に強力なのが、実際に組版した結果の寸法を測って 長さに代入する命令です。**\settowidth{\mylen}{文字列} は与えた文字列を内部で組版し、その 幅** を \mylen に入れます。同様に **\settoheight はベースラインから上の 高さ\settodepth はベースラインから下の 深さ** を測ります(いずれもあらかじめ \newlength で宣言した長さが対象)。

これは「この見出しの語とちょうど同じ幅の罫線を引きたい」「最も長い項目名に合わせてラベル幅を決めたい」といった、中身に合わせて寸法を決める 場面で効きます。下の例は、語の幅を測ってその下に同じ長さの罫線を敷くものです。

document.tex
\newlength{\wd}
\settowidth{\wd}{重要}        % 「重要」の組版幅を測る
\noindent 重要\par
\rule{\wd}{0.4pt}            % 同じ幅の罫線

同じ「組版して測る」発想は、前節で触れた calc パッケージの **\widthof{文字列}\heightof\depthof** にも引き継がれています。違いは、\settowidth が結果を長さに 代入する命令 なのに対し、\widthof は式の中にそのまま 値として書ける ことです。

組み合わせ例 — 自作カウンタと測った長さ

最後に、カウンタと長さを両方使う小さな例を見ます。自前のカウンタ question を作り、表示を「Q1.」「Q2.」…の形式に整え、進めるたびに番号を刷る簡単な命令 \question を定義します。\refstepcounter を使っているので、各問いに \label を付けて後から \ref で参照できます。

document.tex
\newcounter{question}
\renewcommand{\thequestion}{Q\arabic{question}}
\newcommand{\question}{\refstepcounter{question}\par\noindent\textbf{\thequestion.}\ }
\begin{document}
\question 最初の問い。\label{q:first}
\question 次の問い。
問い~\ref{q:first} を参照。   % → 問い Q1 を参照
\end{document}

\thequestion\renewcommand で定義したことで、番号の書式(Q + アラビア数字)が一か所に集約され、後から変えるのも簡単です。長さの側でも同じ発想が活き、版面の幅(\textwidth)を基準に相対的な長さを組み立てたり、中身を \settowidth で測って寸法を決めたりすれば、用紙サイズや余白を変えても比率の崩れない、変更に強い文書になります。固定値の直書きより、名前を付けて一元管理する ——それがカウンタと長さをプログラミングの道具として使う勘どころです。