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.
\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 howfilecontents
works, it just uses a file stream for its output rather than the log file.\newcommand
, but struggle with defining an environment that reads its body without shipping outenviron
package (at least if your goal is to collect the contents of the env in order to deal with it later).filecontents
reads the contents line by line, stopping when it finds a line that starts with\end{filecontents}
. It's just a different form ofverbatim
: instead of printing the line,filecontents
sends it to the output file stream.