I'm still trying to understand how exactly tex parses documents. This time I'm trying to understand all the parameter-tokens-handling in \newcommand and friends, which looks like black magic to me - the crux here seems to happen in \@yargdef and \@yargd@f, which can be found in latex.ltx lines 868 and 877 respectively. The aim is obviously to create the parameter string that will ultimately be following a \def\foo, but I don't understand how this works.
To explain where I think my problem is, I'll have to explain my thinking a little, unfortunately.
So: If I do \newcommand\foo[2]{\bar}, then as far as I can tell, this ultimately (after various checks for whether \foo
is already defined and checking for optional arguments etc.pp.) expands to \@argdef\foo[2]{\bar}.
I'll go step by step how I read the definitions:
\@argdefis defined via:\long\def\@argdef#1[#2]#3{% \@ifdefinable #1{\@yargdef#1\@ne{#2}{#3}}}So we end up with
@yargdef\foo@ne{2}(leaving{\bar}).\@yargdefis defined thus:\long \def \@yargdef #1#2#3{% \ifx#2\tw@ \def\reserved@b##11{[####1]}% \else \let\reserved@b\@gobble \fi \expandafter \@yargd@f \expandafter{\number #3}#1% }which defines
\reserved@bas@gobbleand ultimately expands to@yargd@f{2}\foo(leaving{\bar}).- Now
\@yargd@fis the weird part. It is defined via:\long \def \@yargd@f#1#2{% \def \reserved@a ##1#1##2##{% \expandafter\def\expandafter#2\reserved@b ##1#1% }% \l@ngrel@x \reserved@a 0##1##2##3##4##5##6##7##8##9###1% }So the expansion in my case should be (if I'm not mistaken?):
\def\reserved@a #12#2#{% \expandafter\def\expandafter\foo\reserved@b #12% }% \l@ngrel@x \reserved@a 0#1#2#3#4#5#6#7#8#9#2So in the application of
\reserved@a, the first argument should be0#1#and the second argument should be... empty, I guess, since the immediate following token is already#...? Leaving3#4#5#6#7#8#9#2{\bar}as the next tokens?
This must be where my thinking goes wrong, because if I pretend that string before the {\bar} isn't there, the rest makes sense:
\reserved@a then expands to
\expandafter\def\expandafter\foo\reserved@b 0#1#2 - \reserved@b is defined as \@gobble which just eats the first token it finds, so the expansion of that should be \def\foo#1#2 - which would be followed by the {\bar}.
So apparently I'm interpreting the argument-string of \reserved@a wrong? What exactly is the second argument of \reserved@a in its application, if not empty? The only possible other explanation I can think of is that it eats to the next #-token, but even then, it would only eat the #3 part and leave a whole string of parameter tokens...?
am I expanding 0##1##2##3##4##5##6##7##8##9###1 or the ##1#1##2## in the definition of \reserved@a wrong?
#{: Macros with # as the last parameter and “Grab to #{” macro arguments – campa Feb 24 '20 at 13:58#{was special - that was my problem. Thanks a lot :) – Dennis Müller Feb 24 '20 at 14:21#must be followed by 1--9" rule. See egreg's answer to my question here, and perhaps §476 in TeX-the-program (texdoc tex) to see where does that exception come from. – Phelype Oleinik Feb 24 '20 at 14:30