マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

LaTeX 的 \relax の使い方 12連発(補足)

例の「LaTeX で \relax を使う(使わない)話」であるが、実は、例の元ネタの記事で述べられている事項の中で「LaTeX で…」の記事ではちゃんと検討されていないものがある。

特に,LaTeX 用のマクロを書く人にとっては重要であろう分岐命令 \ifmmode(数式モードか否かで条件分岐)ではこのような問題が発生しやすいので \relax を前置する癖をつけておいた方がよいでしょう.
(例の元ネタの記事)

元ネタの記事の中では、一見すると軽い扱いになっているようにも見える(これの例すら出していない)か、実際には、6 節の中で表題の「条件分岐命令に前置する」に関連しているのは実質的にこれだけなので、この節の中の核心の部分はここのはずである。

なるほど……。

% plain TeX 文書
% 数式モードでは "M", それ以外では "T" を出力するマクロ
\def\MorT{\ifmmode M\else T\fi}

% 普通に使うと結果は普通...
\MorT              %==>T
$\MorT$            %==>M

% でも halign 中で使うと...アレ?
\halign{$#$\cr
  \MorT \cr        %==>T (アレレ!?)
  A\MorT \cr       %==>AM
  \relax \MorT \cr %==>M
}
\bye

要するにこういう問題のようである。さらに出力をよく見ると、「T」の文字自体は数式モード(数式イタリック)で出力されていることがわかる。つまり、実際に数式モードに切り替わったの時点は、\ifmmodeT の間、ということになる。(これ以上追及すると“TeX沼”になるので止めておく。)

先の例は plain TeX のものであったが、 同様の問題は、TeX の配列(alignment)機能を利用している LaTeX の機能、例えば array 環境や amsmath の align 環境などでも発生する。

% LaTeX 文書
\documentclass[a4paper]{article}
% さっきと同じ(TeX レベルの定義)
\def\MorT{\ifmmode M\else T\fi}
\begin{document}
% array の中で \MorT を使うと...
$\begin{array}{l}
  \MorT \\      %==> T  (アレレ!?)
  A\MorT \\     %==> aM
  \relax \MorT  %==> M
\end{array}$

\end{document}

……となると、LaTeX\relax の出番がなくて落胆していた熱狂的なファン達が俄然色めき立つことになるだろう。しかし落ち着いてほしい。ここで \relax を利用して対策しなければいけないのは「\ifmmode を使う者」、つまり TeX 言語者であり、LaTeX ユーザではない。

いや、LaTeX でも ifthen パッケージがあれば条件分岐ができるので、LaTeX ユーザ自身が \MorT のようなマクロを作ることは可能なはずだ。

ふむ、では実際に試してみよう。

% LaTeX 文書
\documentclass[a4paper]{article}
\usepackage{ifthen}
% "LaTeXで"実装した
\newcommand*{\MorT}{\ifthenelse{\boolean{mmode}}{M}{T}}
\begin{document}
% array の中で \MorT を使うと...
$\begin{array}{l}
  \MorT         %==> M  (よかった!)
\end{array}$

\end{document}

確かに実装できた。素晴らしい。

……え、\relax……? 何ソレ?