# How to expand arguments of an unexpanded macro?

I have fallen into a hole of never-expanding macros and don't feel that I will be able to climb out without any help.

In general, I think that my question can be formulated as:

What do I do when I have a macro \x that I do not want to expand but wants to supply it with an argument \y that I do want to expand?

That is not really a well-defined question, so I have constructed an MWE that is printed in its entirety after some explanation. I will start by explaining the background of the problem, in the hopes that it will make it clearer what I'm trying to do. I have created a sort of cut and paste function using the aux-file to be able to duplicate text across a document (idea taken from this answer: https://tex.stackexchange.com/a/150839/214956)

\makeatletter
\newcommand\ctrlC[1]{
\immediate\write\@auxout{\unexpanded{\global\long\@namedef{aux_clipboard}{#1}}}%
#1
}
\newcommand\ctrlV{
\ifcsname aux_clipboard\endcsname
\@nameuse{aux_clipboard}
\else
??''
\fi
}
\makeatother


(I removed a lot of functionality for this MWE.) The idea is that the command

ctrlC{This is a test}


will create the following line in the aux-file:

\global \long \@namedef {aux_clipboard}{This is a test}


The ctrlV function on the other hand can search for the "csname: aux_clipboard" in the aux-file, and print the stored text if found.

That works great.

However, I want to be able to duplicate text from theorem-environments, and to automate this, I came up with the following (using the environ-package to got control of the text-body of the environment with the variable \BODY) - which is the MWE of my problem:

\documentclass{article}
\usepackage{environ}

\makeatletter
\newcommand\ctrlC[1]{
\immediate\write\@auxout{\unexpanded{\global\long\@namedef{aux_clipboard}{#1}}}%
#1
}
\newcommand\ctrlV{
\ifcsname aux_clipboard\endcsname
\@nameuse{aux_clipboard}
\else
??''
\fi
}
\makeatother

\NewEnviron{foo}[1]{
\ctrlC{\BODY}
}
\begin{document}

\begin{foo}{a}
This is a test.
\end{foo}

\ctrlV

\end{document}


However, this doesn't work since \BODY is not expanded. The aux-file looks like this:

\global \long \@namedef {aux_clipboard}{\BODY }


resulting in the error (which is obvious since ctrlV has no idea what \BODY is):

! Undefined control sequence. \aux_clipboard ->\BODY

The reason behind the error is on the line:

\immediate\write\@auxout{\unexpanded{\global\long\@namedef{aux_clipboard}{#1}}}


where I want to not expand @namedef to \def, but I want to expand #1 (which is \BODY) to the text "This is a test". In summary, I feel like an idiot and can't figure out how to expand \BODY before it is written to the aux-file...

I would be very happy if someone could give me an idea of how to solve this specific problem, as well as if someone could give a general answer to my original fuzzy question. Thanks in advance!

You want to expand \BODY before passing it to \ctrlC:

\documentclass{article}
\usepackage{environ}

\makeatletter
\newcommand\ctrlC[1]{%
\immediate\write\@auxout{%
\unexpanded{\global\long\@namedef{aux_clipboard}{#1}}%
}%
#1%
}
\newcommand\ctrlV{%
\ifcsname aux_clipboard\endcsname
\@nameuse{aux_clipboard}%
\else
??''%
\fi
}
\makeatother

\NewEnviron{foo}[1]{%
\expandafter\ctrlC\expandafter{\BODY}%
}

\begin{document}

\begin{foo}{a}
This is a test.
\end{foo}

\ctrlV

\end{document}


This is the contents of the generated .aux file:

\relax
\global \long \@namedef {aux_clipboard}{This is a test.}


I've added several missing % characters.

An expl3 version:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\ctrlC}{m}
{
\iow_now:cn { @auxout }
{
\global\long\@namedef{aux_clipboard}{#1}
}
#1
}

\NewDocumentCommand{\ctrlV}{}
{
\cs_if_exist_use:cF { aux_clipboard } { ??'' }
}
\ExplSyntaxOff

\NewDocumentEnvironment{foo}{mb}
{\ctrlC{#2}}
{}

\begin{document}

\begin{foo}{a}
This is a test.
\end{foo}

\ctrlV

\end{document}

• Thanks a lot, this solved my problem! I guess this answer circumvents my general fuzzy question, as you very nicely expanded the variable before passing it the problematic function - if the situation was different and we couldn't expand the variable beforehand, do you know if it would be possible to expand \y while not expanding \x in something like: \unexpanded\x#1\y (maybe with same clever combination of several \expandafter). I realize that you imply that expl3 would be a better solution, where such a situation might never occur. – Gustahl May 7 at 19:12
• @Gustahl The question you pose cannot be answered in generality: what you place in \unexpanded is not expanded at the time of a \write, So you need to expand what you need before passing it to \write. Case by case strategy applies. – egreg May 7 at 20:23