Collecting contents of environment and store them for later retrieval
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{}%
\listadd{\mylist}{}% Initialize list
\newrobustcmd{\myexpandingcommand}[1]{%
\listgadd{\mylist}{#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}
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}
\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}
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.
I leave this answer here because they were inspirational for the creation of the scontents
package. With this package it is quite easy to do what you are looking for. Everything stored in memory including verbatim content. If you wish you can also save the content in external files using the key write-env=file.tex
. I am always inclined to store the content in memory:)
\documentclass{article}
\usepackage{scontents}
\pagestyle{empty}
\begin{document}
\begin{scontents}[store-env=main]
Something for main A.
\end{scontents}
\begin{scontents}[store-env=main]
Something for \verb|main B|.
\end{scontents}
\begin{scontents}[store-env=other]
Something for \verb|other|.
\end{scontents}
\textbf{Let's print them}
This is first stored in main: \getstored[1]{main}\par
This is second stored in main: \getstored[2]{main}\par
This is stored in other: \getstored[1]{other}
\textbf{Print all of stored in main}\par
\foreachsc[sep={\\[10pt]}]{main}
\end{document}
Saludos