Add a test for the case where a latex file uses \input{} to include the
authormanagan <managan@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 25 Nov 2009 21:47:43 +0000 (21:47 +0000)
committermanagan <managan@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 25 Nov 2009 21:47:43 +0000 (21:47 +0000)
file that contains the documentclass command

Add logic to is_LaTeX routine to search through included files until
\documentclass is found

Also added comments, converted comments at start of 2 routines into doc
strings..

git-svn-id: http://scons.tigris.org/svn/scons/trunk@4483 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Tool/pdftex.py
src/engine/SCons/Tool/tex.py
test/TEX/input_docClass.py [new file with mode: 0644]

index 01b7f85ee301ae0001b14ed10e1fdf0b08c9e9f6..4fadf5efe57e9f31718f0a24ab9113cf45c83c2a 100644 (file)
@@ -34,6 +34,7 @@ selection method.
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
+import os
 import SCons.Action
 import SCons.Util
 import SCons.Tool.tex
@@ -52,7 +53,10 @@ def PDFTeXLaTeXFunction(target = None, source= None, env=None):
     """A builder for TeX and LaTeX that scans the source file to
     decide the "flavor" of the source and then executes the appropriate
     program."""
-    if SCons.Tool.tex.is_LaTeX(source):
+    basedir = os.path.split(str(source[0]))[0]
+    abspath = os.path.abspath(basedir)
+
+    if SCons.Tool.tex.is_LaTeX(source,env,abspath):
         result = PDFLaTeXAuxAction(target,source,env)
         if result != 0:
             print env['PDFLATEX']," returned an error, check the log file"
index 77715f4b183677b55c9fcaa21655c765b8c7f29e..c5093fcbfcfc6f387dfbb11029627cb11ff77bee 100644 (file)
@@ -406,19 +406,85 @@ def LaTeXAuxAction(target = None, source= None, env=None):
 
 LaTeX_re = re.compile("\\\\document(style|class)")
 
-def is_LaTeX(flist):
-    # Scan a file list to decide if it's TeX- or LaTeX-flavored.
+def is_LaTeX(flist,env,abspath):
+    """Scan a file list to decide if it's TeX- or LaTeX-flavored."""
+
+    # We need to scan files that are included in case the
+    # \documentclass command is in them.
+
+    # 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
+        # TODO(1.5)
+        #paths = paths.split(os.pathsep)
+        paths = string.split(paths, 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 "is_LaTeX search path ",paths
+        print "files to search :",flist
+
+    # Now that we have the search path and file list, check each one
     for f in flist:
+        if Verbose:
+            print " checking for Latex source ",str(f)
+
         content = f.get_text_contents()
         if LaTeX_re.search(content):
+            if Verbose:
+                print "file %s is a LaTeX file" % str(f)
             return 1
+        if Verbose:
+            print "file %s is not a LaTeX file" % str(f)
+
+        # now find included files
+        inc_files = [ ]
+        inc_files.extend( include_re.findall(content) )
+        if Verbose:
+            print "files included by '%s': "%str(f),inc_files
+        # inc_files is list of file names as given. need to find them
+        # using TEXINPUTS paths.
+
+        # search the included files
+        for src in inc_files:
+            srcNode = FindFile(src,['.tex','.ltx','.latex'],paths,env,requireExt=False)
+            # make this a list since is_LaTeX takes a list.
+            fileList = [srcNode,]
+            if Verbose:
+                print "FindFile found ",srcNode
+            if srcNode is not None:
+                file_test = is_LaTeX(fileList, env, abspath)
+
+            # return on first file that finds latex is needed.
+            if file_test:
+                return file_test
+
+        if Verbose:
+            print " done scanning ",str(f)
+
     return 0
 
 def TeXLaTeXFunction(target = None, source= None, env=None):
     """A builder for TeX and LaTeX that scans the source file to
     decide the "flavor" of the source and then executes the appropriate
     program."""
-    if is_LaTeX(source):
+
+    # find these paths for use in is_LaTeX to search for included files
+    basedir = os.path.split(str(source[0]))[0]
+    abspath = os.path.abspath(basedir)
+
+    if is_LaTeX(source,env,abspath):
         result = LaTeXAuxAction(target,source,env)
         if result != 0:
             print env['LATEX']," returned an error, check the log file"
@@ -433,7 +499,12 @@ def TeXLaTeXStrFunction(target = None, source= None, env=None):
     decide the "flavor" of the source and then returns the appropriate
     command string."""
     if env.GetOption("no_exec"):
-        if is_LaTeX(source):
+
+        # find these paths for use in is_LaTeX to search for included files
+        basedir = os.path.split(str(source[0]))[0]
+        abspath = os.path.abspath(basedir)
+
+        if is_LaTeX(source,env,abspath):
             result = env.subst('$LATEXCOM',0,target,source)+" ..."
         else:
             result = env.subst("$TEXCOM",0,target,source)+" ..."
@@ -460,8 +531,9 @@ def tex_pdf_emitter(target, source, env):
     return (target, source)
 
 def ScanFiles(theFile, target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir):
-    # for theFile (a Node) update any file_tests and search for graphics files
-    # then find all included files and call ScanFiles for each of them
+    """ For theFile (a Node) update any file_tests and search for graphics files
+    then find all included files and call ScanFiles recursively for each of them"""
+
     content = theFile.get_text_contents()
     if Verbose:
         print " scanning ",str(theFile)
@@ -479,9 +551,9 @@ def ScanFiles(theFile, target, paths, file_tests, file_tests_search, env, graphi
     # using TEXINPUTS paths.
 
     for src in inc_files:
-        srcNode = srcNode = FindFile(src,['.tex','.ltx','.latex'],paths,env,requireExt=False)
+        srcNode = FindFile(src,['.tex','.ltx','.latex'],paths,env,requireExt=False)
         if srcNode is not None:
-            file_test = ScanFiles(srcNode, target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir)
+            file_tests = ScanFiles(srcNode, target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir)
     if Verbose:
         print " done scanning ",str(theFile)
     return file_tests
diff --git a/test/TEX/input_docClass.py b/test/TEX/input_docClass.py
new file mode 100644 (file)
index 0000000..0b03c1f
--- /dev/null
@@ -0,0 +1,96 @@
+#!/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 LaTeX document that uses \input{filename}
+to set the documentclass. When the file has .tex we have to search 
+to find the documentclass command.
+
+Test courtesy Rob Managan.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+latex = test.where_is('latex')
+if not latex:
+    test.skip_test("Could not find 'latex'; skipping test.\n")
+
+test.write(['SConstruct'], """\
+import os
+
+env = Environment(ENV = { 'PATH' : os.environ['PATH'] })
+
+test = env.PDF(source='test.tex')
+""")
+
+test.write(['test.tex'],
+r"""
+\input{theClass}
+
+\begin{document}
+\title{Report Title}
+
+\author{A. N. Author}
+\maketitle 
+\begin{abstract}
+there is no abstract
+\end{abstract}
+
+\tableofcontents
+\listoffigures
+
+\chapter{Introduction}
+
+The introduction is short.
+
+\section{Acknowledgements}
+
+The Acknowledgements are shown as well.  
+
+\end{document}
+""")
+
+test.write(['theClass.tex'],
+r"""
+\documentclass{report}
+
+""")
+
+# makeindex will write status messages to stderr (grrr...), so ignore it.
+test.run(arguments = '.', stderr=None)
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: