2

According to filecontents' manual (version number v1.3, last revised 2011/10/08, p.1) :

(The comment about filecontents being valid only before \documentclass is, in fact, untrue. filecontents is allowed anywhere in the document’s preamble.)

The filecontents package provides a hacked-up version of the filecontents and filecontents* environments that lifts the two restrictions stated above, namely that existing files are never overwritten and that filecontents must be used before the \documentclass declaration (really, the \begin{document}). filecontents is therefore a more convenient way to write external files from within a LaTeX document than is provided by default by the LaTeX 2ε kernel.

However, the following code :

\begin{filecontents}{a}
a
\end{filecontents}
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{b}
b
\end{filecontents}
\begin{document}
\begin{filecontents}{c}
c
\end{filecontents}
This is a test.
\end{document}
\begin{filecontents}{d}
d
\end{filecontents}

will produce only three files and three warnings:

LaTeX Warning: Writing file `./a'.
LaTeX Warning: Writing file `./b'.
LaTeX Warning: Writing file `./c'.

Is everything after the \end{document} discarded? Is there any way to bypass this limitation? Shouldn't the documentation of filecontents be more specific?

Clément
  • 5,591
  • 2
    By rule everything after \end{document} is discarded, because \@@end (the primitive \end) command is executed. Nothing to do about it, sorry. – egreg May 19 '15 at 23:55
  • 1
    yes \end{document} stops the job and causes the final statistics to be printed and the pdf to be finalised – David Carlisle May 19 '15 at 23:55
  • 2
    While I do not consider myself a TeX expert, if I remember my reading of The TeXbook correctly, the parsing completely stops at \end{document} for a LaTeX file or at \bye for a TeX file. By the way, \end{document} is just a wrapper for \bye with some very necessary housecleaning at the end of the compile. – R. Schumacher May 19 '15 at 23:56
  • 3
    Perhaps the filecontents documentation should indeed be revised for this technical note. I have to ask, though: why would you want this? – Sean Allred May 20 '15 at 01:36
  • @SeanAllred I'm writing a script to "compact" a whole tex document into one single file, to ease upload, sharing, storage and deposit on e-print services (see http://tex.stackexchange.com/q/184152/34551). I enclose the bib file into a tex file thanks to filecontents. The trick is that if that filecontents is at the beginning on the file, arXiv assume the document is a bib file and refuse to compile it. One obvious alternative would have been to concatenate the bib file at the end, rather than at the beginning. – Clément May 20 '15 at 07:44
  • @SeanAllred Yes, exactly ;-). But I was really curious whereas \end{document} was corresponding to a strict "stop reading the source file". And apart from filecontents, I never saw any command pretending that they were working anywhere in the source file. So it might be more like "I found a very special case that interest me". – Clément May 20 '15 at 12:42

1 Answers1

5

As others have said in the comments, \end{document} causes TeX execution to end by calling \@@end, as we can see in latex.ltx:3900:

\def\enddocument{%
   \let\AtEndDocument\@firstofone
   \@enddocumenthook
   \@checkend{document}%
   \clearpage
   \begingroup
     % 24 lines omitted
   \endgroup
   \deadcycles\z@\@@end}

After \@@end is seen/expanded/processed, TeX simply stops reading the file. The final {filecontents} has no hope of being seen.

Heiko noted in the comments that you can pull a trick to have TeX simply continue on after \end{document}, but beware – hic sunt dracones :)

\documentclass{article}
\usepackage{filecontents}
\begin{document}
hello, world

\makeatletter
\let\@@sean@end\@@end
\let\@@end\begingroup
\end{document}
\begin{filecontents}{d}
d
\end{filecontents}
\@@sean@end

This creates four files: ./{a,b,c,d}.

Heiko notes:

LaTeX does some trickery to get rid of the group for document by the environment code. Otherwise, putting the document in a group would raise memory issues, when TeX wants to restore all local assignments after the group. But since \end{document} is the end of the TeX job, there is no point restoring assignments afterwards.

I'm still willing to say that attempting to engineer this behavior out of LaTeX is a futile effort or, at the very least, effort better well spent asking why the behavior is needed in the first place.

Sean Allred
  • 27,421
  • 2
    \let\@@end\begingroup instead of \let\@@end\relax fixes the problem. LaTeX does some trickery to get rid of the group for document by the environment code. Otherwise, putting the document in a group would raise memory issues, when TeX wants to restore all local assignments after the group. But since \end{document} is the end of the TeX job, there is no point restoring assignments afterwards. – Heiko Oberdiek May 20 '15 at 06:30
  • @HeikoOberdiek Thanks! I probably should have thought of that when TeX was complaining about the extra \endgroup, but the memory-management information is very interesting and certainly not something I knew :) – Sean Allred May 20 '15 at 11:13