# How do I “unprotect” an argument?

I'm having trouble with an argument that I need to "protect" (a concept I don't completely grasp) in order to avoid errors. When I write

\command{\argument}


I get an error; but when I try to avoid the error by writing

\command{\protect\argument}


I do not get the output I expect. For example, using Tufte-LaTeX, I have to choose between crashing, or failing to format a date as desired:

\documentclass[]{tufte-handout}
\usepackage[orig,american]{isodate}
\begin{document}
%\allcaps{\today}           % ! Illegal parameter number in definition of \reserved@a.
\allcaps{\protect\today}    % Fails to change case
\end{document}


‡This may not be my problem at all, but I'm guessing its the source.

-
Now I see what you're about and I don't understand what's the purpose of using isodate. –  egreg Mar 21 '12 at 14:57

\protect doesn't make sense here. It prevents commands to get expanded when written to a file or to the header. Try e.g. this example and look in the toc-file to see the difference:

\documentclass[]{article}

\begin{document}
\newcommand\test{abc}

\tableofcontents
\section{\test}
\section{\protect\test}
\end{document}


But your problem is not that the \today is moving to a file and needs to be protected so that is doesn't expand. Your problem is the other way round: The \allcaps command must expand its argument to access the real chars. But isodate redefines \today so that is not expandable, so you can't use it in the argument of \allcaps.

Addition: You can build your own expandable \today. e.g.:

\documentclass[]{tufte-handout}
\usepackage[orig,american]{isodate}

\begin{document}

\allcaps{\ifcase\month\or
January\or February\or March\or April\or May\or June\or
July\or August\or September\or October\or November\or
December\fi\space \the\day, \the\year}
\end{document}

-
Is there any way for me to "get at" the actual characters in \today so that I can use them in \allcaps? There must be some way to "extract" them. –  raxacoricofallapatorius Mar 21 '12 at 15:00
@raxaco: I have added an example to get an \today you can use with \allcaps. –  Ulrike Fischer Mar 21 '12 at 15:42

The package isodate defines \today in a way that makes it unsuitable for usage inside \MakeUppercase which expects a string of characters and not the set of instructions to print them (which, for isodate, require performing assignments that are not carried out when \MakeUppercase does its work.

So the answer to your question is: "No, you definitely can't use \today as redefined by isodate in the argument of \allcaps".

There's no sensible way to access at the list produced by \today without going through all the macros of isodate that are defined in a rather inefficient way with \ifthenelse (which is the real culprit).

But if you want a date in the form "March 21, 2012" to be uppercased if need be, the kernel version of \today is precisely what you're looking for: don't load isodate, that's the answer.

-
I'm using isodate to allow switching among date formats. But it sounds like the switch should wrap the package entirely: if I'm not going to use an ISO date, I guess I just shouldn't load it at all. What possible rational can there be for isodate to have redefined \today in a way that makes it unusable by formatting commands like \MakeUppercase? –  raxacoricofallapatorius Mar 21 '12 at 15:26
@raxacoricofallapatorius The developer of isodate didn't think about this and preferred to provide a very generic method adaptable to many languages. If you give the specs of the date formats you need, it should be rather easy to write expandable macros that do the job. –  egreg Mar 21 '12 at 15:50
See the second comment in Error with \newcommand and \section \protect means different things in different contexts, mostly do do with preventing expansion. However if you have a command expecting to parse a fully expanded string, preventing expansion is not what you want, but if the unprotected command is not expandable, then you can't always get what you want.