Commits

Rob Managan committed a8eb61b

first cut at supporting context version of tex document generation

Comments (0)

Files changed (5)

src/engine/SCons/Tool/__init__.py

 
 IDLSuffixes = [".idl", ".IDL"]
 
-LaTeXSuffixes = [".tex", ".ltx", ".latex"]
+LaTeXSuffixes = [".tex", ".ltx", ".latex", ".cld", ".xml"]
 
 for suffix in CSuffixes:
     SourceFileScanner.add_scanner(suffix, CScanner)
                                'jar', 'javac', 'javah', 'rmic',
                                # TeX
                                'dvipdf', 'dvips', 'gs',
-                               'tex', 'latex', 'pdflatex', 'pdftex',
+                               'tex', 'latex', 'pdflatex', 'pdftex', 'pdfcontext',
                                # Archivers
                                'tar', 'zip', 'rpm',
                                # SourceCode factories

src/engine/SCons/Tool/pdfcontext.py

+"""SCons.Tool.ConTeXt
+
+Tool-specific initialization for context.
+Generates .pdf files from .xml or .cld files
+THe .tex option is already handled by the pdflatex tool.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
+
+#
+# __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__"
+
+import SCons.Action
+import SCons.Util
+import SCons.Tool.pdf
+import SCons.Tool.tex
+
+ConTeXtAction = None
+
+def ConTeXtAuxFunction(target = None, source= None, env=None):
+    result = SCons.Tool.tex.InternalLaTeXAuxAction( ConTeXtAction, target, source, env )
+    if result != 0:
+        SCons.Tool.tex.check_file_error_message(env['CONTEXT'])
+    return result
+
+ConTeXtAuxAction = None
+
+def generate(env):
+    """Add Builders and construction variables for context to an Environment."""
+    global ConTeXtAction
+    if ConTeXtAction is None:
+        ConTeXtAction = SCons.Action.Action('$CONTEXTCOM', '$CONTEXTCOMSTR')
+
+    global ConTeXtAuxAction
+    if ConTeXtAuxAction is None:
+        ConTeXtAuxAction = SCons.Action.Action(ConTeXtAuxFunction,
+                              strfunction=SCons.Tool.tex.TeXLaTeXStrFunction)
+
+    env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes)
+
+    import pdf
+    pdf.generate(env)
+
+    bld = env['BUILDERS']['PDF']
+    bld.add_action('.xml', ConTeXtAuxAction)
+    bld.add_action('.cld', ConTeXtAuxAction)
+    bld.add_emitter('.xml', SCons.Tool.tex.tex_pdf_emitter)
+    bld.add_emitter('.cld', SCons.Tool.tex.tex_pdf_emitter)
+
+    SCons.Tool.tex.generate_common(env)
+
+def exists(env):
+    SCons.Tool.tex.generate_darwin(env)
+    return env.Detect('context')
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

src/engine/SCons/Tool/pdftex.py

     result = SCons.Tool.tex.InternalLaTeXAuxAction( PDFLaTeXAction, target, source, env )
     return result
 
+ConTeXtAction = None
+
+def ConTeXtAuxAction(target = None, source= None, env=None):
+    result = SCons.Tool.tex.InternalLaTeXAuxAction( ConTeXtAction, target, source, env )
+    return result
+
 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
     basedir = os.path.split(str(source[0]))[0]
     abspath = os.path.abspath(basedir)
 
-    if SCons.Tool.tex.is_LaTeX(source,env,abspath):
+    filetype = SCons.Tool.tex.is_LaTeX(source,env,abspath)
+    #if Verbose:
+    #    print "PDFTeXLaTeXFunction source ", source, "type ",filetype
+
+    if filetype == 1:
         result = PDFLaTeXAuxAction(target,source,env)
         if result != 0:
-            SCons.Tool.tex.check_file_error_message(env['PDFLATEX'])
+            check_file_error_message(env['PDFLATEX'])
+    elif filetype == 2:
+        result = ConTeXtAuxAction(target,source,env)
+        if result != 0:
+            check_file_error_message(env['CONTEXT'])
     else:
         result = PDFTeXAction(target,source,env)
         if result != 0:
-            SCons.Tool.tex.check_file_error_message(env['PDFTEX'])
+            check_file_error_message(env['PDFTEX'])
     return result
 
 PDFTeXLaTeXAction = None
     if PDFLaTeXAction is None:
         PDFLaTeXAction = SCons.Action.Action("$PDFLATEXCOM", "$PDFLATEXCOMSTR")
 
+    global ConTeXtAction
+    if ConTeXtAction is None:
+        ConTeXtAction = SCons.Action.Action("$CONTEXTCOM", "$CONTEXTCOMSTR")
+
     global PDFTeXLaTeXAction
     if PDFTeXLaTeXAction is None:
         PDFTeXLaTeXAction = SCons.Action.Action(PDFTeXLaTeXFunction,

src/engine/SCons/Tool/tex.py

 # than once if we are dealing with labels and bibtex.
 LaTeXAction = None
 
+# An action to build a context file.  This action might be needed more
+# than once if we are dealing with labels and bibtex.
+ConTeXtAction = None
+
 # An action to run BibTeX on a file.
 BibTeXAction = None
 
     result = InternalLaTeXAuxAction( LaTeXAction, target, source, env )
     return result
 
+def ConTeXtAuxAction(target = None, source= None, env=None):
+    if Verbose:
+        print "enter ConTeXtAuxAction"
+    result = InternalLaTeXAuxAction( ConTeXtAction, target, source, env )
+    return result
+
 LaTeX_re = re.compile("\\\\document(style|class)")
+ConTeXt_re = re.compile("\\\\starttext")
 
 def is_LaTeX(flist,env,abspath):
-    """Scan a file list to decide if it's TeX- or LaTeX-flavored."""
+    """Scan a file list to decide if it's TeX-, LaTeX- or ConTeXt-flavored."""
 
     # We need to scan files that are included in case the
     # \documentclass command is in them.
             if Verbose:
                 print "file %s is a LaTeX file" % str(f)
             return 1
+        if ConTeXt_re.search(content):
+            if Verbose:
+                print "file %s is a ConTeXt file" % str(f)
+            return 2
         if Verbose:
             print "file %s is not a LaTeX file" % str(f)
 
             if srcNode is not None:
                 file_test = is_LaTeX(fileList, env, abspath)
 
-            # return on first file that finds latex is needed.
+            # return on first file that finds LaTeX or ConTeXt is needed.
             if file_test:
                 return file_test
 
     basedir = os.path.split(str(source[0]))[0]
     abspath = os.path.abspath(basedir)
 
-    if is_LaTeX(source,env,abspath):
+    filetype = is_LaTeX(source,env,abspath)
+    if Verbose:
+        print "TeXLaTeXFunction source ", source, "type ",filetype
+
+    if filetype == 1:
         result = LaTeXAuxAction(target,source,env)
         if result != 0:
             check_file_error_message(env['LATEX'])
+    elif filetype == 2:
+        result = ConTeXtAuxAction(target,source,env)
+        if result != 0:
+            check_file_error_message(env['CONTEXT'])
     else:
         result = TeXAction(target,source,env)
         if result != 0:
     return result
 
 def TeXLaTeXStrFunction(target = None, source= None, env=None):
-    """A strfunction for TeX and LaTeX that scans the source file to
+    """A strfunction for TeX, LaTeX, and ConTeXt that scans the source file to
     decide the "flavor" of the source and then returns the appropriate
     command string."""
     if env.GetOption("no_exec"):
         basedir = os.path.split(str(source[0]))[0]
         abspath = os.path.abspath(basedir)
 
-        if is_LaTeX(source,env,abspath):
+        filetype = is_LaTeX(source,env,abspath)
+        if Verbose:
+            print "TeXLaTeXStrFunction source ", source, "type ",filetype
+
+        if filetype == 1:
             result = env.subst('$LATEXCOM',0,target,source)+" ..."
+        elif filetype == 2:
+            result = env.subst('$CONTEXTCOM',0,target,source)+" ..."
         else:
             result = env.subst("$TEXCOM",0,target,source)+" ..."
     else:
                          makeacronyms_re,
                          beamer_re,
                          newglossary_re,
-                         biblatex_re ]
+                         biblatex_re,
+                         ConTeXt_re ]
     # set up list with the file suffixes that need emitting
     # when a feature is found
     file_tests_suff = [['.aux','aux_file'],
                   ['.acn', '.acr', '.alg','acronyms'],
                   ['.nav', '.snm', '.out', '.toc','beamer'],
                   ['newglossary',],
-                  ['.bcf', '.blg','biblatex'] ]
+                  ['.bcf', '.blg','biblatex'],
+                  ['.tuc', 'context'] ]
     # for newglossary the suffixes are added as we find the command
     # build the list of lists
     file_tests = []
     if LaTeXAction is None:
         LaTeXAction = SCons.Action.Action("$LATEXCOM", "$LATEXCOMSTR")
 
+    # An Action to build a context file.  This might be needed more
+    # than once if we are dealing with labels and bibtex.
+    global ConTeXtAction
+    if ConTeXtAction is None:
+        ConTeXtAction = SCons.Action.Action("$CONTEXTCOM", "$CONTEXTCOMSTR")
+
     # Define an action to run BibTeX on a file.
     global BibTeXAction
     if BibTeXAction is None:
     env['PDFLATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
     env['PDFLATEXCOM']   = CDCOM + '${TARGET.dir} && $PDFLATEX $PDFLATEXFLAGS ${SOURCE.file}'
 
+    env['CONTEXT']      = 'context'
+    env['CONTEXTFLAGS'] = SCons.Util.CLVar('--nonstopmode')
+    env['CONTEXTCOM']   = CDCOM + '${TARGET.dir} && $CONTEXT $CONTEXTFLAGS ${SOURCE.file}'
+
     env['BIBTEX']      = 'bibtex'
     env['BIBTEXFLAGS'] = SCons.Util.CLVar('')
     env['BIBTEXCOM']   = CDCOM + '${TARGET.dir} && $BIBTEX $BIBTEXFLAGS ${SOURCE.filebase}'

test/TEX/context.py

+#!/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__"
+
+"""
+Verify that ConTeXt works for a simple file.
+
+"""
+
+import TestSCons
+import os
+
+test = TestSCons.TestSCons()
+
+context = test.where_is('context')
+
+if not context:
+    test.skip_test("Could not find context application; skipping test(s).\n")
+
+test.write(['SConstruct'], """\
+import os
+
+DefaultEnvironment()
+
+PDF("testtex.tex")
+#PDF("testcld.cld")
+PDF("testxml.xml")
+""")
+
+content = r"""
+\environment env_mla
+\MLA[Jin-Ho][King][Professor Wotsisnam][Engrish 250]%
+[30 February 2004][Foundation for Poor Diction]
+
+\starttext
+There once was a young man who wanted to write. He wrote and
+wrote. He wrote nothing of value. All his life, he struggled
+to create something worth reading; all his life, he struggled
+to become someone worth knowing. All his life, he failed
+miserably.
+
+\startlongquote
+Now the question is not whether he can write. His abilities
+in picking up pencils and pens and putting them to paper
+cannot be denied. Actually, I've rarely seen anyone so
+willing to put ideas on paper. The real question is:
+``Should a man like that be given pencils and pens and
+paper?" (Crane 243)
+\stoplongquote
+
+There is little more to be said about this man; this man has
+little more to be said.
+
+\startworkscited
+Crane, Irod. ``The Complications of Existential
+Transcendence." {\em Life and Library}. Boston: Trash, 2004.
+
+\stopworkscited
+\stoptext
+"""
+test.write(['testtex.tex'], content)
+test.write(['testcld.cld'], r"""
+context.starttext()
+context.chapter("Hello There!")
+context.stoptext()
+""")
+test.write(['testxml.xml'], content)
+
+test.write(['env_mla.tex'], r"""
+% Filename: env_mla.tex
+
+%Provided Methods:
+%   \MLA[First][Last][Prof][Class][Date][Title]
+%   \startlongquote ... \stoplongquote
+%   \startworkscited ... \stopworkscited
+
+\startenvironment env_mla
+
+% paper, layout, etc.
+\setuppapersize[letter]
+\setuplayout[width=6.5in,height=10.5in,topspace=0.5in,backspace=1in,
+  header=0.5in,footer=0.5in]
+% double space
+\setupinterlinespace[line=5.6ex]
+% 1/2 inch indents
+\setupindenting[0.5in]
+% jagged-right (aligned to the left)
+\setupalign[right]
+% font
+\setupbodyfont[rm,12pt]
+
+% for long quotes
+\definestartstop[longquote][
+  before={\indenting[never]
+    \setupnarrower[left=0.5in,right=0.5in]
+    \startnarrower[2*left,right]},
+  after={\stopnarrower
+    \indenting[yes]}]
+
+% for heading and header
+\def\MLA#1[#2][#3][#4][#5][#6][#7]%
+    {\setuppagenumbering[left=#3 ,location={header,right}]
+    \indenting[never]
+    #2 #3\par#4\par#5\par#6\par\startalignment[middle]#7\stopalignment
+    \indenting[yes]}
+    
+% following hanging indent code (also in workscited) taken from 
+%  http://www.ntg.nl/pipermail/ntg-context/2004/005280.html
+% [NTG-context] Re: Again: "hanging" for a lot of paragraphs?
+%  ~ Patrick Gundlach
+\def\hangover{\hangafter=1\hangindent=0.5in}
+\definestartstop[workscited][
+  before={
+    \page[yes]
+    \indenting[never]
+    \startalignment[middle]
+    Works Cited
+    \stopalignment
+    \bgroup\appendtoks\hangover\to\everypar
+    },
+  after={
+    \egroup
+    \indenting[yes]}]
+
+\stopenvironment
+""")
+
+test.run()
+
+# All (?) the files we expect will get created in the docs directory
+files = [
+    'testtex.pdf',
+    'testtex.log',
+    'testtex.tuc',
+#    'testcld.pdf',
+#    'testcld.log',
+#    'testcld.tuc',
+    'testxml.pdf',
+    'testxml.log',
+    'testxml.tuc'
+]
+
+
+for f in files:
+    test.must_exist([ f])
+
+
+
+# Double-check:  clean everything and rebuild from scratch, which
+# should force the PDF file to be the 1982 version.
+
+test.run(arguments = '-c')
+
+for f in files:
+    test.must_not_exist([ f])
+
+
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: