Commits

dirkbaechle committed f05f29f

- relinked the build of all documentation outputs to the bootstrap process
- corrected the doc folder SConscripts and added XSL and titlepage files where required

  • Participants
  • Parent commits d4fe8fd

Comments (0)

Files changed (50)

 
 python_ver = sys.version[0:3]
 
+#
+# Adding some paths to sys.path, this is mainly needed
+# for the doc toolchain.
+#
+addpaths = [os.path.abspath(os.path.join(os.getcwd(), 'bin')),
+            os.path.abspath(os.path.join(os.getcwd(), 'QMTest'))]
+for a in addpaths:
+    if a not in sys.path:
+        sys.path.append(a)
+
+
 # Re-exporting LD_LIBRARY_PATH is necessary if the Python version was
 # built with the --enable-shared option.
 
     open(t, 'wb').write(contents)
     os.chmod(t, os.stat(s)[0])
 
+revaction = SCons_revision
 revbuilder = Builder(action = Action(SCons_revision,
                                      varlist=['COPYRIGHT', 'VERSION']))
 
 #
 # Documentation.
 #
-Export('build_dir', 'env', 'whereis')
+Export('build_dir', 'env', 'whereis', 'revaction')
 
 SConscript('doc/SConscript')
 

File bin/scons-proc.py

     prefix = 'f-'
     tag = 'function'
     
-    def xml_term(self):
+    def xml_terms(self):
         if self.arguments is None:
             a = stf.newNode("arguments")
             stf.setText(a, '()')
             arguments = [a]
         else:
-            arguments = self.arguments    
-        t = stf.newNode("term")
+            arguments = self.arguments
+        tlist = []
         for arg in arguments:
             signature = 'both'
             if stf.hasAttribute(arg, 'signature'):
                 signature = stf.getAttribute(arg, 'signature')
             s = stf.getText(arg).strip()
             if signature in ('both', 'global'):
-                syn = stf.newNode("synopsis")
+                t = stf.newNode("term")
+                syn = stf.newNode("literal")
                 stf.setText(syn, '%s%s' % (self.name, s))
                 stf.appendNode(t, syn)
+                tlist.append(t)
             if signature in ('both', 'env'):
-                syn = stf.newNode("synopsis")
+                t = stf.newNode("term")
+                syn = stf.newNode("literal")
                 stf.setText(syn, 'env.%s%s' % (self.name, s))
                 stf.appendNode(t, syn)
+                tlist.append(t)
 
-        return t
+        if not tlist:
+            tlist.append(stf.newNode("term"))
+        return tlist
     
     def entityfunc(self):
         return self.name

File bin/scons_dev_master.py

 ]
 
 BUILDING_PACKAGES = [
-    'docbook',
-    'docbook-dsssl',
-    'docbook-utils',
-    'docbook-xml',
-    'groff-base',
-    'jade',
-    'jadetex',
-    'man2html',
+    'python-libxml2',
+    'python-libxslt1',
+    'fop',
+    'python-dev',
     'python-epydoc',
     'rpm',
-    'sp',
     'tar',
-
+    
     # additional packages that Bill Deegan's web page suggests
     #'docbook-to-man',
     #'docbook-xsl',

File doc/SConscript

 
 import os.path
 import re
+import sys
+import glob
+import SConsDoc
+import SConsExamples
 
-Import('build_dir', 'env', 'whereis')
+Import('build_dir', 'env', 'whereis', 'revaction')
 
 env = env.Clone()
 
 build = os.path.join(build_dir, 'doc')
 
+fop = whereis('fop')
+xep = whereis('xep')
+epydoc_cli = whereis('epydoc')
+
 #
 #
 #
 dist_doc_tar_gz = '$DISTDIR/scons-doc-${VERSION}.tar.gz'
 
-#
-# We'll only try to build text files (for some documents)
-# if lynx is available to do the dump.
-#
-fig2dev = whereis('fig2dev')
-epydoc_cli = whereis('epydoc')
-groff = whereis('groff')
-lynx = whereis('lynx')
-man2html = whereis('man2html')
-jade_original = whereis('jade')
-jade = whereis('openjade') or jade_original
-jadetex = whereis('jadetex')
-pdfjadetex = whereis('pdfjadetex')
-jw = whereis('jw')
-tidy = whereis('tidy')
-
 tar_deps = []
 tar_list = []
 
-entity_re = re.compile(r'<!entity\s+(?:%\s+)?(?:\S+)\s+SYSTEM\s+"([^"]*)">', re.I)
-format_re = re.compile(r'<(?:graphic|imagedata)\s+fileref="([^"]*)"(?:\s+format="([^"]*)")?')
+orig_env = env
+env = orig_env.Clone(SCONS_PY = File('#src/script/scons.py').rfile())
+
+
+def writeVersionXml(verfile, date, ver, rev):
+    """ Helper function: Write a version.xml file. """
+    try:
+        os.unlink(verfile)
+    except OSError:
+        pass    # okay if the file didn't exist
+    dir, f = os.path.split(verfile)
+    try:
+        os.makedirs(dir)
+    except OSError:
+        pass    # okay if the directory already exists
+    open(verfile, "w").write("""<!--
+THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
+-->
+<!ENTITY builddate "%s">
+<!ENTITY buildversion "%s">
+<!ENTITY buildrevision "%s">
+""" % (date, ver, rev))
 
 #
-# Find internal dependencies in .xml files:
+# Check whether we have all tools installed for
+# building the documentation.
 #
-#   <!entity bground SYSTEM "bground.xml">
-#   <graphic fileref="file.jpg">
-#   <imagedata fileref="file.jpg">
-#
-# This only finds one per line, and assumes that anything
-# defined as a SYSTEM entity is, in fact, a file included
-# somewhere in the document.
-#
-def scanxml(node, env, target):
-    includes = []
-
-    contents = node.get_text_contents()
-
-    includes.extend(entity_re.findall(contents))
-
-    matches = format_re.findall(contents)
-    for m in matches:
-        file, format = m
-        if format and file[-len(format):] != format:
-            file = file + '.' + format
-        if not os.path.isabs(file):
-            a = []
-            f = file
-            while f:
-                f, tail = os.path.split(f)
-                if tail == 'doc':
-                    break
-                a = [tail] + a
-            file = os.path.join(*a)
-        includes.append(file)
-
-    return includes
-
-s = Scanner(name = 'xml', function = scanxml, skeys = ['.xml', '.mod'])
-
-orig_env = env
-env = orig_env.Clone(SCANNERS = [s],
-                     SCONS_DOC_PY = File('#bin/scons-doc.py').rfile(),
-                     SCONS_PROC_PY = File('#bin/scons-proc.py').rfile())
-
-# Fetch the list of files in the build engine that contain
-# SCons documentation XML for processing.
-def chop(s): return s[:-1]
-
-manifest_xml_in = File('#src/engine/MANIFEST-xml.in').rstr()
-scons_doc_files = list(map(chop, open(manifest_xml_in).readlines()))
-scons_doc_files = [File('#src/engine/'+x).rstr() for x in scons_doc_files]
-
-if not jw:
-    print "doc: jw not found, skipping building User Guide."
+skip_doc = False
+try:
+    import libxml2
+except:
+    try:
+        import lxml
+    except:
+        print "doc: Neither libxml2 nor lxml Python bindings found!"
+        print "     Please install one of the packages python-libxml2 or python-lxml."
+        skip_doc = True
+        
+if not fop and not xep:
+    print "doc: No PDF renderer found (fop|xep)!"
+    skip_doc = True
+    
+if skip_doc:
+    print "doc: ...skipping building User Guide."
 else:
     #
     # Always create a version.xml file containing the version information
     #
     date, ver, rev = env.Dictionary('DATE', 'VERSION', 'REVISION')
     version_xml = File(os.path.join(build, "version.xml"))
-    #version_xml = File("version.xml")
-    verfile = str(version_xml)
-    try:
-        os.unlink(verfile)
-    except OSError:
-        pass    # okay if the file didn't exist
-    dir, f = os.path.split(verfile)
-    try:
-        os.makedirs(dir)
-    except OSError:
-        pass	# okay if the directory already exists
-    open(verfile, "w").write("""<!--
-THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
--->
-<!ENTITY builddate "%s">
-<!ENTITY buildversion "%s">
-<!ENTITY buildrevision "%s">
-""" % (date, ver, rev))
+    writeVersionXml(str(version_xml), date, ver, rev)
+    
+    if not env.GetOption('clean'):
+        #
+        # Ensure that all XML files are valid against our XSD, and
+        # that all example names and example output suffixes are unique
+        #
+        print "Validating files against SCons XSD..."
+        if SConsDoc.validate_all_xml(['src'], xsdfile='xsd/scons.xsd'):
+            print "OK"
+        else:
+            print "Validation failed! Please correct the errors above and try again."
+            sys.exit(0)
+            
+        print "Checking whether all example names are unique..."
+        if SConsExamples.exampleNamesAreUnique(os.path.join('doc','user')):
+            print "OK"
+        else:
+            print "Not all example names and suffixes are unique! Please correct the errors listed above and try again."
+            sys.exit(0)
+    
+        #
+        # Copy generated files (.gen/.mod/.xml) to the build folder
+        #
+        env.Execute(Mkdir(os.path.join(build, 'generated')))
+        env.Execute(Mkdir(os.path.join(build, 'generated', 'examples')))
+        for g in glob.glob(os.path.join('generated', '*.gen')):
+            env.Execute(Copy(os.path.join(build, 'generated'), g))
+        for g in glob.glob(os.path.join('generated', '*.mod')):
+            env.Execute(Copy(os.path.join(build, 'generated'), g))
+        for g in glob.glob(os.path.join('generated', 'examples', '*')):
+            env.Execute(Copy(os.path.join(build, 'generated', 'examples'), g))
 
-    builders_gen = os.path.join(build, 'user', 'builders.gen')
-    builders_mod = os.path.join(build, 'user', 'builders.mod')
-    functions_gen = os.path.join(build, 'user', 'functions.gen')
-    functions_mod = os.path.join(build, 'user', 'functions.mod')
-    tools_gen = os.path.join(build, 'user', 'tools.gen')
-    tools_mod = os.path.join(build, 'user', 'tools.mod')
-    variables_gen = os.path.join(build, 'user', 'variables.gen')
-    variables_mod = os.path.join(build, 'user', 'variables.mod')
+        #
+        # Copy XSLT files (.xslt) to the build folder
+        #
+        env.Execute(Mkdir(os.path.join(build, 'xslt')))
+        for g in glob.glob(os.path.join('xslt','*.*')):
+            env.Execute(Copy(os.path.join(build, 'xslt'), g))
 
-    # We put $( - $) around $SOURCES in the command line below because
-    # the path names will change when a given input file is found in
-    # a repository one run and locally the next, and we don't want
-    # to rebuild documentation just because it's found in one location
-    # vs. the other.  The *.gen and *.mod targets will still be dependent
-    # on the list of the files themselves.
-    doc_output_files = [builders_gen, builders_mod,
-                        functions_gen, functions_mod,
-                        tools_gen, tools_mod,
-                        variables_gen, variables_mod]
-    b = env.Command(doc_output_files,
-                    scons_doc_files,
-                    "$PYTHON $SCONS_PROC_PY --xml -b ${TARGETS[0]},${TARGETS[1]} -f ${TARGETS[2]},${TARGETS[3]} -t ${TARGETS[4]},${TARGETS[5]} -v ${TARGETS[6]},${TARGETS[7]} $( $SOURCES $)")
-    env.Depends(b, "$SCONS_PROC_PY")
-
-    env.Local(b)
+        #
+        # Copy Docbook stylesheets and Tool to the build folder
+        #
+        dbtoolpath = ['src', 'engine', 'SCons', 'Tool', 'docbook']
+        env.Execute(Mkdir(os.path.join(build_dir, *dbtoolpath)))
+        env.Execute(Mkdir(os.path.join(build_dir, *(dbtoolpath + ['utils']))))
+        env.Execute(Copy(os.path.join(build_dir, *dbtoolpath),
+                         os.path.join('..', *(dbtoolpath + ['__init__.py']))))
+        env.Execute(Copy(os.path.join(build_dir, *(dbtoolpath + ['utils'])),
+                         os.path.join('..', *(dbtoolpath + ['utils', 'xmldepend.xsl']))))
+        dbpath = dbtoolpath + ['docbook-xsl-1.76.1']
+        env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['common']))))
+        env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['lib']))))
+        env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['html']))))
+        env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['fo']))))
+        env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['manpages']))))
+        env.Execute(Copy(os.path.join(build_dir, *dbpath),
+                         os.path.join('..', *(dbpath + ['VERSION']))))
+        for g in glob.glob(os.path.join('..', *(dbpath + ['common', '*.*']))):
+            env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['common'])), g))
+        for g in glob.glob(os.path.join('..', *(dbpath + ['lib', '*.*']))):
+            env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['lib'])), g))
+        for g in glob.glob(os.path.join('..', *(dbpath + ['html', '*.*']))):
+            env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['html'])), g))
+        for g in glob.glob(os.path.join('..', *(dbpath + ['fo', '*.*']))):
+            env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['fo'])), g))
+        for g in glob.glob(os.path.join('..', *(dbpath + ['manpages', '*.*']))):
+            env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['manpages'])), g))
 
     #
     # Each document will live in its own subdirectory.  List them here
-    # as hash keys, with a hash of the info to control its build.
+    # by their subfolder names. Note, how the specifiers for each subdir
+    # have nothing to do with which formats get created...but which 
+    # of the outputs get installed to the build folder and added to
+    # the different source and binary packages in the end.
     #
-    docs = {
-        'design' : {
-                'htmlindex' : 'book1.html',
-                'ps'        : 1,
-                'pdf'       : 1,
-                'text'      : 0,
-        },
-        # This doesn't build on all systems, and the document is old
-        # enough that there's reallyno need to build it every time any
-        # more, so just comment it out for now.
-        #'python10' : {
-        #        'htmlindex' : 't1.html',
-        #        'html'      : 1,
-        #        'ps'        : 1,
-        #        'pdf'       : 0,
-        #        'text'      : 0,
-        #        'graphics'  : [
-        #                        'arch.fig',
-        #                        'builder.fig',
-        #                        'job-task.fig',
-        #                        'node.fig',
-        #                        'scanner.fig',
-        #                        'sig.fig'
-        #                      ],
-        #},
-        'reference' : {
-                'htmlindex' : 'book1.html',
-                'html'      : 1,
-                'ps'        : 1,
-                'pdf'       : 1,
-                'text'      : 0,
-        },
-        # For whenever (if ever?) we start putting developer guide
-        # information in a printable document instead of the wiki.
-        #'developer' : {
-        #        'htmlindex' : 'book1.html',
-        #        'html'      : 1,
-        #        'ps'        : 1,
-        #        'pdf'       : 1,
-        #        'text'      : 0,
-        #},
-        'user' : {
-                'htmlindex' : 'book1.html',
-                'html'      : 1,
-                'ps'        : 1,
-                'pdf'       : 1,
-                'text'      : 1,
-                'graphics'  : [
-                                'SCons-win32-install-1.jpg',
-                                'SCons-win32-install-2.jpg',
-                                'SCons-win32-install-3.jpg',
-                                'SCons-win32-install-4.jpg',
-                              ],
-                'scons-doc' : 1,
-        },
-    }
-
+    docs = {'design' : ['chtml','pdf'],
+            #'python10' : ['chtml','html','pdf'],
+            'reference' : ['chtml','html','pdf'],
+            #'developer' : ['chtml','html','pdf'],
+            'user' : ['chtml','html','pdf'],
+            'man' : ['man']
+           }
+    # The names of the target files for the MAN pages
+    man_page_list = ['scons.1','scons-time.1','sconsign.1']
+    
     #
     # We have to tell SCons to scan the top-level XML files which
     # get included by the document XML files in the subdirectories.
     manifest = File('MANIFEST').rstr()
     src_files = [x[:-1] for x in open(manifest).readlines()]
     for s in src_files:
+        if not s:
+            continue
         base, ext = os.path.splitext(s)
         if ext in ['.fig', '.jpg']:
-            orig_env.Install(build, s)
+            env.Execute(Copy(build, s))
         else:
-            orig_env.SCons_revision(os.path.join(build, s), s)
-        Local(os.path.join(build, s))
+            revaction([env.File(os.path.join(build, s))], 
+                      [env.File(s)], env)
 
     #
-    # For each document, build the document itself in HTML, Postscript,
+    # For each document, build the document itself in HTML,
     # and PDF formats.
     #
-    for doc in docs.keys():
+    for doc in docs:
+        
+        #
+        # Read MANIFEST file and copy the listed files to the
+        # build directory, while branding them with the
+        # SCons copyright and the current revision number...
+        #
+        env.Execute(Mkdir(os.path.join(build, doc)))
+        env.Execute(Mkdir(os.path.join(build, doc, 'titlepage')))
         manifest = File(os.path.join(doc, 'MANIFEST')).rstr()
         src_files = [x[:-1] for x in open(manifest).readlines()]
-        build_doc = docs[doc].get('scons-doc') and int(ARGUMENTS.get('BUILDDOC', 0))
         for s in src_files:
+            if not s:
+                continue
             doc_s = os.path.join(doc, s)
             build_s = os.path.join(build, doc, s)
             base, ext = os.path.splitext(doc_s)
-            if ext in ['.fig', '.jpg']:
-                orig_env.InstallAs(build_s, doc_s)
+            if ext in ['.fig', '.jpg', '.svg']:
+                env.Execute(Copy(build_s, doc_s))
             else:
-                if build_doc and ext == '.xml':
-                    env.Command(doc_s,
-                                base + '.in',
-                                "$PYTHON $SCONS_DOC_PY $SOURCE > $TARGET")
-                orig_env.SCons_revision(build_s, doc_s)
-            Local(build_s)
+                revaction([env.File(build_s)], 
+                          [env.File(doc_s)], env)
 
-        main = os.path.join(build, doc, 'main.xml')
-        out = 'main.out'
+        #
+        # Call SCons in each local doc folder directly, such that
+        # we can Glob for the created *.html files afterwards to
+        # get the dependencies for the install targets right.
+        #
+        cleanopt = ''
+        if env.GetOption('clean'):
+            cleanopt = ' -c'
+        cmd = env.subst("cd %s && $PYTHON ${SCONS_PY.abspath}" % os.path.join(build, doc))+cleanopt
+        os.system(cmd)
 
-        # Hard-coding the scons-src path is a bit of a hack.  This can
-        # be reworked when a better solution presents itself.
-        scons_src_main = os.path.join(build_dir, 'scons-src', 'doc', main)
-        env.Ignore(scons_src_main, version_xml)
+        # Collect the output files for this subfolder
+        htmldir = os.path.join(build, 'HTML', 'scons-%s' % doc)
+        htmlindex = os.path.join(htmldir, 'index.html')
+        html = os.path.join(build, 'HTML', 'scons-%s.html' % doc)
+        pdf = os.path.join(build, 'PDF', 'scons-%s.pdf' % doc)
+        if 'chtml' in docs[doc]:
+            env.Install(htmldir, Glob(os.path.join(build, doc,'scons-%s' % doc, '*.html')))
+            tar_deps.extend([htmlindex])
+            tar_list.extend([htmldir])
+            Local(htmlindex)
+            env.Ignore(htmlindex, version_xml)
 
-        htmldir = os.path.join(build, 'HTML', 'scons-%s' % doc)
-        htmlindex = os.path.join(htmldir, docs[doc]['htmlindex'])
-        html = os.path.join(build, 'HTML', 'scons-%s.html' % doc)
-        ps = os.path.join(build, 'PS', 'scons-%s.ps' % doc)
-        pdf = os.path.join(build, 'PDF', 'scons-%s.pdf' % doc)
-        text = os.path.join(build, 'TEXT', 'scons-%s.txt' % doc)
-
-        if docs[doc].get('html') and jade:
-            def copy_index_html(target, source, env):
-                # Older versions of DocBook|jw|jade|whatever would
-                # create a book1.html file, while newer versions create
-                # an index.html file (logically enough).  The scons.org
-                # web site links expect book1.html, so we're going to
-                # leave the target as is, and run this post-processing
-                # action function to check that the target really did
-                # get created, and if it didn't, copy it from index.html.
-                t = str(target[0])
-                if not os.path.exists(t):
-                    i = os.path.join(os.path.split(t)[0], 'index.html')
-                    open(t, 'w').write(open(i, 'r').read())
-                return None
-
-            cmds = [
-                Delete("${TARGET.dir}/*.html"),
-                "jw -b html -o ${TARGET.dir} $SOURCES",
-            ]
-            if tidy:
-                cmds.append("tidy -m -q $TARGET || true")
-            cmds.append(Action(copy_index_html))
-            env.Command(htmlindex, File(main), cmds)
-            Local(htmlindex)
-
-            cmds = [
-                Delete("${TARGET.dir}/main.html"),
-                "jw -u -b html -o ${TARGET.dir} $SOURCES",
-                Move("$TARGET", "${TARGET.dir}/main.html"),
-            ]
-            if tidy:
-                cmds.append("tidy -m -q $TARGET || true")
-            env.Command(html, File(main), cmds)
+        if 'html' in docs[doc]:
+            env.InstallAs(html, os.path.join(build, doc,'index.html'))
+            tar_deps.extend([html])
+            tar_list.extend([html])
             Local(html)
-
-            env.Ignore([html, htmlindex], version_xml)
-
-            tar_deps.extend([html, htmlindex])
-            tar_list.extend([html, htmldir])
-
-            for g in docs[doc].get('graphics', []):
-                base, ext = os.path.splitext(g)
-                if ext == '.fig':
-                    jpg = base + '.jpg'
-                    htmldir_jpg = os.path.join(htmldir, jpg)
-                    if fig2dev:
-                        fig = os.path.join(build, doc, g)
-                        env.Command(htmldir_jpg, fig,
-                                    "%s -L jpeg -q 100 $SOURCES $TARGET" % fig2dev)
-                    else:
-                        env.InstallAs(htmldir_jpg, jpg)
-                    env.Depends(html, htmldir_jpg)
-                    Local(htmldir_jpg)
-                else:
-                    src = os.path.join(build, doc, g)
-                    Local(env.Install(htmldir, src))
-
-        if docs[doc].get('ps') and jadetex and jade_original:
-            env.Command(ps, main, [
-                Delete("${TARGET.dir}/%s" % out),
-                "jw -b ps -o ${TARGET.dir} -p %s $SOURCES" % jade_original,
-                "mv ${TARGET.dir}/main.ps $TARGET",
-                Delete("${TARGET.dir}/%s" % out),
-            ])
-            Local(ps)
-
-            env.Ignore(ps, version_xml)
-
-            tar_deps.append(ps)
-            tar_list.append(ps)
-
-            for g in docs[doc].get('graphics', []):
-                base, ext = os.path.splitext(g)
-                if ext == '.fig':
-                    eps = base + '.eps'
-                    build_eps = os.path.join(build, 'PS', eps)
-                    if fig2dev:
-                        fig = os.path.join(build, doc, g)
-                        env.Command(build_eps, fig, "%s -L eps $SOURCES $TARGET" % fig2dev)
-                    else:
-                        env.InstallAs(build_eps, eps)
-                    env.Depends(ps, build_eps)
-                    Local(build_eps)
-                else:
-                    src = os.path.join(build, doc, g)
-                    Local(env.Install(htmldir, src))
-
-        if docs[doc].get('pdf') and pdfjadetex and jade_original:
-            env.Command(pdf, main, [
-                Delete("${TARGET.dir}/%s" % out),
-                "jw -b pdf -o ${TARGET.dir} -p %s $SOURCES" % jade_original,
-                "mv ${TARGET.dir}/main.pdf $TARGET",
-                Delete("${TARGET.dir}/out"),
-            ])
+            env.Ignore(html, version_xml)
+            
+        if 'pdf' in docs[doc]:
+            env.InstallAs(pdf, os.path.join(build, doc,'scons-%s.pdf' % doc))
             Local(pdf)
-
             env.Ignore(pdf, version_xml)
 
             tar_deps.append(pdf)
             tar_list.append(pdf)
+            
+        if 'man' in docs[doc]:
+            #
+            # Man page(s)
+            #
+            for m in man_page_list:
+                man, _1 = os.path.splitext(m)
+            
+                pdf = os.path.join(build, 'PDF', '%s-man.pdf' % man)
+                html = os.path.join(build, 'HTML' , '%s-man.html' % man)
+            
+                env.InstallAs(pdf, os.path.join(build, 'man','scons-%s.pdf' % man))
+                env.InstallAs(html, os.path.join(build, 'man','scons-%s.html' % man))
+            
+                tar_deps.extend([pdf, html])
+                tar_list.extend([pdf, html])
 
-        if docs[doc].get('text') and jade and lynx:
-            env.Command(text, html, "lynx -dump ${SOURCE.abspath} > $TARGET")
-            Local(text)
-
-            env.Ignore(text, version_xml)
-
-            tar_deps.append(text)
-            tar_list.append(text)
-
-#
-# Man page(s), in good ol' troff format.
-#
-man_page_list = ['scons.1', 'sconsign.1', 'scons-time.1']
-
-for m in man_page_list:
-    x = orig_env.SCons_revision(os.path.join(build, 'man', m),
-                            os.path.join('man', m))
-
-man_i_files = ['builders.man', 'functions.man', 'tools.man', 'variables.man']
-
-man_intermediate_files = [os.path.join(build, 'man', x) for x in man_i_files]
-
-cmd = "$PYTHON $SCONS_PROC_PY --man -b ${TARGETS[0]} -f ${TARGETS[1]} -t ${TARGETS[2]} -v ${TARGETS[3]} $( $SOURCES $)"
-man_intermediate_files = env.Command(man_intermediate_files,
-                                     scons_doc_files,
-                                     cmd)
-env.Depends(man_intermediate_files, "$SCONS_PROC_PY")
-Local(man_intermediate_files)
-
-for man_1 in man_page_list:
-    man, _1 = os.path.splitext(man_1)
-
-    man_1 = os.path.join(build, 'man', man_1)
-
-    if groff:
-        ps = os.path.join(build, 'PS', '%s-man.ps' % man)
-        text = os.path.join(build, 'TEXT', '%s-man.txt' % man)
-
-        b = env.Command(ps, man_1, "( cd ${SOURCES.dir} && groff -man -Tps ${SOURCES.file} ) > $TARGET")
-        Local(ps)
-        env.Depends(b, man_intermediate_files)
-
-        b = env.Command(text, man_1, "( cd ${SOURCES.dir} && groff -man -Tascii ${SOURCES.file} ) > $TARGET")
-        Local(text)
-        env.Depends(b, man_intermediate_files)
-
-        tar_deps.extend([ps, text])
-        tar_list.extend([ps, text])
-    else:
-        print "doc: WARNING: no groff, skipping text and PostScript versions of man pages"
-
-    if man2html:
-        html = os.path.join(build, 'HTML' , '%s-man.html' % man)
-
-        def strip_to_first_html_tag(target, source, env):
-            t = str(target[0])
-            contents = open(t).read()
-            contents = contents[contents.find('<HTML>'):]
-            open(t, 'w').write(contents)
-            return 0
-
-        cmds = [
-            "( cd %s/man && cp %s .. )" % (build, ' '.join(man_i_files)),
-            "( cd ${SOURCE.dir} && man2html ${SOURCE.file} ) > $TARGET",
-            Action(strip_to_first_html_tag),
-        ]
-        if tidy:
-            cmds.append("tidy -m -q $TARGET || true")
-        b = env.Command(html, man_1, cmds)
-        Local(html)
-        env.Depends(b, man_intermediate_files)
-
-        tar_deps.append(html)
-        tar_list.append(html)
-    else:
-        print "doc: WARNING: no man2html, skipping HTML versions of man pages"
 
 if not epydoc_cli:
     try:

File doc/design/MANIFEST

 copyright.xml
 engine.fig
 engine.jpg
+engine.svg
 engine.xml
 goals.xml
 install.xml
 native.xml
 overview.xml
 summary.xml
+chtml.xsl
+html.xsl
+pdf.xsl
+scons_title.xsl
+scons.css
+SConstruct
+titlepage/bricks.jpg
+titlepage/mapnik_final_colors.svg
+titlepage/SCons_path.svg
+titlepage/SConsBuildBricks_path.svg

File doc/design/SConstruct

 
 env = Environment(ENV={'PATH' : os.environ['PATH']},
                   tools=['docbook'], 
-                  toolpath=['../../src/engine/SCons/Tool'])
+                  toolpath=['../../src/engine/SCons/Tool'],
+                  DOCBOOK_DEFAULT_XSL_HTML='html.xsl',
+                  DOCBOOK_DEFAULT_XSL_HTMLCHUNKED='chtml.xsl',
+                  DOCBOOK_DEFAULT_XSL_PDF='pdf.xsl')
 
 has_pdf = False
 if (env.WhereIs('fop') or 
-    env.WhereIs('xep') or
-    env.WhereIs('jw')):
+    env.WhereIs('xep')):
     has_pdf = True
 
 #
 env.DocbookXInclude('design_xi.xml', 'main.xml')
 env.DocbookXslt('design.xml', 'design_xi.xml', 
                 xsl='../xslt/to_docbook.xslt')
-env.DocbookHtml('design.html','design.xml')
+env.DocbookHtmlChunked('index.html','design.xml', base_dir='scons-design/')
 if has_pdf:
-    env.DocbookPdf('design.pdf','design.xml')
+    env.DocbookPdf('scons-design.pdf','design.xml')

File doc/design/chtml.xsl

+<?xml version='1.0'?>
+<!--
+
+  __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.
+
+-->
+<xsl:stylesheet
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+	xmlns:fo="http://www.w3.org/1999/XSL/Format" 
+	version="1.0"> 
+
+	<xsl:import href="../../src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/html/chunk.xsl"/> 
+
+<xsl:param name="base.dir" select="'scons-design/'"/>
+<xsl:param name="l10n.gentext.default.language" select="'en'"/>
+<xsl:param name="section.autolabel" select="1"/>
+<xsl:param name="html.stylesheet" select="'scons.css'"/>
+<xsl:param name="generate.toc">
+/appendix toc,title
+article/appendix  nop
+/article  toc,title
+book      toc,title,figure,table,example,equation
+/chapter  toc,title
+part      toc,title
+/preface  toc,title
+reference toc,title
+/sect1    toc
+/sect2    toc
+/sect3    toc
+/sect4    toc
+/sect5    toc
+/section  toc
+set       toc,title
+</xsl:param>
+
+</xsl:stylesheet> 
+

File doc/design/engine.svg

+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.1"
+   width="8.5in"
+   height="7.5999999in"
+   viewBox="1188 1638 10224 9174"
+   id="svg3034">
+  <metadata
+     id="metadata3230">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3228" />
+  <g
+     id="g3036"
+     style="fill:none;stroke-width:0.025in">
+    <rect
+       width="1500"
+       height="600"
+       rx="0"
+       x="2100"
+       y="8700"
+       id="rect3038"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1950"
+       height="600"
+       rx="0"
+       x="7050"
+       y="6900"
+       id="rect3040"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1950"
+       height="600"
+       rx="0"
+       x="9450"
+       y="6900"
+       id="rect3042"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1200"
+       height="600"
+       rx="0"
+       x="1200"
+       y="4200"
+       id="rect3044"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1200"
+       height="600"
+       rx="0"
+       x="2400"
+       y="3300"
+       id="rect3046"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1800"
+       height="600"
+       rx="0"
+       x="8700"
+       y="1650"
+       id="rect3048"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1800"
+       height="600"
+       rx="0"
+       x="1500"
+       y="1650"
+       id="rect3050"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1500"
+       height="600"
+       rx="0"
+       x="7800"
+       y="8700"
+       id="rect3052"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="900"
+       height="600"
+       rx="0"
+       x="1500"
+       y="10200"
+       id="rect3054"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="900"
+       height="600"
+       rx="0"
+       x="3300"
+       y="10200"
+       id="rect3056"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1200"
+       height="600"
+       rx="0"
+       x="6000"
+       y="10200"
+       id="rect3058"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1500"
+       height="600"
+       rx="0"
+       x="7800"
+       y="10200"
+       id="rect3060"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="1200"
+       height="600"
+       rx="0"
+       x="9900"
+       y="10200"
+       id="rect3062"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polygon
+       points="6825,5175 6900,5100 6975,5175 6900,5250 6900,5250 "
+       id="polygon3064"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polygon
+       points="6225,5175 6300,5100 6375,5175 6300,5250 6300,5250 "
+       id="polygon3066"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polygon
+       points="5625,5175 5700,5100 5775,5175 5700,5250 5700,5250 "
+       id="polygon3068"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <rect
+       width="2400"
+       height="2400"
+       rx="0"
+       x="4800"
+       y="2700"
+       id="rect3070"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polygon
+       points="5025,5250 5175,5250 5100,5100 5100,5100 "
+       id="polygon3072"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polyline
+       points="6300,5250 6300,5700 8400,5700 8400,4200 7216,4200 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3074" />
+    <polyline
+       points="7322 4170 7202 4200 7322 4230 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3076" />
+    <polyline
+       points="5700,5250 5700,6000 9000,6000 9000,3600 7216,3600 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3078" />
+    <polyline
+       points="7322 3570 7202 3600 7322 3630 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3080" />
+    <polyline
+       points="5100,5250 5100,8100 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3082" />
+    <polygon
+       points="4650,3600 4725,3525 4800,3600 4725,3675 4725,3675 "
+       id="polygon3084"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polygon
+       points="4650,4500 4725,4425 4800,4500 4725,4575 4725,4575 "
+       id="polygon3086"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polyline
+       points="4650,3600 3616,3600 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3088" />
+    <polyline
+       points="3722 3570 3602 3600 3722 3630 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3090" />
+    <polyline
+       points="4650,4500 2416,4500 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3092" />
+    <polyline
+       points="2522 4470 2402 4500 2522 4530 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3094" />
+    <polyline
+       points="1800,2400 1800,4183 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3096" />
+    <polyline
+       points="1770 4078 1800 4198 1830 4078 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3098" />
+    <polyline
+       points="3000,2400 3000,3283 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3100" />
+    <polyline
+       points="2970 3178 3000 3298 3030 3178 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3102" />
+    <polyline
+       points="5850,1950 5850,2700 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:40, 40"
+       id="polyline3104" />
+    <polygon
+       points="2925,2325 3000,2250 3075,2325 3000,2400 3000,2400 "
+       id="polygon3106"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polygon
+       points="1725,2325 1800,2250 1875,2325 1800,2400 1800,2400 "
+       id="polygon3108"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polyline
+       points="3300,1950 8700,1950 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3110" />
+    <polyline
+       points="9600,2400 9600,6600 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3112" />
+    <polyline
+       points="7950,6900 7950,6600 10350,6600 10350,6900 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3114" />
+    <polygon
+       points="9525,2400 9675,2400 9600,2250 9600,2250 "
+       id="polygon3116"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polyline
+       points="4800,3000 7200,3000 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3118" />
+    <polyline
+       points="4800,3300 7200,3300 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3120" />
+    <polygon
+       points="2775,9450 2925,9450 2850,9300 2850,9300 "
+       id="polygon3122"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polyline
+       points="2100,10200 2100,9900 3750,9900 3750,10200 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3124" />
+    <polyline
+       points="6600,10200 6600,9900 10500,9900 10500,10200 10500,10125 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3126" />
+    <polyline
+       points="2850,9450 2850,9900 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3128" />
+    <polyline
+       points="8475,9450 8475,10200 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3130" />
+    <polygon
+       points="8400,9450 8550,9450 8475,9300 8475,9300 "
+       id="polygon3132"
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter" />
+    <polyline
+       points="2775,6825 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3134" />
+    <polyline
+       points="1800,10200 1800,9000 2083,9000 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3136" />
+    <polyline
+       points="1978 9030 2098 9000 1978 8970 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3138" />
+    <polyline
+       points="9900,10500 9316,10500 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3140" />
+    <polyline
+       points="9422 10470 9302 10500 9422 10530 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3142" />
+    <polyline
+       points="7800,10500 7216,10500 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3144" />
+    <polyline
+       points="7322 10470 7202 10500 7322 10530 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3146" />
+    <polyline
+       points="2850,8700 2850,8100 8550,8100 8550,8700 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3148" />
+    <polyline
+       points="10350,7500 10350,9000 9316,9000 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:40, 40"
+       id="polyline3150" />
+    <polyline
+       points="9422 8970 9302 9000 9422 9030 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3152" />
+    <polyline
+       points="7050,7200 2400,7200 2400,8683 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:40, 40"
+       id="polyline3154" />
+    <polyline
+       points="2370 8578 2400 8698 2430 8578 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3156" />
+    <polyline
+       points="6900,5250 6900,5400 7800,5400 7800,4800 7216,4800 "
+       style="stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter"
+       id="polyline3158" />
+    <polyline
+       points="7322 4770 7202 4800 7322 4830 "
+       style="stroke:#000000;stroke-width:7;stroke-miterlimit:8"
+       id="polyline3160" />
+    <text
+       x="2400"
+       y="9075"
+       id="text3162"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Node.FS</text>
+    <text
+       x="7200"
+       y="7275"
+       id="text3164"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Intercessor.FS</text>
+    <text
+       x="9600"
+       y="7275"
+       id="text3166"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Intercessor.DB</text>
+    <text
+       x="1350"
+       y="4575"
+       id="text3168"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Scanner</text>
+    <text
+       x="2625"
+       y="3675"
+       id="text3170"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Builder</text>
+    <text
+       x="9000"
+       y="2025"
+       id="text3172"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Intercessor</text>
+    <text
+       x="1725"
+       y="2025"
+       id="text3174"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Environment</text>
+    <text
+       x="8100"
+       y="9075"
+       id="text3176"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Node.DB</text>
+    <text
+       x="1800"
+       y="10575"
+       id="text3178"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Dir</text>
+    <text
+       x="3600"
+       y="10575"
+       id="text3180"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">File</text>
+    <text
+       x="6300"
+       y="10575"
+       id="text3182"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Table</text>
+    <text
+       x="8100"
+       y="10575"
+       id="text3184"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Record</text>
+    <text
+       x="10200"
+       y="10575"
+       id="text3186"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Field</text>
+    <text
+       x="4950"
+       y="2925"
+       id="text3188"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Helvetica">Node</text>
+    <text
+       x="7350"
+       y="3525"
+       id="text3190"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">dependency</text>
+    <text
+       x="7425"
+       y="3825"
+       id="text3192"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">*</text>
+    <text
+       x="7350"
+       y="4125"
+       id="text3194"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">srcnode</text>
+    <text
+       x="7425"
+       y="4425"
+       id="text3196"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">1</text>
+    <text
+       x="7350"
+       y="4725"
+       id="text3198"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">repnode</text>
+    <text
+       x="7425"
+       y="5025"
+       id="text3200"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">1</text>
+    <text
+       x="2550"
+       y="4725"
+       id="text3202"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">0..1</text>
+    <text
+       x="3750"
+       y="3825"
+       id="text3204"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">0..1</text>
+    <text
+       x="1875"
+       y="4050"
+       id="text3206"
+       xml:space="preserve"
+       style="font-size:144px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Times">*</text>
+    <text
+       x="3075"
+       y="3150"
+       id="text3208"
+       xml:space="preserve"
+       style="font-size:144px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Times">*</text>
+    <text
+       x="5100"
+       y="3750"
+       id="text3210"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">build()</text>
+    <text
+       x="5100"
+       y="4260"
+       id="text3212"
+       xml:space="preserve"
+       style="font-size:168px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">scan()</text>
+    <text
+       x="9750"
+       y="10725"
+       id="text3214"
+       xml:space="preserve"
+       style="font-size:144px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Times">1</text>
+    <text
+       x="1650"
+       y="10125"
+       id="text3216"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">1</text>
+    <text
+       x="1875"
+       y="9225"
+       id="text3218"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">*</text>
+    <text
+       x="7650"
+       y="10725"
+       id="text3220"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">1</text>
+    <text
+       x="7275"
+       y="10725"
+       id="text3222"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">*</text>
+    <text
+       x="9375"
+       y="10725"
+       id="text3224"
+       xml:space="preserve"
+       style="font-size:120px;font-style:normal;font-weight:normal;text-anchor:start;fill:#000000;font-family:Helvetica">*</text>
+  </g>
+</svg>

File doc/design/html.xsl

+<?xml version='1.0'?>
+<!--
+
+  __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.
+
+-->
+<xsl:stylesheet
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+	xmlns:fo="http://www.w3.org/1999/XSL/Format" 
+	version="1.0"> 
+
+	<xsl:import href="../../src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/html/docbook.xsl"/> 
+
+<xsl:param name="l10n.gentext.default.language" select="'en'"/>
+<xsl:param name="section.autolabel" select="1"/>
+<xsl:param name="html.stylesheet" select="'scons.css'"/>
+<xsl:param name="generate.toc">
+/appendix toc,title
+article/appendix  nop
+/article  toc,title
+book      toc,title,figure,table,example,equation
+/chapter  toc,title
+part      toc,title
+/preface  toc,title
+reference toc,title
+/sect1    toc
+/sect2    toc
+/sect3    toc
+/sect4    toc
+/sect5    toc
+/section  toc
+set       toc,title
+</xsl:param>
+
+</xsl:stylesheet> 
+

File doc/design/main.xml

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0/scons.xsd scons.xsd">
   <bookinfo>
-    <title>SCons Design version &buildversion;</title>
-
+    <title>SCons &buildversion;</title>
+    <subtitle>Design</subtitle>
     <author>
       <firstname>Steven</firstname>
       <surname>Knight</surname>
     </author>
 
-    <edition>Revision &buildrevision; (&builddate;)</edition>
+    <corpauthor>Steven Knight</corpauthor>
 
     <pubdate>2001</pubdate>
 

File doc/design/overview.xml

 
  </para>
 
-<!--
-Including this figure makes our PDF build blow up.
-The figure, however,
-is left over from the Software Carpentry contest
-and is therefore old, out-of-date, and needs to be redone anyway.
-This is where it will go, anyway...
--->
-
-   <!--
-   YARG!  THIS MAKES THE PDF BUILD BLOW UP.  HELP!
    <figure>
     <title>&SCons; Architecture</title>
-    <graphic fileref="engine.jpg">
+    <mediaobject>
+     <imageobject>
+      <imagedata fileref="engine.svg" align="center" scale="50"/>
+     </imageobject>
+     <imageobject>
+      <imagedata fileref="engine.jpg" align="center"/>
+     </imageobject>
+    </mediaobject>
    </figure>
-   -->
 
  <para>
 

File doc/design/pdf.xsl

+<?xml version='1.0'?>
+<!--
+
+  __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.
+
+-->
+
+<xsl:stylesheet
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+	xmlns:fo="http://www.w3.org/1999/XSL/Format" 
+	version="1.0"> 
+
+	<xsl:import href="../../src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/fo/docbook.xsl"/> 
+	<xsl:include href="scons_title.xsl"/> 
+<xsl:param name="l10n.gentext.default.language" select="'en'"/>
+<xsl:param name="section.autolabel" select="1"></xsl:param>
+<xsl:param name="paper.type" select="'letter'"></xsl:param>
+<xsl:param name="body.start.indent">0pt</xsl:param>
+<xsl:param name="shade.verbatim" select="1"></xsl:param>
+<xsl:param name="variablelist.term.break.after" select="1"></xsl:param>
+
+<xsl:param name="generate.toc">
+/appendix toc,title
+article/appendix  nop
+/article  toc,title
+book      toc,title,figure,table,example,equation
+/chapter  toc,title
+part      toc,title
+/preface  toc,title
+reference toc,title
+/sect1    toc
+/sect2    toc
+/sect3    toc
+/sect4    toc
+/sect5    toc
+/section  toc
+set       toc,title
+</xsl:param>
+
+<xsl:attribute-set name="variablelist.term.properties">
+  <xsl:attribute name="font-weight">bold</xsl:attribute>
+</xsl:attribute-set>
+
+<xsl:template match="variablelist">
+  <xsl:variable name="presentation">
+    <xsl:call-template name="pi.dbfo_list-presentation"/>
+  </xsl:variable>
+  <xsl:apply-templates select="." mode="vl.as.blocks"/>
+</xsl:template>
+
+</xsl:stylesheet> 
+

File doc/design/scons.css

+body {	
+	background: #ffffff;
+	margin: 10px; 
+	padding: 0;
+	font-family:palatino, georgia, verdana, arial, sans-serif;
+	}
+
+
+a {
+	color: #80572a;
+	}
+
+a:hover {
+	color: #d72816;
+	text-decoration: none;
+	}
+
+tt {
+	color: #a14447;
+	}
+
+pre {
+     background: #e0e0e0;
+    }
+
+#main {
+	border: 1px solid;
+	border-color: black;
+	background-color: white;
+	background-image: url(../images/sconsback.png);
+	background-repeat: repeat-y 50% 0;
+	background-position: right top;
+	margin: 30px auto;
+	width: 750px;
+	}
+	
+#banner {
+	background-image: url(../images/scons-banner.jpg);
+	border-bottom: 1px solid;
+	height: 95px;
+	}
+
+#menu {
+	font-family: sans-serif;
+	font-size: small;
+	line-height: 0.9em;
+	float: right;
+	width: 220px;
+	clear: both;
+	margin-top: 10px;
+	}
+
+#menu li {
+	margin-bottom: 7px;
+	}
+
+#menu li li {
+	margin-bottom: 2px;
+	}
+
+#menu li.submenuitems {
+	margin-bottom: 2px;
+	}
+
+#menu a {
+	text-decoration: none;
+	}
+
+#footer {
+	border-top: 1px solid black;
+	text-align: center;
+	font-size: small;
+	color: #822;
+	margin-top: 4px;
+	background: #eee;
+	}
+
+ul.hack {
+	list-style-position:inside;
+	}
+
+ul.menuitems {
+	list-style-type: none;
+	}
+
+ul.submenuitems {
+	list-style-type: none;
+	font-size: smaller;
+	margin-left: 0;
+	padding-left: 16px;
+	}
+
+ul.subsubmenuitems {
+	list-style-type: none;
+	font-size: smaller;
+	margin-left: 0;
+	padding-left: 16px;
+	}
+
+ol.upper-roman {
+	list-style-type: upper-roman;
+	}
+
+ol.decimal {
+	list-style-type: decimal;
+	}
+
+#currentpage {
+	font-weight: bold;
+	}
+
+#bodycontent {
+	margin: 15px;
+	width: 520px;
+	font-size: small;
+	line-height: 1.5em;
+	}
+
+#bodycontent li {
+	margin-bottom: 6px;
+	list-style-type: square;
+	}
+
+#sconsdownloadtable downloadtable {
+        display: table;
+        margin-left: 5%;
+        border-spacing: 12px 3px;
+        }
+
+#sconsdownloadtable downloadrow {
+        display: table-row;
+        }
+
+#sconsdownloadtable downloadentry {
+        display: table-cell;
+	text-align: center;
+        vertical-align: bottom;
+        }
+
+#sconsdownloadtable downloaddescription {
+        display: table-cell;
+        font-weight: bold;
+	text-align: left;
+        }
+
+#sconsdownloadtable downloadversion {
+        display: table-cell;
+        font-weight: bold;
+	text-align: center;
+        }
+
+#sconsdocversiontable sconsversiontable {
+        display: table;
+        margin-left: 10%;
+        border-spacing: 12px 3px;
+        }
+
+#sconsdocversiontable sconsversionrow {
+        display: table-row;
+        }
+
+#sconsdocversiontable docformat {
+        display: table-cell;
+        font-weight: bold;
+	text-align: center;
+        vertical-align: bottom;
+        }
+
+#sconsdocversiontable sconsversion {
+        display: table-cell;
+        font-weight: bold;
+	text-align: left;
+        }
+
+#sconsdocversiontable docversion {
+        display: table-cell;
+        font-weight: bold;
+	text-align: center;
+        }
+
+#osrating {
+	margin-left: 35px;
+	}
+	
+
+h2 {
+	color: #272;
+	color: #c01714;
+	font-family: sans-serif;
+	font-weight: normal;
+	}
+
+h2.pagetitle {
+	font-size: xx-large;
+	}
+h3 {
+	margin-bottom: 10px;
+	}
+
+.date {
+	font-size: small;
+	color: gray;
+	}
+	
+.link {
+	margin-bottom: 22px;
+	}
+
+.linkname {
+	}
+
+.linkdesc {
+	margin: 10px;
+	margin-top: 0;
+	}
+
+.quote {
+	margin-top: 20px;
+	margin-bottom: 10px;
+	background: #f8f8f8;
+	border: 1px solid;
+	border-color: #ddd;
+	}
+
+.quotetitle {
+	font-weight: bold;
+	font-size: large;
+	margin: 10px;
+	}
+
+.quotedesc {
+	margin-left: 20px;
+	margin-right: 10px;
+	margin-bottom: 15px;
+	}
+
+.quotetext {
+	margin-top: 20px;
+	margin-left: 20px;
+	margin-right: 10px;
+	font-style: italic;
+	}
+
+.quoteauthor {
+	font-size: small;
+	text-align: right;
+	margin-top: 10px;
+	margin-right: 7px;
+	}
+
+.sconslogo {
+	font-style: normal;
+	font-weight: bold;
+	color: #822;
+	}
+	
+.downloadlink {
+	}
+
+.downloaddescription {
+	margin-left: 1em;
+	margin-bottom: 0.4em;
+	}

File doc/design/scons_title.xsl

+<?xml version="1.0"?>
+<!--
+
+  __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.
+
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+                xmlns:exsl="http://exslt.org/common"
+		xmlns:fo="http://www.w3.org/1999/XSL/Format" 
+	        version="1.0" exclude-result-prefixes="exsl">
+
+<!-- This stylesheet was created by template/titlepage.xsl; do not edit it by hand. -->
+
+<xsl:template name="article.titlepage.recto">
+  <xsl:choose>
+    <xsl:when test="articleinfo/title">
+      <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="articleinfo/title"/>
+    </xsl:when>
+    <xsl:when test="artheader/title">
+      <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="artheader/title"/>
+    </xsl:when>
+    <xsl:when test="info/title">
+      <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="info/title"/>
+    </xsl:when>
+    <xsl:when test="title">
+      <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="title"/>
+    </xsl:when>
+  </xsl:choose>
+
+  <xsl:choose>
+    <xsl:when test="articleinfo/subtitle">
+      <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="articleinfo/subtitle"/>
+    </xsl:when>
+    <xsl:when test="artheader/subtitle">
+      <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="artheader/subtitle"/>
+    </xsl:when>
+    <xsl:when test="info/subtitle">
+      <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="info/subtitle"/>
+    </xsl:when>
+    <xsl:when test="subtitle">
+      <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="subtitle"/>
+    </xsl:when>
+  </xsl:choose>
+
+  <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="articleinfo/mediaobject"/>
+  <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="artheader/mediaobject"/>
+  <xsl:apply-templates mode="article.titlepage.recto.auto.mode" select="info/mediaobject"/>
+</xsl:template>
+
+<xsl:template name="article.titlepage.verso">
+</xsl:template>
+
+<xsl:template name="article.titlepage.separator">
+</xsl:template>
+
+<xsl:template name="article.titlepage.before.recto">
+</xsl:template>
+
+<xsl:template name="article.titlepage.before.verso">
+</xsl:template>
+
+<xsl:template name="article.titlepage">
+  <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="{$title.fontset}">
+    <xsl:variable name="recto.content">
+      <xsl:call-template name="article.titlepage.before.recto"/>
+      <xsl:call-template name="article.titlepage.recto"/>
+    </xsl:variable>
+    <xsl:variable name="recto.elements.count">
+      <xsl:choose>
+        <xsl:when test="function-available('exsl:node-set')"><xsl:value-of select="count(exsl:node-set($recto.content)/*)"/></xsl:when>
+        <xsl:when test="contains(system-property('xsl:vendor'), 'Apache Software Foundation')">
+          <!--Xalan quirk--><xsl:value-of select="count(exsl:node-set($recto.content)/*)"/></xsl:when>
+        <xsl:otherwise>1</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:if test="(normalize-space($recto.content) != '') or ($recto.elements.count &gt; 0)">
+      <fo:block start-indent="0pt" text-align="center"><xsl:copy-of select="$recto.content"/></fo:block>
+    </xsl:if>
+    <xsl:variable name="verso.content">
+      <xsl:call-template name="article.titlepage.before.verso"/>
+      <xsl:call-template name="article.titlepage.verso"/>
+    </xsl:variable>
+    <xsl:variable name="verso.elements.count">
+      <xsl:choose>
+        <xsl:when test="function-available('exsl:node-set')"><xsl:value-of select="count(exsl:node-set($verso.content)/*)"/></xsl:when>
+        <xsl:when test="contains(system-property('xsl:vendor'), 'Apache Software Foundation')">
+          <!--Xalan quirk--><xsl:value-of select="count(exsl:node-set($verso.content)/*)"/></xsl:when>
+        <xsl:otherwise>1</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:if test="(normalize-space($verso.content) != '') or ($verso.elements.count &gt; 0)">
+      <fo:block><xsl:copy-of select="$verso.content"/></fo:block>
+    </xsl:if>
+    <xsl:call-template name="article.titlepage.separator"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="*" mode="article.titlepage.recto.mode">
+  <!-- if an element isn't found in this mode, -->
+  <!-- try the generic titlepage.mode -->
+  <xsl:apply-templates select="." mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="*" mode="article.titlepage.verso.mode">
+  <!-- if an element isn't found in this mode, -->
+  <!-- try the generic titlepage.mode -->
+  <xsl:apply-templates select="." mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="title" mode="article.titlepage.recto.auto.mode">
+<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="article.titlepage.recto.style" keep-with-next.within-column="always" font-size="24.8832pt" font-weight="bold">
+<xsl:call-template name="component.title">
+<xsl:with-param name="node" select="ancestor-or-self::article[1]"/>
+</xsl:call-template>
+</fo:block>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="article.titlepage.recto.auto.mode">
+<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="article.titlepage.recto.style">
+<xsl:apply-templates select="." mode="article.titlepage.recto.mode"/>
+</fo:block>
+</xsl:template>
+
+<xsl:template match="mediaobject" mode="article.titlepage.recto.auto.mode">
+<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" xsl:use-attribute-sets="article.titlepage.recto.style">
+<xsl:apply-templates select="." mode="article.titlepage.recto.mode"/>
+</fo:block>
+</xsl:template>
+
+<xsl:template name="set.titlepage.recto">
+  <xsl:choose>
+    <xsl:when test="setinfo/title">
+      <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/title"/>
+    </xsl:when>
+    <xsl:when test="info/title">
+      <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/title"/>
+    </xsl:when>
+    <xsl:when test="title">
+      <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="title"/>
+    </xsl:when>
+  </xsl:choose>
+
+  <xsl:choose>
+    <xsl:when test="setinfo/subtitle">
+      <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/subtitle"/>
+    </xsl:when>
+    <xsl:when test="info/subtitle">
+      <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/subtitle"/>
+    </xsl:when>
+    <xsl:when test="subtitle">
+      <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="subtitle"/>
+    </xsl:when>
+  </xsl:choose>
+
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/corpauthor"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/corpauthor"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/authorgroup"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/authorgroup"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/author"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/author"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/othercredit"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/othercredit"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/releaseinfo"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/releaseinfo"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/copyright"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/copyright"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/legalnotice"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/legalnotice"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/pubdate"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/pubdate"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/revision"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/revision"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/revhistory"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/revhistory"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="setinfo/abstract"/>
+  <xsl:apply-templates mode="set.titlepage.recto.auto.mode" select="info/abstract"/>
+</xsl:template>
+
+<xsl:template name="set.titlepage.verso">
+</xsl:template>
+
+<xsl:template name="set.titlepage.separator">
+</xsl:template>
+
+<xsl:template name="set.titlepage.before.recto">
+</xsl:template>
+
+<xsl:template name="set.titlepage.before.verso">
+</xsl:template>
+
+<xsl:template name="set.titlepage">
+  <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">
+    <xsl:variable name="recto.content">
+      <xsl:call-template name="set.titlepage.before.recto"/>
+      <xsl:call-template name="set.titlepage.recto"/>
+    </xsl:variable>
+    <xsl:variable name="recto.elements.count">
+      <xsl:choose>
+        <xsl:when test="function-available('exsl:node-set')"><xsl:value-of select="count(exsl:node-set($recto.content)/*)"/></xsl:when>
+        <xsl:when test="contains(system-property('xsl:vendor'), 'Apache Software Foundation')">
+          <!--Xalan quirk--><xsl:value-of select="count(exsl:node-set($recto.content)/*)"/></xsl:when>
+        <xsl:otherwise>1</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:if test="(normalize-space($recto.content) != '') or ($recto.elements.count &gt; 0)">
+      <fo:block><xsl:copy-of select="$recto.content"/></fo:block>
+    </xsl:if>
+    <xsl:variable name="verso.content">
+      <xsl:call-template name="set.titlepage.before.verso"/>
+      <xsl:call-template name="set.titlepage.verso"/>
+    </xsl:variable>
+    <xsl:variable name="verso.elements.count">
+      <xsl:choose>