import re
import SCons.Scanner
+import SCons.Util
+
+# list of graphics file extensions for TeX and LaTeX
+TexGraphics = ['.eps', '.ps']
+LatexGraphics = ['.pdf', '.png', '.jpg', '.gif', '.tif']
+
+# Used as a return value of modify_env_var if the variable is not set.
+class _Null:
+ pass
+_null = _Null
+
+# The user specifies the paths in env[variable], similar to other builders.
+# They may be relative and must be converted to absolute, as expected
+# by LaTeX and Co. The environment may already have some paths in
+# env['ENV'][var]. These paths are honored, but the env[var] paths have
+# higher precedence. All changes are un-done on exit.
+def modify_env_var(env, var, abspath):
+ try:
+ save = env['ENV'][var]
+ except KeyError:
+ save = _null
+ env.PrependENVPath(var, abspath)
+ try:
+ if SCons.Util.is_List(env[var]):
+ #TODO(1.5) env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]])
+ env.PrependENVPath(var, map(lambda p: os.path.abspath(str(p)), env[var]))
+ else:
+ # Split at os.pathsep to convert into absolute path
+ #TODO(1.5) env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(os.pathsep)])
+ env.PrependENVPath(var, map(lambda p: os.path.abspath(p), str(env[var]).split(os.pathsep)))
+ except KeyError:
+ pass
+
+ # Convert into a string explicitly to append ":" (without which it won't search system
+ # paths as well). The problem is that env.AppendENVPath(var, ":")
+ # does not work, refuses to append ":" (os.pathsep).
+
+ if SCons.Util.is_List(env['ENV'][var]):
+ env['ENV'][var] = os.pathsep.join(env['ENV'][var])
+ # Append the trailing os.pathsep character here to catch the case with no env[var]
+ env['ENV'][var] = env['ENV'][var] + os.pathsep
+
+ return save
+
+class FindENVPathDirs:
+ """A class to bind a specific *PATH variable name to a function that
+ will return all of the *path directories."""
+ def __init__(self, variable):
+ self.variable = variable
+ def __call__(self, env, dir=None, target=None, source=None, argument=None):
+ import SCons.PathList
+ try:
+ path = env['ENV'][self.variable]
+ except KeyError:
+ return ()
+
+ dir = dir or env.fs._cwd
+ path = SCons.PathList.PathList(path).subst_path(env, target, source)
+ return tuple(dir.Rfindalldirs(path))
+
+
def LaTeXScanner():
"""Return a prototype Scanner instance for scanning LaTeX source files
ds = LaTeX(name = "LaTeXScanner",
suffixes = '$LATEXSUFFIXES',
# in the search order, see below in LaTeX class docstring
- graphics_extensions = ['.eps', '.ps'],
+ graphics_extensions = TexGraphics,
recursive = 0)
return ds
ds = LaTeX(name = "PDFLaTeXScanner",
suffixes = '$LATEXSUFFIXES',
# in the search order, see below in LaTeX class docstring
- graphics_extensions = ['.pdf', '.png', '.jpg', '.gif', '.tif'],
+ graphics_extensions = LatexGraphics,
recursive = 0)
return ds
def __init__(self, dictionary):
self.dictionary = {}
for k,n in dictionary.items():
- self.dictionary[k] = SCons.Scanner.FindPathDirs(n)
+ self.dictionary[k] = ( SCons.Scanner.FindPathDirs(n),
+ FindENVPathDirs(n) )
def __call__(self, env, dir=None, target=None, source=None,
argument=None):
di = {}
- for k,c in self.dictionary.items():
- di[k] = c(env, dir=None, target=None, source=None,
- argument=None)
+ for k,(c,cENV) in self.dictionary.items():
+ di[k] = ( c(env, dir=None, target=None, source=None,
+ argument=None) ,
+ cENV(env, dir=None, target=None, source=None,
+ argument=None) )
# To prevent "dict is not hashable error"
return tuple(di.items())
sub_path = ()
try_names = self._latex_names(include)
for n in try_names:
- i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path)
+ # see if we find it using the path in env[var]
+ i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path[0])
+ if i:
+ return i, include
+ # see if we find it using the path in env['ENV'][var]
+ i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path[1])
if i:
return i, include
return i, include
import SCons.Tool.tex
import SCons.Util
-_null = SCons.Tool.tex._Null
+_null = SCons.Scanner.LaTeX._null
def DviPdfPsFunction(XXXDviAction, target = None, source= None, env=None):
"""A builder for DVI files that sets the TEXPICTS environment
except AttributeError :
abspath = ''
- saved_env = {}
- saved_env['TEXPICTS'] = SCons.Tool.tex.modify_env_var(env, 'TEXPICTS', abspath)
+ saved_env = SCons.Scanner.LaTeX.modify_env_var(env, 'TEXPICTS', abspath)
result = XXXDviAction(target, source, env)
- if saved_env['TEXPICTS'] is _null:
+ if saved_env is _null:
try:
del env['ENV']['TEXPICTS']
except KeyError:
pass # was never set
else:
- env['ENV']['TEXPICTS'] = saved_env['TEXPICTS']
+ env['ENV']['TEXPICTS'] = saved_env
return result
prefix = '$PSPREFIX',
suffix = '$PSSUFFIX',
src_suffix = '.dvi',
- src_builder = 'DVI')
+ src_builder = 'DVI',
+ single_source=True)
env['BUILDERS']['PostScript'] = PSBuilder
bld = env['BUILDERS']['DVI']
bld.add_action('.ltx', LaTeXAuxAction)
bld.add_action('.latex', LaTeXAuxAction)
- bld.add_emitter('.ltx', SCons.Tool.tex.tex_emitter)
- bld.add_emitter('.latex', SCons.Tool.tex.tex_emitter)
+ bld.add_action('.tex', LaTeXAuxAction)
+ bld.add_emitter('.ltx', SCons.Tool.tex.tex_eps_emitter)
+ bld.add_emitter('.latex', SCons.Tool.tex.tex_eps_emitter)
+ bld.add_emitter('.tex', SCons.Tool.tex.tex_eps_emitter)
env['LATEX'] = 'latex'
env['LATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode')
"""SCons.Tool.pdf
Common PDF Builder definition for various other Tool modules that use it.
+Add an explicit action to run epstopdf to convert .eps files to .pdf
"""
PDFBuilder = None
+EpsPdfAction = SCons.Action.Action('$EPSTOPDFCOM', '$EPSTOPDFCOMSTR')
+
def generate(env):
try:
env['BUILDERS']['PDF']
prefix = '$PDFPREFIX',
suffix = '$PDFSUFFIX',
emitter = {},
- source_ext_match = None)
+ source_ext_match = None,
+ single_source=True)
env['BUILDERS']['PDF'] = PDFBuilder
env['PDFPREFIX'] = ''
env['PDFSUFFIX'] = '.pdf'
+# put the epstopdf builder in this routine so we can add it after
+# the pdftex builder so that one is the default for no source suffix
+def generate2(env):
+ bld = env['BUILDERS']['PDF']
+ bld.add_action('.ps', EpsPdfAction)
+ bld.add_action('.eps', EpsPdfAction)
+
+ env['EPSTOPDF'] = 'epstopdf'
+ env['EPSTOPDFFLAGS'] = SCons.Util.CLVar('')
+ env['EPSTOPDFCOM'] = '$EPSTOPDF $EPSTOPDFFLAGS ${SOURCE} -o ${TARGET}'
+
def exists(env):
# This only puts a skeleton Builder in place, so if someone
# references this Tool directly, it's always "available."
bld = env['BUILDERS']['PDF']
bld.add_action('.ltx', PDFLaTeXAuxAction)
bld.add_action('.latex', PDFLaTeXAuxAction)
- bld.add_emitter('.ltx', SCons.Tool.tex.tex_emitter)
- bld.add_emitter('.latex', SCons.Tool.tex.tex_emitter)
+ bld.add_action('.tex', PDFLaTeXAuxAction)
+ bld.add_emitter('.ltx', SCons.Tool.tex.tex_pdf_emitter)
+ bld.add_emitter('.latex', SCons.Tool.tex.tex_pdf_emitter)
+ bld.add_emitter('.tex', SCons.Tool.tex.tex_pdf_emitter)
env['PDFLATEX'] = 'pdflatex'
env['PDFLATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode')
bld = env['BUILDERS']['PDF']
bld.add_action('.tex', PDFTeXLaTeXAction)
- bld.add_emitter('.tex', SCons.Tool.tex.tex_emitter)
+ bld.add_emitter('.tex', SCons.Tool.tex.tex_pdf_emitter)
+
+ # Add the epstopdf builder after the pdftex builder
+ # so pdftex is the default for no source suffix
+ pdf.generate2(env)
env['PDFTEX'] = 'pdftex'
env['PDFTEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode')
import SCons.Node
import SCons.Node.FS
import SCons.Util
+import SCons.Scanner.LaTeX
-Verbose = False
+Verbose = True
must_rerun_latex = True
# used by the emitter
auxfile_re = re.compile(r".", re.MULTILINE)
-tableofcontents_re = re.compile(r"^[^%]*\\tableofcontents", re.MULTILINE)
-makeindex_re = re.compile(r"^[^%]*\\makeindex", re.MULTILINE)
-bibliography_re = re.compile(r"^[^%]*\\bibliography", re.MULTILINE)
-listoffigures_re = re.compile(r"^[^%]*\\listoffigures", re.MULTILINE)
-listoftables_re = re.compile(r"^[^%]*\\listoftables", re.MULTILINE)
-hyperref_re = re.compile(r"^[^%]*\\usepackage.*\{hyperref\}", re.MULTILINE)
-makenomenclature_re = re.compile(r"^[^%]*\\makenomenclature", re.MULTILINE)
-makeglossary_re = re.compile(r"^[^%]*\\makeglossary", re.MULTILINE)
-beamer_re = re.compile(r"^[^%]*\\documentclass\{beamer\}", re.MULTILINE)
+tableofcontents_re = re.compile(r"^[^%\n]*\\tableofcontents", re.MULTILINE)
+makeindex_re = re.compile(r"^[^%\n]*\\makeindex", re.MULTILINE)
+bibliography_re = re.compile(r"^[^%\n]*\\bibliography", re.MULTILINE)
+listoffigures_re = re.compile(r"^[^%\n]*\\listoffigures", re.MULTILINE)
+listoftables_re = re.compile(r"^[^%\n]*\\listoftables", re.MULTILINE)
+hyperref_re = re.compile(r"^[^%\n]*\\usepackage.*\{hyperref\}", re.MULTILINE)
+makenomenclature_re = re.compile(r"^[^%\n]*\\makenomenclature", re.MULTILINE)
+makeglossary_re = re.compile(r"^[^%\n]*\\makeglossary", re.MULTILINE)
+beamer_re = re.compile(r"^[^%\n]*\\documentclass\{beamer\}", re.MULTILINE)
+
+# search to find all files included by Latex
+include_re = re.compile(r'^[^%\n]*\\(?:include|input){([^}]*)}', re.MULTILINE)
+
+# search to find all graphics files included by Latex
+includegraphics_re = re.compile(r'^[^%\n]*\\(?:includegraphics(?:\[[^\]]+\])?){([^}]*)}', re.MULTILINE)
# search to find all files opened by Latex (recorded in .log file)
openout_re = re.compile(r"\\openout.*`(.*)'")
+# list of graphics file extensions for TeX and LaTeX
+TexGraphics = SCons.Scanner.LaTeX.TexGraphics
+LatexGraphics = SCons.Scanner.LaTeX.LatexGraphics
+
# An Action sufficient to build any generic tex file.
TeXAction = None
MakeGlossaryAction = None
# Used as a return value of modify_env_var if the variable is not set.
-class _Null:
- pass
-_null = _Null
-
-# The user specifies the paths in env[variable], similar to other builders.
-# They may be relative and must be converted to absolute, as expected
-# by LaTeX and Co. The environment may already have some paths in
-# env['ENV'][var]. These paths are honored, but the env[var] paths have
-# higher precedence. All changes are un-done on exit.
-def modify_env_var(env, var, abspath):
- try:
- save = env['ENV'][var]
- except KeyError:
- save = _null
- env.PrependENVPath(var, abspath)
- try:
- if SCons.Util.is_List(env[var]):
- #TODO(1.5) env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]])
- env.PrependENVPath(var, map(lambda p: os.path.abspath(str(p)), env[var]))
+_null = SCons.Scanner.LaTeX._null
+
+modify_env_var = SCons.Scanner.LaTeX.modify_env_var
+
+def FindFile(name,suffixes,paths,env):
+ #print "FindFile: name %s, suffixes "% name,suffixes," paths ",paths
+ if Verbose:
+ print " searching for '%s' with extensions: " % name,suffixes
+
+ for path in paths:
+ testName = os.path.join(path,name)
+ if Verbose:
+ print " look for '%s'" % testName
+ if os.path.exists(testName):
+ if Verbose:
+ print " found '%s'" % testName
+ return env.fs.File(testName)
else:
- # Split at os.pathsep to convert into absolute path
- #TODO(1.5) env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(os.pathsep)])
- env.PrependENVPath(var, map(lambda p: os.path.abspath(p), str(env[var]).split(os.pathsep)))
- except KeyError:
- pass
- # Convert into a string explicitly to append ":" (without which it won't search system
- # paths as well). The problem is that env.AppendENVPath(var, ":")
- # does not work, refuses to append ":" (os.pathsep).
- if SCons.Util.is_List(env['ENV'][var]):
- env['ENV'][var] = os.pathsep.join(env['ENV'][var])
- # Append the trailing os.pathsep character here to catch the case with no env[var]
- env['ENV'][var] = env['ENV'][var] + os.pathsep
- return save
+ name_ext = SCons.Util.splitext(testName)[1]
+ if name_ext:
+ continue
+
+ # if no suffix try adding those passed in
+ for suffix in suffixes:
+ testNameExt = testName + suffix
+ if Verbose:
+ print " look for '%s'" % testNameExt
+
+ if os.path.exists(testNameExt):
+ if Verbose:
+ print " found '%s'" % testNameExt
+ return env.fs.File(testNameExt)
+ if Verbose:
+ print " did not find '%s'" % name
+ return None
def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None):
"""A builder for LaTeX files that checks the output in the aux file
for var in SCons.Scanner.LaTeX.LaTeX.env_variables:
saved_env[var] = modify_env_var(env, var, abspath)
- # Create a base file names with the target directory since the auxiliary files
+ # Create base file names with the target directory since the auxiliary files
# will be made there. That's because the *COM variables have the cd
# command in the prolog. We check
# for the existence of files before opening them--even ones like the
result = ''
return result
-def tex_emitter(target, source, env):
+def tex_eps_emitter(target, source, env):
+ """An emitter for TeX and LaTeX sources when
+ executing tex or latex. It will accept .ps and .eps
+ graphics files
+ """
+ (target, source) = tex_emitter_core(target, source, env, TexGraphics)
+
+ return (target, source)
+
+def tex_pdf_emitter(target, source, env):
+ """An emitter for TeX and LaTeX sources when
+ executing pdftex or pdflatex. It will accept graphics
+ files of types .pdf, .jpg, .png, .gif, and .tif
+ """
+ (target, source) = tex_emitter_core(target, source, env, LatexGraphics)
+
+ return (target, source)
+
+def tex_emitter_core(target, source, env, graphics_extensions):
"""An emitter for TeX and LaTeX sources.
For LaTeX sources we try and find the common created files that
are needed on subsequent runs of latex to finish tables of contents,
targetbase = SCons.Util.splitext(str(target[0]))[0]
basename = SCons.Util.splitext(str(source[0]))[0]
basefile = os.path.split(str(basename))[1]
-
+
basedir = os.path.split(str(source[0]))[0]
+ targetdir = os.path.split(str(target[0]))[0]
abspath = os.path.abspath(basedir)
target[0].attributes.path = abspath
env.Clean(target[0],logfilename)
content = source[0].get_contents()
+
idx_exists = os.path.exists(targetbase + '.idx')
nlo_exists = os.path.exists(targetbase + '.nlo')
glo_exists = os.path.exists(targetbase + '.glo')
- file_tests = [(auxfile_re.search(content),['.aux']),
- (makeindex_re.search(content) or idx_exists,['.idx', '.ind', '.ilg']),
- (bibliography_re.search(content),['.bbl', '.blg']),
- (tableofcontents_re.search(content),['.toc']),
- (listoffigures_re.search(content),['.lof']),
- (listoftables_re.search(content),['.lot']),
- (hyperref_re.search(content),['.out']),
- (makenomenclature_re.search(content) or nlo_exists,['.nlo', '.nls', '.nlg']),
- (makeglossary_re.search(content) or glo_exists,['.glo', '.gls', '.glg']),
- (beamer_re.search(content),['.nav', '.snm', '.out', '.toc']) ]
- # Note we add the various makeindex files if the file produced by latex exists (.idx, .glo, .nlo)
- # This covers the case where the \makeindex, \makenomenclature, or \makeglossary
- # is not in the main file but we want to clean the files and those made by makeindex
+ # set up list with the regular expressions
+ # we use to find features used
+ file_tests_search = [auxfile_re,
+ makeindex_re,
+ bibliography_re,
+ tableofcontents_re,
+ listoffigures_re,
+ listoftables_re,
+ hyperref_re,
+ makenomenclature_re,
+ makeglossary_re,
+ beamer_re ]
+ # set up list with the file suffixes that need emitting
+ # when a feature is found
+ file_tests_suff = [['.aux'],
+ ['.idx', '.ind', '.ilg'],
+ ['.bbl', '.blg'],
+ ['.toc'],
+ ['.lof'],
+ ['.lot'],
+ ['.out'],
+ ['.nlo', '.nls', '.nlg'],
+ ['.glo', '.gls', '.glg'],
+ ['.nav', '.snm', '.out', '.toc'] ]
+ # build the list of lists
+ file_tests = []
+ for i in range(len(file_tests_search)):
+ file_tests.append( [file_tests_search[i].search(content), file_tests_suff[i]] )
# TO-DO: need to add a way for the user to extend this list for whatever
# auxiliary files they create in other (or their own) packages
+ inc_files = [str(source[0]), ]
+ inc_files.extend( include_re.findall(content) )
+ if Verbose:
+ print "files included by '%s': "%source[0],inc_files
+ # inc_files is list of file names as given. need to find them
+ # using TEXINPUTS paths.
+
+ # get path list from both env['TEXINPUTS'] and env['ENV']['TEXINPUTS']
+ savedpath = modify_env_var(env, 'TEXINPUTS', abspath)
+ paths = env['ENV']['TEXINPUTS']
+ if SCons.Util.is_List(paths):
+ pass
+ else:
+ # Split at os.pathsep to convert into absolute path
+ paths = paths.split(os.pathsep)
+
+ # now that we have the path list restore the env
+ if savedpath is _null:
+ try:
+ del env['ENV']['TEXINPUTS']
+ except KeyError:
+ pass # was never set
+ else:
+ env['ENV']['TEXINPUTS'] = savedpath
+ if Verbose:
+ print "search path ",paths
+
+ # search all files read (including the original source file)
+ # for files that are \input or \include
+ for src in inc_files:
+ # we already did this for the base file
+ if src != inc_files[0]:
+ content = ""
+ srcNode = FindFile(src,['.tex','.ltx','.latex'],paths,env)
+ if srcNode:
+ content = srcNode.get_contents()
+ for i in range(len(file_tests_search)):
+ if file_tests[i][0] == None:
+ file_tests[i][0] = file_tests_search[i].search(content)
+
+ # For each file see if any graphics files are included
+ # and set up target to create ,pdf graphic
+ # is this is in pdflatex toolchain
+ src_inc_files = includegraphics_re.findall(content)
+ if Verbose:
+ print "graphics files in '%s': "%basename,src_inc_files
+ for graphFile in src_inc_files:
+ graphicNode = FindFile(graphFile,graphics_extensions,paths,env)
+ # see if we can build this graphics file by epstopdf
+ graphicSrc = FindFile(graphFile,TexGraphics,paths,env)
+ if graphicSrc != None:
+ if Verbose and (graphicNode == None):
+ print "need to build '%s' by epstopdf %s -o %s" % (graphFile,graphicSrc,graphFile)
+ graphicNode = env.PDF(os.path.join(targetdir,str(graphicSrc)))
+ env.Depends(target[0],graphicNode)
+
for (theSearch,suffix_list) in file_tests:
if theSearch:
for suffix in suffix_list:
bld = env['BUILDERS']['DVI']
bld.add_action('.tex', TeXLaTeXAction)
- bld.add_emitter('.tex', tex_emitter)
+ bld.add_emitter('.tex', tex_eps_emitter)
env['TEX'] = 'tex'
env['TEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode')
latex3 = r"""
\index{include}
-This is the include file.
+This is the include file. mod %s
\printindex{}
"""
test.subdir('subdir')
test.write('latexi.tex', latex1 % 'latexi.tex');
- test.write([ 'subdir', 'latexinputfile.tex'], latex2)
- test.write([ 'subdir', 'latexincludefile.tex'], latex3)
+ test.write([ 'subdir', 'latexinputfile'], latex2)
+ test.write([ 'subdir', 'latexincludefile.tex'], latex3 % '1')
test.run(arguments = 'foo.dvi', stderr = None)
test.must_not_exist('wrapper.out')
test.must_exist('latexi.dvi')
test.must_exist('latexi.ind')
+ test.write([ 'subdir', 'latexincludefile.tex'], latex3 % '2')
+ test.not_up_to_date(arguments = 'latexi.dvi', stderr = None)
+
test.run(arguments = '-c', stderr = None)
test.must_not_exist('latexi.ind')
test.must_not_exist('latexi.ilg')
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Validate that we can produce several .pdf at once from several sources.
+"""
+
+import os
+import os.path
+import string
+import sys
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+
+latex = test.where_is('latex')
+
+if latex:
+
+ test.write('SConstruct', """
+import os
+ENV = { 'PATH' : os.environ['PATH'],
+ 'TEXINPUTS' : [ os.environ.get('TEXINPUTS', '') ] }
+foo = Environment(ENV = ENV)
+foo['TEXINPUTS'] = ['subdir',]
+foo.PDF(source = ['foo.ltx','bar.latex','makeindex.tex','latexi.tex'])
+""" % locals())
+
+ latex = r"""
+\documentclass{letter}
+\begin{document}
+This is the %s LaTeX file.
+\end{document}
+"""
+
+ makeindex = r"""
+\documentclass{report}
+\usepackage{makeidx}
+\makeindex
+\begin{document}
+\index{info}
+This is the %s LaTeX file.
+\printindex{}
+\end{document}
+"""
+
+ latex1 = r"""
+\documentclass{report}
+\usepackage{makeidx}
+\input{latexinputfile}
+\begin{document}
+\index{info}
+This is the %s LaTeX file.
+
+It has an Index and includes another file.
+\include{latexincludefile}
+\end{document}
+"""
+
+ latex2 = r"""
+\makeindex
+"""
+
+ latex3 = r"""
+\index{include}
+This is the include file. mod %s
+\printindex{}
+"""
+
+ test.write('foo.ltx', latex % 'foo.ltx')
+
+ test.write('bar.latex', latex % 'bar.latex')
+
+ test.write('makeindex.tex', makeindex % 'makeindex.tex')
+ test.write('makeindex.idx', '')
+
+ test.subdir('subdir')
+ test.write('latexi.tex', latex1 % 'latexi.tex');
+ test.write([ 'subdir', 'latexinputfile'], latex2)
+ test.write([ 'subdir', 'latexincludefile.tex'], latex3 % '1')
+
+ test.run(stderr = None)
+ test.must_not_exist('wrapper.out')
+ test.must_exist('foo.pdf')
+
+ test.must_exist('bar.pdf')
+
+ test.must_exist('latexi.pdf')
+ test.must_exist('latexi.ind')
+
+ test.write([ 'subdir', 'latexincludefile.tex'], latex3 % '2')
+ test.not_up_to_date(arguments = 'latexi.pdf', stderr = None)
+
+ test.run(arguments = '-c', stderr = None)
+ test.must_not_exist('latexi.ind')
+ test.must_not_exist('latexi.ilg')
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test creation of a mulitple pdf's from a list of PostScript files.
+
+Test courtesy Rob Managan.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+epstopdf = test.where_is('epstopdf')
+if not epstopdf:
+ test.skip_test("Could not find 'epstopdf'; skipping test.\n")
+
+
+test.write(['SConstruct'], """\
+import os
+
+env = Environment(ENV = { 'PATH' : os.environ['PATH'] })
+
+env.PDF(['Fig1.ps','Fig3.ps','Fig2.ps'])
+""")
+
+
+figure = """\
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: Fig1.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 4
+%%CreationDate: Tue Apr 25 09:56:11 2006
+%%For: managan@mangrove.llnl.gov (Rob Managan)
+%%BoundingBox: 0 0 98 98
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+
+end
+save
+newpath 0 98 moveto 0 0 lineto 98 0 lineto 98 98 lineto closepath clip newpath
+-24.9 108.2 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/sc {scale} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/tr {translate} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+7.500 slw
+% Ellipse
+n 1170 945 766 766 0 360 DrawEllipse gs col0 s gr
+
+$F2psEnd
+rs
+"""
+test.write('Fig1.ps',figure )
+test.write('Fig2.ps',figure )
+test.write('Fig3.ps',figure )
+
+
+test.run(arguments = '.', stderr=None)
+
+
+files = [
+ 'Fig1.pdf',
+ 'Fig2.pdf',
+ 'Fig3.pdf',
+]
+
+for f in files:
+ test.must_exist(f)
+
+
+test.pass_test()