Okay, after playing around with the syntax a lot, I got something to work by modifying the code in xcite
(which loops through the aux file to pull out all of the \bibcite
items) so that it just counts the number of \bibcite
items in the aux file. Here is my modified version of the sample document, with added code between the lines beginning with %%
. I don't have much experience with writing TeX macros, so I'd appreciate any suggestions for improvement.
\documentclass{article}
\usepackage[numbers]{natbib}
\newcount\bibcounter
\bibcounter=0
%% start citation counting
\def \maindoc {mymaindoc}
\newread\auxfile
\openin\auxfile = \maindoc .aux
\long\def\bibcitecheck#1#2\bibcitecheckstop{%
\ifx#1\bibcite
\advance \bibcounter by 1
\fi
}
\newif\ifnoteof
\loop
\read\auxfile to \holder
\ifeof\auxfile
\noteoffalse
\else
\expandafter\bibcitecheck\holder...\bibcitecheckstop
\noteoftrue
\fi
\ifnoteof
\repeat
\closein\auxfile
%% End citation counting
\usepackage{etoolbox}
\makeatletter
\apptocmd{\thebibliography}{\global\c@NAT@ctr \bibcounter\relax}{}{}
\makeatother
\begin{document}
Here we cite reference \citealp{firstCite}.
\begin{thebibliography}{99}
\bibitem{firstCite} Dow, W. \& Jones, E.A.,
{\it Wall Street Journal},
March 29, 1929.
\end{thebibliography}
\end{document}
With the help of When is the aux file read and written? and Barbara Beetons kind assistance I was able to determine what goes wrong and how to prevent it.
This is the problem:
Normally I then don't work with the TeX engine on the console, but simply correct my error and restart.
This is what I should have done on the console:
- Type
?
+Return
to get an idea of what can be done.
- Simply hit
Return
repeatedly until Tex is finished.
- Type
X
+Return
to finish the run immediately.
- Type
E
+Return
to have the cursor jump to the point where the error occurred.
What happens is, that TeX buffers the \write commands to the .aux file in two stages. First stage, it waits until a page is shipped out to get the page numbers right. Second stage, it waits until it sees fit to issue a write()
system call, to reduce the number of (potentially slow) system calls. This second buffer seemingly does not care, if the chunks it writes to file are self-contained legal TeX since it will complete the file before the TeX run is finished anyway.
In the environment of TeXShop however it is tempting to let TeX hang unfinished after an error. Thus the second output puffer is not flushed and the .aux file possibly left unfinished and in an illegal state.
My personal conclusion from this: Always let TeX finish.
The assumption that TeX will have a chance to finish it's run after it stopped for an error was very reasonable before windowed environments, where it became easy and normal to leave processes hanging in the background.
Things that could be done on software side to facilitate this user behavior:
- Change Tex's second buffer behavior to issue a
write()
system call in case of an error or to break only into TeX-legal chunks.
- Adjust the environment (TexShop) to either clean the .aux file after a process abortion or provide default input to always correctly finish the process.
Things that the user can do, other than always letting TeX finish:
- Use
\include{...}
. That way the .aux files of the sections before are closed an finished by the time the error occurs. Chances are the .aux file of your current section isn't large enough yet and no TeX-illegal parts were written.
- Hack something involving
\immediate\closeout\@mainaux
followed by an \openout\@mainaux
and a copy of the contents so they don't get overwritten. This will effectively flush the output buffer. Does not seem worth the effort though.
Best Answer
The
.aux
file is read as part of the\document
macro (\begin{document}
) but before the\AtBeginDocument
hook is used. (You can check this by inserting some 'test code' into the.aux
file and the hook.)Writing to the
.aux
file takes place both 'immediately' and at shipout. The latter is important to get for example the correct page numbers for cross-references, so things like\label
take place in a delayed fashion, using the\protected@write
'wrapper' around the\write
primitive. Thus for exampleonly places
\foo
in the.aux
file:\baz
is never written as there is no page shipout. In your example, shipout occurs after\foo
, so you see nothing in the.aux
file at that point although a shipout does occur later.Note that TeX keeps the
.aux
file open until the end of the run, so you cannot be sure that any particular\write
will appear in the partial.aux
file during a run. As such, the only safe time to check on what gets written to the file is after the run completes. In particular, badly-terminated jobs may leave the.aux
file in an incomplete state even if the crash occurs after writes 'should' have taken place.