[Tex/LaTex] How to display command name and its value

expansionmacros

Latex displays the command values by default – I am finding it more difficult to display the command names along with the values.

I have a list of commands that I would like to loop over and print each one's name and value.

\documentclass[11pt,letterpaper]{article}
\usepackage{tikz}  % defines foreach

\begin{document}

\def\one{this is one}
\def\two{this is two}
\def\three{this is three}

\def\CMDs{\one,\two,\three}  % list of commands I would like to loop over

\foreach \cmd in \CMDs
{
    \string\cmd = \cmd \\ % should be name = value
}

\end{document}

But the \string is not resolving the \cmd, its just printing cmd.

Even tried \expandafter\string\csname\cmd\endcsname = \cmd as suggested here – no use, it is expanding and printing the value on both sides, not the name.

Please advice on how to achieve this.

In case one would like to know the background, this is for my CVMaker project – to keep track of internal variables and dump their values on demand, as debug-aid for the package users.

Best Answer

You are lucky that \cmd is a macro that contains the target macro, thus one \expandafter solves the problem, it expands \cmd and reveals the target macro to \string:

\documentclass[11pt,letterpaper]{article}
\usepackage[T1]{fontenc}% to get correct backslash
\usepackage{tikz}  % defines foreach

\begin{document}

\def\one{this is one}
\def\two{this is two}
\def\three{this is three}

\def\CMDs{\one,\two,\three}  % list of commands I would like to loop over

\foreach \cmd in \CMDs
{
    \expandafter\string\cmd = \cmd\par % should be name = value
}

\end{document}

Result

Further remarks:

  • You can inspect a macro definition by \show, e.g.: After \show\cmd TeX stops and shows the meaning on the console:

    > \cmd=macro:
    ->\one .
    
  • Another method is \meaning. It works similar to \string, but instead of the token, it converts the meaning of the token to a string, e.g.:

    \typeout{\string\cmd=\meaning\cmd}%
    

    prints to the console/.log file:

    \cmd=macro:->\one 
    \cmd=macro:->\two 
    \cmd=macro:->\three 
    
  • If \cmd would be have assigned via \let, e.g.:

    \let\cmd=\one
    

    then \cmd has the same \meaning as \one. And the name \one cannot be derived from \cmd anymore.

Related Question