Package wafadmin :: Package Tools :: Module tex
[hide private]
[frames] | no frames]

Source Code for Module wafadmin.Tools.tex

  1  #!/usr/bin/env python 
  2  # encoding: utf-8 
  3  # Thomas Nagy, 2006 (ita) 
  4   
  5  "TeX/LaTeX/PDFLaTeX support" 
  6   
  7  import os, re 
  8  import Utils, TaskGen, Task, Runner, Build 
  9  from Logs import error, warn, debug 
 10   
 11  re_tex = re.compile(r'\\(?P<type>include|import|bringin){(?P<file>[^{}]*)}', re.M) 
12 -def scan(self):
13 node = self.inputs[0] 14 env = self.env 15 16 nodes = [] 17 names = [] 18 if not node: return (nodes, names) 19 20 fi = open(node.abspath(env), 'r') 21 code = fi.read() 22 fi.close() 23 24 curdirnode = self.curdirnode 25 abs = curdirnode.abspath() 26 for match in re_tex.finditer(code): 27 path = match.group('file') 28 if path: 29 for k in ['', '.tex', '.ltx']: 30 # add another loop for the tex include paths? 31 debug('tex: trying %s%s' % (path, k)) 32 try: 33 os.stat(abs+os.sep+path+k) 34 except OSError: 35 continue 36 found = path+k 37 node = curdirnode.find_resource(found) 38 if node: 39 nodes.append(node) 40 else: 41 debug('tex: could not find %s' % path) 42 names.append(path) 43 44 debug("tex: found the following : %s and names %s" % (nodes, names)) 45 return (nodes, names)
46 47 g_bibtex_re = re.compile('bibdata', re.M)
48 -def tex_build(task, command='LATEX'):
49 env = task.env 50 51 com = '%s %s' % (env[command], env.get_flat(command+'FLAGS')) 52 if not env['PROMPT_LATEX']: com = "%s %s" % (com, '-interaction=batchmode') 53 54 node = task.inputs[0] 55 reldir = node.bld_dir(env) 56 srcfile = node.srcpath(env) 57 58 lst = [] 59 for c in Utils.split_path(reldir): 60 if c: lst.append('..') 61 sr = os.path.join(*(lst + [srcfile])) 62 sr2 = os.path.join(*(lst + [node.parent.srcpath(env)])) 63 64 aux_node = node.change_ext('.aux') 65 idx_node = node.change_ext('.idx') 66 67 hash = '' 68 old_hash = '' 69 70 nm = aux_node.name 71 docuname = nm[ : len(nm) - 4 ] # 4 is the size of ".aux" 72 73 latex_compile_cmd = 'cd %s && TEXINPUTS=%s:$TEXINPUTS %s %s' % (reldir, sr2, com, sr) 74 warn('first pass on %s' % command) 75 ret = Runner.exec_command(latex_compile_cmd) 76 if ret: return ret 77 78 # look in the .aux file if there is a bibfile to process 79 try: 80 file = open(aux_node.abspath(env), 'r') 81 ct = file.read() 82 file.close() 83 except (OSError, IOError): 84 error('erreur bibtex scan') 85 else: 86 fo = g_bibtex_re.findall(ct) 87 88 # yes, there is a .aux file to process 89 if fo: 90 bibtex_compile_cmd = 'cd %s && BIBINPUTS=%s:$BIBINPUTS %s %s' % (reldir, sr2, env['BIBTEX'], docuname) 91 92 warn('calling bibtex') 93 ret = Runner.exec_command(bibtex_compile_cmd) 94 if ret: 95 error('error when calling bibtex %s' % bibtex_compile_cmd) 96 return ret 97 98 # look on the filesystem if there is a .idx file to process 99 try: 100 idx_path = idx_node.abspath(env) 101 os.stat(idx_path) 102 except OSError: 103 error('erreur file.idx scan') 104 else: 105 makeindex_compile_cmd = 'cd %s && %s %s' % (reldir, env['MAKEINDEX'], idx_path) 106 warn('calling makeindex') 107 ret = Runner.exec_command(makeindex_compile_cmd) 108 if ret: 109 error('error when calling makeindex %s' % makeindex_compile_cmd) 110 return ret 111 112 i = 0 113 while i < 10: 114 # prevent against infinite loops - one never knows 115 i += 1 116 117 # watch the contents of file.aux 118 old_hash = hash 119 try: 120 hash = Utils.h_file(aux_node.abspath(env)) 121 except KeyError: 122 error('could not read aux.h -> %s' % aux_node.abspath(env)) 123 pass 124 125 # debug 126 #print "hash is, ", hash, " ", old_hash 127 128 # stop if file.aux does not change anymore 129 if hash and hash == old_hash: break 130 131 # run the command 132 warn('calling %s' % command) 133 ret = Runner.exec_command(latex_compile_cmd) 134 if ret: 135 error('error when calling %s %s' % (command, latex_compile_cmd)) 136 return ret 137 138 # 0 means no error 139 return 0
140 141 latex_vardeps = ['LATEX', 'LATEXFLAGS']
142 -def latex_build(task):
143 return tex_build(task, 'LATEX')
144 145 pdflatex_vardeps = ['PDFLATEX', 'PDFLATEXFLAGS']
146 -def pdflatex_build(task):
147 return tex_build(task, 'PDFLATEX')
148 149 g_texobjs = ['latex','pdflatex']
150 -class tex_taskgen(TaskGen.task_gen):
151 - def __init__(self, *k, **kw):
152 TaskGen.task_gen.__init__(self, *k) 153 154 global g_texobjs 155 self.type = kw['type'] 156 if not self.type in g_texobjs: 157 raise Utils.WafError('type %s not supported for texobj' % type) 158 self.outs = '' # example: "ps pdf" 159 self.prompt = 1 # prompt for incomplete files (else the batchmode is used) 160 self.deps = ''
161
162 - def apply(self):
163 164 tree = Build.bld 165 outs = self.outs.split() 166 self.env['PROMPT_LATEX'] = self.prompt 167 168 deps_lst = [] 169 170 if self.deps: 171 deps = self.to_list(self.deps) 172 for filename in deps: 173 n = self.path.find_resource(filename) 174 if not n in deps_lst: deps_lst.append(n) 175 176 for filename in self.source.split(): 177 base, ext = os.path.splitext(filename) 178 179 node = self.path.find_resource(filename) 180 if not node: raise Utils.WafError('cannot find %s' % filename) 181 182 if self.type == 'latex': 183 task = self.create_task('latex') 184 task.set_inputs(node) 185 task.set_outputs(node.change_ext('.dvi')) 186 elif self.type == 'pdflatex': 187 task = self.create_task('pdflatex') 188 task.set_inputs(node) 189 task.set_outputs(node.change_ext('.pdf')) 190 else: 191 raise Utils.WafError('no type or invalid type given in tex object (should be latex or pdflatex)') 192 193 task.env = self.env 194 task.curdirnode = self.path 195 196 # add the manual dependencies 197 if deps_lst: 198 variant = node.variant(self.env) 199 try: 200 lst = tree.node_deps[task.unique_id()] 201 for n in deps_lst: 202 if not n in lst: 203 lst.append(n) 204 except KeyError: 205 tree.node_deps[task.unique_id()] = deps_lst 206 207 if self.type == 'latex': 208 if 'ps' in outs: 209 pstask = self.create_task('dvips') 210 pstask.set_inputs(task.outputs) 211 pstask.set_outputs(node.change_ext('.ps')) 212 if 'pdf' in outs: 213 pdftask = self.create_task('dvipdf') 214 pdftask.set_inputs(task.outputs) 215 pdftask.set_outputs(node.change_ext('.pdf')) 216 elif self.type == 'pdflatex': 217 if 'ps' in outs: 218 pstask = self.create_task('pdf2ps') 219 pstask.set_inputs(task.outputs) 220 pstask.set_outputs(node.change_ext('.ps'))
221
222 -def detect(conf):
223 v = conf.env 224 for p in 'tex latex pdflatex bibtex dvips dvipdf ps2pdf makeindex'.split(): 225 conf.find_program(p, var=p.upper()) 226 v[p.upper()+'FLAGS'] = '' 227 v['DVIPSFLAGS'] = '-Ppdf'
228 229 b = Task.simple_task_type 230 b('tex', '${TEX} ${TEXFLAGS} ${SRC}', color='BLUE') 231 b('bibtex', '${BIBTEX} ${BIBTEXFLAGS} ${SRC}', color='BLUE') 232 b('dvips', '${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}', color='BLUE', after="latex pdflatex tex bibtex") 233 b('dvipdf', '${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}', color='BLUE', after="latex pdflatex tex bibtex") 234 b('pdf2ps', '${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}', color='BLUE', after="dvipdf pdflatex") 235 b = Task.task_type_from_func 236 cls = b('latex', latex_build, vars=latex_vardeps) 237 cls.scan = scan 238 cls = b('pdflatex', pdflatex_build, vars=pdflatex_vardeps) 239 cls.scan = scan 240