tags:

views:

2252

answers:

13

I'm trying to figure out the best build system for latex.

Currently, I use latex-makefile, editing in vim, and viewing changes in Okular or gv. The major problem is that it sometimes gets hides errors on me, and I have to run latex manually. The major advantages are that it does all the iteration I need, and offers both pdf and ps simply.

If you have experience with

  • latex-mk
  • vim-latex
  • kile
  • lyx
  • miktex
  • latex-makefile
  • the ultimate latex makefile
  • rubber
  • any others I havent come across

Would you recommend them, and why/why not?

+6  A: 

I haven't used it myself, but I've heard of Rubber as a good alternative.

From their website:

Rubber is a program whose purpose is to handle all tasks related to the compilation of LaTeX documents. This includes compiling the document itself, of course, enough times so that all references are defined, and running BibTeX to manage bibliographic references. Automatic execution of dvips to produce PostScript documents is also included, as well as usage of pdfLaTeX to produce PDF documents.

obvio171
I tried this before, and I don't remember what problems I had that made me look elsewhere. I just tried it now and it seems to work very well. Thanks.
Paul Biggar
I moved my comments about rubber into their own answer: http://stackoverflow.com/questions/1240037/recommended-build-system-for-latex/1321905#1321905
Paul Biggar
A: 

"Better" is a very relative term... what else do you want to do? It seems like this makefile handles quite a bit, and it makes me wish I was running a *nix at work instead of windows... if there are more things you need to handle with the makefile, why not add them in?

To make it "better" you would need to provide more details on what exactly you're doing.

For instance, you could have it parse the .log file with grep, search for errors or warnings, dump them into another file, then open the new file so you can read through the errors.

It all depends on what you want to do...

Mica
OK, I've clarified "better" in the question.
Paul Biggar
What is your end goal? "More productive" is still quite relative... If your major headache is errors and having to run latex manually, I might suggest moving away from vim and onto something like Kile, which will spit out errors in the bottom pane... do you have the latex vim plugin? You could tell latex to run in non-stop mode (i.e. not stop on errors) by adding the -r flag to your makefile. Again, it all depends on what you want to do, since latex is pretty flexable. Thus, if you do not have anything really specific in mind, you probably are not going to get great answers :D
Mica
Mica S.: I'm trying to get suggestions as to potentially better ways to do it. I'll clarify better.
Paul Biggar
+3  A: 

I use Eclipse with the TexEcplise add-on for editing my TeX-files. It has syntax highlight for LaTeX. When you ask a preview of a non-altered and already compiled tex file, it open the file in the viewer. When the tex file was altered, then it compiles the tex file prior to viewing it. It does the necessary iterations, but only if needed.

Another advantage is that all errors and warnings are summarised in a box and they are highlighted in the tex file! This is a screenshot from the TexEclipse homepage.

Thierry
A: 

I've been using the latex-makefile for a while. Its pretty good if you're trying to use an edit-compile-preview cycle:

  • Takes almost zero configuration.
  • Builds .ps or .pdf.
  • Handles all the necessary iteration. I literally have to write nothing else.
  • Quite robust, but occasionally the errors and warnings get mangled.
  • It doesn't kill the old pdf until the new one is built.
  • It builds other files, like generating eps from gnuplot. I havent found this hugely useful though.
  • The author is very quick to respond to feature requests.
  • I can replicate the advantages of latexmk fairly easily with:

    while [ 1 ]; do /usr/bin/make; done
    

Some downsides:

  • It only allows pdf generation via dvi -> ps -> pdf, instead of directly via pdftex.
  • Its error output isnt the same as the standard latex one, so vim isnt moving to the correct line.
  • It doesnt always recompile on changes in bibtex and other non-tex sources.
  • If I remove a file, it doesn't remove the dependency without a make clean.
Paul Biggar
+6  A: 

I've just tried out latexmk. If you do

latexmk -pvc file.tex

Then it will auto preview (DVI by default).

  • Handles dependencies
  • DVI, ps or pdf
  • Iterates fine.
  • Very configurable, see man latexmk

Downsides:

  • It doesnt condense errors, which isnt hugely useful (workaround: use rubber-info seperately)
  • Bug in the man file: "Sometimes a viewer (gv) tries to read an updated .ps or .pdf file after its creation is started but before the file is complete. Work around: manually refresh (or reopen) display.". It would be better if it built it via a temporary .pdf file to avoid this.
  • Not hugely user friendly.
Paul Biggar
`latexmk` doesn’t support XeTeX and there’s apparently no way of changing this short of hacking the hard-coded value of the `pdflatex` executable. Very annoying.
Konrad Rudolph
I agree with Paul's answers re: Rubber and Latexmk.I tried Rubber before, it does present build errors nicely, but it's 2-3 years old and doesn't seem that maintained. **Latexmk is my current builder of choice.**The latest release is from 3 weeks ago, it has quite powerful configuration possibilities (e.g. I have it [automatically generate PDF figures from the OmniGraffle files](http://people.untyped.org/damien.pollet/notes/2010/latexmk-omnigraffle.html)), maybe XeTeX support in even on the author's todo list?
Damien Pollet
+1  A: 

(This is a work in progress)

I'm trying vim-latexsuite at the moment. It basically turns vim into an IDE for latex.

Learning curve:

  • Very unintuitive, but after the tutorial, it seems OK.
  • It redefines some keys I like, and I can't seem to fix them.

Autocomplete:

  • Makes using some built-in macros simpler
  • Adding <<+>> to for user macros is very annoying.
  • Replacing " with `` and the like is nice until you want " for some reason, then its an exercise in frustration.
  • Its autocomplete can be annoying too. I have to reprogram myself for working in latex.

Build system:

  • Awful
  • quickfix doesn't work - it often puts me in the wrong file
  • When latex reports errors with the result split over 2 lines, it doesn't detect it.
Paul Biggar
Much the same experience here, but I now use it all the time and it works quite nicely *for editing*. I like the macros, after some getting used to.
Konrad Rudolph
A: 

I'm using MikTeX in combination with TeXnicCenter. It works fine for my purposes. I've never ever had the system hiding errors or warnings. Custom build scripts are easy to create and configure.

Martijn
is that multi-platform?
fortran
Nope, seems to be windows only
Martijn
A: 

ltx claims to be a wrapper to latex to speed up the compilation of latex documents. I couldn't make it work though (some problems with initex).

Paul Biggar
+3  A: 

I'm trying rubber for a while. I'll condense the results here:

  • Rubber will automatically convert .eps files into .pdfs for pfdlatex. However, it seems to only do this for includegraphics macros. If you have your own macro, it wont.
  • rubber-info is great, which is magic. It is certainly better than anything else I've seen at getting error message and lines. And you don't actually need to use rubber to build to use it.
  • It doesn't seem to know when to stop iterating, often stopping early.
  • It overwrites your PDF as it builds, which is irritating (it lacks a nice feature from latex-makefile where it builds it in a temp file).
Paul Biggar
+3  A: 

After considering all these options for some time, I have settled with the following solution.

  • Set vim to write continuously as I type.
  • Run a script in the background to build continuously, refreshing the pdf as it goes. latexmk is nearly good enough, except that it builds in place, which gets reloaded at a bad time in okular (my viewer).

(Apologies for the hacked code - it works for me).

#!/usr/bin/env python

# Continuously builds a latex document, refreshing it only when it has changed.

# What makes this different from latexmk, is that it just continually builds in
# the background, and refreshes to the latest copy _after each build_. This
# means you get to see the latest copy, even if there are 3 or 4 iterations
# left to go to make it perfect.

# However, it won't just constantly rebuild while there are no changes.

# It does _not_ attempt to do an error parser. rubber-info does that
# spectacularly. However, it will copy the log file, so that its not constantly
# changing, and only update it to the latest.

import subprocess
import shutil
import time
import os
import sys
import hashlib

def get_input_files(base):
    try:
        lines = open(base + ".fls", "r").readlines ()
    except Exception:
        # If the file doesnt exist, it'll be fixed later, when they see an empty list, and run it again.
        debug (".fls file missing")
        return []

    result = set()
    for line in lines:
        (before, _, after) = line.rstrip().partition (" ")
        if before == "INPUT" and after[0] != "/":
            result.add (after)

    return result

def debug (message):
    global logfileobject
    print >>logfileobject, time.strftime("%H:%M:%S") + " - " + message

def msg (message):
    debug (message)
    print str(time.strftime("%H:%M:%S")) + " - " + message


filename = sys.argv[1]
base = os.path.splitext (os.path.basename (filename))[0]
final = base + ".pdf"
logfile = base + ".log"
auxfile = base + ".aux"

texbuildlogfile = "texbuild.log"

latex = ["pdflatex", "-recorder", "-interaction=nonstopmode", filename]
bibtex = ["bibtex", base]


# Start the logfile again
if os.path.exists(texbuildlogfile):
    os.remove (texbuildlogfile)

logfileobject = open (texbuildlogfile, "w")




timestamps = {}
md5s = {}


while (True):

    files = get_input_files (base)

    # No .fls file
    if len (files) == 0:
        files = [filename]


    # Keep checking the files until a timestamp changes
    build = False
    while build == False:

        time.sleep (0.2)
        new_timestamps = []
        changed_files = []
        for f in files:

            # First check the timestamp
            try:
                t = os.path.getmtime(f)
            except Exception:
                debug ("Time stamp error, always build")
                build = True
            else:
                if t > timestamps.get (f, 0):
                    new_timestamps.append (f)
                    timestamps[f] = t

                    # Check if it has actually changed
                    m = hashlib.md5( open( f, "r" ).read()).hexdigest()
                    if m != md5s.get (f, ""):
                        changed_files.append (f)
                        md5s[f] = m
                        build = True


        if len (changed_files):
            msg ("Changed files: " + ", ".join (changed_files))
        elif len (new_timestamps):
            msg ("Touched files: " + ", ".join (new_timestamps))


        # If the .pdf if missing, build it
        if not os.path.exists(final):
            msg ("PDF missing")
            build = True



    # Now build it


    # We dont care about outputs or exit code
    msg ("Beginning build")
    subprocess.call (bibtex, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    p = subprocess.Popen (latex, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    # This can hang. Don't wait longer than 20 seconds (when it takes longer,
    # its generally building something incredibly broken, possibly because it
    # saved just after an open brace was added, and it can't make sense of the
    # thing.
    start = time.time ()
    while True:
        retcode = p.poll()

        if retcode != None:
            break;

        # It might timeout
        finish = time.time ()
        if finish > start + 30:
            try:
                #p.terminate()
                p.kill()
            except Exception:
                pass

            debug ("Timeout (" + str(finish - start) + ") running: " + " ".join (latex))
            break

        time.sleep (0.2)

    msg ("Built");


    if os.path.exists(final):
        debug ("copying pdf")

        # Delete before copying for okular
        if os.path.exists("t.pdf"):
            os.remove ("t.pdf")
        shutil.copy (final, "t.pdf")

    debug ("copying log")
    shutil.copy (logfile, "t.log")
    shutil.copy (auxfile, "t.aux") # for bibtex

Use rubber-info to get the errors and warnings from the log file. The script above saves the log file in t.log. In vim:

autocmd FileType tex set makeprg=rubber-info\ t.log
autocmd FileType tex set errorformat=%f:%l:\ %m
Paul Biggar
Could you post your code again. It's quite weirdly formated as some is in code blocks, and some are not. Meanwhile, some are in headlines etc.
martiert
@martiert: I posted it a few times, and I think I got it right at the end (works for me). Is it OK for you now?
Paul Biggar
+1  A: 

I wanted to use the script you posted in your final answer.

Unfortunately, it didn’t work with my setting (MacVim with vim-latexsuite, Skim as the viewer and XeTeX). I also use forward search (i.e. I use the feature that pressing \ls in Vim will jump to the corresponding point in the PDF document in the open viewer).

Furthermore, my document isn’t called thesis.tex (big surprise; it’s not a thesis). I’ve therefore done some more configuration work that I’d like to share. Attention, my bash skills are horrible.

#!/bin/bash

set -x
ulimit -t 10 # sometimes pdflatex gets stuck

if [ "$1" = "" ]; then
    echo "No target name specified"
    exit 1
fi

TARGET=$1
SOURCE=$1.tex
TMPSOURCE=_$TARGET.tex
TMPTARGET=_$TARGET

while [ 1 ]; do
    # Compile a different file ($TMPSOURCE.pdf) so that it doesn't reload mid-compile
    cp $SOURCE $TMPSOURCE
    # better than running pdflatex manually, as this wont rebuild if there's nothing there.
    latexmk -pdf -silent $TMPTARGET > /dev/null

    # For rubber-info
    cp $TMPTARGET.log $TARGET.log

    if [ -e $TMPTARGET.pdf ]; then # Check the compile succeeded first
        # No output file yet.
        [ ! -e $TARGET.pdf ]
        HASNOPDF=$?
        # ignore if it's unchanged.
        # OS X diff doesn't consider binary files. Single-line output, return value 2
        diff $TARGET.pdf $TMPTARGET.pdf
        OUTPUTDIFFERS=$?
        if [ $HASNOPDF -eq 0 -o $OUTPUTDIFFERS -ne 0 ]; then
            # Do NOT RM since Skim cannot deal with this.
            cp $TMPTARGET.pdf $TARGET.pdf
        fi
    fi

    sleep 1 # give it time to be killed by a CTRL-C
done

This compiles a temporary file and copies it back to whatever name was given (instead of the other way round as your script does); usage of the script:

./scriptname project

Where project is the name of the TeX file, without file extension.

I’ve also changed the rubber-info line:

autocmd FileType tex exe "set makeprg=rubber-info\\ _" . expand("%:t:r") . ".log"

And I needed to patch my latexmk to use XeTeX since the name of the executable was hard-coded.

Unfortunately, this still destroys the output PDF file when I’ve saved my document before completing a statement, since latexmk seems to always produce a PDF file, even on error – and its return code is always 0, which sucks.

(To clarify this, say that I’ve just typed emph{ into my document and save it. The background script will promptly compile the document, and fail. But it will still produce a (largely empty) output file).

Additionally, forward search no longer works properly; it basically jumps to a wrong point in the document. I suspect that this has something to do with my copying the document before compilation.

So, this is still a completely unsatisfactory solution, even though I didn’t even enable continuous saving on typing in MacVim yet.

Konrad Rudolph
Actually, I rewrote the script over the last while. I'll post it later.
Paul Biggar
+1  A: 

AUCTEX & preview-latex with Emacs another option.

You can also have emacs open up the resultant dvi, or pdf file, and if you turn auto-revert-mode on for that buffer, the changes will be rendered everytime you recompile the document.

mhb
A: 

Have a look at TeXMaker. :-)

features (from wiki):

  • In-line spell check.
  • A unicode editor to write LaTeX source files (syntax highlighting, undo-redo, search-replace, spell checker...)
  • LaTeX tags and mathematical symbols can be entered with a mouse
  • Document and section templates
  • LaTeX-related programs can be launched
  • BibTeX database management
  • An outline or "structure view"
  • Logfiles during LaTeX compilation and the ability to "step through" source errors that are discovered by the compiler
  • An integrated LaTeX to HTML conversion tool

features (from me):

  • useful wizards for inserting tables, citation, referencing
  • bidirectional support
  • useful keyboard shortcuts
  • Auto Complete words (specially is useful with referencing)
  • define your own instructions
Sorush Rabiee
Make sure to additionally check out TeXMakerX ( http://texmakerx.sourceforge.net/ ) - it's a fork of TeXMaker with some more useful features.
Martin