Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am interested in the basic mechanism behind writing stuff to the .aux file. (Or some other auxiliary file).

Let's say I want to write myself a basic package for making notes on my files. (I know packages already exist for doing this. The point of this question is not to work out how to get comments on my paper, it is to learn about an aspect of the basics of TeX/LaTeX.)

So I have something like this in my preamble:

\usepackage{xcolor}
\newif\ifcomments
\commentstrue
\newcommand\comment[1]{%
  \ifcomments
  \textcolor{red}{\textsf{#1}}
  \else
  \fi
}

This means I have comments I can turn on and off. Now, the next stage is I want a list of comments to appear in an itemize at the end of the document, each comment listed along with its page number. To achieve this, it seems like the easiest way would be to write each comment (plus its page number) to an auxiliary file, and then have a command \writecomments that prints the contents of that file. (Or something of that sort).

How, in simple terms, could I achieve this?

NB this question is designed to help me learn about the basics of TeX/LaTeX, so solutions that involve packages doing a lot of the work will be frowned upon.

Edit I've had two very interesting answers offering different ways to achieve what I want in my example. Neither answer, however, really gets to the real answer I wanted, which would be a, accessible introduction to TeX's/LaTeX's "write to auxiliary file" mechanism.

What I'd like is a more basic answer that someone newer to TeX/LaTeX could read and understand. I feel the current answers are a little too high level.

share|improve this question
3  
@Seamus: I don't think this question should be community wiki - it may receive a higher-than-average number of answers, but it is not a big-list/subjective one. –  lockstep Feb 12 '11 at 16:09
    
@lockstep I guess my reasoning was that it would be cool to have one nice introductory/summary answer that could be CWed into providing a nice resource for people interested in how the auxiliary files work. –  Seamus Feb 12 '11 at 17:26
1  
@Seamus: I see -- but in this case, only the summary answer (to be added later) should be CWed, while any other answer (and the question itself) should be able to generate reputation. –  lockstep Feb 12 '11 at 17:34
1  
@lockstep I have removed the suggestion to CW. I agree with you. –  Seamus Feb 12 '11 at 19:15
    
@Seamus: Well, you said you wanted to learn about an aspect of the basics of TeX/_LaTeX_, and both answers address how it's done in LaTeX. Or am I mistaken? –  Hendrik Vogt Feb 21 '11 at 19:37

2 Answers 2

up vote 33 down vote accepted

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}
share|improve this answer

If you have one write handle left you can do it with the following commands which are also used for .toc, .lof, .lot, etc.

\@starttoc{<extension>}

Reads the file with the given extension (\jobname.<extension>) and opens it for writing afterwards. The file is initially empty. Creates the output file handle \tf@<extension> .

\@writefile{<extension>}{<code>}

Writes code using the output handle \tf@<extension> if it exists.

I have these macros in macros2e and was planning to add a short HowTo for exactly this application.

You can define a \listofcomments initially as \relax and \writecomments (or \makecomments) defines it than to \@starttoc{cmt}, which reads/creates '\jobname.cmt'.


You should be able to write directly to the current .aux file (main or include file) with:

 \write\@auxout{...}

or, if you want to write explicitly to the main .aux file:

 \write\@mainaux{...}

They create an whatsit so the page number should be correct.

For other, new files you need to create a write handle and open the file first. This is done using:

 \newwrite\myhandle% There are only 16 write handles, even with eTeX!
 \openout\myhandle=<filename>\relax% or space
 % ...
 \closeout\myhandle % to close the file

You can prefix all of these commands (except \newwrite) with \immediate to make same execute immediately without creating a whatsit. Then however the page counter won't be correct yet.

share|improve this answer
1  
When you used up all 16 write handles, the morewrites package could be helpful. –  Stephen Nov 16 '13 at 13:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.