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.

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}
  \begin{head}
    foo1 (say, an exercise)
  \end{head}
  \begin{body}
    \begin{head} 
      short answer to foo1
    \end{head}
    \begin{body}
      long explanation of the answer to foo1
    \end{body}
  \end{body}

  \begin{head}
    foo2 (say, a theorem)
  \end{head}
  \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

  short answer to foo1
  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 `head`s in parallel of all `body`s 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 `body`s 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?

share|improve this question
    
I would go for the auxiliary file solution. –  Yiannis Lazarides Dec 29 '10 at 3:36
1  
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
add comment

2 Answers

up vote 3 down vote accepted

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.

share|improve this answer
    
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
add comment

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
\keepblocks[HEAD]
\hideblocks[BODY] %Default


\beginHEAD
foo1
\starttyping
  Some # verbatim & text
\stoptyping
\endHEAD

\beginBODY
body1
\endBODY

\beginHEAD
foo2
\endHEAD

\beginBODY
body2
\endBODY

\page

% Show only BODY
\processblocks[BODY]

\page

% Show both HEAD and BODY
\processblocks[HEAD,BODY]

\stoptext
share|improve this answer
    
Unfortunately, I don't know much about ConTeXt. I will look at their implementation, though. –  Bruno Le Floch Dec 29 '10 at 15:27
add comment

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.