A trick for triggering expansion is using \romannumeral
:
When due to \romannumeral
(La)TeX does gather together a sequence of digits trailed by a space as the number which it has to convert, expandable tokens get expanded.
When in the end a number is gathered together which is not positive, as the result of the conversion (La)TeX will not deliver any token at all.
Thus one can nicely (ab?)use \romannumeral
for triggering a lot of expansion-work and flipping-arguments-around-work as long as one ensures that in the end \romannumeral
will not find a positive number.
Here is a variant of egreg's answer which does with \romannumeral
and \exchange
instead of \xdef
and \unexpanded
.
\documentclass{article}
\usepackage{environ}
\newcommand\exchange[2]{#2#1}
\NewEnviron{exercise}{%
\expandafter\gdef\expandafter\savedexercises\expandafter{%
\romannumeral0\expandafter\exchange\expandafter{\BODY}{%
\exchange{ }{\expandafter}\savedexercises
\begin{printedexercise}%
}%
\end{printedexercise}%
}%
}
\newcommand{\printexercises}{%
\savedexercises
\gdef\savedexercises{}%
}
\newcommand{\savedexercises}{}
\newtheorem{printedexercise}{Exercise}
\begin{document}
Here we talk about addition and show that $1+1=2$.
\begin{exercise}
Compute $1+2$
\end{exercise}
Here we talk about integrals.
\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$
\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}
Now we can print the exercises.
\printexercises
\end{document}

If you wish to wrap the name of the macro that is to be defined into \csname
..\endcsname
, i.e., if you wish to use \csname savedexercises\endcsname
rather than \savedexercises
, you can take advantage of the fact that (La)TeX does expand expandable tokens while due to \csname
gathering the name of a control sequence token and hereby searching for the matching \endcsname
:
\documentclass{article}
\usepackage{environ}
\newcommand\exchange[2]{#2#1}
\NewEnviron{exercise}{%
\expandafter\gdef\csname savedexercises\expandafter\endcsname\expandafter{%
\romannumeral0\expandafter\exchange\expandafter{\BODY}{%
\exchange{ }{\expandafter\expandafter\expandafter}\csname savedexercises\endcsname
\begin{printedexercise}%
}%
\end{printedexercise}%
}%
}
\newcommand{\printexercises}{%
\csname savedexercises\endcsname
\expandafter\gdef\csname savedexercises\endcsname{}%
}
\expandafter\newcommand\expandafter{\csname savedexercises\endcsname}{}
\newtheorem{printedexercise}{Exercise}
\begin{document}
Here we talk about addition and show that $1+1=2$.
\begin{exercise}
Compute $1+2$
\end{exercise}
Here we talk about integrals.
\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$
\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}
Now we can print the exercises.
\printexercises
\end{document}

Be aware that with the approaches presented by now you cannot use \printexercises
for having exercises occur in arbitrary places. You can have exercises occur only in places of the document which in the source correspond to places behind the exercise-environments.
Perhaps an environment which does read its content under verbatim-catcode-régime for unexpanded-writing it to .aux-file in a way where from the .aux-file it gets read back under verbatim-catcode-régime also for defining a macro where \scantokens
will be applied to, and thus some sort of re-implementation of the \label
-\ref
-mechanism or of the \tableofcontents
-mechanism for verbatimized stuff might make it possible to make exercises printable throughout the entire document.
Implementing such a mechanism might be a nice challenge. But before taking that into consideration at all, exact information is needed on the intended usage and the desired "user-interface", i.e., what additional things you wish to be able to specify in which ways, etc, ...
\def
?\let
does what it should do: use the the next token.\NewEnviron{testc}{\global\expandafter\def\csname foo\endcsname{\BODY}}
, I get:! Undefined control sequence. \foo ->\BODY
\global\expandafter\let\csname bar\endcsname\BODY
: it's entirely normal TeX.