# Why can't filecontents work in a macro

I am trying to output some text in a file. I use filecontents and it works nicely. However, if I put the filecontents environment inside a macro, it only ouputs the comments but not the text when the macro is called.

Here is an example:

\documentclass{article}
\usepackage{filecontents}
\usepackage{etoolbox}

\begin{filecontents}{\jobname.abc}
this gets in the file
}
\end{filecontents}

\newcommand{\toto}{
\begin{filecontents}{\jobname.def}
this won't...
\end{filecontents}
}

\begin{document}

\toto

\end{document}


I also tried using the filecontents in the \AtEndDocument hook, but again, nothing is found in the file. To that end, I added in the preamble of the above code

  \AtEndDocument{
\typeout{AtEndDocument is being executed}
\begin{filecontents}{\jobname.ghi}
this won't either...
\end{filecontents}
}


In all three cases, I have the warning saying that the file is created/replaced:

LaTeX Warning: Overwriting file xxx.ghi


Anyone has any clue what is going on? How this could be corrected so that contents gets to the files?

• Well, the filecontents is supposed to only be used in the preamble, so writing it at the end of the document seems likely to fail. You are probably better off writing to an external file directly (or using a specialized package). – jon Feb 23 '16 at 4:23
• @jon egreg told me it should be used only before \documentclass. – cfr Feb 23 '16 at 12:28
• @cfr -- That was the official recommendation, but it does work in the preamble as is now noted (cf. §.8.11 of LaTeX2e). Of course, loading the filecontents package is usually recommended beyond the most simple applications.... – jon Feb 23 '16 at 18:47
• @jon It doesn't always work in the preamble. It was because it didn't for me that egreg told me it should come prior to that with \RequirePackage{} if necessary. It depends on the content of the file. – cfr Feb 23 '16 at 20:23
• @cfr -- Interesting. Is this a question here? And is that true even with the package? And should the (admittedly unofficial [not official as I miswrote!]) LaTeX2e manual maintainers be informed of this? As far as I remember, it used to be said that the filecontents environement should only be used in the way you say.... – jon Feb 23 '16 at 22:34

You're better off creating an output stream that you append stuff to; newfile provides this functionality:

\documentclass{article}
\usepackage{filecontents,newfile}

\begin{filecontents*}{\jobname.abc}
this gets in the file \jobname.abc
\end{filecontents*}

\newoutputstream{mystream}
\openoutputfile{\jobname.def}{mystream}
\newcommand{\toto}{%
\addtostream{mystream}{this will be written to \jobname.def.}%
}

\begin{document}

Some text. \toto

\end{document}


The written files - \jobname.abc and \jobname.def - contain the following:

• latex_stuff.abc

this gets in the file latex_stuff.abc.

• latex_stuff.def

this will be written to latex_stuff.def.

• The answer of @egreg explains well the cause of the problem, but this answer gave a neat alternative which could be expanded to solve my problem. Thanks Werner – Denis Cousineau Feb 23 '16 at 13:47
• \jobname is not expanded in the contents of abc (created with filecontents*), it seems. – Georges Dupéron Feb 8 at 16:32

There are various reasons why it fails.

First and most important reason: when tokens are absorbed as the argument to another command, including \newcommand and \AtEndDocument, they receive their category code (if not control sequences) and endlines are converted to spaces or \par tokens.

When \begin{filecontents} is being processed, several changes are made, which are quite similar to what happens for verbatim (not completely the same); for instance you don't want that the backslash maintains its usual meaning, nor you want that an endline is converted to a space.

For this reason, the closing \end{filecontents} which TeX looks for is not 15 tokens

\end • { f • i • l • e • c • o • n • t • e • n • t • s • }


but 18:

\ • e • n • d • { f • i • l • e • c • o • n • t • e • n • t • s • }


where the backslash and the braces have category code 12; actually the lookup also includes the endline (which must be an active character, with a very particular meaning).

There are several other issues, particularly in connection with non ASCII characters.

Can this be corrected? Not in full generality.

Chances are that you don't really need filecontents, because writing a file, with a given content, at the beginning or at the end of processing should not make any difference. So probably you're looking at the wrong tool for what you have in mind.

• Could you explain the significance of category code 12? To me, category codes are a mysterious black box supposed to explain any kind of strange behaviour. (But maybe there's another question you could link that part of the explanation to instead? I suspect the answer might be too large for this answer, even just asking about code 12.) – cfr Feb 23 '16 at 12:31