source: waflib/Tools/tex.py @ c82a034

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since c82a034 was 904702d, checked in by Paul Brossier <piem@piem.org>, 10 years ago

waf, waflib: update to 1.8.7

  • Property mode set to 100644
File size: 10.4 KB
Line 
1#! /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,Node
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','.sty']
27exts_tex=['.ltx','.tex']
28re_tex=re.compile(r'\\(?P<type>usepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
29g_bibtex_re=re.compile('bibdata',re.M)
30g_glossaries_re=re.compile('\\@newglossary',re.M)
31class tex(Task.Task):
32        bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
33        bibtex_fun.__doc__="""
34        Execute the program **bibtex**
35        """
36        makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False)
37        makeindex_fun.__doc__="""
38        Execute the program **makeindex**
39        """
40        makeglossaries_fun,_=Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}',shell=False)
41        makeglossaries_fun.__doc__="""
42        Execute the program **makeglossaries**
43        """
44        def exec_command(self,cmd,**kw):
45                bld=self.generator.bld
46                Logs.info('runner: %r'%cmd)
47                try:
48                        if not kw.get('cwd',None):
49                                kw['cwd']=bld.cwd
50                except AttributeError:
51                        bld.cwd=kw['cwd']=bld.variant_dir
52                return Utils.subprocess.Popen(cmd,**kw).wait()
53        def scan_aux(self,node):
54                nodes=[node]
55                re_aux=re.compile(r'\\@input{(?P<file>[^{}]*)}',re.M)
56                def parse_node(node):
57                        code=node.read()
58                        for match in re_aux.finditer(code):
59                                path=match.group('file')
60                                found=node.parent.find_or_declare(path)
61                                if found and found not in nodes:
62                                        Logs.debug('tex: found aux node '+found.abspath())
63                                        nodes.append(found)
64                                        parse_node(found)
65                parse_node(node)
66                return nodes
67        def scan(self):
68                node=self.inputs[0]
69                nodes=[]
70                names=[]
71                seen=[]
72                if not node:return(nodes,names)
73                def parse_node(node):
74                        if node in seen:
75                                return
76                        seen.append(node)
77                        code=node.read()
78                        global re_tex
79                        for match in re_tex.finditer(code):
80                                multibib=match.group('type')
81                                if multibib and multibib.startswith('bibliography'):
82                                        multibib=multibib[len('bibliography'):]
83                                        if multibib.startswith('style'):
84                                                continue
85                                else:
86                                        multibib=None
87                                for path in match.group('file').split(','):
88                                        if path:
89                                                add_name=True
90                                                found=None
91                                                for k in exts_deps_tex:
92                                                        for up in self.texinputs_nodes:
93                                                                Logs.debug('tex: trying %s%s'%(path,k))
94                                                                found=up.find_resource(path+k)
95                                                                if found:
96                                                                        break
97                                                        for tsk in self.generator.tasks:
98                                                                if not found or found in tsk.outputs:
99                                                                        break
100                                                        else:
101                                                                nodes.append(found)
102                                                                add_name=False
103                                                                for ext in exts_tex:
104                                                                        if found.name.endswith(ext):
105                                                                                parse_node(found)
106                                                                                break
107                                                        if found and multibib and found.name.endswith('.bib'):
108                                                                try:
109                                                                        self.multibibs.append(found)
110                                                                except AttributeError:
111                                                                        self.multibibs=[found]
112                                                if add_name:
113                                                        names.append(path)
114                parse_node(node)
115                for x in nodes:
116                        x.parent.get_bld().mkdir()
117                Logs.debug("tex: found the following : %s and names %s"%(nodes,names))
118                return(nodes,names)
119        def check_status(self,msg,retcode):
120                if retcode!=0:
121                        raise Errors.WafError("%r command exit status %r"%(msg,retcode))
122        def bibfile(self):
123                for aux_node in self.aux_nodes:
124                        try:
125                                ct=aux_node.read()
126                        except EnvironmentError:
127                                Logs.error('Error reading %s: %r'%aux_node.abspath())
128                                continue
129                        if g_bibtex_re.findall(ct):
130                                Logs.info('calling bibtex')
131                                self.env.env={}
132                                self.env.env.update(os.environ)
133                                self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
134                                self.env.SRCFILE=aux_node.name[:-4]
135                                self.check_status('error when calling bibtex',self.bibtex_fun())
136                for node in getattr(self,'multibibs',[]):
137                        self.env.env={}
138                        self.env.env.update(os.environ)
139                        self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
140                        self.env.SRCFILE=node.name[:-4]
141                        self.check_status('error when calling bibtex',self.bibtex_fun())
142        def bibunits(self):
143                try:
144                        bibunits=bibunitscan(self)
145                except OSError:
146                        Logs.error('error bibunitscan')
147                else:
148                        if bibunits:
149                                fn=['bu'+str(i)for i in range(1,len(bibunits)+1)]
150                                if fn:
151                                        Logs.info('calling bibtex on bibunits')
152                                for f in fn:
153                                        self.env.env={'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}
154                                        self.env.SRCFILE=f
155                                        self.check_status('error when calling bibtex',self.bibtex_fun())
156        def makeindex(self):
157                self.idx_node=self.inputs[0].change_ext('.idx')
158                try:
159                        idx_path=self.idx_node.abspath()
160                        os.stat(idx_path)
161                except OSError:
162                        Logs.info('index file %s absent, not calling makeindex'%idx_path)
163                else:
164                        Logs.info('calling makeindex')
165                        self.env.SRCFILE=self.idx_node.name
166                        self.env.env={}
167                        self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun())
168        def bibtopic(self):
169                p=self.inputs[0].parent.get_bld()
170                if os.path.exists(os.path.join(p.abspath(),'btaux.aux')):
171                        self.aux_nodes+=p.ant_glob('*[0-9].aux')
172        def makeglossaries(self):
173                src_file=self.inputs[0].abspath()
174                base_file=os.path.basename(src_file)
175                base,_=os.path.splitext(base_file)
176                for aux_node in self.aux_nodes:
177                        try:
178                                ct=aux_node.read()
179                        except EnvironmentError:
180                                Logs.error('Error reading %s: %r'%aux_node.abspath())
181                                continue
182                        if g_glossaries_re.findall(ct):
183                                if not self.env.MAKEGLOSSARIES:
184                                        raise Errors.WafError("The program 'makeglossaries' is missing!")
185                                Logs.warn('calling makeglossaries')
186                                self.env.SRCFILE=base
187                                self.check_status('error when calling makeglossaries %s'%base,self.makeglossaries_fun())
188                                return
189        def texinputs(self):
190                return os.pathsep.join([k.abspath()for k in self.texinputs_nodes])+os.pathsep
191        def run(self):
192                env=self.env
193                if not env['PROMPT_LATEX']:
194                        env.append_value('LATEXFLAGS','-interaction=batchmode')
195                        env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
196                        env.append_value('XELATEXFLAGS','-interaction=batchmode')
197                self.cwd=self.inputs[0].parent.get_bld().abspath()
198                Logs.info('first pass on %s'%self.__class__.__name__)
199                cur_hash=self.hash_aux_nodes()
200                self.call_latex()
201                self.hash_aux_nodes()
202                self.bibtopic()
203                self.bibfile()
204                self.bibunits()
205                self.makeindex()
206                self.makeglossaries()
207                for i in range(10):
208                        prev_hash=cur_hash
209                        cur_hash=self.hash_aux_nodes()
210                        if not cur_hash:
211                                Logs.error('No aux.h to process')
212                        if cur_hash and cur_hash==prev_hash:
213                                break
214                        Logs.info('calling %s'%self.__class__.__name__)
215                        self.call_latex()
216        def hash_aux_nodes(self):
217                try:
218                        nodes=self.aux_nodes
219                except AttributeError:
220                        try:
221                                self.aux_nodes=self.scan_aux(self.inputs[0].change_ext('.aux'))
222                        except IOError:
223                                return None
224                return Utils.h_list([Utils.h_file(x.abspath())for x in self.aux_nodes])
225        def call_latex(self):
226                self.env.env={}
227                self.env.env.update(os.environ)
228                self.env.env.update({'TEXINPUTS':self.texinputs()})
229                self.env.SRCFILE=self.inputs[0].abspath()
230                self.check_status('error when calling latex',self.texfun())
231class latex(tex):
232        texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
233class pdflatex(tex):
234        texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False)
235class xelatex(tex):
236        texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False)
237class dvips(Task.Task):
238        run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}'
239        color='BLUE'
240        after=['latex','pdflatex','xelatex']
241class dvipdf(Task.Task):
242        run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}'
243        color='BLUE'
244        after=['latex','pdflatex','xelatex']
245class pdf2ps(Task.Task):
246        run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}'
247        color='BLUE'
248        after=['latex','pdflatex','xelatex']
249@feature('tex')
250@before_method('process_source')
251def apply_tex(self):
252        if not getattr(self,'type',None)in('latex','pdflatex','xelatex'):
253                self.type='pdflatex'
254        tree=self.bld
255        outs=Utils.to_list(getattr(self,'outs',[]))
256        self.env['PROMPT_LATEX']=getattr(self,'prompt',1)
257        deps_lst=[]
258        if getattr(self,'deps',None):
259                deps=self.to_list(self.deps)
260                for dep in deps:
261                        if isinstance(dep,str):
262                                n=self.path.find_resource(dep)
263                                if not n:
264                                        self.bld.fatal('Could not find %r for %r'%(dep,self))
265                                if not n in deps_lst:
266                                        deps_lst.append(n)
267                        elif isinstance(dep,Node.Node):
268                                deps_lst.append(dep)
269        for node in self.to_nodes(self.source):
270                if self.type=='latex':
271                        task=self.create_task('latex',node,node.change_ext('.dvi'))
272                elif self.type=='pdflatex':
273                        task=self.create_task('pdflatex',node,node.change_ext('.pdf'))
274                elif self.type=='xelatex':
275                        task=self.create_task('xelatex',node,node.change_ext('.pdf'))
276                task.env=self.env
277                if deps_lst:
278                        for n in deps_lst:
279                                if not n in task.dep_nodes:
280                                        task.dep_nodes.append(n)
281                if hasattr(self,'texinputs_nodes'):
282                        task.texinputs_nodes=self.texinputs_nodes
283                else:
284                        task.texinputs_nodes=[node.parent,node.parent.get_bld(),self.path,self.path.get_bld()]
285                        lst=os.environ.get('TEXINPUTS','')
286                        if self.env.TEXINPUTS:
287                                lst+=os.pathsep+self.env.TEXINPUTS
288                        if lst:
289                                lst=lst.split(os.pathsep)
290                        for x in lst:
291                                if x:
292                                        if os.path.isabs(x):
293                                                p=self.bld.root.find_node(x)
294                                                if p:
295                                                        task.texinputs_nodes.append(p)
296                                                else:
297                                                        Logs.error('Invalid TEXINPUTS folder %s'%x)
298                                        else:
299                                                Logs.error('Cannot resolve relative paths in TEXINPUTS %s'%x)
300                if self.type=='latex':
301                        if'ps'in outs:
302                                tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
303                                tsk.env.env=dict(os.environ)
304                        if'pdf'in outs:
305                                tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
306                                tsk.env.env=dict(os.environ)
307                elif self.type=='pdflatex':
308                        if'ps'in outs:
309                                self.create_task('pdf2ps',task.outputs,node.change_ext('.ps'))
310        self.source=[]
311def configure(self):
312        v=self.env
313        for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split():
314                try:
315                        self.find_program(p,var=p.upper())
316                except self.errors.ConfigurationError:
317                        pass
318        v['DVIPSFLAGS']='-Ppdf'
Note: See TracBrowser for help on using the repository browser.