catcode を使用してマクロを個々のトークン/文字に分割しますか (条件をデバッグするため)?

catcode を使用してマクロを個々のトークン/文字に分割しますか (条件をデバッグするため)?

このMWEを、iftheelse 等しい文字列の比較が失敗する:

\documentclass{article}

\edef\test{german\relax}
\edef\curentry{\string german\relax}

\typeout{test: \meaning\test, curentry: \meaning\curentry}
\ifx\curentry\test
  \typeout{ equal}
\else
  \typeout{ unequal}
\fi

\begin{document}
\end{document}

これを でコンパイルするとpdflatex test.tex、ターミナルに次の出力が表示されます。

test: macro:->german\relax , curentry: macro:->german\relax
 unequal

さて、リンクされた投稿では、なぜそうなるのかを説明しています。

\string は、最初に見つかったトークン (この場合は g) に適用されます。2 つの結果を比較すると、同じではありません。1 つには 1 つの非文字があり、その後に 5 つの文字があり、2 つ目では 6 つの文字があります。

しかし、マクロがどのように定義されているかよくわからないパッケージで、ある状況を調べようとしたとします。そこで、マクロの を実行する\typeoutことにし、\meaning全く同じ内容は印刷されましたが、条件はまだ失敗します。このような状況をデバッグするにはどうすればよいでしょうか?

言い換えれば、私が使用できる何らかの関数があるのでしょうか?(Latex で catcode テーブルを生成しますか (ターミナルへの \typeout を使用)?) は、上記のマクロに対して次のように出力します。

% \typeoutComponents{\test}
g (catcode 11)
e (catcode 11)
r (catcode 11)
m (catcode 11)
a (catcode 11)
n (catcode 11)
\relax (catcode ?)

% \typeoutComponents{\curentry}
g (catcode 12)
e (catcode 11)
r (catcode 11)
m (catcode 11)
a (catcode 11)
n (catcode 11)
\relax (catcode ?)

...「文字列」(マクロ) の等価性が失敗する理由を自分で推測する機会が得られるようにするためですか?

(ところで、サブ質問: マクロ/コマンド/トークン/制御シーケンス (つまり、 で始まるもの\) には catcode を含めることができますか?)

答え1

コマンドは\tl_analysis_show:N要求した内容を実行します。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\checktokenbytoken}{sm}
 {
  \IfBooleanTF{#1}
   {
    \tl_show_analysis:n { #2 }
   }
   {
    \tl_show_analysis:N #2
   }
 }
\ExplSyntaxOff

\edef\xgerman{\string german\relax}

\checktokenbytoken{\xgerman}
\checktokenbytoken*{german\relax}

端末で、

The token list \xgerman contains the tokens:
>  g (the character g)
>  e (the letter e)
>  r (the letter r)
>  m (the letter m)
>  a (the letter a)
>  n (the letter n)
>  \relax (control sequence=\relax).
<recently read> }

l.19 \checktokenbytoken{\xgerman}

? 
The token list contains the tokens:
>  g (the letter g)
>  e (the letter e)
>  r (the letter r)
>  m (the letter m)
>  a (the letter a)
>  n (the letter n)
>  \relax (control sequence=\relax).
<recently read> }

l.20 \checktokenbytoken*{german\relax}

(TeX Live 2017 より前のリリースでは、これを動作させるに\usepackage{l3tl-analysis}は に加えて とが必要ですが、現在は非推奨です)\usepackage{xparse}\tl_show_analysis:N

答え2

私のソリューションは外部パッケージを必要としません。 が\showcat\macro実装されています。

\def\test{ger{$##m}a~n \relax \foo}
\edef\curentry{\string german \relax}

\showcat\test
\showcat\curentry

結果は次のようになります:

\test -> 
  the letter g (catcode 11)   
  the letter e (catcode 11)
  the letter r (catcode 11)
  begin-group character { (catcode 1)
  math shift character $ (catcode 3)
  macro parameter character # (catcode 6)
  the letter m (catcode 11)
  end-group character } (catcode 2)
  the letter a (catcode 11)
  the token ~ (catcode 13)
  the letter n (catcode 11)
  blank space   (catcode 10)
  the token \relax (catcode 16)
  the token \foo (catcode 16)
\curentry -> 
  the character g (catcode 12)
  the letter e (catcode 11)
  the letter r (catcode 11)
  the letter m (catcode 11)
  the letter a (catcode 11)
  the letter n (catcode 11)
  blank space   (catcode 10)
  the token \relax (catcode 16)

そして実装は次のようになります。

\def\showcat#1{\immediate\write16{\string#1 -> }\expandafter\showcatA#1\showcatA}
\def\showcatA{\futurelet\tmp\showcatB}
\def\showcatB{\let\next=\showcatE
   \ifx\tmp\bgroup \let\next=\showcatC \fi
   \ifx\tmp\egroup \let\next=\showcatC \fi
   \expandafter\ifx\space\tmp \let\next=\showcatC \fi
   \ifx\tmp\showcatA \let\next=\showcatF \fi
   \next
}
\def\showcatC{\afterassignment\showcatD \let\tmp= }
\def\showcatD{\showcatE\tmp}

\def\showcatE#1{\edef\next{\string#1}%
   \immediate\write16{\space\space 
       \ifnum\showcatG<13 \meaningtmp \else the token \next
       \fi \space (catcode \showcatG)}%
   \showcatA
}
\def\meaningtmp{\meaning\tmp}
\def\showcatF#1{}
\def\showcatG{\showcatH\bgroup1\showcatH\egroup2\showcatH$3\showcatH&4%
   \showcatH##6\showcatH^7\showcatH_8\showcatH{ }{10}%
   \showcatH A{11}\showcatH/{12}\showcatH~{13}16}
\def\showcatH#1#2{\ifcat\noexpand\tmp\noexpand#1#2\expandafter\showcatI\fi}
\def\showcatI#116{}

もちろん、カテゴリ 0、5、9、14、15 のトークンはマクロ本体には出現しません。また、制御シーケンス (カテゴリのないトークン) は、テスト\showcatGでの使用を簡単にするために、ここではカテゴリ 16 として表現されています\ifnum

関連情報