views:

206

answers:

4

I'm trying to build a continuous builder for my latex document, which calls latex and bibtex the appropriate number of times. It checks the myfile.fls file for all the inputs, so it seems I know what all the inputs are.

But how can I tell when to stop iterating? It is enough that none of the inputs change? Note that the input files include files like myfile.aux, so there does seem to be some feedback in the system, but I don't know if I'm missing something.

Note that I can't say "3 or 4 times", since it builds continuously. If an input changes, I may need to run it 3 or 4 times, but more likely I'll only need to run it once. In a rare situation, an input will change something like a reference, which will need maybe 3 builds. I'm trying to find out how I know when this happens.

(I'm not looking for answers like "use latexmk", unless I can somehow use them only to query if the document needs to be rebuilt, thanks.)

More context: I'm trying to find a replacement for latexmk in my answer to a previous question. I want to replace it because it might iterate 3 or 4 times, but I want to get feedback after every build.

+1  A: 

As a rule of thumb, you should build three times. In exceptional cases (with makeindex, pagerefs and stuff) you might need a fourth time.

Apart from reading the log file, there's no way to be sure. IMO you should automate just one build, and output any warnings/errors given; so that the user can decide whether or not to rebuild. In my experience, LaTeX will warn you to rebuild if necessary.

Martijn
Thanks. What would I be looking for in the log file? I'm not interested in asking the user (who is me :)), I just want to keep running it in the background, but I want to stop if there are no changes.
Paul Biggar
Also, it is possible it will never converge: http://www.tex.ac.uk/cgi-bin/texfaq2html?label=rerun
Jouni K. Seppänen
I believe the message read "label(s) may have changed, return to get crossreferences right".
Martijn
@Jouni: Thanks, very interesting. I think I can just ignore that edge case though.
Paul Biggar
@Martijn: Ah, OK. But what about for example makeindex?
Paul Biggar
@Martijn: would you be able to take a look at my answer? http://stackoverflow.com/questions/1465726/latex-how-do-i-know-to-stop-building-programatically/1473166#1473166. Thanks :)
Paul Biggar
+2  A: 

There are really only four passes that are necessary. If you're trying to build something similar to an ant script or makefile, I would say that you should look for changes to the source .tex file and then fire off this process:

  1. Run LaTeX (finds all the bibliographical references, figure entries, etc.)
  2. Run BibTeX (creates an initial set of text for the bibliographic entries)
  3. Run LaTeX (populates the document with bibliography, figure references)
  4. Run LaTeX (general good luck: there are some corner cases when references need two passes to fully populate)

If Latex doesn't need to do extra work for any of these passes, it won't do it.

Responding to the OP:

Note that I can't say "3 or 4 times", since it builds continuously. If an input changes, I may need to run it 3 or 4 times, but more likely I'll only need to run it once. In a rare situation, an input will change something like a reference, which will need maybe 3 builds. I'm trying to find out how I know when this happens.

An ant script or makefile is your friend here: make your final output product (.dvi file, for example) depend on your source .tex and .bib files. Seriously, though, you need those four passes to be certain that you have avoided getting trapped by any corner cases.

Responding to the comment:

Suppose I fix a typo in some paragraph, I run latex, and now have a perfect version. Is there not some way to tell that it hasnt updated the .aux file, or the .bbl file, etc, and so doesnt need to full set of passes.

It is possible to build the ant script or makefile such that each step depends on the appropriate intermediate file and, thus, would only fire if there was a change. I would recommend against doing this for two reasons:

  1. You're duplicating the work and file management that LaTeX is already doing for you.
  2. If you change your document structure, you're going to have to update those dependencies.

For example, when I was writing my dissertation, at one point I decided that it would be helpful to split one chapter into two and add another appendix. All I had to do was change my \include section from this:

\include{chapter1.tex}
\include{chapter2.tex}
\include{chapter3.tex}
\include{chapter4.tex}
\include{appendix.tex}

to this:

\include{chapter1.tex}
\include{chapter2a.tex}
\include{chapter2b.tex}
\include{chapter3.tex}
\include{chapter4.tex}
\include{appendix.tex}
\include{appendix2.tex}

If I was attempting to duplicate the multi-pass implementation of LaTeX in a build script, I would have to update all the dependencies for .tex, .aux, etc., every time I made a similar change.

Instead, I just continued to run my four passes (using an alias at the command line) and carried on writing my text.

Bob Cross
Suppose I fix a typo in some paragraph, I run latex, and now have a perfect version. Is there not some way to tell that it hasnt updated the .aux file, or the .bbl file, etc, and so doesnt need to full set of passes.
Paul Biggar
Same for makeindex.
Marco van de Voort
I'm not using make, I'm writing a script. I know the input files because I read them from myfile.fls, which is generated by `pdflatex -recorder`. So it fixes automatically every time I add or remove or rename any files in the document. I only need to provide myfile.tex, and the rest is magic.
Paul Biggar
@Bob: would you be able to take a look at my answer? http://stackoverflow.com/questions/1465726/latex-how-do-i-know-to-stop-building-programatically/1473166#1473166. Thanks :)
Paul Biggar
@Paul Biggar, done - if it works for you, it works.
Bob Cross
A: 

Here is what I did at one time. It is very incomplete but could be a starting point for you:

#!/usr/bin/perl

use strict;
use warnings;

my $prefix = 'LaTeX Warning:';
my $max_tries = 10;

while ( my $x = `pdflatex -halt-on-error mydocument` ) {

    if ( $x =~ /^$prefix Citation/m ) {
        `bibtex mh`;
        `pdflatex mh`;
    }

    last unless
        $x =~ /^$prefix Label\(s\) may have changed/m
            or $x =~ /^$prefix There were undefined references/m
            or $x =~ /^$prefix Reference/m
        ;
    last unless --$max_tries;
}

LaTeX::Driver might also be useful although I remember getting a little frustrated with the earlier versions.

Sinan Ünür
This is very similar to mine, except that I want to continuously build: http://stackoverflow.com/questions/1240037/recommended-build-system-for-latex/1394702#1394702
Paul Biggar
A: 

I wrote a script, with the following algorithm:

  1. When the program starts, always build (with the -recorder flag of pdflatex, which creates a .fls file).
  2. Get the list of files from myfile.fls
  3. Wait until a file has changed (use md5sum on any file which has a new timestamp), then rebuild.
  4. Goto 2.

I've noticed that myfile.fls includes all dependencies, such as myfile.bbl for bibliographies, myfile.toc for table of contents, and myfile.aux for most basic things. When there is a need for a rebuild, these change, so relying on this algorithm only, I seem to be able to rebuild until the files reach a fixpoint.

Note that the output file generally differs, as the .pdf files tend to include build date. However, this is irrelevent, as the result has still successfully converges.

The only thing I can think of that this won't handle is that it may not converge (thanks to Jouni K. Seppänen, in a comment on another answer).

Paul Biggar
@Paul, if it works, it works. That's really the only useful measure of success.
Bob Cross
Assuming the -recorder flag gives the .fls, this seems to be OK. As you say, the only risk is an infinite loop (which is highly improbable). You could limit the number of build to, say, four or five, and display a warning if that doesn't suffice. For any practical purposes, this will suffice. I've never ever encountered any document that required more than four builds.
Martijn