[Tex/LaTex] Collecting contents of environment and store them for later retrieval

content-replicationenvironmentsmacros

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}

Best Answer

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

This requires two runs (when the saved environments change), because of the usage of \label.

Update

Since etex methods are now discouraged, here's a reimplementation with expl3.

\documentclass{article}
\usepackage{refcount}

\ExplSyntaxOn

\newcounter{savedenv}
\seq_new:N \g_ephraim_savedenv_seq

\NewDocumentEnvironment{savedenv}{ o +b }
 {
  \refstepcounter{savedenv}
  \IfValueT{#1}{\label{savedenv@#1}}
  \seq_gput_right:Nn \g_ephraim_savedenv_seq { #2 }
}{}

\NewDocumentCommand{\printsaved}{m}
 {% #1 is a list of labels
  \clist_map_inline:nn { #1 }
   {
    \seq_item:Nn \g_ephraim_savedenv_seq { \getrefnumber{savedenv@##1} }
    \par
   }
 }
\NewDocumentCommand{\printallsaved}{}
 {
  \seq_use:Nn \g_ephraim_savedenv_seq { \par }
 }


\ExplSyntaxOff

\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{Let's print them in different order}

\printsaved{b,a}

\textbf{Print all of them}

\printallsaved

\end{document}

enter image description here

Original code

\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}
    \advance\@tempcnta\@ne
    \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}

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.

enter image description here

Related Question