# Collecting contents of environment and store them for later retrieval

I want to store contents of an environment and add them to a macro or command I could easily retrieve them, but I do not want to use the collect package. Are there any alternatives?

\documentclass{article}
\usepackage{environ}
\usepackage{blindtext}

\NewEnviron{env}{
\global\let\content\BODY
%i want to add content to running list and later get whole contents
}

\begin{document}
\begin{env}
text text text\\
\end{env}

\blindtext

\begin{env}
moretext moretext more text\\
\end{env}

\end{document}

-
Does How keep a running list of strings and then process them one at a time answer your question? – Peter Grill Jun 12 '14 at 7:25
@Ephraim Ncory: Please note: My solution works only for pure strings, not sophisticated code inside – Christian Hupfer Jun 12 '14 at 7:34
@Christian Hupfer: just tested it and you are right, it doesnt allow sophisticated code inside, any way you could modify it to do so? thanx in advance. – Ephraim Ncory Jun 12 '14 at 7:42
– egreg Jun 12 '14 at 7:50
@EphraimNcory: I updated my version, please have a look. The outputting tcolorbox is just for eye-catching, nothing more, to show the combined content more nicely. – Christian Hupfer Jun 12 '14 at 22:09

You can print the saved environments by “name” or all of them.

\documentclass{article}
\usepackage{etex,environ,refcount}

\globtoksblk\savedenvtoks{1000}
\newcounter{savedenvcount}

\NewEnviron{savedenv}[1][]{%
\refstepcounter{savedenvcount}%
\if\relax\detokenize{#1}\relax
\else
\label{#1}%
\fi
\global\toks\numexpr\savedenvtoks+\value{savedenvcount}\relax=\expandafter{\BODY}%
}
\toks\savedenvtoks={??}

\newcommand{\printsaved}[1]{%
\the\toks\numexpr\savedenvtoks+\getrefnumber{#1}\relax
}

\makeatletter
\newcommand{\printallsaved}{%
\@tempcnta=\z@
\loop
\ifnum\@tempcnta<\value{savedenvcount}
\the\toks\numexpr\savedenvtoks+\@tempcnta\relax\par
\repeat
}
\makeatother

\begin{document}

\begin{savedenv}[a]
Something for a
\end{savedenv}

\begin{savedenv}[b]
Something for b
\end{savedenv}

\begin{savedenv}
Something with no label
\end{savedenv}

\textbf{Let's print them}

This is a: \printsaved{a}

This is b: \printsaved{b}

\textbf{Print all of them}

\printallsaved

\end{document}


This requires two runs (when the saved environments change), because of the usage of \label. You can save up to 1000 environments, but you can change the number in the obvious way. Don't try setting the number to much more than 30000.

-
how about if i want to create multiple \globtoksblk eg \savedenvtoks1{10}, need help making savedenv to take a \globtoksblk parameter and also for printallsaved to take a parameter indicating which \globtoksblk...? – Ephraim Ncory Jun 13 '14 at 7:58
@EphraimNcory It's not very clear. Do you want to have different classes of "saved environments"? – egreg Jun 13 '14 at 8:00
yeah something like that, i want to create multiple tok blocks and be able to get their toks. – Ephraim Ncory Jun 13 '14 at 8:03
@EphraimNcory I think you should ask a new question, with more details explaining your needs. – egreg Jun 13 '14 at 8:05
i asked a new question with more details, hope you find time to help. – Ephraim Ncory Jun 13 '14 at 10:12

I suggest to use newenviron package instead of environ, because it defines a \envnamebody command.

Note: Do not call your environment env, because it will collide with the implicit \envbody command always being defined for any environment by newenviron.

After changing to that, one can use the etoolbox - list commands \listgadd etc. and forlistloop do add the current content to the list and processing later on, e.g. printing it.

You need a 'printing' command, I named it \showlist.

The content is glued together without any spacing between at the end of the environment code.

Edited version -- glueing 'arbitrary(?)' texts together

\documentclass{article}
\usepackage{tcolorbox}
\usepackage{newenviron}
\usepackage{blindtext}
\usepackage{etoolbox}

\def\mylist{}%

\newrobustcmd{\myexpandingcommand}[1]{%
}%

\newenviron{content}{%
}{%
\noindent\textbf{\LARGE \textcolor{blue}{Environment content}}  % Remove later on!

\noindent\envbody%
\expandafter\myexpandingcommand\expandafter{\envbody}%
\endgraf\bigskip\bigskip% Can be removed
}%

% Macro showing the current list element%
\newrobustcmd{\showlist}[1]{%
#1%
}%

\begin{document}

\begin{content}  % Store some content%
\blindtext%
\end{content}

\noindent\textbf{\LARGE \textcolor{green}{Text content outside of environment}}  % Can be removed, just for diagnosis/test

\noindent\blindtext
\endgraf\bigskip

\begin{content}

\textbf{\textcolor{red}{Even more text and now even some math: \huge $$\displaystyle\int\limits^{b}_{a} f(x) dx$$}}%

\end{content}

\begin{center}
\begin{tcolorbox}[width=0.8\textwidth,title={Now the combined content of the list}]
\forlistloop{\showlist}{\mylist}%
\end{tcolorbox}%
\end{center}

\end{document}


-
The last version of environ allows for changing the macro the body is stored in. – egreg Jun 12 '14 at 7:44
@egreg: I will look into it and post another solution, eventually... – Christian Hupfer Jun 12 '14 at 9:03
i need to create more lists which could be different but \myexpandingcommand will only work for \mylist, help. – Ephraim Ncory Jun 13 '14 at 8:02
@EphraimNcory: I know, there is some problem with that, I will look after later on, but I had no idea, that you need more than one list, it was not stated in your question – Christian Hupfer Jun 13 '14 at 8:06