From 2fa424ece5fd4df18a3aeff1f6e59e2ecb41a28e Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Sat, 23 Mar 2002 16:12:25 +0000 Subject: Support the build of TeX documents (Task 47116). (Steve Leblanc) --- doc/man/scons.1 | 23 ++++++++ src/CHANGES.txt | 9 +++ src/engine/SCons/Defaults.py | 31 +++++++++- test/LATEX.py | 125 +++++++++++++++++++++++++++++++++++++++++ test/LATEXFLAGS.py | 131 +++++++++++++++++++++++++++++++++++++++++++ test/TEX.py | 116 ++++++++++++++++++++++++++++++++++++++ test/TEXFLAGS.py | 122 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 555 insertions(+), 2 deletions(-) create mode 100644 test/LATEX.py create mode 100644 test/LATEXFLAGS.py create mode 100644 test/TEX.py create mode 100644 test/TEXFLAGS.py diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 16c5e6b..cee4e65 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -639,6 +639,19 @@ if it is not already present. Example: env.CXXFile(target = 'foo.cc', source = 'foo.ll') # builds foo.cc env.CXXFile(target = 'bar', source = 'bar.yy') # builds bar.cc .EE + +.IP DVI +Builds a .dvi file from a .tex, .ltx or .latex input file. +The suffix specified by the $DVISUFFIX construction variable +(.dvi by default) +is automatically added to the target +if it is not already present. Example: + +.ES +env.DVI(target = 'aaa.dvi', source = 'aaa.tex') # builds from aaa.tex +env.DVI(target = 'bbb', source = 'bbb.ltx') # builds bbb.dvi +env.DVI(target = 'ccc.dvi', source = 'ccc.latex') # builds from ccc.latex +.EE .LP C/C++ source files are automatically scanned for dependencies by .B scons @@ -744,6 +757,16 @@ env.InstallAs(target = '../lib/libfoo.a ../lib/libbar.a', .EE .TP +.RI Precious( target ", ...)" +Marks each given +.I target +as precious so it is not deleted before it is rebuilt. Normally +.B scons +deletes a target before building it. +Multiple targets can be passed in to a single call to +.BR Precious (). + +.TP .RI Update( key = val ", [...])" Updates the contents of an environment with the specified keyword arguments. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 97ac313..b53da0f 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -15,6 +15,10 @@ RELEASE 0.06 - - Fix: Construction variables with values of 0 were incorrectly interpolated as ''. + - Support env['VAR'] to fetch construction variable values. + + - Man page: document Precious(). + From Charles Crain: - Fix command generators to expand construction variables. @@ -48,6 +52,9 @@ RELEASE 0.06 - - Add a --profile=FILE option to make profiling SCons easier. + - Modify the new DVI builder to create .dvi files from LaTeX (.ltx + and .latex) files. + From Steve Leblanc: - Add support for the -U option. @@ -55,6 +62,8 @@ RELEASE 0.06 - - Allow CPPPATH, LIBPATH and LIBS to be specified as white-space separated strings. + - Add a document builder to create .dvi files from TeX (.tex) files. + RELEASE 0.05 - Thu, 21 Feb 2002 16:50:03 -0600 diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index d58126e..26c59a6 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -106,6 +106,19 @@ Library = SCons.Builder.Builder(name = 'Library', src_suffix = '$OBJSUFFIX', src_builder = Object) +LaTeXAction = SCons.Action.Action('$LATEXCOM') + +DVI = SCons.Builder.Builder(name = 'DVI', + action = { '.tex' : '$TEXCOM', + '.ltx' : LaTeXAction, + '.latex' : LaTeXAction, + }, + # The suffix is not configurable via a + # construction variable like $DVISUFFIX + # because the output file name is + # hard-coded within TeX. + suffix = '.dvi') + CScan = SCons.Scanner.C.CScan() def get_devstudio_versions (): @@ -228,7 +241,14 @@ def make_win32_env_from_paths(include, lib, path): 'YACC' : 'yacc', 'YACCFLAGS' : '', 'YACCCOM' : '$YACC $YACCFLAGS -o $TARGET $SOURCES', - 'BUILDERS' : [CFile, CXXFile, Object, Program, Library], + 'TEX' : 'tex', + 'TEXFLAGS' : '', + 'TEXCOM' : '$TEX $TEXFLAGS $SOURCES', + 'LATEX' : 'latex', + 'LATEXFLAGS' : '', + 'LATEXCOM' : '$LATEX $LATEXFLAGS $SOURCES', + 'DVISUFFIX' : '.dvi', + 'BUILDERS' : [CFile, CXXFile, Object, Program, Library, DVI], 'SCANNERS' : [CScan], 'OBJPREFIX' : '', 'OBJSUFFIX' : '.obj', @@ -291,7 +311,14 @@ if os.name == 'posix': 'YACC' : 'yacc', 'YACCFLAGS' : '', 'YACCCOM' : '$YACC $YACCFLAGS -o $TARGET $SOURCES', - 'BUILDERS' : [CFile, CXXFile, Object, Program, Library], + 'TEX' : 'tex', + 'TEXFLAGS' : '', + 'TEXCOM' : '$TEX $TEXFLAGS $SOURCES', + 'LATEX' : 'latex', + 'LATEXFLAGS' : '', + 'LATEXCOM' : '$LATEX $LATEXFLAGS $SOURCES', + 'DVISUFFIX' : '.dvi', + 'BUILDERS' : [CFile, CXXFile, Object, Program, Library, DVI], 'SCANNERS' : [CScan], 'OBJPREFIX' : '', 'OBJSUFFIX' : '.o', diff --git a/test/LATEX.py b/test/LATEX.py new file mode 100644 index 0000000..9ac74f5 --- /dev/null +++ b/test/LATEX.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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__" + +import os +import os.path +import string +import sys +import TestSCons + +python = sys.executable + +if sys.platform == 'win32': + _exe = '.exe' +else: + _exe = '' + +test = TestSCons.TestSCons() + + + +test.write('mylatex.py', r""" +import sys +import os +base_name = os.path.splitext(sys.argv[1])[0] +infile = open(sys.argv[1], 'rb') +out_file = open(base_name+'.dvi', 'wb') +for l in infile.readlines(): + if l[0] != '\\': + out_file.write(l) +sys.exit(0) +""") + +test.write('SConstruct', """ +env = Environment(LATEX = r'%s mylatex.py') +env.DVI(target = 'test1.dvi', source = 'test1.ltx') +env.DVI(target = 'test2.dvi', source = 'test2.latex') +""" % python) + +test.write('test1.ltx', r"""This is a .ltx test. +\end +""") + +test.write('test2.latex', r"""This is a .latex test. +\end +""") + +test.run(arguments = '.', stderr = None) + +test.fail_test(test.read('test1.dvi') != "This is a .ltx test.\n") + +test.fail_test(test.read('test2.dvi') != "This is a .latex test.\n") + + + +latex = None +for dir in string.split(os.environ['PATH'], os.pathsep): + l = os.path.join(dir, 'latex' + _exe) + if os.path.exists(l): + latex = l + break + +if latex: + + test.write("wrapper.py", """import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + + test.write('SConstruct', """ +foo = Environment() +latex = foo.Dictionary('LATEX') +bar = Environment(LATEX = r'%s wrapper.py ' + latex) +foo.DVI(target = 'foo.dvi', source = 'foo.ltx') +bar.DVI(target = 'bar', source = 'bar.latex') +""" % python) + + latex = r""" +\documentclass{letter} +\begin{document} +This is the %s LaTeX file. +\end{document} +""" + + test.write('foo.ltx', latex % 'foo.ltx') + + test.write('bar.latex', latex % 'bar.latex') + + test.run(arguments = 'foo.dvi', stderr = None) + + test.fail_test(os.path.exists(test.workpath('wrapper.out'))) + + test.fail_test(not os.path.exists(test.workpath('foo.dvi'))) + + test.run(arguments = 'bar.dvi', stderr = None) + + test.fail_test(test.read('wrapper.out') != "wrapper.py\n") + + test.fail_test(not os.path.exists(test.workpath('bar.dvi'))) + +test.pass_test() diff --git a/test/LATEXFLAGS.py b/test/LATEXFLAGS.py new file mode 100644 index 0000000..c366c8a --- /dev/null +++ b/test/LATEXFLAGS.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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__" + +import os +import os.path +import string +import sys +import TestSCons + +python = sys.executable + +if sys.platform == 'win32': + _exe = '.exe' +else: + _exe = '' + +test = TestSCons.TestSCons() + + + +test.write('mylatex.py', r""" +import getopt +import os +import sys +cmd_opts, args = getopt.getopt(sys.argv[1:], 'tx', []) +opt_string = '' +for opt, arg in cmd_opts: + opt_string = opt_string + ' ' + opt +base_name = os.path.splitext(args[0])[0] +infile = open(args[0], 'rb') +out_file = open(base_name+'.dvi', 'wb') +out_file.write(opt_string + "\n") +for l in infile.readlines(): + if l[0] != '\\': + out_file.write(l) +sys.exit(0) +""") + +test.write('SConstruct', """ +env = Environment(LATEX = r'%s mylatex.py', LATEXFLAGS = '-x') +env.DVI(target = 'test1.dvi', source = 'test1.ltx') +env.Copy(LATEXFLAGS = '-t').DVI(target = 'test2.dvi', source = 'test2.latex') +""" % python) + +test.write('test1.ltx', r"""This is a .ltx test. +\end +""") + +test.write('test2.latex', r"""This is a .latex test. +\end +""") + +test.run(arguments = '.', stderr = None) + +test.fail_test(test.read('test1.dvi') != " -x\nThis is a .ltx test.\n") + +test.fail_test(test.read('test2.dvi') != " -t\nThis is a .latex test.\n") + + + +latex = None +for dir in string.split(os.environ['PATH'], os.pathsep): + l = os.path.join(dir, 'latex' + _exe) + if os.path.exists(l): + latex = l + break + +if latex: + + test.write("wrapper.py", """import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + + test.write('SConstruct', """ +foo = Environment(LATEXFLAGS = '--output-comment Commentary') +latex = foo.Dictionary('LATEX') +bar = Environment(LATEX = r'%s wrapper.py ' + latex) +foo.DVI(target = 'foo.dvi', source = 'foo.ltx') +bar.DVI(target = 'bar', source = 'bar.latex') +""" % python) + + latex = r""" +\documentclass{letter} +\begin{document} +This is the %s LaTeX file. +\end{document} +""" + + test.write('foo.ltx', latex % 'foo.ltx') + + test.write('bar.latex', latex % 'bar.latex') + + test.run(arguments = 'foo.dvi', stderr = None) + + test.fail_test(os.path.exists(test.workpath('wrapper.out'))) + + test.fail_test(not os.path.exists(test.workpath('foo.dvi'))) + + test.run(arguments = 'bar.dvi', stderr = None) + + test.fail_test(test.read('wrapper.out') != "wrapper.py\n") + + test.fail_test(not os.path.exists(test.workpath('bar.dvi'))) + +test.pass_test() diff --git a/test/TEX.py b/test/TEX.py new file mode 100644 index 0000000..9b442c9 --- /dev/null +++ b/test/TEX.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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__" + +import os +import os.path +import string +import sys +import TestSCons + +python = sys.executable + +if sys.platform == 'win32': + _exe = '.exe' +else: + _exe = '' + +test = TestSCons.TestSCons() + + + +test.write('mytex.py', r""" +import sys +import os +base_name = os.path.splitext(sys.argv[1])[0] +infile = open(sys.argv[1], 'rb') +out_file = open(base_name+'.dvi', 'wb') +for l in infile.readlines(): + if l[0] != '\\': + out_file.write(l) +sys.exit(0) +""") + +test.write('SConstruct', """ +env = Environment(TEX = r'%s mytex.py') +env.DVI(target = 'test.dvi', source = 'test.tex') +""" % python) + +test.write('test.tex', r"""This is a test. +\end +""") + +test.run(arguments = 'test.dvi', stderr = None) + +test.fail_test(test.read('test.dvi') != "This is a test.\n") + + + +tex = None +for dir in string.split(os.environ['PATH'], os.pathsep): + t = os.path.join(dir, 'tex' + _exe) + if os.path.exists(t): + tex = t + break + +if tex: + + test.write("wrapper.py", """import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + + test.write('SConstruct', """ +foo = Environment() +tex = foo.Dictionary('TEX') +bar = Environment(TEX = r'%s wrapper.py ' + tex) +foo.DVI(target = 'foo.dvi', source = 'foo.tex') +bar.DVI(target = 'bar', source = 'bar.tex') +""" % python) + + tex = r""" +This is the %s TeX file. +\end +""" + + test.write('foo.tex', tex % 'foo.tex') + + test.write('bar.tex', tex % 'bar.tex') + + test.run(arguments = 'foo.dvi', stderr = None) + + test.fail_test(os.path.exists(test.workpath('wrapper.out'))) + + test.fail_test(not os.path.exists(test.workpath('foo.dvi'))) + + test.run(arguments = 'bar.dvi', stderr = None) + + test.fail_test(not os.path.exists(test.workpath('wrapper.out'))) + + test.fail_test(not os.path.exists(test.workpath('bar.dvi'))) + +test.pass_test() diff --git a/test/TEXFLAGS.py b/test/TEXFLAGS.py new file mode 100644 index 0000000..4cc08d3 --- /dev/null +++ b/test/TEXFLAGS.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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__" + +import os +import os.path +import string +import sys +import TestSCons + +python = sys.executable + +if sys.platform == 'win32': + _exe = '.exe' +else: + _exe = '' + +test = TestSCons.TestSCons() + + + +test.write('mytex.py', r""" +import getopt +import os +import sys +cmd_opts, args = getopt.getopt(sys.argv[1:], 'tx', []) +opt_string = '' +for opt, arg in cmd_opts: + opt_string = opt_string + ' ' + opt +base_name = os.path.splitext(args[0])[0] +infile = open(args[0], 'rb') +out_file = open(base_name+'.dvi', 'wb') +out_file.write(opt_string + "\n") +for l in infile.readlines(): + if l[0] != '\\': + out_file.write(l) +sys.exit(0) +""") + +test.write('SConstruct', """ +env = Environment(TEX = r'%s mytex.py', TEXFLAGS = '-x') +env.DVI(target = 'test.dvi', source = 'test.tex') +""" % python) + +test.write('test.tex', r"""This is a test. +\end +""") + +test.run(arguments = 'test.dvi', stderr = None) + +test.fail_test(test.read('test.dvi') != " -x\nThis is a test.\n") + + + +tex = None +for dir in string.split(os.environ['PATH'], os.pathsep): + t = os.path.join(dir, 'tex' + _exe) + if os.path.exists(t): + tex = t + break + +if tex: + + test.write("wrapper.py", """import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + + test.write('SConstruct', """ +foo = Environment(TEXFLAGS = '--output-comment Commentary') +tex = foo.Dictionary('TEX') +bar = Environment(TEX = r'%s wrapper.py ' + tex) +foo.DVI(target = 'foo.dvi', source = 'foo.tex') +bar.DVI(target = 'bar', source = 'bar.tex') +""" % python) + + tex = r""" +This is the %s TeX file. +\end +""" + + test.write('foo.tex', tex % 'foo.tex') + + test.write('bar.tex', tex % 'bar.tex') + + test.run(arguments = 'foo.dvi', stderr = None) + + test.fail_test(os.path.exists(test.workpath('wrapper.out'))) + + test.fail_test(not os.path.exists(test.workpath('foo.dvi'))) + + test.run(arguments = 'bar.dvi', stderr = None) + + test.fail_test(not os.path.exists(test.workpath('wrapper.out'))) + + test.fail_test(not os.path.exists(test.workpath('bar.dvi'))) + +test.pass_test() -- cgit v0.12