マクロツイーター

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

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}TFTF に展開される)とするか、または \@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進表記)