diff options
| -rwxr-xr-x | texall | 192 |
1 files changed, 96 insertions, 96 deletions
@@ -6,16 +6,17 @@ import os import os.path import re import subprocess -import tempfile -parser = OptionParser(usage="%prog [-v] DIR/FILE [...]", version="%prog $Id: $") +parser = OptionParser(usage="%prog [options] DIR/FILE", + version="%prog $Id: $", + description="Call LaTeX and friends to typeset all tex files in DIR/FILE. By default up-to-date files are skipped. Care is taken to run all required commands until the result is stable. By default, pdflatex is used, but use of pstricks forces dvi->ps->pdf. The utility program rmligs ist used to improve output for german language texts. Use -Sqvvvf to simulate the behaviour of (pdf)latex in non-interactive mode (useful for emacs).") parser.add_option("-n", "--dry-run", action="store_false", dest="act", default=True, help="do not run any program") parser.add_option("-f", "--force", action="store_true", dest="force", default=False, help="regenerate up-to-date files") -parser.add_option("-R", "--non-recursive", +parser.add_option("-N", "--non-recursive", action="store_false", dest="recurse", default=True, help="disable recursion into subdirectories") parser.add_option("-s", "--summary", dest="summary", @@ -23,25 +24,27 @@ parser.add_option("-s", "--summary", dest="summary", choices=("no","files","failures","both"), default="failures") parser.add_option("-v", "--verbose", action="count", dest="verbosity", default=1, - help="give reasons for actions, may be repeated") + help="explain what is going on") parser.add_option("-q", "--quiet", action="store_false", dest="progress", default=True, help="suppress progress reports") -parser.add_option("-i", "--ignore", +parser.add_option("-i", "--interaction", + dest="interactionmode", choices=("batchmode", "nonstopmode", "scrollmode", "errorstopmode"), default="batchmode", + help="control the behaviour of latex (on of batchmode (default), nonstopmode, scrollmode, errorstopmode)") +parser.add_option("-I", "--ignore", action="store", dest="ignorepattern", default=".*vorlage.*|\.\#.*", help="regular expression of filenames to ignore") -parser.add_option("-p", "--required-pattern", +parser.add_option("-P", "--required-pattern", action="store", dest="requiredpattern", default='^\\\\documentclass|%%% TeX-master: t', help="regular expression that must match the file content") parser.add_option("-T", "--preserve-tempfiles", action="store_false", dest="deletetempfiles", default=True, help="preserve temporary files (default: delete)") +parser.add_option("-S", "--single-run", + action="store_true", dest="singlerun", default=False, + help="stop after the first LaTeX run, no matter if finished") (options, args) = parser.parse_args() -interactionmode = "batchmode" -if options.verbosity>2: - interactionmode = "nonstopmode" - re_ignore = None if options.ignorepattern != "": re_ignore = re.compile(options.ignorepattern) @@ -101,14 +104,14 @@ def alltexfiles(args): for name in files: if re_texfile.match(name): if re_ignore.match(name): - if options.verbosity > 1: + if options.verbosity > 2: print "%s: skipped because of ignored name"%os.path.normpath(os.path.join(dir,name)) continue for m in texgrep(re_required, dir, name): yield (dir, name) break else: - if options.verbosity > 1: + if options.verbosity > 2: print "%s: skipped because no main latex file"%os.path.normpath(os.path.join(dir,name)) def texgrep(matcher, dirname, filename, recurse=False): @@ -242,7 +245,7 @@ def outdatedtexfiles(args): elif options.force: reason = " (because of --force)" yield (dirname, texname, reason) - elif options.verbosity > 1: + elif options.verbosity > 2: print "%s: skipped because up-to-date"%os.path.normpath(os.path.join(dirname, texname)) re_nopdftex = re.compile('\\\\usepackage(\\[.*?\\])?\\{[^}]*pstricks[^}]*\\}') @@ -276,63 +279,63 @@ def processtexfiles(args): realname = preparermligs(texname, dirname, tmplist) runtex(tex, texname, realname, dirname) - - #strip .tex extension - jobname=texname[:-4] - # run bibtex if any bibfile changed: - for bib in bibfiles(dirname, texname): - bbl = os.path.normpath(os.path.join(dirname, jobname+".bbl")) - if options.force or not os.path.isfile(bbl) or os.path.getmtime(bbl) < os.path.getmtime(bib): - reason = "" - if options.verbosity: - if not os.path.isfile(bbl): - reason = " (because .bbl does not exist yet)" - elif os.path.getmtime(bbl) < os.path.getmtime(bib): - reason = " (because %s is newer than .bbl)"%bib - else: - reason = " (because of --force)" - run(["bibtex8", "--wolfgang", jobname], dirname, reason=reason) - runtex(tex, texname, realname, dirname, reason=" (because of updated .bbl)") - break - - # check for undefined references and run requests - numrun=0 - reqs=options.act - while reqs: - reqs = requests(os.path.join(dirname, jobname+".log")) - pri = reqs.values() - pri.sort(reverse=True) - for p in pri: - for req in reqs.keys(): - rp = reqs[req] - if rp == p: - reason = "" - if options.verbosity: - reason = " (because of request in .aux file, priority %d)"%rp - if req == "latex": - runtex(tex, texname, realname, dirname, reason=reason) - elif req == "bibtex": - run(["bibtex8", "--wolfgang", jobname], dirname, reason=reason) + if not options.singlerun: + #strip .tex extension + jobname=texname[:-4] + + # run bibtex if any bibfile changed: + for bib in bibfiles(dirname, texname): + bbl = os.path.normpath(os.path.join(dirname, jobname+".bbl")) + if options.force or not os.path.isfile(bbl) or os.path.getmtime(bbl) < os.path.getmtime(bib): + reason = "" + if options.verbosity: + if not os.path.isfile(bbl): + reason = " (because .bbl does not exist yet)" + elif os.path.getmtime(bbl) < os.path.getmtime(bib): + reason = " (because %s is newer than .bbl)"%bib else: - error(os.path.join(dirname,jobname+".aux"), "unsupported request: %s"%req) - numrun+=1 - if numrun==MAXRUNS: - error(os.path.join(dirname, texname), "does not stabilise after %i runs"%MAXRUNS) - break - - # update index if it exists - no way of knowing if it was updated - idx = jobname + ".idx" - if os.path.isfile(os.path.join(dirname, idx)): - run(["makeindex", jobname], dirname, reason=" (because .idx file might have changed)") - runtex(tex, texname, realname, dirname, reason=" (because .ind file might have changed)") - - if tex == "latex": - run(["dvips", jobname+".dvi"], dirname) - run(["ps2pdf", jobname+".ps"], dirname) - - for n in tmplist: - rmtempfile(n, dirname) + reason = " (because of --force)" + run(["bibtex8", "--wolfgang", jobname], dirname, reason=reason) + runtex(tex, texname, realname, dirname, reason=" (because of updated .bbl)") + break + + # check for undefined references and run requests + numrun=0 + reqs=options.act + while reqs: + reqs = requests(os.path.join(dirname, jobname+".log")) + pri = reqs.values() + pri.sort(reverse=True) + for p in pri: + for req in reqs.keys(): + rp = reqs[req] + if rp == p: + reason = "" + if options.verbosity: + reason = " (because of request in .aux file, priority %d)"%rp + if req == "latex": + runtex(tex, texname, realname, dirname, reason=reason) + elif req == "bibtex": + run(["bibtex8", "--wolfgang", jobname], dirname, reason=reason) + else: + error(os.path.join(dirname,jobname+".aux"), "unsupported request: %s"%req) + numrun+=1 + if numrun==MAXRUNS: + error(os.path.join(dirname, texname), "does not stabilise after %i runs"%MAXRUNS) + break + + # update index if it exists - no way of knowing if it was updated + idx = jobname + ".idx" + if os.path.isfile(os.path.join(dirname, idx)): + run(["makeindex", jobname], dirname, reason=" (because .idx file might have changed)") + runtex(tex, texname, realname, dirname, reason=" (because .ind file might have changed)") + + if tex == "latex": + run(["dvips", jobname+".dvi"], dirname) + run(["ps2pdf", jobname+".ps"], dirname) + + rmtempfile(tmplist, dirname) re_logmatcher = re.compile("^LaTeX Warning: There were undefined references\.$|^LaTeX Warning: Label\(s\) may have changed\. Rerun to get cross-references right\.$|^REQ:(\d+):(\w+):") def requests(logpath): @@ -379,19 +382,22 @@ def haderrors(dirname, jobname): return False def rmtempfile(filename, dirname): - fullname = os.path.join(dirname, filename) if options.deletetempfiles: - if options.progress: - print " removing %s"%filename + if not isinstance(filename, list): + filename = [filename] + if options.progress and options.verbosity > 1: + print " removing %s"%(", ".join(filename)) if options.act: - if os.path.isfile(fullname): - os.remove(fullname) - else: - error(filename, "could not be removed (does not exist)", warning=True) + for f in filename: + fullname = os.path.join(dirname, f) + if os.path.isfile(fullname): + os.remove(fullname) + else: + error(fullname, "could not be removed (does not exist)", warning=True) def run(arglist, dirname, reason="", stdin=None, stdout=None): - if options.verbosity>2: - # use default + if options.interactionmode != "batchmode": + # use stdout (default) output=None else: output=null @@ -404,48 +410,42 @@ def run(arglist, dirname, reason="", stdin=None, stdout=None): if ret: error(dirname, "failed command: %s"%(" ".join(arglist))) -re_include = re.compile('\\\\include\\{([^}]*)\\}') def preparermligs(texname, dirname, tmplist): jobname=texname[:-4] - if options.progress: + if options.progress and options.verbosity > 1: print " running rmligs on %s..."%texname try: texfile = open(os.path.join(dirname, texname)) except IOError, (errno, strerror): - error(texname, "could not be read: %s. Not using rmligs."%strerror) + error(os.path.join(dirname, texname), "could not be read: %s. Not using rmligs."%strerror) return texname else: try: + (subdir, texbasename) = os.path.split(texname) + rmligsbasename = ".%s.rmligs.tex"%texbasename[:-4] + rmligsname = os.path.join(subdir, rmligsbasename) if options.act: - (rmligsfd, rmligspath) = tempfile.mkstemp("-rmligs.tex", "%s-"%jobname, dirname) - realrmligspath = os.path.realpath(rmligspath) - realdirname = os.path.realpath(dirname) - if realrmligspath[:len(realdirname)] == realdirname: - rmligsname = realrmligspath[len(realdirname)+1:] - else: - rmligsname = rmligspath # should not happen - rmligsfile = os.fdopen(rmligsfd, "w") + rmligsfile = open(os.path.join(dirname, rmligsname), "w") else: - rmligsname = jobname + "-rmligs-XXXXX.tex" rmligsfile = null except IOError, (errno, strerror): - error(rmligsname, "could not be written: %s. Not using rmligs."%strerror) + error(os.path.join(dirname, rmligsname), "could not be written: %s. Not using rmligs."%strerror) return texname else: tmplist.append(rmligsname) proc = subprocess.Popen([rmligs_name, "-f"], stdin=texfile, stdout=subprocess.PIPE, cwd=dirname) def rewriteinputrmligs(m): - name=m.group(1) + name=m.group(2) if not os.path.isfile(os.path.join(dirname,name)): name+=".tex" if os.path.isfile(os.path.join(dirname, name)): name = preparermligs(name, dirname, tmplist) else: - error(texname, "%s: File could not be located. Not using rmligs."%name, warning=True) - return "\\include{%s}"%name + error(os.path.join(dirnam, texname), "%s: File could not be located. Not using rmligs."%name, warning=True) + return "\\%s{%s}"%(m.group(1), name[:-4]) for line in proc.stdout: - rmligsfile.write(re_include.sub(rewriteinputrmligs, line)) + rmligsfile.write(re_inputinclude.sub(rewriteinputrmligs, line)) texfile.close() if rmligsfile is not null: rmligsfile.close() @@ -453,9 +453,9 @@ def preparermligs(texname, dirname, tmplist): def runtex(tex, texname, realname, dirname, reason=""): if texname != realname: - run([tex, "-interaction", interactionmode, "-jobname", texname[:-4], realname], dirname, reason=reason) + run([tex, "-interaction", options.interactionmode, "-jobname", texname[:-4], realname], dirname, reason=reason) else: - run([tex, "-interaction", interactionmode, texname], dirname, reason=reason) + run([tex, "-interaction", options.interactionmode, texname], dirname, reason=reason) # main program: try: |
