I was puzzled ats \expandafter
, and I started with simple observations. Here're AI-generated explanations.
The command \expandafter
is a low-level TeX primitive that controls the order of macro expansion. Its job is to force the expansion of a token that is not immediately next to it.
In the provided code, \expandafter
is used to ensure that the recursive call \rrep
receives a concrete number as its first argument, rather than an unexpanded macro sequence.
Let's break down the key line from the \rrep
macro:
\expandafter\rrep\expandafter{\number\numexpr#1-1\relax}{\rep{#2}}
Normally, TeX expands tokens from left to right. Without \expandafter
, TeX would try to execute \rrep
and would pass the entire sequence {\number\numexpr#1-1\relax}
as the first argument, which is not what we want.
Here's how the \expandafter
commands work together:
- The first
\expandafter
is encountered. It skips the next token (\rrep
) and looks at the token after that, which is the second\expandafter
. - The second
\expandafter
is now being expanded. It skips the next token ({
) and looks at the token after that, which is\number
. - The
\number\numexpr#1-1\relax
sequence is then expanded. For example, if#1
is4
, this sequence is calculated and expands to the literal number3
. - After these forced expansions, the token stream effectively becomes
\rrep{3}{\rep{#2}}
. The\rrep
macro is now called with a simple number (3
) as its first argument, which allows the\ifnum
conditional check to work correctly on the next recursive step.
In short, \expandafter
is essential here to perform the subtraction (\numexpr#1-1
) and convert the result to a number (\number
) before the recursive call to \rrep
is made. This prevents an infinite loop and allows the counter to correctly decrement and eventually reach the base case (#1 <= 0
).
I only know some basic resursion. Thinking that typst will replace LaTeX, I don't think I'll spend more time on this and the Expl3 syntax.