Logo Search packages:      
Sourcecode: waf version File versions  Download package

tex.py

#!/usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2006 (ita)

"TeX/LaTeX/PDFLaTeX support"

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'\\(?P<type>include|input|import|bringin){(?P<file>[^{}]*)}', 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']:
                        # add another loop for the tex include paths?
                        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)

g_bibtex_re = re.compile('bibdata', re.M)
def tex_build(task, command='LATEX'):
      env = task.env
      bld = task.generator.bld

      com = '%s %s' % (env[command], env.get_flat(command+'FLAGS'))
      if not env['PROMPT_LATEX']: com = "%s %s" % (com, '-interaction=batchmode')

      node = task.inputs[0]
      reldir  = node.bld_dir(env)
      srcfile = node.srcpath(env)

      lst = []
      for c in Utils.split_path(reldir):
            if c: lst.append('..')
      sr = os.path.join(*(lst + [srcfile]))
      sr2 = os.path.join(*(lst + [node.parent.srcpath(env)]))

      aux_node = node.change_ext('.aux')
      idx_node = node.change_ext('.idx')

      hash     = ''
      old_hash = ''

      nm = aux_node.name
      docuname = nm[ : len(nm) - 4 ] # 4 is the size of ".aux"

      latex_compile_cmd = 'cd %s && TEXINPUTS=%s:$TEXINPUTS %s %s' % (reldir, sr2, com, sr)
      warn('first pass on %s' % command)
      ret = bld.exec_command(latex_compile_cmd)
      if ret: return ret

      # look in the .aux file if there is a bibfile to process
      try:
            ct = Utils.readf(aux_node.abspath(env))
      except (OSError, IOError):
            error('error bibtex scan')
      else:
            fo = g_bibtex_re.findall(ct)

            # yes, there is a .aux file to process
            if fo:
                  bibtex_compile_cmd = 'cd %s && BIBINPUTS=%s:$BIBINPUTS %s %s' % (reldir, sr2, env['BIBTEX'], docuname)

                  warn('calling bibtex')
                  ret = bld.exec_command(bibtex_compile_cmd)
                  if ret:
                        error('error when calling bibtex %s' % bibtex_compile_cmd)
                        return ret

      # look on the filesystem if there is a .idx file to process
      try:
            idx_path = idx_node.abspath(env)
            os.stat(idx_path)
      except OSError:
            error('error file.idx scan')
      else:
            makeindex_compile_cmd = 'cd %s && %s %s' % (reldir, env['MAKEINDEX'], idx_path)
            warn('calling makeindex')
            ret = bld.exec_command(makeindex_compile_cmd)
            if ret:
                  error('error when calling makeindex %s' % makeindex_compile_cmd)
                  return ret

      i = 0
      while i < 10:
            # prevent against infinite loops - one never knows
            i += 1

            # watch the contents of file.aux
            old_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

            # debug
            #print "hash is, ", hash, " ", old_hash

            # stop if file.aux does not change anymore
            if hash and hash == old_hash: break

            # run the command
            warn('calling %s' % command)
            ret = bld.exec_command(latex_compile_cmd)
            if ret:
                  error('error when calling %s %s' % (command, latex_compile_cmd))
                  return ret

      # 0 means no error
      return 0

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)

@feature('tex')
@before('apply_core')
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', []))

      # prompt for incomplete files (else the batchmode is used)
      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

            # add the manual dependencies
            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:
                        self.create_task('dvips', task.outputs, node.change_ext('.ps'))
                  if 'pdf' in outs:
                        self.create_task('dvipdf', task.outputs, node.change_ext('.pdf'))
            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


Generated by  Doxygen 1.6.0   Back to index