# Is it possible to have an undetermined character length argument in a macro?

I have the following macro,

\def\RCS#1: #2 {\expandafter\def\csname RCS#1\endcsname{#2}}


Which is used for revision version control, i.e,

\RCSRevision: 1.2 
\RCSDate: 2010/04/02 18:20:00 
\pagestyle{fancy}


Which works great. However if I then use latexdiff on it with another revision, the diff file doesn't expand the macro correctly,

\RCSRevision: \DIFdelbegin \DIFdel{1.2 }\DIFdelend \DIFaddbegin \DIFadd{1.8 }\DIFaddend 


Is there a way to get it to expand the second argument as a single text block?

(This relates to my question Can latexdiff-cvs handle RCS tags?)

-

Total Edit: Effectively, you want \edef, which totally expands its contents before defining a macro. However, there is a hitch: latexdiff defines \DIFadd and \DIFend to print something involving colors, which is not really good material for parsing as text like you want to do. On top of that, it is careful enough to \protect them, and the whole point of \protect is to interfere with normal expansion. So trying to use \edef directly will give you an error (apparently, "TeX capacity exceeded").

What I do, then, is temporarily redefine these two macros to do what they "logically" do: include or ignore their contents. Since that shouldn't be a permanent change, I do it in a group, and this necessitates that I use \xdef, the global version of \edef.

The way this little program works is that it grabs the material between dollar signs like your \RCS does, but then feeds it to \edef to produce an expanded text \expandedRCS. It then places the contents of \expandedRCS after another macro, \innerRCS, that does what your \RCS used to. \expandedRCS is created in a group as explained above, but once it is defined I no longer need the new definitions of \DIFadd and \DIFend, so I can (and should) expand \innerRCS outside the group.

Here is a complete document. I've included the latexdiff preamble for verisimilitude.

\documentclass{article}
\def\RCS#1{%
{%
\renewcommand{\DIFdel}[1]{}%
\xdef\expandedRCS{#1}%
}%
\expandafter\innerRCS\expandedRCS
}
\def\innerRCS#1: #2 {\expandafter\def\csname RCS#1\endcsname{#2}}

%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF
%DIF UNDERLINE PREAMBLE %DIF PREAMBLE
\RequirePackage[normalem]{ulem} %DIF PREAMBLE
\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} %DIF PREAMBLE
\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}}                      %DIF PREAMBLE
%DIF SAFE PREAMBLE %DIF PREAMBLE
\providecommand{\DIFdelbegin}{} %DIF PREAMBLE
\providecommand{\DIFdelend}{} %DIF PREAMBLE
%DIF FLOATSAFE PREAMBLE %DIF PREAMBLE
\providecommand{\DIFdelFL}[1]{\DIFdel{#1}} %DIF PREAMBLE
\providecommand{\DIFdelbeginFL}{} %DIF PREAMBLE
\providecommand{\DIFdelendFL}{} %DIF PREAMBLE
%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF

\begin{document}
\RCSRevision: \DIFdelbegin \DIFdel{1.2 }\DIFdelend \DIFaddbegin \DIFadd{1.8 }\DIFaddend 
Revision \RCSRevision.
\end{document}

-
I guess what I don't understand is the "regular expression" part of defining the macro. Specifically, how to match what comes after the first argument. In this case, I want #2 to be all of \DIFdelbegin \DIFdel{1.2 }\DIFdelend \DIFaddbegin \DIFadd{1.8 }\DIFaddend. Is there a way I can change the macro definition to accommodate this? –  Shaun Nov 7 '11 at 1:32
@Shaun: I don't use latexdiff-cvs, so I don't know exactly what you are after, but I have made a revision based on what seems to be the problem. –  Ryan Reich Nov 7 '11 at 3:30
Thanks Ryan. But this doesn't seem to work for me - something about running out of memory. Isn't the \edef\expandedRCS{#1}\expandafter\innerRCS\expandedRCS part recursively using \expandedRCS? –  Shaun Nov 7 '11 at 6:48
@Shaun: No, it doesn't expand recursively because \expandedRCS is set to #1; the \expandafter just places whatever #1 expanded to after \innerRCS. Your problem is actually that, in reality, the \DIFadd macro expands to something unexpandable (the \protect macro, whose point is to obstruct expansion). The reason it's there is that \DIFadd is set to print its argument in color, and this is not a macro-expansion-level thing, but a lowlevel command. Let me take a stab at correcting this. –  Ryan Reich Nov 7 '11 at 15:06
Hi @Ryan thanks again. But I think I might have failed to explain what my end goal was. I want two things 1) to define a macro that can parse RCS tags (e.g Revision, Date, Author, etc) so that they can be used in text. I.e. if the date tag is $Date: 2010/04/02 18:20:00$ then I want \RCSDate to print 2010/04/02 18:20:00 in the text. I know how to achieve this, but I don't know how to combine it with the second thing I want - 2) I want the RCS tags to print BOTH rcs tags (before and after replacement) like latexdiff does with other text changes (i.e red strikethrough and blue underline) –  Shaun Nov 9 '11 at 6:53