# Collecting contents of LaTeX environment

I have the following for collecting contents of an environment and printing them later, it works but for my real task i want to use the environ package because i need to be able to have access to \BODY. How can i produce the same output with \NewEnviron instead of \newenvironment used?

\documentclass{article}
\usepackage{collect}
\usepackage{environ}

\definecollection{notes}

%works but not what i realy want i need access to \BODY and for that i cant  use \newenvironment command
\makeatletter
\newenvironment{note}
{\@nameuse{collect}{notes}{\par\noindent}{\par}{}{}}
{\@nameuse{endcollect}}
\makeatother

%what i realy want
%\NewEnviron{note}{
%\@nameuse{collect}{notes}{\par\noindent}{\par}{}{}
%\BODY
%\@nameuse{endcollect}
%}

\begin{document}

\begin{note}
First note
\end{note}

\begin{note}
Second note
\end{note}

\begin{note}
Third note
\end{note}

\section{collected}
\includecollection{notes}
\end{document}

-
One of the many answers to questions tagged content-replication may help solve your problem. – Ethan Bolker Jun 27 '14 at 13:14

## 2 Answers

If your collected notes are only needed at the end of the document, you can avoid writing out files: just use token registers.

\documentclass{article}
\usepackage{environ}

\newtoks\mainnotetoks
\newtoks\tempnotetoks
\newtoks\prenotetoks
\newtoks\postnotetoks

\NewEnviron{note}{%
\tempnotetoks=\expandafter{\BODY}%
\edef\notetemp{%
\the\mainnotetoks % what was already stored
\the\prenotetoks % text before the new note
\the\tempnotetoks % the current note
\the\postnotetoks % text after the new note
}%
% update \mainnotetoks
\global\mainnotetoks=\expandafter{\notetemp}%
}
\newcommand\includenotes{\the\mainnotetoks}

% set the pre and post note
\prenotetoks={\par\noindent}
\postnotetoks={\par}

\begin{document}

Here we have a first note.
\begin{note}
First note
\end{note}

Here we have a second note.
\begin{note}
Second note
\end{note}

Here we have a third note.
\begin{note}
Third note
\end{note}

\section{collected}
\includenotes
\end{document}


-

If you don't stick to the collect package, there is just the way to directly write the \BODY command to a file and expand it there, afterwards reread that file:

\documentclass{article}
\usepackage{collect}
\usepackage{xcolor}
\usepackage{amsmath}
\usepackage{environ}

\definecollection{notes}

\newwrite\collecthandle%

\AtBeginDocument{%
\immediate\openout\collecthandle=\jobname.mynotes%
}

\newcommand{\CollectNotes}[1]{%
\immediate\closeout\collecthandle%
\IfFileExists{#1}{\input{#1}}{Nope}%
}%

\AtEndDocument{%
\immediate\closeout\collecthandle% Close it anyway
}%

%works but not what i realy want i need access to \BODY and for that i cant  use \newenvironment command
\makeatletter
\newenvironment{note}
{\@nameuse{collect}{notes}{\par\noindent}{\par}{}{}}
{\@nameuse{endcollect}}
\makeatother

%what i realy want
\NewEnviron{Note}{%
\immediate\write\collecthandle{%
\unexpanded\expandafter{\expandafter{\BODY}}%
}%
\immediate\write\collecthandle{%
\string\newline
}%
}%

\begin{document}

\begin{Note}
First Note
\end{Note}

\begin{Note}
Second Note
\end{Note}

\begin{Note}
Third Note
\end{Note}

\begin{Note}
fourth Note with coloured mathematical markup \textcolor{red}{$\int\limits \left({x^2}\right)dx = \dfrac{1}{3}x^3 +C$}
and even with \textbf{bold font}
\end{Note}

\section{collected}
\CollectNotes{\jobname.mynotes}
\end{document}


-