# Why does \today crash in Tufte-LaTeX using 'isodate' when passed as an argument?

I'm trying to use the isodate package with Tufte-LaTeX, but get

! Illegal parameter number in definition of \reserved@a.


when I use \today as an argument to certain functions (e.g. \printdate or \allcaps):

\documentclass[]{tufte-handout}
\usepackage[iso,american]{isodate}
\begin{document}
\allcaps{\today}
\end{document}


If \date is set, I get a different error

! Argument of \reserved@a has extra }.


Using \protect\today fixes the above, but I still get the errors when I try to use the date as I need to:

\documentclass[]{tufte-handout}
\usepackage[iso,american]{isodate}
\date{\protect\today}
%\date{5/16/1961} % Works fine if a date is provided
\begin{document}
\makeatletter
\printdate{\@date}
\end{document}

-
Try \protect\today instead of \today (I can't test right now). –  Bruno Le Floch Mar 20 '12 at 22:33
@BrunoLeFloch: Thanks, that gets me part way there, but I still can't do what I need to do (see edit to question). –  raxacoricofallapatorius Mar 20 '12 at 23:07

The default definition of \@date and \date is

\def\@date{\today}
\def\date#1{\gdef\@date{#1}}


This is not changed by isodate, which however redefines \today. You can check if the user has said \date{...} with

\def\kernel@date{\today}
\ifx\@date\kernel@date
<what to do if no \date command has been given>
\else
<what to do if \date has been given>
\fi


Of course if one says \date{21 marzo 2012}, \printdate would have a hard time in producing the date in correct form with

\printdate{\csname @date\endcsname}


(this is the same as \makeatletter\printdate{\@date}\makeatother, but more economical).

-
This produces "<what to do if \date has been given>" always (for no \date call, for \date{}, for date{\protect\today}, and for \date{14/10/1066}). –  raxacoricofallapatorius Mar 21 '12 at 0:35
For the above to work: \makeatletter \def\kernel@date{\protect\today}. –  raxacoricofallapatorius Mar 21 '12 at 3:11

Bruno's answer of using \protect\today works for the \allcaps treatment (though I'm not sure why you'd want to print an ISO-format date with that spacing).

You can't use \today as an argument to \printdate. It needs to be in the format yyyy-mm-dd, mm.dd.yyyy, or dd/mm/yyyy.

\documentclass{tufte-handout}

\usepackage[iso,american]{isodate}

\begin{document}

\printdate{2012/03/20}
\printdate{20.03.2012}
\printdate{20/03/2012}

\end{document}


Based on the comments below, here's a more complete solution:

\documentclass{article}

\usepackage[iso,american]{isodate}

\makeatletter
% Set default date to today's date (in ISO format)
\xdef\@date{\the\year-\the\month-\the\day}

% Helper macro to avoid @s in macro name
\newcommand{\thedate}{\@date}

% Helper macro to avoid more typing
\newcommand{\printthedate}{\printdate{\@date}}
\makeatother

% Optionally change the date
%\date{2010-01-31}% must be in ISO format

\begin{document}

% Prints the date set by \date or today's date by default
\printdate{\thedate}

% Same as above
\printthedate

\end{document}


First, we redefine \@date to be today's date (using the ISO format). This means that if \date isn't specified, we'll default to today's date.

Next, we've written a \thedate helper macro. This just saves us some typing in the document. Without this macro, we'd have to write \makeatletter\printdate{\@date}\makeatother instead of \printdate{\thedate}. Additionally, we've created a \printthedate macro that is equivalent to \printdate{\thedate}. (Yes, I'm a lazy typist!)

If you want to use a date other than today's date, you must specify it using in ISO format \date{yyyy-mm-dd} (or one of the other formats supported by the \printdate macro).

Finally, the document demonstrates the helper macros.

-
Thanks, see addition to question above. What I'm trying to do, FWIW, is use the current date if none is specified, and otherwise use the specified date (in whatever form it is entered) to print out the date in whatever format has been selected for the isodate package (which might not be the ISO date format). –  raxacoricofallapatorius Mar 20 '12 at 23:10
@raxacoricofallapatorius: Can't you just use \today then? It'll print the current date in ISO format. If you want a date other than today's date, use \printdate. –  godbyk Mar 20 '12 at 23:18
Yes, but I can only do that if I know that \date{} hasn't been set (or is "today"). I'm not sure how to do either (by testing \@date). –  raxacoricofallapatorius Mar 20 '12 at 23:26
Could you edit your question to provide an example of what you'd like to write (code) and what the result should be (for both the case where \date is \today and the case where it's set to something else)? That'll give us an idea of what you're really trying to do. –  godbyk Mar 20 '12 at 23:29
When the date has been set by using \date{...}, I want to print that date in the format specified by isodate; when it hasn't been set (there's no \date) I want to print the current date in that format. If I could detect which of these two has occurred, I could use \today (or \protect\today) in the latter case and \printdate{\@date} in the former. (But this method for distinguishing does not work.) –  raxacoricofallapatorius Mar 21 '12 at 0:44

I would like to precise that Tufte classes redefine some macros

First \newcommand{\thedate}{\today}

and

\renewcommand*{\date}[1]{%
\gdef\@date{#1}%
\begingroup%
% TODO store contents of \thanks command
\renewcommand{\thanks}[1]{}% swallow \thanks contents
\protected@xdef\thedate{#1}%
\endgroup%
}


I think you need to take care of these modifications and you can define an iso format without ìsodate` package.

-