3 Tool-specific initialization for TeX.
5 There normally shouldn't be any need to import this module directly.
6 It will usually be imported through the generic SCons.Tool.Tool()
14 # Permission is hereby granted, free of charge, to any person obtaining
15 # a copy of this software and associated documentation files (the
16 # "Software"), to deal in the Software without restriction, including
17 # without limitation the rights to use, copy, modify, merge, publish,
18 # distribute, sublicense, and/or sell copies of the Software, and to
19 # permit persons to whom the Software is furnished to do so, subject to
20 # the following conditions:
22 # The above copyright notice and this permission notice shall be included
23 # in all copies or substantial portions of the Software.
25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
26 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
27 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
45 # An Action sufficient to build any generic tex file.
48 # An action to build a latex file. This action might be needed more
49 # than once if we are dealing with labels and bibtex.
52 # An action to run BibTeX on a file.
55 # An action to run MakeIndex on a file.
56 MakeIndexAction = None
58 def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None):
59 """A builder for LaTeX files that checks the output in the aux file
60 and decides how many times to use LaTeXAction, and BibTeXAction."""
62 basename, ext = SCons.Util.splitext(str(target[0]))
64 # Run LaTeX once to generate a new aux file.
65 XXXLaTeXAction(target,source,env)
67 # Decide if various things need to be run, or run again. We check
68 # for the existence of files before opening them--even ones like the
69 # aux file that TeX always creates--to make it possible to write tests
70 # with stubs that don't necessarily generate all of the same files.
72 # Now decide if bibtex will need to be run.
73 auxfilename = basename + '.aux'
74 if os.path.exists(auxfilename):
75 content = open(auxfilename, "rb").read()
76 if string.find(content, "bibdata") != -1:
77 bibfile = env.fs.File(basename)
78 BibTeXAction(None,bibfile,env)
80 # Now decide if makeindex will need to be run.
81 idxfilename = basename + '.idx'
82 if os.path.exists(idxfilename):
83 idxfile = env.fs.File(basename)
84 # TODO: if ( idxfile has changed) ...
85 MakeIndexAction(None,idxfile,env)
86 LaTeXAction(target,source,env)
88 # Now decide if latex needs to be run yet again.
89 logfilename = basename + '.log'
90 for trial in range(int(env.subst('$LATEXRETRIES'))):
91 if not os.path.exists(logfilename):
93 content = open(logfilename, "rb").read()
94 if not re.search("^LaTeX Warning:.*Rerun",content,re.MULTILINE) and not re.search("^LaTeX Warning:.*undefined references",content,re.MULTILINE):
96 XXXLaTeXAction(target,source,env)
99 def LaTeXAuxAction(target = None, source= None, env=None):
100 InternalLaTeXAuxAction( LaTeXAction, target, source, env )
102 LaTeX_re = re.compile("\\\\document(style|class)")
105 # Scan a file list to decide if it's TeX- or LaTeX-flavored.
107 content = f.get_contents()
108 if LaTeX_re.search(content):
112 def TeXLaTeXFunction(target = None, source= None, env=None):
113 """A builder for TeX and LaTeX that scans the source file to
114 decide the "flavor" of the source and then executes the appropriate
117 LaTeXAuxAction(target,source,env)
119 TeXAction(target,source,env)
122 def tex_emitter(target, source, env):
123 base = SCons.Util.splitext(str(source[0]))[0]
124 target.append(base + '.aux')
125 target.append(base + '.log')
126 return (target, source)
128 TeXLaTeXAction = None
131 """Add Builders and construction variables for TeX to an Environment."""
133 # A generic tex file Action, sufficient for all tex files.
135 if TeXAction is None:
136 TeXAction = SCons.Action.Action("$TEXCOM", "$TEXCOMSTR")
138 # An Action to build a latex file. This might be needed more
139 # than once if we are dealing with labels and bibtex.
141 if LaTeXAction is None:
142 LaTeXAction = SCons.Action.Action("$LATEXCOM", "$LATEXCOMSTR")
144 # Define an action to run BibTeX on a file.
146 if BibTeXAction is None:
147 BibTeXAction = SCons.Action.Action("$BIBTEXCOM", "$BIBTEXCOMSTR")
149 # Define an action to run MakeIndex on a file.
150 global MakeIndexAction
151 if MakeIndexAction is None:
152 MakeIndexAction = SCons.Action.Action("$MAKEINDEXCOM", "$MAKEINDEXOMSTR")
154 global TeXLaTeXAction
155 if TeXLaTeXAction is None:
156 TeXLaTeXAction = SCons.Action.Action(TeXLaTeXFunction, strfunction=None)
161 bld = env['BUILDERS']['DVI']
162 bld.add_action('.tex', TeXLaTeXAction)
163 bld.add_emitter('.tex', tex_emitter)
166 env['TEXFLAGS'] = SCons.Util.CLVar('')
167 env['TEXCOM'] = '$TEX $TEXFLAGS $SOURCE'
169 # Duplicate from latex.py. If latex.py goes away, then this is still OK.
170 env['LATEX'] = 'latex'
171 env['LATEXFLAGS'] = SCons.Util.CLVar('')
172 env['LATEXCOM'] = '$LATEX $LATEXFLAGS $SOURCE'
173 env['LATEXRETRIES'] = 3
175 env['BIBTEX'] = 'bibtex'
176 env['BIBTEXFLAGS'] = SCons.Util.CLVar('')
177 env['BIBTEXCOM'] = '$BIBTEX $BIBTEXFLAGS $SOURCE'
179 env['MAKEINDEX'] = 'makeindex'
180 env['MAKEINDEXFLAGS'] = SCons.Util.CLVar('')
181 env['MAKEINDEXCOM'] = '$MAKEINDEX $MAKEINDEXFLAGS $SOURCES'
184 return env.Detect('tex')