17

We all know filecontents.sty can do

\documentclass{article}

\usepackage{filecontents}

\begin{document}

Hello World

\begin{filecontents}{dummy.txt}
No one will read this if I don't use it elsewhere
\end{filecontents}

\end{document}

But since the filecontents.sty's code is pretty advanced chemistry, I do not get how it prevents including No one will read this if I don't use it elsewhere.

  • If you do \immediate\write20{This won't go in the PDF file}, the text won't appear in the PDF output, but only in the log file (and on the terminal). This is basically how filecontents works, it just uses a file stream for its output rather than the log file. – egreg Mar 27 '13 at 16:42
  • Clarification: I know how to do this with \newcommand, but struggle with defining an environment that reads its body without shipping out – arney Mar 27 '13 at 16:45
  • See the environ package (at least if your goal is to collect the contents of the env in order to deal with it later). – daleif Mar 27 '13 at 16:52
  • 1
    @arney filecontents reads the contents line by line, stopping when it finds a line that starts with \end{filecontents}. It's just a different form of verbatim: instead of printing the line, filecontents sends it to the output file stream. – egreg Mar 27 '13 at 16:54
  • @egrep Yes, I know the tactic, but which commands do actually cause TeX to "change its stdout". I cannot see through all this plainTeX and multi-@-commands. – arney Mar 27 '13 at 23:05
14

The basic working of the filecontents environment is the same as verbatim: every character is made printable and the end of line character is made active so that LaTeX can define it to delimit an argument which will be an entire line of input.

First the environment checks whether the named file already exists and, in this case, does nothing else than discarding everything up to \end{filecontents}. Otherwise it opens an output stream and writes some information lines (this is suppressed with \begin{filecontents*}.

Then it reads one line at a time as roughly explained above; if this line turns out to be \end{filecontents} (or \end{filecontents*} for the variant environment), the write stream is closed, otherwise the line is written to the output file.

A possible more efficient strategy is outlined in the documentation of the verbatim package, where the definition of a possible verbatimwrite environment is shown. I used the same in my abc package.

  • Sorry for the offtopic question, but is it possible to store some data inside a macro instead of a physical file? For example, can I have something like \begin{filecontents*}{\mydata} instead of \begin{filecontents*}{mydata.dat}? – Diaa Nov 20 '18 at 21:04

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.