#! /usr/bin/env python # encoding: utf-8 import os,re import Utils,TaskGen,Task,Runner,Build from TaskGen import feature,before from Logs import error,warn,debug re_tex=re.compile(r'\\(?Pinclude|input|import|bringin|lstinputlisting){(?P[^{}]*)}',re.M) def scan(self): node=self.inputs[0] env=self.env nodes=[] names=[] if not node:return(nodes,names) code=Utils.readf(node.abspath(env)) curdirnode=self.curdirnode abs=curdirnode.abspath() for match in re_tex.finditer(code): path=match.group('file') if path: for k in['','.tex','.ltx']: debug('tex: trying %s%s'%(path,k)) try: os.stat(abs+os.sep+path+k) except OSError: continue found=path+k node=curdirnode.find_resource(found) if node: nodes.append(node) else: debug('tex: could not find %s'%path) names.append(path) debug("tex: found the following : %s and names %s"%(nodes,names)) return(nodes,names) latex_fun,_=Task.compile_fun('latex','${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False) pdflatex_fun,_=Task.compile_fun('pdflatex','${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False) bibtex_fun,_=Task.compile_fun('bibtex','${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False) makeindex_fun,_=Task.compile_fun('bibtex','${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False) g_bibtex_re=re.compile('bibdata',re.M) def tex_build(task,command='LATEX'): env=task.env bld=task.generator.bld if not env['PROMPT_LATEX']: env.append_value('LATEXFLAGS','-interaction=batchmode') env.append_value('PDFLATEXFLAGS','-interaction=batchmode') fun=latex_fun if command=='PDFLATEX': fun=pdflatex_fun node=task.inputs[0] reldir=node.bld_dir(env) srcfile=node.abspath(env) sr2=node.parent.abspath()+os.pathsep+node.parent.abspath(env)+os.pathsep aux_node=node.change_ext('.aux') idx_node=node.change_ext('.idx') nm=aux_node.name docuname=nm[:len(nm)-4] task.cwd=task.inputs[0].parent.abspath(task.env) warn('first pass on %s'%command) task.env.env={'TEXINPUTS':sr2} task.env.SRCFILE=srcfile ret=fun(task) if ret: return ret try: ct=Utils.readf(aux_node.abspath(env)) except(OSError,IOError): error('error bibtex scan') else: fo=g_bibtex_re.findall(ct) if fo: warn('calling bibtex') task.env.env={'BIBINPUTS':sr2,'BSTINPUTS':sr2} task.env.SRCFILE=docuname ret=bibtex_fun(task) if ret: error('error when calling bibtex %s'%docuname) return ret try: idx_path=idx_node.abspath(env) os.stat(idx_path) except OSError: error('error file.idx scan') else: warn('calling makeindex') task.env.SRCFILE=idx_node.name task.env.env={} ret=makeindex_fun(task) if ret: error('error when calling makeindex %s'%idx_path) return ret hash='' i=0 while i<10: i+=1 prev_hash=hash try: hash=Utils.h_file(aux_node.abspath(env)) except KeyError: error('could not read aux.h -> %s'%aux_node.abspath(env)) pass if hash and hash==prev_hash: break warn('calling %s'%command) task.env.env={'TEXINPUTS':sr2+os.pathsep} task.env.SRCFILE=srcfile ret=fun(task) if ret: error('error when calling %s %s'%(command,latex_compile_cmd)) return ret return None latex_vardeps=['LATEX','LATEXFLAGS'] def latex_build(task): return tex_build(task,'LATEX') pdflatex_vardeps=['PDFLATEX','PDFLATEXFLAGS'] def pdflatex_build(task): return tex_build(task,'PDFLATEX') class tex_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def apply_tex(self): if not getattr(self,'type',None)in['latex','pdflatex']: self.type='pdflatex' tree=self.bld outs=Utils.to_list(getattr(self,'outs',[])) self.env['PROMPT_LATEX']=getattr(self,'prompt',1) deps_lst=[] if getattr(self,'deps',None): deps=self.to_list(self.deps) for filename in deps: n=self.path.find_resource(filename) if not n in deps_lst:deps_lst.append(n) self.source=self.to_list(self.source) for filename in self.source: base,ext=os.path.splitext(filename) node=self.path.find_resource(filename) if not node:raise Utils.WafError('cannot find %s'%filename) if self.type=='latex': task=self.create_task('latex',node,node.change_ext('.dvi')) elif self.type=='pdflatex': task=self.create_task('pdflatex',node,node.change_ext('.pdf')) task.env=self.env task.curdirnode=self.path if deps_lst: variant=node.variant(self.env) try: lst=tree.node_deps[task.unique_id()] for n in deps_lst: if not n in lst: lst.append(n) except KeyError: tree.node_deps[task.unique_id()]=deps_lst if self.type=='latex': if'ps'in outs: tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps')) tsk.env.env={'TEXINPUTS':node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.abspath(self.env)} if'pdf'in outs: tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf')) tsk.env.env={'TEXINPUTS':node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.abspath(self.env)} elif self.type=='pdflatex': if'ps'in outs: self.create_task('pdf2ps',task.outputs,node.change_ext('.ps')) self.source=[] def detect(conf): v=conf.env for p in'tex latex pdflatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split(): conf.find_program(p,var=p.upper()) v[p.upper()+'FLAGS']='' v['DVIPSFLAGS']='-Ppdf' b=Task.simple_task_type b('tex','${TEX} ${TEXFLAGS} ${SRC}',color='BLUE',shell=False) b('bibtex','${BIBTEX} ${BIBTEXFLAGS} ${SRC}',color='BLUE',shell=False) b('dvips','${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}',color='BLUE',after="latex pdflatex tex bibtex",shell=False) b('dvipdf','${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}',color='BLUE',after="latex pdflatex tex bibtex",shell=False) b('pdf2ps','${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}',color='BLUE',after="dvipdf pdflatex",shell=False) b=Task.task_type_from_func cls=b('latex',latex_build,vars=latex_vardeps) cls.scan=scan cls=b('pdflatex',pdflatex_build,vars=pdflatex_vardeps) cls.scan=scan feature('tex')(apply_tex) before('apply_core')(apply_tex)