[Tex/LaTex] Create a capitalized macro token using \csname

capitalizationexpansionmacros

Two things I understand and one thing I don't:

I often use \csname to create user-defined tokens. For instance, the following code uses \expandafter to expand everything between \csname and \endcsname before \gdefing the result:

\newcommand{\mycommand}[1]{%
  \expandafter\gdef\csname #1\endcsname{Here is #1 printed.}%
}

\begin{document}
\mycommand{abc} % Creates a macro \abc
Demonstration: \abc % Prints Demonstration: Here is abc printed.
\end{document}

I wanted to do something similar by using \mycommand{abc} to create a macro \Abc (note the capital letter). Unfortunately, \uppercase cannot be used inside \csname. (I'm guessing some parts expand to TeX primitives?) But I found a somewhat related answer from Heiko Oberdiek (http://newsgroups.derkeiler.com/Archive/Comp/comp.text.tex/2006-02/msg01220.html) and created the following, which I don't entirely understand.

It should create a new uppercase token, and I think it is working, since I can then \let it to another macro and it does not error.

\newcommand{\mycommand}[1]{% 
  \uppercase\expandafter{\expandafter\csname #1}\endcsname% Creates token 
}%
\def\temp{if it worked}
\let\Abc\temp% Now \Abc expands to something other than \relax

\begin{document}
\mycommand{abc}% Creates \Abc
This lets you see \Abc.% Prints This lets you see if it worked.
\end{document}

So my question is: how can I create an uppercase token and define the expansion at the same time? (Basically, I want to combine both of the above approaches.) Here are two ways I have tried (both return Error: extra \endcsname).

\newcommand{\mycommand}[1]{% 
  \expandafter\gdef%   I think this tries to do \gdef\uppercase = bad 
  \uppercase\expandafter{\expandafter\csname #1}\endcsname{the macro #1 expanded}%  
}%
\mycommand{abc}
Use \Abc. % Should print Use the macro abc expanded.

or

\newcommand{\mycommand}[1]{% 
  \expandafter\gdef\expandafter{% 
  \uppercase\expandafter{\expandafter\csname #1}\endcsname}{the macro #1 expanded}% 
}%
\mycommand{abc}
Use \Abc. % Should print Use the macro abc expanded.

Best Answer

You have to isolate the first token in #1 from the rest and uppercase it; the fact that \uppercase doesn't expand anything and puts back the token list into the input stream after its operation can be exploited in the following way:

\newcommand{\mycommand}[1]{\mycommandaux#1\relax}
\def\mycommandaux#1#2\relax{%
  \uppercase{\expandafter\gdef\csname #1}#2\endcsname{the macro #1#2 expanded}%
}
\mycommand{abc}
\show\Abc

Of course an empty argument to \mycommand will result in an error.

If you want to provide a definition, say

\mycommand{abc}{Something else}

to be equivalent to \def\Abc{Something else}, just leave out the tokens after \endcsname

\newcommand{\mycommand}[1]{\mycommandaux#1\relax}
\def\mycommandaux#1#2\relax{%
  \uppercase{\expandafter\gdef\csname #1}#2\endcsname
}
\mycommand{abc}{Something else}
\show\Abc

The command \uppercase is a bit stranger than other TeX primitives. Indeed the <general text> it requires as argument first does a travel down TeX's stomach to be "regurgitated" after each character token has been transformed using the \uccode vector: if a character has positive \uccode, TeX will transform it into that character (the category code is unchanged). So, for instance, TeX is setup so that \uccode`a=`A and so an a becomes an A after regurgitation. Non character token are left unchanged and no expansion is performed.

Here's the working in slow motion (first version).

  1. \mycommand{abc}
    Here #1 is abc

  2. \mycommandaux abc\relax
    Here #1 is a and #2 is bc (argument #2 is delimited by \relax, while #1 is undelimited, so the only first token is grabbed)

  3. \uppercase{\expandafter\gdef\csname a}bc\endcsname {the macro abc expanded}
    Tex executes the \uppercase and puts back

    \expandafter\gdef\csname A
    

    in the input stream.

  4. \expandafter\gdef\csname Abc\endcsname{the macro abc expanded}

  5. \gdef\Abc{the macro abc expanded}

Et voilĂ .


A variant with \newcommand instead of \gdef, that makes it easy to define macros with arguments:

\newcommand{\mycommand}[1]{\mycommandaux#1\relax}
\def\mycommandaux#1#2\relax{%
  \uppercase{\expandafter\newcommand\csname #1}#2\endcsname
}
\mycommand{abc}{Something else}
\show\Abc

\mycommand{uvw}[1]{Something else with #1}
\show\Uvw

With \gdef the standard parameter text should be used.

\newcommand{\mycommand}[1]{\mycommandaux#1\relax}
\def\mycommandaux#1#2\relax{%
  \uppercase{\expandafter\gdef\csname #1}#2\endcsname
}
\mycommand{abc}{Something else}
\show\Abc

\mycommand{uvw}#1{Something else with #1}
\show\Uvw
Related Question