マクロツイーター

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

TeX プログラムのデバッグで絶望する前に知るべきこと (3)

(前回の続き)
デバッグ出力の「傾向と対策」

ここでは中身を調べたいものの“型”で分類して、それぞれの場合にどの命令を用いるべきかを記す。show 系の表示をしたい場合と print デバッグの出力(\write や \meaning を用いる)で用いる命令が異なるが、ここでは“show 系/print 出力系”の形式で示す。

マクロ \CS の定義内容を調べる → \show\CS/\meaning\CS

  • LaTeX の命令も実態はマクロなので同じ。
  • LaTeX の環境 ENV は、開始側が \ENV、終了側は \endENV というマクロで実現されている。
\def\xTerm#1#2{\textsf{#1}(\textit{#2})}
%\newcommand*\xTerm[2]{\textsf{#1}(\textit{#2})} % LaTeX の命令定義
\show\xTerm               %==> > \xTerm=macro:
                          %    #1#2->\textsf {#1}(\textit {#2}).
\typeout{\meaning\xTerm}  %==> macro:#1#2->\textsf {#1}(\textit {#2})

トークン列(文字列)変数 \CS の内容を調べる:\CS がマクロである → \show\CS/\meaning\CS(単純(完全展開可能)な文字列しか扱わないのなら \CS でもよい)

\def\xx@mode{plain} % 文字列変数なマクロ
\show\xx@mode              %==> > \xx@mode=macro:
                           %    ->plain.
\typeout{\meaning\xx@mode} %==> macro:->plain
\typeout{mode=\xx@mode}    %==> mode=plain

トークン列(文字列)変数 \CS の内容を調べる:\CS がトークン列レジスタである → \showthe\CS/\the\CS(それ以上展開されない)

\newtoks\xx@mode \xx@mode{plain} % 文字列変数なレジスタ
\showthe\xx@mode           %==> > plain.
\typeout{(\the\xx@mode)}   %==> (plain)

整数変数 \CS の値を調べる:\CS が整数レジスタである → \showthe\CS/\the\CS

\newcount\xx@max \xx@max=42
\showthe\xx@max            %==> > 42.
\typeout{max:\the\xx@max}  %==> max:42
\newlength{\phewwidth}\setlength{\phewlength}{2pt}% LaTeX の長さ命令
\showthe\phewlength        %==> > 2.0pt.
\typeout{\the\phewlength}  %==> 2.0pt

LaTeX カウンタ CTR の値を調べる → \showthe\value{CTR}(または \showthe\c@CTR)/\arabic{CTR}(または \the\c@CTR)

  • カウンタ CTR の実態は整数レジスタ c@CTR。
  • \arabic や \Roman は完全展開可能なのでそのまま print 出力に使える。
\newcounter{maxglemish} \setcounter{maxglemish}{42} % LaTeX のカウンタ
\showthe\value{maxglemish}    %==> > 42.
\showthe\c@maxglemish         %==> > 42.
\typeout{\arabic{maxglemish}} %==> 42
\typeout{\Roman{maxglemish}}  %==> XLII

整数定数 \CS の値を調べる:\CS が chardef である → \showthe\CS/\the\CS

  • 要するに、整数・寸法・グルー型の内部値として通用するものなら \showthe/\the でよい。
\chardef\xx@max=42 % chardef で定数定義
\showthe\xx@max            %==> > 42.
\typeout{max:\the\xx@max}  %==> max:42

ブール変数(スイッチ) \ifCS の値を調べる → \show\ifCS/\meaning\ifCS

  • ifthen パッケージの \newboolean{CS} や etoolbox パッケージの \newbool{CS} で定義された場合も同じ。
  • ただし、この方法でテストすると不均衡の \if が発生する。これを防ぐには、etoolbox を使って、\csshow{ifCS} や \ifbool{CS}TF(T か F に展開される)とするか、または \@gobble\fi を適宜挿入する。
  • etoolbox の \newtoggle{CS} で定義されたブール変数の場合は、素直に \iftoggle で頑張る。
\newif\ifxx@draft \xx@drafttrue
% \newboolean{xx@draft}\setboolean{xx@draft}{true} %ifthen パッケージ
% \newbool{xx@draft}\booltrue{xx@draft} %etoolbox パッケージ
\show\ifxx@draft \@gobble\fi             %==> > \ifxx@draft=\iftrue.
\csshow{xx@draft}                        %==> > \ifxx@draft=\iftrue.
\typeout{\meaning\ifxx@draft\@gobble\fi} %==> \iftrue
\typeout{\ifbool{xx@draft}TF}            %==> T

暗黙の文字トークン \CS(文字に \let された制御綴)の値を調べる → \show\CS/\meaning\CS

  • 暗黙の文字トークンは簡便な“列挙体(enum)”として利用される。
  • print 出力で単に \CS とやっても“その文字”に展開されるわけでないので注意。
\let\xx@align=c % l=左,c=中央,r=右, の様に決める
\show\xx@align                      %==> > \xx@align=the letter c.
\typeout{align:(\meaning\xx@align)} %==> align:(the letter c)

マクロの引数 #1 として渡されたトークン列を調べる → \showtokens{#1} / \unexpanded{#1}(単純な文字列しか扱わないのなら #1 でもよい)

  • TeX では、引数の扱いは“変数”(マクロ、レジスタ)のそれとは異なることに注意。
  • 当該のマクロが展開された時に引数(#1、#2、…)は渡された引数のトークン列に置き換えられている。なので、「渡されたトークン列をそのまま出力する」\showtokens を利用するのが正解。
  • ちなみに、まだ e-TeX 拡張が使えなかった時代は、「\def\ARGS{#1}\show\ARGS」のようにしていた。
\def\xx@some@proc#1{%
\showtokens{#1}% デバッグ
  %...実際の処理
}
\xx@some@proc{{\TeX}はアレ} %==> > {\TeX }はアレ.

マクロの引数 #1 に何か整数変数(レジスタ)が渡されている、という前提でその変数の値を調べる → \showthe#1 / \the#1

  • さっき書いた通り、#1 は実際の引数(例えば \CS)に置き換わっている。なのでその前提で適切な命令を選ぶ。
  • 他の「#1 に〜が渡されている前提で〜」というパターンも同じ。
\def\xx@some@proc#1{%
\showthe#1% デバッグ
  %...実際の処理
}
\newcount\xx@ans \xx@ans=42
\xx@some@proc{\xx@ans} %==> > 42.
% (\showthe\xx@ans が実行される)

マクロの引数 #1 に何か“整数”が渡されている、という前提でその値を調べる → \showthe\numexpr#1\relax / \the\numexpr#1\relax(または \number#1)

  • “整数”なのは確かだが、変数(レジスタ)なのか定数(chardef)なのか即値(“42”のような数字)なのかは不定である、という場合。e-TeX 拡張の \numexpr を流用する。
  • 同様に、寸法の場合は \dimexpr、グルー値の場合は \glueexpr を流用する。
  • e-TeX 拡張がない場合、整数値の print 出力に限っては \number が使える。
\def\xx@some@proc#1{%
\showthe\numexpr#1\relax% デバッグ
  %...実際の処理
}
\xx@some@proc{\m@ne} %==> > -1.
\xx@some@proc{"64}   %==> > 100. %(16進表記)