blob: 68130221a8f5ec712cfd26300f92001de2d19597 [file] [log] [blame]
akmhoquefa8ee9b2014-03-14 09:06:24 -05001#! /usr/bin/env python
2# encoding: utf-8
3# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
4
5import os,re
6from waflib import Utils,Task,Errors,Logs
7from waflib.TaskGen import feature,before_method
8re_bibunit=re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
9def bibunitscan(self):
10 node=self.inputs[0]
11 nodes=[]
12 if not node:return nodes
13 code=node.read()
14 for match in re_bibunit.finditer(code):
15 path=match.group('file')
16 if path:
17 for k in['','.bib']:
18 Logs.debug('tex: trying %s%s'%(path,k))
19 fi=node.parent.find_resource(path+k)
20 if fi:
21 nodes.append(fi)
22 else:
23 Logs.debug('tex: could not find %s'%path)
24 Logs.debug("tex: found the following bibunit files: %s"%nodes)
25 return nodes
26exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps']
27exts_tex=['.ltx','.tex']
28re_tex=re.compile(r'\\(?P<type>include|bibliography|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
29g_bibtex_re=re.compile('bibdata',re.M)
30class tex(Task.Task):
31 bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
32 bibtex_fun.__doc__="""
33 Execute the program **bibtex**
34 """
35 makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False)
36 makeindex_fun.__doc__="""
37 Execute the program **makeindex**
38 """
39 def exec_command(self,cmd,**kw):
40 bld=self.generator.bld
41 try:
42 if not kw.get('cwd',None):
43 kw['cwd']=bld.cwd
44 except AttributeError:
45 bld.cwd=kw['cwd']=bld.variant_dir
46 return Utils.subprocess.Popen(cmd,**kw).wait()
47 def scan_aux(self,node):
48 nodes=[node]
49 re_aux=re.compile(r'\\@input{(?P<file>[^{}]*)}',re.M)
50 def parse_node(node):
51 code=node.read()
52 for match in re_aux.finditer(code):
53 path=match.group('file')
54 found=node.parent.find_or_declare(path)
55 if found and found not in nodes:
56 Logs.debug('tex: found aux node '+found.abspath())
57 nodes.append(found)
58 parse_node(found)
59 parse_node(node)
60 return nodes
61 def scan(self):
62 node=self.inputs[0]
63 nodes=[]
64 names=[]
65 seen=[]
66 if not node:return(nodes,names)
67 def parse_node(node):
68 if node in seen:
69 return
70 seen.append(node)
71 code=node.read()
72 global re_tex
73 for match in re_tex.finditer(code):
74 for path in match.group('file').split(','):
75 if path:
76 add_name=True
77 found=None
78 for k in exts_deps_tex:
79 Logs.debug('tex: trying %s%s'%(path,k))
80 found=node.parent.find_resource(path+k)
81 for tsk in self.generator.tasks:
82 if not found or found in tsk.outputs:
83 break
84 else:
85 nodes.append(found)
86 add_name=False
87 for ext in exts_tex:
88 if found.name.endswith(ext):
89 parse_node(found)
90 break
91 if add_name:
92 names.append(path)
93 parse_node(node)
94 for x in nodes:
95 x.parent.get_bld().mkdir()
96 Logs.debug("tex: found the following : %s and names %s"%(nodes,names))
97 return(nodes,names)
98 def check_status(self,msg,retcode):
99 if retcode!=0:
100 raise Errors.WafError("%r command exit status %r"%(msg,retcode))
101 def bibfile(self):
102 for aux_node in self.aux_nodes:
103 try:
104 ct=aux_node.read()
105 except(OSError,IOError):
106 Logs.error('Error reading %s: %r'%aux_node.abspath())
107 continue
108 if g_bibtex_re.findall(ct):
109 Logs.warn('calling bibtex')
110 self.env.env={}
111 self.env.env.update(os.environ)
112 self.env.env.update({'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS})
113 self.env.SRCFILE=aux_node.name[:-4]
114 self.check_status('error when calling bibtex',self.bibtex_fun())
115 def bibunits(self):
116 try:
117 bibunits=bibunitscan(self)
118 except OSError:
119 Logs.error('error bibunitscan')
120 else:
121 if bibunits:
122 fn=['bu'+str(i)for i in xrange(1,len(bibunits)+1)]
123 if fn:
124 Logs.warn('calling bibtex on bibunits')
125 for f in fn:
126 self.env.env={'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS}
127 self.env.SRCFILE=f
128 self.check_status('error when calling bibtex',self.bibtex_fun())
129 def makeindex(self):
130 try:
131 idx_path=self.idx_node.abspath()
132 os.stat(idx_path)
133 except OSError:
134 Logs.warn('index file %s absent, not calling makeindex'%idx_path)
135 else:
136 Logs.warn('calling makeindex')
137 self.env.SRCFILE=self.idx_node.name
138 self.env.env={}
139 self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun())
140 def bibtopic(self):
141 p=self.inputs[0].parent.get_bld()
142 if os.path.exists(os.path.join(p.abspath(),'btaux.aux')):
143 self.aux_nodes+=p.ant_glob('*[0-9].aux')
144 def run(self):
145 env=self.env
146 if not env['PROMPT_LATEX']:
147 env.append_value('LATEXFLAGS','-interaction=batchmode')
148 env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
149 env.append_value('XELATEXFLAGS','-interaction=batchmode')
150 fun=self.texfun
151 node=self.inputs[0]
152 srcfile=node.abspath()
153 texinputs=self.env.TEXINPUTS or''
154 self.TEXINPUTS=node.parent.get_bld().abspath()+os.pathsep+node.parent.get_src().abspath()+os.pathsep+texinputs+os.pathsep
155 self.cwd=self.inputs[0].parent.get_bld().abspath()
156 Logs.warn('first pass on %s'%self.__class__.__name__)
157 self.env.env={}
158 self.env.env.update(os.environ)
159 self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
160 self.env.SRCFILE=srcfile
161 self.check_status('error when calling latex',fun())
162 self.aux_nodes=self.scan_aux(node.change_ext('.aux'))
163 self.idx_node=node.change_ext('.idx')
164 self.bibtopic()
165 self.bibfile()
166 self.bibunits()
167 self.makeindex()
168 hash=''
169 for i in range(10):
170 prev_hash=hash
171 try:
172 hashes=[Utils.h_file(x.abspath())for x in self.aux_nodes]
173 hash=Utils.h_list(hashes)
174 except(OSError,IOError):
175 Logs.error('could not read aux.h')
176 pass
177 if hash and hash==prev_hash:
178 break
179 Logs.warn('calling %s'%self.__class__.__name__)
180 self.env.env={}
181 self.env.env.update(os.environ)
182 self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
183 self.env.SRCFILE=srcfile
184 self.check_status('error when calling %s'%self.__class__.__name__,fun())
185class latex(tex):
186 texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
187class pdflatex(tex):
188 texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False)
189class xelatex(tex):
190 texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False)
191class dvips(Task.Task):
192 run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}'
193 color='BLUE'
194 after=['latex','pdflatex','xelatex']
195class dvipdf(Task.Task):
196 run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}'
197 color='BLUE'
198 after=['latex','pdflatex','xelatex']
199class pdf2ps(Task.Task):
200 run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}'
201 color='BLUE'
202 after=['latex','pdflatex','xelatex']
203@feature('tex')
204@before_method('process_source')
205def apply_tex(self):
206 if not getattr(self,'type',None)in['latex','pdflatex','xelatex']:
207 self.type='pdflatex'
208 tree=self.bld
209 outs=Utils.to_list(getattr(self,'outs',[]))
210 self.env['PROMPT_LATEX']=getattr(self,'prompt',1)
211 deps_lst=[]
212 if getattr(self,'deps',None):
213 deps=self.to_list(self.deps)
214 for filename in deps:
215 n=self.path.find_resource(filename)
216 if not n:
217 self.bld.fatal('Could not find %r for %r'%(filename,self))
218 if not n in deps_lst:
219 deps_lst.append(n)
220 for node in self.to_nodes(self.source):
221 if self.type=='latex':
222 task=self.create_task('latex',node,node.change_ext('.dvi'))
223 elif self.type=='pdflatex':
224 task=self.create_task('pdflatex',node,node.change_ext('.pdf'))
225 elif self.type=='xelatex':
226 task=self.create_task('xelatex',node,node.change_ext('.pdf'))
227 task.env=self.env
228 if deps_lst:
229 try:
230 lst=tree.node_deps[task.uid()]
231 for n in deps_lst:
232 if not n in lst:
233 lst.append(n)
234 except KeyError:
235 tree.node_deps[task.uid()]=deps_lst
236 v=dict(os.environ)
237 p=node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.get_bld().abspath()+os.pathsep+v.get('TEXINPUTS','')+os.pathsep
238 v['TEXINPUTS']=p
239 if self.type=='latex':
240 if'ps'in outs:
241 tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
242 tsk.env.env=dict(v)
243 if'pdf'in outs:
244 tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
245 tsk.env.env=dict(v)
246 elif self.type=='pdflatex':
247 if'ps'in outs:
248 self.create_task('pdf2ps',task.outputs,node.change_ext('.ps'))
249 self.source=[]
250def configure(self):
251 v=self.env
252 for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
253 try:
254 self.find_program(p,var=p.upper())
255 except self.errors.ConfigurationError:
256 pass
257 v['DVIPSFLAGS']='-Ppdf'