Created
February 28, 2012 17:57
-
-
Save ihaque/1933998 to your computer and use it in GitHub Desktop.
Thesis compilation tools
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: master.pdf | |
clean: | |
rm -f *.pdf *.log *.aux *.blg *.bbl *.lof *.lot *.out *.toc | |
rm -f *_lores.tex | |
rm -f images/*/downsampled/* | |
master.pdf: master.tex PAPER_lores.tex SIML.tex GPUCG_lores.tex SCISSORS_lores.tex \ | |
kernelnoise_lores.tex kernelnoise_chapter.tex nips_abstract.tex nips_appendices.tex\ | |
bibliography.bib introduction.tex master-macros.sty conclusion.tex \ | |
bounds.tex realtime_lores.tex acknowledgement.tex abstract.tex | |
pdflatex master && bibtex master && pdflatex master && pdflatex master | |
PAPER_lores.tex: resample.py PAPER.tex | |
python resample.py PAPER.tex | |
SCISSORS_lores.tex: resample.py SCISSORS.tex | |
python resample.py SCISSORS.tex | |
GPUCG_lores.tex: resample.py GPUCG.tex | |
python resample.py GPUCG.tex | |
kernelnoise_lores.tex: resample.py kernelnoise.tex | |
python resample.py kernelnoise.tex | |
realtime_lores.tex: resample.py realtime.tex | |
python resample.py realtime.tex |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys,os,re,os.path | |
from subprocess import Popen,PIPE | |
from time import sleep | |
class Environment: | |
def __init__(self): | |
# units = inches; quantities taken from suthesis-2e.sty | |
env = {'textwidth': 6, 'textheight': 8.1} | |
self.stack = [env] | |
def enter(self,width=None,height=None): | |
if width is None: | |
width = self.width() | |
if height is None: | |
height = self.height() | |
env = {'textwidth': width, 'textheight': height} | |
self.stack.insert(0,env) | |
#print "Entering new environment with width =",self.width(),"height =",self.height() | |
return | |
def leave(self): | |
del self.stack[0] | |
#print "Leaving environment, now width =",self.width(),"height =",self.height() | |
return | |
def height(self): | |
return self.stack[0]["textheight"] | |
def width(self): | |
return self.stack[0]["textwidth"] | |
class ProcessQueue: | |
def __init__(self,maxProcs = 16): | |
self.q = [] | |
self.maxprocs = maxProcs | |
def append(self,p): | |
if len(self.q) == self.maxprocs: | |
self.waitfirst() | |
self.q.append(p) | |
def waitfirst(self): | |
if len(self.q) == 0: | |
return | |
while self.q[0].poll() is None: | |
sleep(0.2) | |
del self.q[0] | |
return | |
def wait(self): | |
while len(self.q) > 0: | |
self.waitfirst() | |
return | |
def resize(fnfrom,fnto,outw,outh,inpw,inph,dpi=150): | |
#print "\tResizing",fnfrom,"to",fnto,"to width = %.2f in and height = %.2f in"%(outw,outh) | |
print "\tResizing",fnfrom,"to width = %.2f in and height = %.2f in"%(outw,outh) | |
out_pw = int(round(dpi*outw)) | |
out_ph = int(round(dpi*outh)) | |
if out_pw > inpw or out_ph > inph: | |
print "\tRefusing to scale up image",fnfrom | |
return False | |
size_ratio = float(inpw*inph)/(out_pw*out_ph) | |
print "\t(%d,%d) -> (%d,%d) pixels (%.2fx reduction)"%(inpw,inph,out_pw,out_ph,size_ratio) | |
args = ['convert',fnfrom,"-resize","%dx%d!"%(out_pw,out_ph),fnto] | |
#print "\t",args | |
return True,Popen(args) | |
def getDims(filename): | |
# Uses ImageMagick 'identify' to get dimensions | |
p = Popen(["identify",filename],stdout=PIPE) | |
(out,err) = p.communicate() | |
(w,h) = map(int,out.split()[2].split("x")) | |
return w,h | |
def processJPG(env,opts,filename): | |
optarr = opts.split(",") | |
#print "JPEG file:",filename,"with options",optarr | |
width = None | |
height = None | |
for o in optarr: | |
if o.startswith("width="): | |
width = parseSize(env,o.split("=")[1]) | |
elif o.startswith("height="): | |
height = parseSize(env,o.split("=")[1]) | |
else: | |
raise ValueError,"Don't know how to handle option %s in JPEG processor"%o | |
(fw,fh) = getDims(filename) | |
#print "\tFile",filename,"is",fw,"x",fh,"pixels" | |
aspect = float(fw)/float(fh) | |
if height is None and not width is None: | |
height = width/aspect | |
elif width is None and not height is None: | |
width = aspect*height | |
elif width is None and height is None: | |
raise ValueError,"No size information specified for file",filename | |
(dir,fn) = os.path.split(filename) | |
newdir = os.path.join(dir,"downsampled") | |
newfn = os.path.join(newdir,fn) | |
retcode,p = resize(filename,newfn,width,height,fw,fh) | |
if retcode: | |
return newfn,p | |
else: | |
return filename,None | |
def processPDF(env,opts,filename): | |
#print "Skipping PDF file",filename | |
return filename,None | |
def parseSize(env,w): | |
#print "Parsing sizespec",w | |
w = w.replace("linewidth","textwidth") | |
w = w.replace("columnwidth","textwidth") | |
w = w.replace(r"\textwidth","*%.2f"%env.width()) | |
w = w.replace(r"\textheight","*%.2f"%env.width()) | |
w = w.replace("in","*1") | |
w = w.replace("cm","*(1.0/2.54)") | |
if w[0] == "*": | |
w = "1"+w | |
#print "\tevaluating",w | |
return eval(w) | |
def parseFile(texfile): | |
handlers = {'.pdf':processPDF,'.jpg':processJPG} | |
re_gfx = re.compile(r"\includegraphics\[([^\]]*)\]\{([^\}]*)\}") | |
re_mp_start = re.compile(r"begin{minipage}\[[^\]]*\]\{([^\}]*)\}") | |
re_mp_end = re.compile(r"end\{minipage\}") | |
env = Environment() | |
newfile = [] | |
changedgfx = False | |
pq = ProcessQueue() | |
f = open(texfile,"rt") | |
for line in f: | |
line = line.rstrip("\n") | |
# This parser assumes you're not interspersing commands on the same line | |
mp_start = re_mp_start.search(line) | |
mp_end = re_mp_end.search(line) | |
gfx = re_gfx.search(line) | |
if mp_start: | |
env.enter(width=parseSize(env,mp_start.group(1))) | |
newfile.append(line) | |
elif mp_end: | |
env.leave() | |
newfile.append(line) | |
elif gfx: | |
filename = gfx.group(2) | |
opts = gfx.group(1) | |
filetype = os.path.splitext(filename)[1] | |
if filetype not in handlers: | |
raise ValueError,"Found file %s of type %s with no handler"%(filename,filetype) | |
newfn,p = handlers[filetype](env,opts,filename) | |
if newfn != filename: | |
newfile.append("\\includegraphics[%s]{%s}"%(opts,newfn)) | |
changedgfx = True | |
pq.append(p) | |
else: | |
newfile.append(line) | |
else: | |
newfile.append(line) | |
f.close() | |
newfile.append("") #newline at end of file | |
if changedgfx: | |
newtex = os.path.splitext(texfile)[0]+"_lores.tex" | |
print "Writing modified texfile to",newtex | |
f = open(newtex,"wt") | |
f.write("\n".join(newfile)) | |
f.close() | |
pq.wait() | |
return | |
def main(files): | |
for f in files: | |
if not f.endswith(".tex"): | |
raise ValueError,"Error, given non-LaTeX file %s"%f | |
parseFile(f) | |
return | |
if __name__ == "__main__": | |
main(sys.argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment