There is a user friendly LaTeX package: newfile
. You can use it to read and write files easily. It provides normal file IO functions, and also verbatim file IO functions. It is more suitable for your example, than those low-level macros. The package document has some good examples.
A naive example (similar to table of contents):
\documentclass{article}
\usepackage{newfile}
\newoutputstream{comment}
\openoutputfile{\jobname.comment}{comment}
\begin{document}
\section{Test}
text one
\addtostream{comment}{\noexpand\item comment one at page \thepage}
text two
\addtostream{comment}{\noexpand\item comment two}
\section{Comments}
\closeoutputstream{comment}
\begin{enumerate}
\input{\jobname.comment}
\end{enumerate}
\end{document}
Macros will expand when write to file. It is very important to control the expansion. Some macros should not be expanded, like \item
here; while some macros should be expanded, like \thepage
and \thesection
here.
In TeX, there are \newwrite
, \openout
, \immediate
, \write
, \closeout
, \ifeof
etc. A good resource is chapter 30 of TeX by Topic.
The same example using TeX primitives:
\documentclass{article}
\newwrite\commentfile
\openout\commentfile=\jobname.comment
\begin{document}
\section{Test}
text one
\write\commentfile{\noexpand\item comment one at page \thepage}
text two
\write\commentfile{\noexpand\item comment two in section \thesection}
\section{Comments}
\closeout\commentfile
\begin{enumerate}
\input{\jobname.comment}
\end{enumerate}
\end{document}
In LaTeX kernel, which you can refer source2e
, you can learn from \@starttoc
, \@wirtefile
, \addcontentsline
(for contents) etc.
The same example (works like standard TOC):
\documentclass{article}
\makeatletter
\newcommand\addcommentitem[1]{%
\write\@auxout{\noexpand\@writefile{comment}{\noexpand\item #1}}}
\newcommand\printcomment{%
\section*{Comments}
\begin{enumerate}
\item[] Here are some comments:
\@starttoc{comment}
\end{enumerate}}
\makeatother
\begin{document}
\section{Test}
text one
\addcommentitem{comment one at page \thepage}
text two
\addcommentitem{comment two in section \thesection}
\printcomment
\end{document}
You can look at the definition of verbatimwrite
in verbatim.sty
or use the facilities provided by the fancyvrb package:
\documentclass{article}
\usepackage{fancyvrb}
\newenvironment{tobiwrite}[1]
{\typeout{Writing file #1}\VerbatimOut{#1}}
{\endVerbatimOut}
\begin{document}
\begin{tobiwrite}{tobi.txt}
a
b
c
\end{tobiwrite}
\end{document}
Instead of \typeout
you can do whatever you want (for example, checking whether the file already exists with \IfFileExists
).
Best Answer
There is
\@percentchar
that expands to a literal%
character. You need to enclose your writing operation in a\makeatletter
\makeatother
pairAn alternative with escaping the
%
inspired by an example whereneeds to be passed to
\write18
so the command above can be executed by saying
With
\dosystem*
the\write
is delayed at the next shipout (because\immediate
is not executed).Other characters can be escaped using the same idea, adding other
\let
instructions. If also braces and#
are needed, an extended definition would beand in the argument also
\#
,\{
and\}
can be used for escaping those characters.