3 # Thomas Nagy, 2006 (ita)
5 "TeX/LaTeX/PDFLaTeX support"
8 import Utils
, TaskGen
, Task
, Runner
, Build
9 from TaskGen
import feature
, before
10 from Logs
import error
, warn
, debug
12 re_tex
= re
.compile(r
'\\(?P<type>include|input|import|bringin|lstinputlisting){(?P<file>[^{}]*)}', re
.M
)
19 if not node
: return (nodes
, names
)
21 code
= Utils
.readf(node
.abspath(env
))
23 curdirnode
= self
.curdirnode
24 abs = curdirnode
.abspath()
25 for match
in re_tex
.finditer(code
):
26 path
= match
.group('file')
28 for k
in ['', '.tex', '.ltx']:
29 # add another loop for the tex include paths?
30 debug('tex: trying %s%s' % (path
, k
))
32 os
.stat(abs+os
.sep
+path
+k
)
36 node
= curdirnode
.find_resource(found
)
40 debug('tex: could not find %s' % path
)
43 debug("tex: found the following : %s and names %s" % (nodes
, names
))
46 latex_fun
, _
= Task
.compile_fun('latex', '${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell
=False)
47 pdflatex_fun
, _
= Task
.compile_fun('pdflatex', '${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell
=False)
48 bibtex_fun
, _
= Task
.compile_fun('bibtex', '${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}', shell
=False)
49 makeindex_fun
, _
= Task
.compile_fun('bibtex', '${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}', shell
=False)
51 g_bibtex_re
= re
.compile('bibdata', re
.M
)
52 def tex_build(task
, command
='LATEX'):
54 bld
= task
.generator
.bld
56 if not env
['PROMPT_LATEX']:
57 env
.append_value('LATEXFLAGS', '-interaction=batchmode')
58 env
.append_value('PDFLATEXFLAGS', '-interaction=batchmode')
61 if command
== 'PDFLATEX':
65 reldir
= node
.bld_dir(env
)
68 #for c in Utils.split_path(reldir):
69 # if c: lst.append('..')
70 #srcfile = os.path.join(*(lst + [node.srcpath(env)]))
71 #sr2 = os.path.join(*(lst + [node.parent.srcpath(env)]))
72 srcfile
= node
.abspath(env
)
73 sr2
= node
.parent
.abspath() + os
.pathsep
+ node
.parent
.abspath(env
) + os
.pathsep
75 aux_node
= node
.change_ext('.aux')
76 idx_node
= node
.change_ext('.idx')
79 docuname
= nm
[ : len(nm
) - 4 ] # 4 is the size of ".aux"
81 # important, set the cwd for everybody
82 task
.cwd
= task
.inputs
[0].parent
.abspath(task
.env
)
85 warn('first pass on %s' % command
)
87 task
.env
.env
= {'TEXINPUTS': sr2
}
88 task
.env
.SRCFILE
= srcfile
93 # look in the .aux file if there is a bibfile to process
95 ct
= Utils
.readf(aux_node
.abspath(env
))
96 except (OSError, IOError):
97 error('error bibtex scan')
99 fo
= g_bibtex_re
.findall(ct
)
101 # there is a .aux file to process
103 warn('calling bibtex')
105 task
.env
.env
= {'BIBINPUTS': sr2
, 'BSTINPUTS': sr2
}
106 task
.env
.SRCFILE
= docuname
107 ret
= bibtex_fun(task
)
109 error('error when calling bibtex %s' % docuname
)
112 # look on the filesystem if there is a .idx file to process
114 idx_path
= idx_node
.abspath(env
)
117 error('error file.idx scan')
119 warn('calling makeindex')
121 task
.env
.SRCFILE
= idx_node
.name
123 ret
= makeindex_fun(task
)
125 error('error when calling makeindex %s' % idx_path
)
132 # prevent against infinite loops - one never knows
135 # watch the contents of file.aux
138 hash = Utils
.h_file(aux_node
.abspath(env
))
140 error('could not read aux.h -> %s' % aux_node
.abspath(env
))
144 #print "hash is, ", hash, " ", old_hash
146 # stop if file.aux does not change anymore
147 if hash and hash == prev_hash
:
151 warn('calling %s' % command
)
153 task
.env
.env
= {'TEXINPUTS': sr2
+ os
.pathsep
}
154 task
.env
.SRCFILE
= srcfile
157 error('error when calling %s %s' % (command
, latex_compile_cmd
))
162 latex_vardeps
= ['LATEX', 'LATEXFLAGS']
163 def latex_build(task
):
164 return tex_build(task
, 'LATEX')
166 pdflatex_vardeps
= ['PDFLATEX', 'PDFLATEXFLAGS']
167 def pdflatex_build(task
):
168 return tex_build(task
, 'PDFLATEX')
170 class tex_taskgen(TaskGen
.task_gen
):
171 def __init__(self
, *k
, **kw
):
172 TaskGen
.task_gen
.__init
__(self
, *k
, **kw
)
175 @before('apply_core')
177 if not getattr(self
, 'type', None) in ['latex', 'pdflatex']:
178 self
.type = 'pdflatex'
181 outs
= Utils
.to_list(getattr(self
, 'outs', []))
183 # prompt for incomplete files (else the batchmode is used)
184 self
.env
['PROMPT_LATEX'] = getattr(self
, 'prompt', 1)
188 if getattr(self
, 'deps', None):
189 deps
= self
.to_list(self
.deps
)
190 for filename
in deps
:
191 n
= self
.path
.find_resource(filename
)
192 if not n
in deps_lst
: deps_lst
.append(n
)
194 self
.source
= self
.to_list(self
.source
)
195 for filename
in self
.source
:
196 base
, ext
= os
.path
.splitext(filename
)
198 node
= self
.path
.find_resource(filename
)
199 if not node
: raise Utils
.WafError('cannot find %s' % filename
)
201 if self
.type == 'latex':
202 task
= self
.create_task('latex', node
, node
.change_ext('.dvi'))
203 elif self
.type == 'pdflatex':
204 task
= self
.create_task('pdflatex', node
, node
.change_ext('.pdf'))
207 task
.curdirnode
= self
.path
209 # add the manual dependencies
211 variant
= node
.variant(self
.env
)
213 lst
= tree
.node_deps
[task
.unique_id()]
218 tree
.node_deps
[task
.unique_id()] = deps_lst
220 if self
.type == 'latex':
222 tsk
= self
.create_task('dvips', task
.outputs
, node
.change_ext('.ps'))
223 tsk
.env
.env
= {'TEXINPUTS' : node
.parent
.abspath() + os
.pathsep
+ self
.path
.abspath() + os
.pathsep
+ self
.path
.abspath(self
.env
)}
225 tsk
= self
.create_task('dvipdf', task
.outputs
, node
.change_ext('.pdf'))
226 tsk
.env
.env
= {'TEXINPUTS' : node
.parent
.abspath() + os
.pathsep
+ self
.path
.abspath() + os
.pathsep
+ self
.path
.abspath(self
.env
)}
227 elif self
.type == 'pdflatex':
229 self
.create_task('pdf2ps', task
.outputs
, node
.change_ext('.ps'))
234 for p
in 'tex latex pdflatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
235 conf
.find_program(p
, var
=p
.upper())
236 v
[p
.upper()+'FLAGS'] = ''
237 v
['DVIPSFLAGS'] = '-Ppdf'
239 b
= Task
.simple_task_type
240 b('tex', '${TEX} ${TEXFLAGS} ${SRC}', color
='BLUE', shell
=False) # not used anywhere
241 b('bibtex', '${BIBTEX} ${BIBTEXFLAGS} ${SRC}', color
='BLUE', shell
=False) # not used anywhere
242 b('dvips', '${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}', color
='BLUE', after
="latex pdflatex tex bibtex", shell
=False)
243 b('dvipdf', '${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}', color
='BLUE', after
="latex pdflatex tex bibtex", shell
=False)
244 b('pdf2ps', '${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}', color
='BLUE', after
="dvipdf pdflatex", shell
=False)
246 b
= Task
.task_type_from_func
247 cls
= b('latex', latex_build
, vars=latex_vardeps
)
249 cls
= b('pdflatex', pdflatex_build
, vars=pdflatex_vardeps
)