[texhax] Macros that define other macros

Neal H. Walfield neal at walfield.org
Mon Dec 3 08:29:43 CET 2012


Hi, Pablo,

At Sun, 2 Dec 2012 21:04:45 -0300,
Pablo Mayckon wrote:
> I would like to define macros that in their turns define other macros, in the
> spirit of the following erroneous TeX code:
> 
> ---------------------
> \def\macromaker#1{%
>   \def\submacro#1{I am submacro #1}%
>   \def\anothersubmacro#1{I am another submacro #1}}
> 
> \macromaker{test}
> \submacrotest
> \anothersubmacrotest

This should do what you want:

  \def \macromaker#1%
       {%
           \expandafter \def \csname submacro#1\endcsname{I am submacro#1}%
           \expandafter \def \csname anothersubmacro#1\endcsname{I am another submacro#1}%
       }                                                                          
  
  \macromaker {test}
  \submacrotest
  \anothersubmacrotest
  \end

> Could someone please explain "what's going on" here?

When TeX is expanding \macromaker, it doesn't paste the control
sequence and #1 together.  As I understand it, when the definition of
\macromaker is processed, the control sequences are already recognized
as control sequences.  Instead, TeX recognizes #1 as an argument
delimiter.  So, to invoke your macro, you'd do:

  \submacro test

instead of

  \submacrotest

> One last thing, so that I can understand it better: what if I wanted
> "\submacrotest" to have two parameters and to print them, say, "I am submacro
> test and received #1 and #2"?

You need to double the number of hashes to avoid expansion of the
arguments.

  \def \macromaker#1%
       {%
           \expandafter\def \csname submacro#1\endcsname##1##2{I am submacro#1; '##1'; '##2'}%
       }
  
  \submacrotest{a}{b}

Neal


More information about the texhax mailing list