# Processing the body of an environment multiple times

Dear all, I am new to package writing (LaTeX2e) and to this forum, and I probably read to much of the TeXBook and not enough on LaTeX.

My package works, except that verbatim is verboten. Given a user input of

\begin{file}
foo1 (say, an exercise)
\begin{body}
\begin{body}
long explanation of the answer to foo1
\end{body}
\end{body}

foo2 (say, a theorem)
\begin{body}
long explanation of foo2 (say, a very long
proof that we want to put in an Appendix)
\end{body}
\end{file}


I typeset the content of the head environments, followed by the content of the body environments, followed by the body of the body, etc:

  foo1
foo2

long explanation of foo2

long explanation of the answer to foo1


with links pointing from each item in one part to the corresponding item of the previous and next parts. The links are (almost) easy to get with some clever numbering.

The file environment is only there to allow me to read its contents multiple times: I use Will Robertson's environ.sty, which defines environments that gobble their content and can use it multiple times. Unfortunately, since the content is read before being executed, catcodes are fixed, and verbatim fails. Also, this is quite slow, and memory consuming.

I see three other ways of doing it:

• 2. I guess I could write a custom output routine: typeset all heads in parallel of all bodys in two (or more in case of nesting) boxes, and only then cut into pages. This would be incompatible at least with the multicols package (and I would be limited to ~20 pages stored in a single box: maximum length ~6m).
• 3. Write the content of the bodys verbatim to an auxiliary file. Then load the auxiliary file and execute its content. I am not yet confortable with the read and write possibilities in (La)TeX, but this might be the way to go. Can one write a file and read from it in the same run?
• 4. My last idea is to use the docstrip trickery: make \end{file} input the document again, with some booleans/counters set differently. In order to ignore everything until the \begin{file}, I need to set quite a few catcodes. Reaching this \begin{file}, I need to switch back, and parse the \begin and \end. Changing catcodes like this is probably not great for compatibility.

Also, nesting of head/body makes some of these approaches harder.

Which one (or more) of the four approaches would you recommend?

-
I would go for the auxiliary file solution. –  Yiannis Lazarides Dec 29 '10 at 3:36
I agree with Yiannis that writing to an aux.file seems the best bet. Possibly, writing both head and body envs to separate files which are then both input once is easier than switching back and forth at every end{file}. (It's unclear whether all your document consists just of file and body environments.) –  Ulrich Schwarz Dec 29 '10 at 5:39
@Ulrich: a typical document would just have one file environment enclosing everything. In fact, I wouldn't mind getting rid of that, keeping only the head s and body s. Would inputting a/several file/s \AtEndDocument be reasonable? –  Bruno Le Floch Dec 29 '10 at 13:27

Summarising what others have put as comments, the best approach here is likely to be to write the content of the environment to a separate file, then read back as appropriate. To allow verbatim material, you'll probably want to do this in a verbatim-like manner. Obvious places to look for inspiration are packages such as listings and beamer, or as Aditya says the ConTeXt implementation (I guess Mark II as you seem to be looking for a TeX-based solution).

Of course, an alternative would be to separate out your input yourself and read in with appropriate parts skipped. This would have a master file, one or more additional files and use something like the comment package to deactivate some parts selectively.

What might be useful is a little more detail on the nature of the real problem. It's not entirely clear to me the full nature of these environments.

-
I updated my question with a more precise example. I should maybe extend environ.sty to allow environments that write their content verbatim to a file before using it. A first step might be to code a \ReadVerbatimUntil command that acts as follows: \ReadVerbatimUntil[label]|begin|end| some text begin end more stuff end. This would store some text begin end more stuff in an auxiliary file \jobname.\value{...}.rvu, which can then be used, say, with \InputRvu[label]. I think many separate files are needed, if e.g., these commands are nested. –  Bruno Le Floch Dec 29 '10 at 14:35
So, I now have written a command \verbify that does the following: \verbify\footnote redefines \footnote to accept any content (including \verb, \begin{verbatim}, \catcode,...), as long as it has balanced braces. Of course, any command can be \verbify-ed. I will work on \verbifying environments next. The code is of course too long for a comment here. Should I make it a package and submit to CTAN? –  Bruno Le Floch Dec 30 '10 at 6:53

In ConTeXt, this can be easily achieved using blocks. As the following example shows, verbatim works fine inside blocks. Internally, in MkII, the contents of blocks are stored in an external file \jobname.tub while in MkIV, they are stored in memory. See strc-blk.(mkii|mkiv|lua) for the code.

\defineblock[HEAD]
\defineblock[BODY]

\starttext
\hideblocks[BODY] %Default

foo1
\starttyping
Some # verbatim & text
\stoptyping

\beginBODY
body1
\endBODY

foo2

\beginBODY
body2
\endBODY

\page

% Show only BODY
\processblocks[BODY]

\page

% Show both HEAD and BODY