nsajko
Suppose I wrote a macro, for example a LaTeX expl3 function called `\nsajko_some_fun:n`. Suppose I suspect that function is buggy, and I'd like to check that.
Is it possible to insert some command into my code that would tell TeX to print the value of the expansion of an invocation of my macro (e.g., `\nsajko_some_fun:n{13}`) to the terminal?
This would be analogous to other programming languages where it's usually possible to insert a print statement into code to print values of variables for debugging.
Top Answer
frougon
It's almost always a bad idea not to provide a Minimal Working Example, so... you'll get what you deserve. :)
First, macros are not all [expandable](https://topanswers.xyz/tex?q=2007#a2255) (see the “Annex” at the end of that answer). If `\nsajko_some_fun:n` is not an expandable macro, your “print the value of the expansion of an invocation of my macro” is “meh...” (the first-level expansion as shown below could be what you want, full expansion probably not).
From now on, I'll assume that you intend to debug an expandable macro. What you want is still a bit unclear, though, because expansion proceeds in steps. The following code defines a simple expandable macro called `\foo_bar:n` and prints three things on the terminal:
- the first-level expansion of `\foo_bar:n { 13a$ }`;
- its full expansion (similar to what `\edef` does, except printing to the terminal has special rules for unexpandable tokens);
- a detailed analysis of its full expansion (among other things, this includes wording that tells you the category code of every character token; this can be very helpful in some debugging situations since category codes are otherwise “invisible”).
```
\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \foo_bar:n #1
{
\foo_bar_aux:n {#1}
\c_space_token
\foo_bar_aux:n {#1}
}
\cs_new:Npn \foo_bar_aux:n #1
{
\exp_not:n {#1}
}
% Show the first-level expansion of ”\foo_bar:n { 13a$ }”
% => \foo_bar_aux:n {13a$}\c_space_token \foo_bar_aux:n {13a$}
\iow_term:x { \exp_not:o { \foo_bar:n { 13a$ } } }
% Show the full expansion of “\foo_bar:n { 13a$ }”
% => 13a$\c_space_token 13a$
\iow_term:x { \foo_bar:n { 13a$ } }
\iow_term:n { } % blank line
\cs_generate_variant:Nn \tl_analysis_show:n { e }
% Detailed analysis of all tokens of the expansion performed by \expanded
\tl_analysis_show:e { \foo_bar:n { 13a$ } }
\ExplSyntaxOff
\begin{document}
\end{document}
```
The output of the `\tl_analysis_show:e` call is:
```
The token list contains the tokens:
> 1 (the character 1)
> 3 (the character 3)
> a (the letter a)
> $ (math shift character $)
> \c_space_token (control sequence=blank space )
> 1 (the character 1)
> 3 (the character 3)
> a (the letter a)
> $ (math shift character $).
```
Another way to do the same, except for how the output is presented, is to store the tokens you want to examine in a token list variable (a macro) and use `\tl_show:N` or `\tl_analysis_show:N` on it:
```
\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \foo_bar:n #1
{
\foo_bar_aux:n {#1}
\c_space_token
\foo_bar_aux:n {#1}
}
\cs_new:Npn \foo_bar_aux:n #1
{
\exp_not:n {#1}
}
% Show the first-level expansion of ”\foo_bar:n { 13a$ }”
\tl_set:No \l_tmpa_tl { \foo_bar:n { 13a$ } }
\tl_show:N \l_tmpa_tl
% Show the x-expansion of “\foo_bar:n { 13a$ }”
\tl_set:Nx \l_tmpa_tl { \foo_bar:n { 13a$ } }
\tl_show:N \l_tmpa_tl
\iow_term:n { } % blank line
% Only to precisely match the previous code. In practice, \tl_set:Nx is
% most of the time suitable for this purpose and readily available.
\cs_generate_variant:Nn \tl_set:Nn { Ne }
% Detailed analysis of all tokens of the expansion performed by \expanded
\tl_set:Ne \l_tmpa_tl { \foo_bar:n { 13a$ } }
\tl_analysis_show:N \l_tmpa_tl
\ExplSyntaxOff
\begin{document}
\end{document}
```
Answer #2
Skillmon
TeX has built in debugging means with the different `\tracing...` settings. You can specify with these to which level of detail you get information on what TeX is doing (different engines have extended these `\tracing...` macros beyond what Knuth originally built into TeX, but this answer is non-exhaustive in every way, instead I'll focus on what is interesting to see what a macro gets for arguments, and to what it expands).
- `\tracingonline=1` will print the tracing information to stdout and the log (without it information ends up in the log)
- `\tracingmacros=1` will result in macro expansions being printed, as well as their arguments, for instance (this is in plain TeX not LaTeX)
```
\def\mymacro{\mymacroA}
\def\mymacroA#1{\if xxFoo\else Bar\fi with #1}
\begingroup
\tracingonline=1
\tracingmacros=1
\mymacro{abc}
\endgroup
\bye
```
will print the following:
```none
\mymacro ->\mymacroA
\mymacroA #1->\if xxFoo\else Bar\fi with #1
#1<-abc
```
`\tracingmacros=2` will also show what stuff like `\everypar` is doing
- `\tracingcommands=1` will result in TeX telling you about mode switches, the first thingy that starts a word, a few spaces etc., and `\tracingcommands=2` will additionally tell you about conditionals (like `\if` etc.) being used and what the results of those tests was, so adding that to the example above will now print:
```none
\mymacro ->\mymacroA
\mymacroA #1->\if xxFoo\else Bar\fi with #1
#1<-abc
{vertical mode: \if}
{true}
{the letter F}
{horizontal mode: the letter F}
{\else}
{blank space }
{the letter a}
{blank space }
{\endgroup}
```
There are more `\tracing...` primitives/macros, but I think these will give you most of what you need for debugging macros (another interesting one I haven't showed is `\tracingrestores`, it'll show information on macros being restored at group ends).
To turn on (almost?) every tracing at once in plain TeX or LaTeX you can use `\tracingall`, but this usually gives more information than you need.
Answer #3
Skillmon
The `unravel` package turns your TeX into a debugger in which you can step through macro expansions and assignments. It doesn't support all primitives though, for instance it can't be used to step through or over a `tabular` since the underlying `\halign` isn't supported, and using it across cell boundaries would most likely not work as well.
But for much stuff you can use it to debug. Whether it's the fastest way for you I can't say, I really like it for much of my stuff.
I'll give a small example here, but you should really take a look at the documentation if you're interested (there is a list of things that don't work inside the documentation as well).
Assume we want to see how the fancy macro `\mymacro` works. It has the following definition (also includes the use of `unravel`):
```
\documentclass{article}
\newcommand\mymacro{\mymacroA}
\newcommand\mymacroA{\mymacroB}
\newcommand\mymacroB{\mymacroC}
\newcommand\mymacroC{\mymacroD}
\newcommand\mymacroD{\mymacroE}
\newcommand\mymacroE{\mymacroF}
\newcommand\mymacroF{\mymacroG}
\newcommand\mymacroG{\mymacroH}
\newcommand\mymacroH{\mymacroI}
\newcommand\mymacroI{\mymacroJ}
\newcommand\mymacroJ{\mymacroK}
\newcommand\mymacroK{\mymacroL}
\newcommand\mymacroL{This is the interesting part}
\usepackage{unravel}
\begin{document}
Starting a paragraph (this serves to not get the entirety of the begin-paragraph
hook in the unravel-output).
\unravel{\mymacro}
\end{document}
```
When we start this we're greeted with the following on the terminal:
```none
======== Welcome to the unravel package ========
"<|" denotes the output to TeX's stomach.
"||" denotes tokens waiting to be used.
"|>" denotes tokens that we will act on.
Press <enter> to continue; 'h' <enter> for help.
||
|> \mymacro
```
Hitting `<enter>` we get a step forward and see:
```none
[===== Step 1 =====] \mymacro = \long macro:->\mymacroA
||
|> \mymacroA
```
`<enter>` again:
```none
[===== Step 2 =====] \mymacroA = \long macro:->\mymacroB
||
|> \mymacroB
```
We realise this gets boring, but know the interesting part is somewhere after `\mymacroK` so we skip forward to that input `u\mymacroK` and hit `<enter>` at the prompt:
```none
[===== Step 3 =====] \mymacroB = \long macro:->\mymacroC
[===== Step 4 =====] \mymacroC = \long macro:->\mymacroD
[===== Step 5 =====] \mymacroD = \long macro:->\mymacroE
[===== Step 6 =====] \mymacroE = \long macro:->\mymacroF
[===== Step 7 =====] \mymacroF = \long macro:->\mymacroG
[===== Step 8 =====] \mymacroG = \long macro:->\mymacroH
[===== Step 9 =====] \mymacroH = \long macro:->\mymacroI
[===== Step 10 =====] \mymacroI = \long macro:->\mymacroJ
[===== Step 11 =====] \mymacroJ = \long macro:->\mymacroK
||
|> \mymacroK
```
Hitting `<enter>` a few more times:
```none
[===== Step 12 =====] \mymacroK = \long macro:->\mymacroL
||
|> \mymacroL
[===== Step 13 =====] \mymacroL = \long macro:->This is the interesti...
||
|> This is the interesting part
```