16

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}
6

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.

enter image description here

  • 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
8

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}

enter image description here

  • 1
    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... – user31729 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 – user31729 Jun 13 '14 at 8:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.