aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtexall131
1 files changed, 82 insertions, 49 deletions
diff --git a/texall b/texall
index a6f98d4..03d6d9c 100755
--- a/texall
+++ b/texall
@@ -44,10 +44,10 @@ class TexallOptionParser(OptionParser):
dest="interactionmode", choices=("batchmode", "nonstopmode", "scrollmode", "errorstopmode"),
help="control the behaviour of latex (on of batchmode (default), nonstopmode (default for -o), scrollmode, errorstopmode)")
self.add_option("-I", "--ignore",
- action="store", dest="ignorepattern", default=".*vorlage.*|\.\#.*|\..*\.rmligs\.tex",
+ action="store", dest="ignorepattern", default=".*vorlage|\.\#|.*-rmligs\.tex$",
help="regular expression of filenames to ignore")
self.add_option("-P", "--required-pattern",
- action="store", dest="requiredpattern", default='^\\\\documentclass|%%% TeX-master: t',
+ action="store", dest="requiredpattern", default='^\\\\documentclass|^%%% TeX-master: t',
help="regular expression that must match the file content")
self.add_option("-T", "--preserve-tempfiles",
action="store_false", dest="deletetempfiles", default=True,
@@ -110,10 +110,10 @@ class AnalyseTexRequired(Analyser):
d.required = False
Analyser.__init__(self,d)
def parse(self, text):
- if re_required.match(text):
+ if re_required.search(text):
self.d.required = True
def merge(self, d):
- pass # do not take over master file status
+ self.d.required |= d.required
class AnalyseTexDependencies(Analyser):
def __init__(self, d):
@@ -123,7 +123,7 @@ class AnalyseTexDependencies(Analyser):
def parse(self, text):
for m in re_inputinclude.finditer(text):
self.d.deps.append((m.group(2), (".tex", "")))
- m = re_documentclass.match(text)
+ m = re_documentclass.search(text)
if m:
cls = m.group(2)
self.d.deps.append((cls, (".cls", "")))
@@ -141,7 +141,7 @@ class AnalyseTexDependencies(Analyser):
def merge(self, d):
self.d.deps.extend(d.deps)
self.d.grfdeps.extend(d.grfdeps)
- def finish(self, _):
+ def finish(self, dirname):
if hasattr(self.d, "needsPS"):
if self.d.needsPS:
for f in self.d.grfdeps:
@@ -149,6 +149,17 @@ class AnalyseTexDependencies(Analyser):
else:
for f in self.d.grfdeps:
self.d.deps.append((f, (".pdf", ".jpg", ".png", "")))
+ expandeddeps = []
+ for dep, extlist in self.d.deps:
+ if extlist == None:
+ expandeddeps.append((dep, extlist))
+ else:
+ try:
+ expandeddeps.append((texpath(dirname, dep, extlist=extlist), None))
+ except ValueError, e:
+ if opts.verbosity > 2:
+ error(self.d.name, "ignoring dependency: %s"%e, warning=True)
+ self.d.deps = expandeddeps
class AnalyseTexBibfiles(Analyser):
def __init__(self, d):
@@ -168,7 +179,7 @@ class AnalyseTexBibfiles(Analyser):
try:
bibpath = texpath(dirname, bib, pathtype="bib",progname="bibtex")
bibpath = strippath(bibpath, dirname)
- self.d.deps.append((bibpath, ("",)))
+ self.d.deps.append((bibpath, None))
bibpaths.append(bibpath)
except ValueError, e:
error(self.d.name, str(e), warning=True)
@@ -181,7 +192,7 @@ class AnalyseTexNeedsPs(Analyser):
d.needsPS = False
Analyser.__init__(self, d)
def parse(self, text):
- if re_needsps.match(text):
+ if re_needsps.search(text):
self.d.needsPS = True
def merge(self, d):
self.d.needsPS |= d.needsPS
@@ -191,7 +202,7 @@ class AnalyseTexRmligs(Analyser):
d.rmligs = False
Analyser.__init__(self, d)
def parse(self, text):
- if re_rmligs.match(text):
+ if re_rmligs.search(text):
self.d.rmligs = True
def merge(self, d):
self.d.rmligs |= d.rmligs
@@ -203,25 +214,32 @@ class AnalyseLogErrors(Analyser):
d.errors = False
Analyser.__init__(self, d)
def parse(self, text):
- if re_error.match(text):
+ if re_error.search(text):
self.d.errors = True
class AnalyseLogRequests(Analyser):
def __init__(self, d):
d.requests = {}
+ d.requestreason = {}
Analyser.__init__(self, d)
self.inrequest = False
- def addrequest(self, name, priority):
+ def addrequest(self, name, priority, reason=None):
if self.d.requests.has_key(name):
- self.d.requests[name] = max(self.d.requests[name], priority)
+ if self.d.requests[name] < priority:
+ self.d.requests[name] = priority
+ if reason:
+ self.d.reqeustreason[name] = reason
+ elif not self.d.requestreason[name]:
+ self.d.requestreason[name] = reason
else:
self.d.requests[name] = priority
+ self.d.requestreason[name] = reason
def parse(self, text):
for m in re_logmatcher.finditer(text):
if m.group() == 'LaTeX Warning: There were undefined references.':
- self.addrequest("latex",0)
+ self.addrequest("latex", 0, " (because of undefined references)")
elif m.group() == 'LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.':
- self.addrequest("latex",0)
+ self.addrequest("latex", 0, " (because of changed labels)")
elif m.group(1)!=None:
self.addrequest(m.group(2), int(m.group(1)))
elif m.group(3)!=None:
@@ -246,6 +264,9 @@ class AnalyseLogRequests(Analyser):
if infile != None:
options.append(infile)
self.addrequest(tuple(options), pri)
+ def finish(self, _):
+ if self.d.errors:
+ self.addrequest("latex", 0, " (because of errors in .log file)")
loganalysers = (AnalyseLogErrors, AnalyseLogRequests)
@@ -282,18 +303,21 @@ def analyseFile(dirname, filename, analyserclasses, parsetype, fulltext=False, c
f.close()
if hasattr(data, "deps") and (recurse
or (recurse==None
- and hasattr(data, "requrired")
+ and hasattr(data, "required")
and data.required)):
# recurse:
for dep, extlist in data.deps:
- deppath = texpath(dirname, dep, extlist=extlist)
+ try:
+ deppath = texpath(dirname, dep, extlist=extlist)
+ except ValueError, e:
+ continue
if (not recursesystemfiles) and re_systemfile.match(deppath): # skip system files
continue
depname = strippath(deppath, dirname)
- depdata = analyseFile(dirname, depname, fulltext, cache, recurse=True)
+ depdata = analyseFile(dirname, depname, analyserclasses, parsetype, fulltext, cache, True, recursesystemfiles)
for a in analysers:
a.merge(depdata)
- if hasattr(data, "required") and data.required:
+ if (hasattr(data, "required") and data.required) or parsetype == "log":
for a in analysers:
a.finish(dirname)
if cache:
@@ -309,6 +333,8 @@ def analyseLog(dirname, filename):
kpsecache = {}
kpseproc = {}
def texpath(dirname,filename,pathtype="tex",progname="latex",extlist=("",)):
+ if extlist == None:
+ return filename
filename = os.path.expanduser(filename)
# first try files in current directory
if pathtype=="bib" and extlist==("",):
@@ -360,7 +386,7 @@ def texpath(dirname,filename,pathtype="tex",progname="latex",extlist=("",)):
stdin=slave,
cwd="/")
kpseproc[(pathtype, progname)] = (proc, master)
- if select.select([master], [], [], .2)[0]:
+ if select.select([master], [], [], .05)[0]:
pathname = os.read(master, 1024)
else:
pathname = None
@@ -458,6 +484,10 @@ def alltexfiles(arglist):
for directory, subdirs, files in os.walk(a):
if not opts.recurse:
subdirs[:] = []
+ else:
+ for skipdir in (".svn", ".bzr"):
+ if skipdir in subdirs:
+ subdirs.remove(skipdir)
for name in files:
if re_texfile.match(name):
if re_ignore.match(name):
@@ -507,14 +537,10 @@ def needsupdate(dirname, texname, data=None):
outdate = os.path.getmtime(outpath)
if outdate < os.path.getmtime(os.path.join(dirname, texname)):
return " (because .tex is newer than .pdf)"
- for filename, extlist in data.deps:
- try:
- deppath = texpath(dirname, filename, extlist=extlist)
- if outdate < os.path.getmtime(os.path.join(dirname, deppath)):
- return " (because %s is newer than .pdf)"%deppath
- except ValueError, e:
- if opts.verbosity > 2:
- error(os.path.join(dirname, texname), "ignored dependency: " + str(e), warning=True)
+ for deppath, extlist in data.deps:
+ assert extlist == None
+ if outdate < os.path.getmtime(os.path.join(dirname, deppath)):
+ return " (because %s is newer than .pdf)"%deppath
# check for errors and requests
logname = jobname + ".log"
@@ -579,7 +605,7 @@ def processTex(dirname, texname, data=None, reason=""):
reason = " (because %s is newer than %s)"%(bib,bbl)
else:
reason = " (because of --force)"
- rmtempfile(bbl, dirname, force=True, reason=reason)
+ rmtempfile(bblpath, force=True, reason=reason)
nextbbls.remove(bbl)
bbls = nextbbls
@@ -589,8 +615,10 @@ def processTex(dirname, texname, data=None, reason=""):
# check for undefined references and run requests
numrun=0
reqs=opts.act # ignore requests if programs are not run
+ logname = jobname + ".log"
while reqs:
- reqs = analyseLog(dirname, jobname+".log").requests
+ logdata = analyseLog(dirname, logname)
+ reqs = logdata.requests
if not reqs: break
pri = reqs.values()
pri.sort(reverse=True)
@@ -603,7 +631,9 @@ def processTex(dirname, texname, data=None, reason=""):
if rp == p:
reason = ""
if opts.verbosity:
- reason = " (because of request in .log file, priority %d)"%rp
+ reason = logdata.requestreason[req]
+ if not reason:
+ reason = " (because of request in .log file, priority %d)"%rp
if req == "latex":
runtex(tex, texname, realname, dirname, reason=reason)
elif isinstance(req, tuple):
@@ -621,16 +651,16 @@ def processTex(dirname, texname, data=None, reason=""):
runtex(tex, texname, realname, dirname, reason=" (because .ind file might have changed)")
if data.needsPS:
- run(["dvips", jobname+".dvi"], dirname)
+ run(["dvips", jobname+".dvi"], dirname, stderr=subprocess.STDOUT)
run(["ps2pdf", jobname+".ps"], dirname)
- rmtempfile(tmplist, dirname)
+ rmtempfile(tmplist)
def bblfiles(dirname, jobname):
files = dircache.listdir(dirname)
return fnmatch.filter(files, "%s*.bbl"%jobname)
-def rmtempfile(filenames, dirname, force=False, reason=""):
+def rmtempfile(filenames, force=False, reason=""):
if (opts.deletetempfiles or force) and filenames:
if not isinstance(filenames, list):
filenames = [filenames]
@@ -638,11 +668,10 @@ def rmtempfile(filenames, dirname, force=False, reason=""):
print " removing %s%s"%(", ".join(filenames), reason)
if opts.act:
for f in filenames:
- fullname = os.path.join(dirname, f)
- if os.path.exists(fullname):
- os.remove(fullname)
+ if os.path.exists(f):
+ os.remove(f)
else:
- error(fullname, "could not be removed (does not exist)", warning=True)
+ error(f, "could not be removed (does not exist)", warning=True)
def run(arglist, dirname, reason="", inf=None, outf=None, stderr=None):
"""Run a command with optional io redirections.
@@ -761,7 +790,7 @@ def preparermligs(texname, dirname, texpath, tmplist):
else:
try:
(subdir, texbasename) = os.path.split(texname)
- rmligsbasename = ".%s.rmligs.tex"%texbasename[:-4]
+ rmligsbasename = "%s-rmligs.tex"%texbasename[:-4]
rmligsname = os.path.join(subdir, rmligsbasename)
rmligspath = os.path.join(dirname, rmligsname)
if opts.act:
@@ -773,17 +802,18 @@ def preparermligs(texname, dirname, texpath, tmplist):
return texname
else:
tmplist.append(rmligspath)
-
def rewriteinputrmligs(m):
- name=m.group(2)
+ name = m.group(2)
if not os.path.exists(os.path.join(dirname,name)):
name+=".tex"
- if os.path.exists(os.path.join(dirname, name)):
- name = preparermligs(name, dirname, tmplist)
+ path = os.path.join(dirname, name)
+ if os.path.exists(path):
+ name = preparermligs(name, dirname, path, tmplist)
else:
error(texpath, "%s: File could not be located. Not using rmligs."%name, warning=True)
return "\\%s{%s}"%(m.group(1), name[:-4])
def filteroutput(d):
+ d = re_commentinclude.sub("", d)
rmligsfile.write(re_inputinclude.sub(rewriteinputrmligs, d))
return None
run([rmligs_name, "-f"], dirname, inf=texfile, outf=filteroutput)
@@ -835,14 +865,17 @@ try:
re_texfile = re.compile(".*\.tex$", re.I)
if iswindows:
re_systemfile = re.compile("^?:\\\\Program", re.I)
+ re_nonlocal = re.compile("^?:\\\\")
else:
re_systemfile = re.compile("^/usr/")
+ re_nonlocal = re.compile("^/")
re_texcomment = re.compile("(?<!\\\\)%.*?$", re.M)
re_required = re.compile(opts.requiredpattern)
re_inputinclude = re.compile('\\\\(input|include|@input)\\{([^}]*)\\}')
+ re_commentinclude = re.compile('(?<!\\\\)%[^%\n\r]*\\\\(input|include|@input)\\{([^}]*?)\\}[^%\n\r]*?$', re.M)
re_documentclass = re.compile('\\\\documentclass(\\[.*?\\])?\\{([^}]*)\\}')
re_usepackage = re.compile('\\\\usepackage(\\[.*?\\])?\\{([^}]*)\\}')
re_usetheme = re.compile('\\\\use(|color|font|inner|outer)theme(\\[.*?\\])?\\{([^}]*)\\}')
@@ -859,15 +892,15 @@ try:
re_longreq = re.compile("^(binary|option|infile)=(.*?)$", re.M)
re_error = re.compile('^! ', re.M)
- re_rmligsfile = re.compile("\\.([^/ ]+)\\.rmligs\\.tex")
+ re_rmligsfile = re.compile("([^/ ]+)-rmligs\\.tex")
if __name__ == "__main__":
-# import cProfile
-# import pstats
-# cProfile.run("main(programargs)", "mystats")
-# p = pstats.Stats("mystats")
-# p.sort_stats('time').print_stats()
-
+ #import cProfile
+ #import pstats
+ #cProfile.run("main(programargs)", "mystats")
+ #p = pstats.Stats("mystats")
+ #p.sort_stats('time').print_stats()
+
main(programargs)
except KeyboardInterrupt: