18

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.

5
  • 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
    Commented Mar 27, 2013 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
    Commented Mar 27, 2013 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
    Commented Mar 27, 2013 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
    Commented Mar 27, 2013 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
    Commented Mar 27, 2013 at 23:05

1 Answer 1

15

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.

2
  • 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
    Commented Nov 20, 2018 at 21:04
  • @Diaa Perhaps have a try on the filecontentsdef package that seems to do what you are looking for (not tested, as I use my own more involved version)
    – Jhor
    Commented May 22, 2021 at 13:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .