How can one write the body of an environment verbatim to an external file. I tried the following but get problems if the body contains undefined macros (error) or e.g. a %
(disappears in the output).
Try 1
Using environ
to get the environment content.
\ProvidesPackage{tofile1}
\RequirePackage{environ}
% counter for external files
\newcounter{TF@File}
\newwrite\TF@out
\NewEnviron{tofile}{%
\stepcounter{TF@File}
\edef\TF@outFile{ext-\jobname-\theTF@File.tex}
\typeout{Name: \TF@outFile}
\immediate\openout\TF@out=\TF@outFile
\typeout{\TF@outFile\space opened}
\immediate\write\TF@out{\BODY}
\typeout{\TF@outFile\space written}
\immediate\closeout\TF@out
\typeout{\TF@outFile\space closed}
}
% test.tex
\documentclass{article}
\usepackage{tofile1}
\begin{document}
Test
\begin{tofile}
That's {a short Test}
which works
but ignores line breaks
\end{tofile}
Text
\begin{tofile}
\xx That's {another Test}%
This one doesn't work ...
it gives an error because \xx is undefined
\end{tofile}
\end{document}
This one creates the two desired files ext-test-1.tex
and ext-test-1.tex
but linebreaks are ignored and an undefined control sequence (\xx
) causes an error. Furthermore the percent char is interpreted as comment not as simple character. I guess come catcode magic could help.
Try 2
Using the filecontents
package.
\ProvidesPackage{tofile2}
\RequirePackage{environ}
\RequirePackage{filecontents}
% counter for external files
\newcounter{TF@File}
\newwrite\TF@out
\newenvironment{tofile}{%
\stepcounter{TF@File}
\edef\TF@outFile{ext-\jobname-\theTF@File.tex}
\begin{filecontents}{\TF@outFile}
}{
\end{filecontents}
}
Same test file as above ...
This one creates only the first file ext-test-1.tex
and the an error occurs because the end of filecontens
can’t be determined correctly.
Is there another way do do this, maybe a package?
Best Answer
You can look at the definition of
verbatimwrite
inverbatim.sty
or use the facilities provided by the fancyvrb package:Instead of
\typeout
you can do whatever you want (for example, checking whether the file already exists with\IfFileExists
).