Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question
    
    
@Ephraim Ncory: Please note: My solution works only for pure strings, not sophisticated code inside –  Christian Hupfer Jun 12 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 at 7:42
3  
1  
@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 at 22:09

2 Answers 2

up vote 4 down vote accepted

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

share|improve this answer
    
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 at 7:58
    
@EphraimNcory It's not very clear. Do you want to have different classes of "saved environments"? –  egreg Jun 13 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 at 8:03
    
@EphraimNcory I think you should ask a new question, with more details explaining your needs. –  egreg Jun 13 at 8:05
    
i asked a new question with more details, hope you find time to help. –  Ephraim Ncory Jun 13 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{}%
\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

share|improve this answer
1  
The last version of environ allows for changing the macro the body is stored in. –  egreg Jun 12 at 7:44
    
@egreg: I will look into it and post another solution, eventually... –  Christian Hupfer Jun 12 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 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 at 8:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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