Fix tex code to handle broken nomenclature package. (Fixes test failure on centos5...
[scons.git] / src / engine / SCons / Tool / tex.py
index 2fc13d14fdf61cd819e3434ac6a0bed084196579..77715f4b183677b55c9fcaa21655c765b8c7f29e 100644 (file)
@@ -1,6 +1,7 @@
 """SCons.Tool.tex
 
 Tool-specific initialization for TeX.
+Generates .dvi files from .tex files
 
 There normally shouldn't be any need to import this module directly.
 It will usually be imported through the generic SCons.Tool.Tool()
@@ -52,7 +53,7 @@ must_rerun_latex = True
 check_suffixes = ['.toc', '.lof', '.lot', '.out', '.nav', '.snm']
 
 # these are files that require bibtex or makeindex to be run when they change
-all_suffixes = check_suffixes + ['.bbl', '.idx', '.nlo', '.glo']
+all_suffixes = check_suffixes + ['.bbl', '.idx', '.nlo', '.glo', '.acn']
 
 #
 # regular expressions used to search for Latex features
@@ -87,6 +88,8 @@ 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)
+makeglossaries_re = re.compile(r"^[^%\n]*\\makeglossaries", re.MULTILINE)
+makeacronyms_re = re.compile(r"^[^%\n]*\\makeglossaries", re.MULTILINE)
 beamer_re = re.compile(r"^[^%\n]*\\documentclass\{beamer\}", re.MULTILINE)
 
 # search to find all files included by Latex
@@ -121,6 +124,9 @@ MakeNclAction = None
 # An action to run MakeIndex (for glossary) on a file.
 MakeGlossaryAction = None
 
+# An action to run MakeIndex (for acronyms) on a file.
+MakeAcronymsAction = None
+
 # Used as a return value of modify_env_var if the variable is not set.
 _null = SCons.Scanner.LaTeX._null
 
@@ -206,6 +212,8 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
     run_makeindex = makeindex_re.search(src_content) and not os.path.exists(targetbase + '.idx')
     run_nomenclature = makenomenclature_re.search(src_content) and not os.path.exists(targetbase + '.nlo')
     run_glossary = makeglossary_re.search(src_content) and not os.path.exists(targetbase + '.glo')
+    run_glossaries = makeglossaries_re.search(src_content) and not os.path.exists(targetbase + '.glo')
+    run_acronyms = makeacronyms_re.search(src_content) and not os.path.exists(targetbase + '.acn')
 
     saved_hashes = {}
     suffix_nodes = {}
@@ -321,10 +329,10 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
             result = MakeNclAction(nclfile, nclfile, env)
             if result != 0:
                 print env['MAKENCL']," (nomenclature) returned an error, check the nlg file"
-                return result
+                #return result
 
         # Now decide if latex will need to be run again due to glossary.
-        if check_MD5(suffix_nodes['.glo'],'.glo') or (count == 1 and run_glossary):
+        if check_MD5(suffix_nodes['.glo'],'.glo') or (count == 1 and run_glossaries) or (count == 1 and run_glossary):
             # We must run makeindex
             if Verbose:
                 print "Need to run makeindex for glossary"
@@ -332,6 +340,17 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
             result = MakeGlossaryAction(glofile, glofile, env)
             if result != 0:
                 print env['MAKEGLOSSARY']," (glossary) returned an error, check the glg file"
+                #return result
+
+        # Now decide if latex will need to be run again due to acronyms.
+        if check_MD5(suffix_nodes['.acn'],'.acn') or (count == 1 and run_acronyms):
+            # We must run makeindex
+            if Verbose:
+                print "Need to run makeindex for acronyms"
+            acrfile = suffix_nodes['.acn']
+            result = MakeAcronymsAction(acrfile, acrfile, env)
+            if result != 0:
+                print env['MAKEACRONYMS']," (acronymns) returned an error, check the alg file"
                 return result
 
         # Now decide if latex needs to be run yet again to resolve warnings.
@@ -473,19 +492,19 @@ def tex_emitter_core(target, source, env, graphics_extensions):
     are needed on subsequent runs of latex to finish tables of contents,
     bibliographies, indices, lists of figures, and hyperlink references.
     """
-    targetbase, targetext = SCons.Util.splitext(str(target[0]))
     basename = SCons.Util.splitext(str(source[0]))[0]
     basefile = os.path.split(str(basename))[1]
+    targetdir = os.path.split(str(target[0]))[0]
+    targetbase = os.path.join(targetdir, basefile)
 
     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
     
     #
     # file names we will make use of in searching the sources and log file
     #
-    emit_suffixes = ['.aux', '.log', '.ilg', '.blg', '.nls', '.nlg', '.gls', '.glg'] + all_suffixes
+    emit_suffixes = ['.aux', '.log', '.ilg', '.blg', '.nls', '.nlg', '.gls', '.glg', '.alg'] + all_suffixes
     auxfilename = targetbase + '.aux'
     logfilename = targetbase + '.log'
     flsfilename = targetbase + '.fls'
@@ -493,6 +512,8 @@ def tex_emitter_core(target, source, env, graphics_extensions):
     env.SideEffect(auxfilename,target[0])
     env.SideEffect(logfilename,target[0])
     env.SideEffect(flsfilename,target[0])
+    if Verbose:
+        print "side effect :",auxfilename,logfilename,flsfilename
     env.Clean(target[0],auxfilename)
     env.Clean(target[0],logfilename)
     env.Clean(target[0],flsfilename)
@@ -502,6 +523,7 @@ def tex_emitter_core(target, source, env, graphics_extensions):
     idx_exists = os.path.exists(targetbase + '.idx')
     nlo_exists = os.path.exists(targetbase + '.nlo')
     glo_exists = os.path.exists(targetbase + '.glo')
+    acr_exists = os.path.exists(targetbase + '.acn')
 
     # set up list with the regular expressions
     # we use to find features used
@@ -514,6 +536,8 @@ def tex_emitter_core(target, source, env, graphics_extensions):
                          hyperref_re,
                          makenomenclature_re,
                          makeglossary_re,
+                         makeglossaries_re,
+                         makeacronyms_re,
                          beamer_re ]
     # set up list with the file suffixes that need emitting
     # when a feature is found
@@ -526,6 +550,8 @@ def tex_emitter_core(target, source, env, graphics_extensions):
                   ['.out'],
                   ['.nlo', '.nls', '.nlg'],
                   ['.glo', '.gls', '.glg'],
+                  ['.glo', '.gls', '.glg'],
+                  ['.acn', '.acr', '.alg'],
                   ['.nav', '.snm', '.out', '.toc'] ]
     # build the list of lists
     file_tests = []
@@ -563,6 +589,8 @@ def tex_emitter_core(target, source, env, graphics_extensions):
         if theSearch:
             for suffix in suffix_list:
                 env.SideEffect(targetbase + suffix,target[0])
+                if Verbose:
+                    print "side effect :",targetbase + suffix
                 env.Clean(target[0],targetbase + suffix)
 
     # read fls file to get all other files that latex creates and will read on the next pass
@@ -575,6 +603,8 @@ def tex_emitter_core(target, source, env, graphics_extensions):
             if filename in myfiles:
                 out_files.remove(filename)
         env.SideEffect(out_files,target[0])
+        if Verbose:
+            print "side effect :",out_files
         env.Clean(target[0],out_files)
 
     return (target, source)
@@ -585,6 +615,25 @@ TeXLaTeXAction = None
 def generate(env):
     """Add Builders and construction variables for TeX to an Environment."""
 
+    global TeXLaTeXAction
+    if TeXLaTeXAction is None:
+        TeXLaTeXAction = SCons.Action.Action(TeXLaTeXFunction,
+                              strfunction=TeXLaTeXStrFunction)
+
+    env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes)
+
+    generate_common(env)
+
+    import dvi
+    dvi.generate(env)
+
+    bld = env['BUILDERS']['DVI']
+    bld.add_action('.tex', TeXLaTeXAction)
+    bld.add_emitter('.tex', tex_eps_emitter)
+
+def generate_common(env):
+    """Add internal Builders and construction variables for LaTeX to an Environment."""
+
     # A generic tex file Action, sufficient for all tex files.
     global TeXAction
     if TeXAction is None:
@@ -616,28 +665,28 @@ def generate(env):
     if MakeGlossaryAction is None:
         MakeGlossaryAction = SCons.Action.Action("$MAKEGLOSSARYCOM", "$MAKEGLOSSARYCOMSTR")
 
-    global TeXLaTeXAction
-    if TeXLaTeXAction is None:
-        TeXLaTeXAction = SCons.Action.Action(TeXLaTeXFunction,
-                              strfunction=TeXLaTeXStrFunction)
-
-    import dvi
-    dvi.generate(env)
-
-    bld = env['BUILDERS']['DVI']
-    bld.add_action('.tex', TeXLaTeXAction)
-    bld.add_emitter('.tex', tex_eps_emitter)
+    # Define an action to run MakeIndex on a file for acronyms.
+    global MakeAcronymsAction
+    if MakeAcronymsAction is None:
+        MakeAcronymsAction = SCons.Action.Action("$MAKEACRONYMSCOM", "$MAKEACRONYMSCOMSTR")
 
     env['TEX']      = 'tex'
     env['TEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
     env['TEXCOM']   = 'cd ${TARGET.dir} && $TEX $TEXFLAGS ${SOURCE.file}'
 
-    # Duplicate from latex.py.  If latex.py goes away, then this is still OK.
+    env['PDFTEX']      = 'pdftex'
+    env['PDFTEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
+    env['PDFTEXCOM']   = 'cd ${TARGET.dir} && $PDFTEX $PDFTEXFLAGS ${SOURCE.file}'
+
     env['LATEX']        = 'latex'
     env['LATEXFLAGS']   = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
     env['LATEXCOM']     = 'cd ${TARGET.dir} && $LATEX $LATEXFLAGS ${SOURCE.file}'
     env['LATEXRETRIES'] = 3
 
+    env['PDFLATEX']      = 'pdflatex'
+    env['PDFLATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
+    env['PDFLATEXCOM']   = 'cd ${TARGET.dir} && $PDFLATEX $PDFLATEXFLAGS ${SOURCE.file}'
+
     env['BIBTEX']      = 'bibtex'
     env['BIBTEXFLAGS'] = SCons.Util.CLVar('')
     env['BIBTEXCOM']   = 'cd ${TARGET.dir} && $BIBTEX $BIBTEXFLAGS ${SOURCE.filebase}'
@@ -651,16 +700,16 @@ def generate(env):
     env['MAKEGLOSSARYFLAGS'] = SCons.Util.CLVar('-s ${MAKEGLOSSARYSTYLE} -t ${SOURCE.filebase}.glg')
     env['MAKEGLOSSARYCOM']   = 'cd ${TARGET.dir} && $MAKEGLOSSARY ${SOURCE.filebase}.glo $MAKEGLOSSARYFLAGS -o ${SOURCE.filebase}.gls'
 
+    env['MAKEACRONYMS']      = 'makeindex'
+    env['MAKEACRONYMSSTYLE'] = '${SOURCE.filebase}.ist'
+    env['MAKEACRONYMSFLAGS'] = SCons.Util.CLVar('-s ${MAKEACRONYMSSTYLE} -t ${SOURCE.filebase}.alg')
+    env['MAKEACRONYMSCOM']   = 'cd ${TARGET.dir} && $MAKEACRONYMS ${SOURCE.filebase}.acn $MAKEACRONYMSFLAGS -o ${SOURCE.filebase}.acr'
+
     env['MAKENCL']      = 'makeindex'
-    env['MAKENCLSTYLE'] = '$nomencl.ist'
+    env['MAKENCLSTYLE'] = 'nomencl.ist'
     env['MAKENCLFLAGS'] = '-s ${MAKENCLSTYLE} -t ${SOURCE.filebase}.nlg'
     env['MAKENCLCOM']   = 'cd ${TARGET.dir} && $MAKENCL ${SOURCE.filebase}.nlo $MAKENCLFLAGS -o ${SOURCE.filebase}.nls'
 
-    # Duplicate from pdflatex.py.  If latex.py goes away, then this is still OK.
-    env['PDFLATEX']      = 'pdflatex'
-    env['PDFLATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
-    env['PDFLATEXCOM']   = 'cd ${TARGET.dir} && $PDFLATEX $PDFLATEXFLAGS ${SOURCE.file}'
-
 def exists(env):
     return env.Detect('tex')