Commits

Gary Oberbrunner committed da1bb12 Merge

Merge pull request #98, DocBook improvements

Comments (0)

Files changed (31)

doc/generated/builders.gen

 </example_commands>
 </listitem>
   </varlistentry>
+  <varlistentry id="b-DocbookEpub">
+    <term>
+      <function>DocbookEpub()</function>
+    </term>
+    <term>
+      <function>env.DocbookEpub()</function>
+    </term>
+    <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+A pseudo-Builder, providing a Docbook toolchain for EPUB output.
+</para>
+
+<example_commands xmlns="http://www.scons.org/dbxsd/v1.0">env = Environment(tools=['docbook'])
+env.DocbookEpub('manual.epub', 'manual.xml')
+</example_commands>
+
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+or simply
+</para>
+
+<example_commands xmlns="http://www.scons.org/dbxsd/v1.0">env = Environment(tools=['docbook'])
+env.DocbookEpub('manual')
+</example_commands>
+
+</listitem>
+  </varlistentry>
   <varlistentry id="b-DocbookHtml">
     <term>
       <function>DocbookHtml()</function>

doc/generated/builders.mod

 <!ENTITY b-CFile "<function xmlns='http://www.scons.org/dbxsd/v1.0'>CFile</function>">
 <!ENTITY b-Command "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Command</function>">
 <!ENTITY b-CXXFile "<function xmlns='http://www.scons.org/dbxsd/v1.0'>CXXFile</function>">
+<!ENTITY b-DocbookEpub "<function xmlns='http://www.scons.org/dbxsd/v1.0'>DocbookEpub</function>">
 <!ENTITY b-DocbookHtml "<function xmlns='http://www.scons.org/dbxsd/v1.0'>DocbookHtml</function>">
 <!ENTITY b-DocbookHtmlChunked "<function xmlns='http://www.scons.org/dbxsd/v1.0'>DocbookHtmlChunked</function>">
 <!ENTITY b-DocbookHtmlhelp "<function xmlns='http://www.scons.org/dbxsd/v1.0'>DocbookHtmlhelp</function>">
 <!ENTITY b-env-CFile "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.CFile</function>">
 <!ENTITY b-env-Command "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.Command</function>">
 <!ENTITY b-env-CXXFile "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.CXXFile</function>">
+<!ENTITY b-env-DocbookEpub "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.DocbookEpub</function>">
 <!ENTITY b-env-DocbookHtml "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.DocbookHtml</function>">
 <!ENTITY b-env-DocbookHtmlChunked "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.DocbookHtmlChunked</function>">
 <!ENTITY b-env-DocbookHtmlhelp "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.DocbookHtmlhelp</function>">
 <!ENTITY b-link-CFile "<link linkend='b-CFile' xmlns='http://www.scons.org/dbxsd/v1.0'><function>CFile</function></link>">
 <!ENTITY b-link-Command "<link linkend='b-Command' xmlns='http://www.scons.org/dbxsd/v1.0'><function>Command</function></link>">
 <!ENTITY b-link-CXXFile "<link linkend='b-CXXFile' xmlns='http://www.scons.org/dbxsd/v1.0'><function>CXXFile</function></link>">
+<!ENTITY b-link-DocbookEpub "<link linkend='b-DocbookEpub' xmlns='http://www.scons.org/dbxsd/v1.0'><function>DocbookEpub</function></link>">
 <!ENTITY b-link-DocbookHtml "<link linkend='b-DocbookHtml' xmlns='http://www.scons.org/dbxsd/v1.0'><function>DocbookHtml</function></link>">
 <!ENTITY b-link-DocbookHtmlChunked "<link linkend='b-DocbookHtmlChunked' xmlns='http://www.scons.org/dbxsd/v1.0'><function>DocbookHtmlChunked</function></link>">
 <!ENTITY b-link-DocbookHtmlhelp "<link linkend='b-DocbookHtmlhelp' xmlns='http://www.scons.org/dbxsd/v1.0'><function>DocbookHtmlhelp</function></link>">
 <!ENTITY b-link-env-CFile "<link linkend='b-CFile' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.CFile</function></link>">
 <!ENTITY b-link-env-Command "<link linkend='b-Command' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.Command</function></link>">
 <!ENTITY b-link-env-CXXFile "<link linkend='b-CXXFile' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.CXXFile</function></link>">
+<!ENTITY b-link-env-DocbookEpub "<link linkend='b-DocbookEpub' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.DocbookEpub</function></link>">
 <!ENTITY b-link-env-DocbookHtml "<link linkend='b-DocbookHtml' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.DocbookHtml</function></link>">
 <!ENTITY b-link-env-DocbookHtmlChunked "<link linkend='b-DocbookHtmlChunked' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.DocbookHtmlChunked</function></link>">
 <!ENTITY b-link-env-DocbookHtmlhelp "<link linkend='b-DocbookHtmlhelp' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.DocbookHtmlhelp</function></link>">

doc/generated/functions.gen

 </example_commands>
 </listitem>
   </varlistentry>
+  <varlistentry id="f-Pseudo">
+    <term>
+      <literal>Pseudo(target, ...)</literal>
+    </term>
+    <term>
+      <literal>env.Pseudo(target, ...)</literal>
+    </term>
+    <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+This indicates that each given
+<varname>target</varname>
+should not be created by the build rule, and if the target is created,
+an error will be generated. This is similar to the gnu make .PHONY
+target. However, in the vast majority of cases, an
+<function xmlns="http://www.scons.org/dbxsd/v1.0">Alias</function>
+is more appropriate.
+
+Multiple targets can be passed in to a single call to
+<function xmlns="http://www.scons.org/dbxsd/v1.0">Pseudo</function>.
+</para>
+</listitem>
+  </varlistentry>
   <varlistentry id="f-RCS">
     <term>
       <literal>env.RCS()</literal>

doc/generated/functions.mod

 <!ENTITY f-PrependENVPath "<function xmlns='http://www.scons.org/dbxsd/v1.0'>PrependENVPath</function>">
 <!ENTITY f-PrependUnique "<function xmlns='http://www.scons.org/dbxsd/v1.0'>PrependUnique</function>">
 <!ENTITY f-Progress "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Progress</function>">
+<!ENTITY f-Pseudo "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Pseudo</function>">
 <!ENTITY f-RCS "<function xmlns='http://www.scons.org/dbxsd/v1.0'>RCS</function>">
 <!ENTITY f-Replace "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Replace</function>">
 <!ENTITY f-Repository "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Repository</function>">
 <!ENTITY f-env-PrependENVPath "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.PrependENVPath</function>">
 <!ENTITY f-env-PrependUnique "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.PrependUnique</function>">
 <!ENTITY f-env-Progress "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.Progress</function>">
+<!ENTITY f-env-Pseudo "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.Pseudo</function>">
 <!ENTITY f-env-RCS "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.RCS</function>">
 <!ENTITY f-env-Replace "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.Replace</function>">
 <!ENTITY f-env-Repository "<function xmlns='http://www.scons.org/dbxsd/v1.0'>env.Repository</function>">
 <!ENTITY f-link-PrependENVPath "<link linkend='f-PrependENVPath' xmlns='http://www.scons.org/dbxsd/v1.0'><function>PrependENVPath</function></link>">
 <!ENTITY f-link-PrependUnique "<link linkend='f-PrependUnique' xmlns='http://www.scons.org/dbxsd/v1.0'><function>PrependUnique</function></link>">
 <!ENTITY f-link-Progress "<link linkend='f-Progress' xmlns='http://www.scons.org/dbxsd/v1.0'><function>Progress</function></link>">
+<!ENTITY f-link-Pseudo "<link linkend='f-Pseudo' xmlns='http://www.scons.org/dbxsd/v1.0'><function>Pseudo</function></link>">
 <!ENTITY f-link-RCS "<link linkend='f-RCS' xmlns='http://www.scons.org/dbxsd/v1.0'><function>RCS</function></link>">
 <!ENTITY f-link-Replace "<link linkend='f-Replace' xmlns='http://www.scons.org/dbxsd/v1.0'><function>Replace</function></link>">
 <!ENTITY f-link-Repository "<link linkend='f-Repository' xmlns='http://www.scons.org/dbxsd/v1.0'><function>Repository</function></link>">
 <!ENTITY f-link-env-PrependENVPath "<link linkend='f-PrependENVPath' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.PrependENVPath</function></link>">
 <!ENTITY f-link-env-PrependUnique "<link linkend='f-PrependUnique' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.PrependUnique</function></link>">
 <!ENTITY f-link-env-Progress "<link linkend='f-Progress' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.Progress</function></link>">
+<!ENTITY f-link-env-Pseudo "<link linkend='f-Pseudo' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.Pseudo</function></link>">
 <!ENTITY f-link-env-RCS "<link linkend='f-RCS' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.RCS</function></link>">
 <!ENTITY f-link-env-Replace "<link linkend='f-Replace' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.Replace</function></link>">
 <!ENTITY f-link-env-Repository "<link linkend='f-Repository' xmlns='http://www.scons.org/dbxsd/v1.0'><function>env.Repository</function></link>">

doc/generated/tools.gen

 </para>
 </important>
 <para xmlns="http://www.scons.org/dbxsd/v1.0">The rules given above are valid for the Builders <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookHtml"><function>DocbookHtml</function></link>, 
-<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookPdf"><function>DocbookPdf</function></link>, <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookSlidesPdf"><function>DocbookSlidesPdf</function></link> and <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookXInclude"><function>DocbookXInclude</function></link>. For the 
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookPdf"><function>DocbookPdf</function></link>, <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookEpub"><function>DocbookEpub</function></link>, <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookSlidesPdf"><function>DocbookSlidesPdf</function></link> and <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookXInclude"><function>DocbookXInclude</function></link>. For the 
 <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookMan"><function>DocbookMan</function></link> transformation you
 can specify a target name, but the actual output names are automatically
 set from the <literal>refname</literal> entries in your XML source.
 DOCBOOK_DEFAULT_XSL_HTMLCHUNKED        
 DOCBOOK_DEFAULT_XSL_HTMLHELP        
 DOCBOOK_DEFAULT_XSL_PDF        
+DOCBOOK_DEFAULT_XSL_EPUB        
 DOCBOOK_DEFAULT_XSL_MAN        
 DOCBOOK_DEFAULT_XSL_SLIDESPDF        
 DOCBOOK_DEFAULT_XSL_SLIDESHTML        
                   DOCBOOK_DEFAULT_XSL_PDF='pdf.xsl')
 env.DocbookHtml('manual') # now uses html.xsl
 </screen>
-<para>Sets:  &cv-link-DOCBOOK_DEFAULT_XSL_HTML;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLHELP;, &cv-link-DOCBOOK_DEFAULT_XSL_MAN;, &cv-link-DOCBOOK_DEFAULT_XSL_PDF;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESHTML;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESPDF;, &cv-link-DOCBOOK_FOP;, &cv-link-DOCBOOK_FOPCOM;, &cv-link-DOCBOOK_FOPFLAGS;, &cv-link-DOCBOOK_XMLLINT;, &cv-link-DOCBOOK_XMLLINTCOM;, &cv-link-DOCBOOK_XMLLINTFLAGS;, &cv-link-DOCBOOK_XSLTPROC;, &cv-link-DOCBOOK_XSLTPROCCOM;, &cv-link-DOCBOOK_XSLTPROCFLAGS;, &cv-link-DOCBOOK_XSLTPROCPARAMS;.</para><para>Uses:  &cv-link-DOCBOOK_FOPCOMSTR;, &cv-link-DOCBOOK_XMLLINTCOMSTR;, &cv-link-DOCBOOK_XSLTPROCCOMSTR;.</para></listitem>
+<para>Sets:  &cv-link-DOCBOOK_DEFAULT_XSL_EPUB;, &cv-link-DOCBOOK_DEFAULT_XSL_HTML;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLHELP;, &cv-link-DOCBOOK_DEFAULT_XSL_MAN;, &cv-link-DOCBOOK_DEFAULT_XSL_PDF;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESHTML;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESPDF;, &cv-link-DOCBOOK_FOP;, &cv-link-DOCBOOK_FOPCOM;, &cv-link-DOCBOOK_FOPFLAGS;, &cv-link-DOCBOOK_XMLLINT;, &cv-link-DOCBOOK_XMLLINTCOM;, &cv-link-DOCBOOK_XMLLINTFLAGS;, &cv-link-DOCBOOK_XSLTPROC;, &cv-link-DOCBOOK_XSLTPROCCOM;, &cv-link-DOCBOOK_XSLTPROCFLAGS;, &cv-link-DOCBOOK_XSLTPROCPARAMS;.</para><para>Uses:  &cv-link-DOCBOOK_FOPCOMSTR;, &cv-link-DOCBOOK_XMLLINTCOMSTR;, &cv-link-DOCBOOK_XSLTPROCCOMSTR;.</para></listitem>
   </varlistentry>
   <varlistentry id="t-dvi">
     <term>dvi</term>

doc/generated/variables.gen

 </para>
 </listitem>
   </varlistentry>
+  <varlistentry id="cv-DOCBOOK_DEFAULT_XSL_EPUB">
+    <term>DOCBOOK_DEFAULT_XSL_EPUB</term>
+    <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+The default XSLT file for the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-DocbookEpub"><function>DocbookEpub</function></link> builder within the
+current environment, if no other XSLT gets specified via keyword.
+</para>
+</listitem>
+  </varlistentry>
   <varlistentry id="cv-DOCBOOK_DEFAULT_XSL_HTML">
     <term>DOCBOOK_DEFAULT_XSL_HTML</term>
     <listitem>

doc/generated/variables.mod

 <!ENTITY cv-DESCRIPTION_lang "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$DESCRIPTION_lang</envar>">
 <!ENTITY cv-Dir "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$Dir</envar>">
 <!ENTITY cv-Dirs "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$Dirs</envar>">
+<!ENTITY cv-DOCBOOK_DEFAULT_XSL_EPUB "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$DOCBOOK_DEFAULT_XSL_EPUB</envar>">
 <!ENTITY cv-DOCBOOK_DEFAULT_XSL_HTML "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$DOCBOOK_DEFAULT_XSL_HTML</envar>">
 <!ENTITY cv-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$DOCBOOK_DEFAULT_XSL_HTMLCHUNKED</envar>">
 <!ENTITY cv-DOCBOOK_DEFAULT_XSL_HTMLHELP "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$DOCBOOK_DEFAULT_XSL_HTMLHELP</envar>">
 <!ENTITY cv-link-DESCRIPTION_lang "<link linkend='cv-DESCRIPTION_lang' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$DESCRIPTION_lang</envar></link>">
 <!ENTITY cv-link-Dir "<link linkend='cv-Dir' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$Dir</envar></link>">
 <!ENTITY cv-link-Dirs "<link linkend='cv-Dirs' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$Dirs</envar></link>">
+<!ENTITY cv-link-DOCBOOK_DEFAULT_XSL_EPUB "<link linkend='cv-DOCBOOK_DEFAULT_XSL_EPUB' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$DOCBOOK_DEFAULT_XSL_EPUB</envar></link>">
 <!ENTITY cv-link-DOCBOOK_DEFAULT_XSL_HTML "<link linkend='cv-DOCBOOK_DEFAULT_XSL_HTML' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$DOCBOOK_DEFAULT_XSL_HTML</envar></link>">
 <!ENTITY cv-link-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED "<link linkend='cv-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$DOCBOOK_DEFAULT_XSL_HTMLCHUNKED</envar></link>">
 <!ENTITY cv-link-DOCBOOK_DEFAULT_XSL_HTMLHELP "<link linkend='cv-DOCBOOK_DEFAULT_XSL_HTMLHELP' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$DOCBOOK_DEFAULT_XSL_HTMLHELP</envar></link>">

doc/man/SConstruct

 # Create the EPUB format
 #
 if has_gs and has_pdf:
-    metainf = env.Command('META-INF','',[Mkdir('META-INF'), Mkdir('OEBPS')])
-    css = env.Command('OEBPS/epub.css','epub.css',[Copy('OEBPS/epub.css','epub.css')])
-    env.Depends(css, metainf)
     jpg = env.Gs('OEBPS/cover.jpg','scons-scons.pdf', 
                  GSFLAGS='-dNOPAUSE -dBATCH -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -dJPEGQ=100 -r72x72 -q')
-    env.Depends(jpg, metainf)
-    oebps = env.DocbookXslt('OEBPS/toc.ncx', 'scons_db.xml', xsl='epub.xsl')
-    env.Depends(oebps, jpg)
-    env.Zip('scons-man.epub', 'OEBPS', ZIPFLAGS='-Xr9D')
-    env.Clean(oebps, Glob('OEBPS/*.*'))
-    env.Clean(oebps, Glob('META-INF/*.*'))
+    epub = env.DocbookEpub('scons-man.epub', 'scons_db.xml', xsl='epub.xsl')
+    env.Depends(epub, jpg)

doc/user/SConstruct

 # Create the EPUB format
 #
 if has_gs and has_pdf:
-    metainf = env.Command('META-INF','',[Mkdir('META-INF'), Mkdir('OEBPS')])
-    css = env.Command('OEBPS/epub.css','epub.css',[Copy('OEBPS/epub.css','epub.css')])
-    env.Depends(css, metainf)
     jpg = env.Gs('OEBPS/cover.jpg','scons-user.pdf', 
                  GSFLAGS='-dNOPAUSE -dBATCH -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -dJPEGQ=100 -r72x72 -q')
-    env.Depends(jpg, metainf)
-    oebps = env.DocbookXslt('OEBPS/toc.ncx', 'scons_db.xml', xsl='epub.xsl')
-    env.Depends(oebps, jpg)
-    env.Zip('scons-user.epub', 'OEBPS', ZIPFLAGS='-Xr9D')
-    env.Clean(oebps, Glob('OEBPS/*.*'))
-    env.Clean(oebps, Glob('META-INF/*.*'))
+    epub = env.DocbookEpub('scons-user.epub', 'scons_db.xml', xsl='epub.xsl')
+    env.Depends(epub, jpg)
 
 RELEASE 2.3.1.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE
 
+  From Andrew Featherstone:
+    - Added support for EPUB output format to the DocBook tool.
+
   From Tom Tanner:
     - Stop leaking file handles to subprocesses by switching to using subprocess
       always.

src/engine/SCons/Tool/docbook/__init__.py

 docbook_xml_scanner = SCons.Script.Scanner(function = __xml_scan,
                                            argument = None)
 
+
+#
+# Action generators
+#
+def __generate_xsltproc_action(source, target, env, for_signature):
+    cmd = env['DOCBOOK_XSLTPROCCOM']    
+    # Does the environment have a base_dir defined?
+    base_dir = env.subst('$base_dir')
+    if base_dir:
+        # Yes, so replace target path by its filename
+        return cmd.replace('$TARGET','${TARGET.file}')
+    return cmd
+
+
+#
+# Emitters
+#
+def __emit_xsl_basedir(target, source, env):
+    # Does the environment have a base_dir defined?
+    base_dir = env.subst('$base_dir')
+    if base_dir:
+        # Yes, so prepend it to each target
+        return [os.path.join(base_dir, str(t)) for t in target], source
+    
+    # No, so simply pass target and source names through
+    return target, source
+
+
 #
 # Builders
 #
     """
     from lxml import etree
     
+    xslt_ac = etree.XSLTAccessControl(read_file=True, 
+                                      write_file=True, 
+                                      create_dir=True, 
+                                      read_network=False, 
+                                      write_network=False)
     xsl_style = env.subst('$DOCBOOK_XSL')
     xsl_tree = etree.parse(xsl_style)
-    transform = etree.XSLT(xsl_tree)
+    transform = etree.XSLT(xsl_tree, access_control=xslt_ac)
     doc = etree.parse(str(source[0]))
     # Support for additional parameters
     parampass = {}
 __libxml2_builder = SCons.Builder.Builder(
         action = __build_libxml2,
         src_suffix = '.xml',
-        source_scanner = docbook_xml_scanner)
+        source_scanner = docbook_xml_scanner,
+        emitter = __emit_xsl_basedir)
 __lxml_builder = SCons.Builder.Builder(
         action = __build_lxml,
         src_suffix = '.xml',
-        source_scanner = docbook_xml_scanner)
+        source_scanner = docbook_xml_scanner,
+        emitter = __emit_xsl_basedir)
 
 __xinclude_libxml2_builder = SCons.Builder.Builder(
         action = __xinclude_libxml2,
         source_scanner = docbook_xml_scanner)
 
 __xsltproc_builder = SCons.Builder.Builder(
-        action = SCons.Action.Action('$DOCBOOK_XSLTPROCCOM','$DOCBOOK_XSLTPROCCOMSTR'),
+        action = SCons.Action.CommandGeneratorAction(__generate_xsltproc_action,
+                                                     {'cmdstr' : '$DOCBOOK_XSLTPROCCOMSTR'}),
         src_suffix = '.xml',
-        source_scanner = docbook_xml_scanner)
+        source_scanner = docbook_xml_scanner,
+        emitter = __emit_xsl_basedir)
 __xmllint_builder = SCons.Builder.Builder(
         action = SCons.Action.Action('$DOCBOOK_XMLLINTCOM','$DOCBOOK_XMLLINTCOMSTR'),
         suffix = '.xml',
         src_suffix = '.fo',
         ensure_suffix=1)
 
+def DocbookEpub(env, target, source=None, *args, **kw):
+    """
+    A pseudo-Builder, providing a Docbook toolchain for ePub output.
+    """
+    import zipfile
+    import shutil
+    
+    def build_open_container(target, source, env):
+        """Generate the *.epub file from intermediate outputs
+
+        Constructs the epub file according to the Open Container Format. This 
+        function could be replaced by a call to the SCons Zip builder if support
+        was added for different compression formats for separate source nodes.
+        """
+        zf = zipfile.ZipFile(str(target[0]), 'w')
+        mime_file = open('mimetype', 'w')
+        mime_file.write('application/epub+zip')
+        mime_file.close()
+        zf.write(mime_file.name, compress_type = zipfile.ZIP_STORED)
+        for s in source:
+            for dirpath, dirnames, filenames in os.walk(str(s)):
+                for fname in filenames:
+                    path = os.path.join(dirpath, fname)
+                    if os.path.isfile(path):
+                        zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', ''))),
+                            zipfile.ZIP_DEFLATED)
+        zf.close()
+        
+    def add_resources(target, source, env):
+        """Add missing resources to the OEBPS directory
+
+        Ensure all the resources in the manifest are present in the OEBPS directory.
+        """
+        hrefs = []
+        content_file = os.path.join(source[0].abspath, 'content.opf')
+        if not os.path.isfile(content_file):
+            return
+        
+        hrefs = []
+        if has_libxml2:
+            nsmap = {'opf' : 'http://www.idpf.org/2007/opf'}
+            # Read file and resolve entities
+            doc = libxml2.readFile(content_file, None, 0)
+            opf = doc.getRootElement()
+            # Create xpath context
+            xpath_context = doc.xpathNewContext()
+            # Register namespaces
+            for key, val in nsmap.iteritems():
+                xpath_context.xpathRegisterNs(key, val)
+
+            if hasattr(opf, 'xpathEval') and xpath_context:
+                # Use the xpath context
+                xpath_context.setContextNode(opf)
+                items = xpath_context.xpathEval(".//opf:item")
+            else:
+                items = opf.findall(".//{'http://www.idpf.org/2007/opf'}item")
+
+            for item in items:
+                if hasattr(item, 'prop'):
+                    hrefs.append(item.prop('href'))
+                else:
+                    hrefs.append(item.attrib['href'])
+
+            doc.freeDoc()
+            xpath_context.xpathFreeContext()            
+        elif has_lxml:
+            from lxml import etree
+            
+            opf = etree.parse(content_file)
+            # All the opf:item elements are resources
+            for item in opf.xpath('//opf:item', 
+                    namespaces= { 'opf': 'http://www.idpf.org/2007/opf' }):
+                hrefs.append(item.attrib['href'])
+        
+        for href in hrefs:
+            # If the resource was not already created by DocBook XSL itself, 
+            # copy it into the OEBPS folder
+            referenced_file = os.path.join(source[0].abspath, href)
+            if not os.path.exists(referenced_file):
+                shutil.copy(href, os.path.join(source[0].abspath, href))
+        
+    # Init list of targets/sources
+    target, source = __extend_targets_sources(target, source)
+    
+    # Init XSL stylesheet
+    __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_EPUB', ['epub','docbook.xsl'])
+
+    # Setup builder
+    __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+    
+    # Create targets
+    result = []
+    tlist = ['OEBPS/toc.ncx', 'META-INF/container.xml']
+    dirs = [SCons.Script.Dir('OEBPS'), SCons.Script.Dir('META-INF')]
+    r = __builder.__call__(env, tlist, source[0], **kw)
+    
+    env.Depends(r, kw['DOCBOOK_XSL'])
+    result.extend(r)
+
+    container = env.Command(__ensure_suffix(str(target[0]), '.epub'), 
+        tlist, [add_resources, build_open_container])    
+    
+    env.Depends(container, r)
+    result.extend(container)
+    # Add supporting files for cleanup
+    env.Clean(r, dirs + [SCons.Script.File('mimetype')])
+
+    return result
+
 def DocbookHtml(env, target, source=None, *args, **kw):
     """
     A pseudo-Builder, providing a Docbook toolchain for HTML output.
    
     # Create targets
     result = []
-    r = __builder.__call__(env, base_dir+__ensure_suffix(str(target[0]), '.html'), source[0], **kw)
+    r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw)
     env.Depends(r, kw['DOCBOOK_XSL'])
     result.extend(r)
     # Add supporting files for cleanup
-    env.Clean(r, glob.glob(base_dir+'*.html'))
+    env.Clean(r, glob.glob(os.path.join(base_dir, '*.html')))
 
     return result
 
     
     # Create targets
     result = []
-    r = __builder.__call__(env, base_dir+__ensure_suffix(str(target[0]), '.html'), source[0], **kw)
+    r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw)
     env.Depends(r, kw['DOCBOOK_XSL'])
     result.extend(r)
     # Add supporting files for cleanup
     env.Clean(r, ['toc.hhc', 'htmlhelp.hhp', 'index.hhk'] +
-                 glob.glob(base_dir+'[ar|bk|ch]*.html'))
+                 glob.glob(os.path.join(base_dir, '[ar|bk|ch]*.html')))
 
     return result
 
 
     # Create targets
     result = []
-    r = __builder.__call__(env, base_dir+__ensure_suffix(str(target[0]), '.html'), source[0], **kw)
+    r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw)
     env.Depends(r, kw['DOCBOOK_XSL'])
     result.extend(r)
     # Add supporting files for cleanup
-    env.Clean(r, [base_dir+'toc.html'] +
-                 glob.glob(base_dir+'foil*.html'))
+    env.Clean(r, [os.path.join(base_dir, 'toc.html')] +
+                 glob.glob(os.path.join(base_dir, 'foil*.html')))
 
     return result
 
     return result
 
 
-
 def generate(env):
     """Add Builders and construction variables for docbook to an Environment."""
 
     env.SetDefault(
         # Default names for customized XSL stylesheets
-        DOCBOOK_DEFAULT_XSL_HTML = '',        
-        DOCBOOK_DEFAULT_XSL_HTMLCHUNKED = '',        
-        DOCBOOK_DEFAULT_XSL_HTMLHELP = '',        
-        DOCBOOK_DEFAULT_XSL_PDF = '',        
-        DOCBOOK_DEFAULT_XSL_MAN = '',        
-        DOCBOOK_DEFAULT_XSL_SLIDESPDF = '',        
-        DOCBOOK_DEFAULT_XSL_SLIDESHTML = '',        
+        DOCBOOK_DEFAULT_XSL_EPUB = '',
+        DOCBOOK_DEFAULT_XSL_HTML = '',
+        DOCBOOK_DEFAULT_XSL_HTMLCHUNKED = '',
+        DOCBOOK_DEFAULT_XSL_HTMLHELP = '',
+        DOCBOOK_DEFAULT_XSL_PDF = '',
+        DOCBOOK_DEFAULT_XSL_MAN = '',
+        DOCBOOK_DEFAULT_XSL_SLIDESPDF = '',
+        DOCBOOK_DEFAULT_XSL_SLIDESHTML = '',
         
         # Paths to the detected executables
         DOCBOOK_XSLTPROC = '',
     _detect(env)
 
     try:
+        env.AddMethod(DocbookEpub, "DocbookEpub")
         env.AddMethod(DocbookHtml, "DocbookHtml")
         env.AddMethod(DocbookHtmlChunked, "DocbookHtmlChunked")
         env.AddMethod(DocbookHtmlhelp, "DocbookHtmlhelp")
     except AttributeError:
         # Looks like we use a pre-0.98 version of SCons...
         from SCons.Script.SConscript import SConsEnvironment
+        SConsEnvironment.DocbookEpub = DocbookEpub        
         SConsEnvironment.DocbookHtml = DocbookHtml
         SConsEnvironment.DocbookHtmlChunked = DocbookHtmlChunked
         SConsEnvironment.DocbookHtmlhelp = DocbookHtmlhelp

src/engine/SCons/Tool/docbook/__init__.xml

 </para>
 </important>
 <para>The rules given above are valid for the Builders &b-link-DocbookHtml;, 
-&b-link-DocbookPdf;, &b-link-DocbookSlidesPdf; and &b-link-DocbookXInclude;. For the 
+&b-link-DocbookPdf;, &b-link-DocbookEpub;, &b-link-DocbookSlidesPdf; and &b-link-DocbookXInclude;. For the 
 &b-link-DocbookMan; transformation you
 can specify a target name, but the actual output names are automatically
 set from the <literal>refname</literal> entries in your XML source.
 DOCBOOK_DEFAULT_XSL_HTMLCHUNKED        
 DOCBOOK_DEFAULT_XSL_HTMLHELP        
 DOCBOOK_DEFAULT_XSL_PDF        
+DOCBOOK_DEFAULT_XSL_EPUB        
 DOCBOOK_DEFAULT_XSL_MAN        
 DOCBOOK_DEFAULT_XSL_SLIDESPDF        
 DOCBOOK_DEFAULT_XSL_SLIDESHTML        
 <item>DOCBOOK_DEFAULT_XSL_HTMLCHUNKED</item>
 <item>DOCBOOK_DEFAULT_XSL_HTMLHELP</item>
 <item>DOCBOOK_DEFAULT_XSL_PDF</item>
+<item>DOCBOOK_DEFAULT_XSL_EPUB</item>
 <item>DOCBOOK_DEFAULT_XSL_MAN</item>
 <item>DOCBOOK_DEFAULT_XSL_SLIDESPDF</item>
 <item>DOCBOOK_DEFAULT_XSL_SLIDESHTML</item>
 </summary>
 </cvar>
 
+<cvar name="DOCBOOK_DEFAULT_XSL_EPUB">
+<summary>
+<para>
+The default XSLT file for the &b-link-DocbookEpub; builder within the
+current environment, if no other XSLT gets specified via keyword.
+</para>
+</summary>
+</cvar>
+
 <cvar name="DOCBOOK_DEFAULT_XSL_MAN">
 <summary>
 <para>
 </summary>
 </builder>
 
+<builder name="DocbookEpub">
+<summary>
+<para>
+A pseudo-Builder, providing a Docbook toolchain for EPUB output.
+</para>
+
+<example_commands>env = Environment(tools=['docbook'])
+env.DocbookEpub('manual.epub', 'manual.xml')
+</example_commands>
+
+<para>
+or simply
+</para>
+
+<example_commands>env = Environment(tools=['docbook'])
+env.DocbookEpub('manual')
+</example_commands>
+
+</summary>
+</builder>
+
 <builder name="DocbookMan">
 <summary>
 <para>

test/Docbook/basedir/htmlchunked/htmlchunked_cmd.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the base_dir argument for the chunked HTML builder while using
+the xsltproc executable, if it exists.
+"""
+
+import os
+import sys
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+xsltproc = test.where_is('xsltproc')
+if not (xsltproc and
+        os.path.isdir('/usr/share/xml/docbook/stylesheet/docbook-xsl')):
+    test.skip_test('No xsltproc or no stylesheets installed, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(arguments=['-f','SConstruct.cmd'], stderr=None)
+test.must_exist(test.workpath('output/index.html'))
+
+# Cleanup
+test.run(arguments=['-f','SConstruct.cmd','-c'])
+test.must_not_exist(test.workpath('output/index.html'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

test/Docbook/basedir/htmlchunked/image/SConstruct.cmd

+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtmlChunked('manual', xsl='html.xsl', base_dir='output/')

test/Docbook/basedir/htmlhelp/htmlhelp_cmd.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the base_dir argument for the HTMLHELP builder while using
+the xsltproc executable, if it exists.
+"""
+
+import os
+import sys
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+xsltproc = test.where_is('xsltproc')
+if not (xsltproc and
+        os.path.isdir('/usr/share/xml/docbook/stylesheet/docbook-xsl')):
+    test.skip_test('No xsltproc or no stylesheets installed, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(arguments=['-f','SConstruct.cmd'], stderr=None)
+test.must_exist(test.workpath('output/index.html'))
+test.must_exist(test.workpath('htmlhelp.hhp'))
+test.must_exist(test.workpath('toc.hhc'))
+
+# Cleanup
+test.run(arguments=['-f','SConstruct.cmd','-c'])
+test.must_not_exist(test.workpath('output/index.html'))
+test.must_not_exist(test.workpath('htmlhelp.hhp'))
+test.must_not_exist(test.workpath('toc.hhc'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

test/Docbook/basedir/htmlhelp/image/SConstruct.cmd

+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtmlhelp('manual', xsl='htmlhelp.xsl', base_dir='output/')
+

test/Docbook/basedir/slideshtml/image/SConstruct.cmd

+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookSlidesHtml('virt', xsl='slides.xsl', base_dir='output/')
+

test/Docbook/basedir/slideshtml/slideshtml_cmd.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the base_dir argument for the Slides HTML builder while using
+the xsltproc executable, if it exists.
+"""
+
+import os
+import sys
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+xsltproc = test.where_is('xsltproc')
+if not (xsltproc and
+        os.path.isdir('/usr/share/xml/docbook/stylesheet/docbook-xsl/slides') and
+        os.path.isdir('/usr/share/xml/docbook/custom/slides/3.3.1')):
+    test.skip_test('No xsltproc or no "slides" stylesheets installed, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(arguments=['-f','SConstruct.cmd'], stderr=None)
+test.must_exist(test.workpath('output/index.html'))
+test.must_exist(test.workpath('output/toc.html'))
+test.must_exist(test.workpath('output/foil01.html'))
+test.must_exist(test.workpath('output/foilgroup01.html'))
+
+# Cleanup
+test.run(arguments=['-f','SConstruct.cmd','-c'])
+test.must_not_exist(test.workpath('output/index.html'))
+test.must_not_exist(test.workpath('output/toc.html'))
+test.must_not_exist(test.workpath('output/foil01.html'))
+test.must_not_exist(test.workpath('output/foilgroup01.html'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

test/Docbook/basic/epub/epub.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the EPUB builder.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+try:
+    import libxml2
+except:
+    try:
+        import lxml
+    except:
+        test.skip_test('Cannot find installed Python binding for libxml2 or lxml, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(stderr=None)
+test.must_exist(test.workpath('manual.epub'))
+test.must_exist(test.workpath('OEBPS','toc.ncx'))
+test.must_exist(test.workpath('OEBPS','content.opf'))
+test.must_exist(test.workpath('META-INF','container.xml'))
+
+# Cleanup
+test.run(arguments='-c')
+test.must_not_exist(test.workpath('manual.epub'))
+test.must_not_exist(test.workpath('OEBPS'))
+test.must_not_exist(test.workpath('META-INF'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

test/Docbook/basic/epub/image/SConstruct

+env = Environment(tools=['docbook'])
+env.DocbookEpub('manual')

test/Docbook/basic/epub/image/manual.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Copyright (c) 2001-2010 The SCons Foundation
+
+  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.
+
+-->
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<article>
+  <title>The SCons qt4 tool</title>
+
+  <articleinfo>
+    <author>
+      <surname>Dirk Baechle</surname>
+    </author>
+
+    <pubdate>2010-12-06</pubdate>
+  </articleinfo>
+
+  <section id="basics">
+    <title>Basics</title>
+
+    <para>This tool can be used to compile Qt projects, designed for versions
+    4.x.y and higher. It is not usable for Qt3 and older versions, since some
+    of the helper tools (<literal>moc</literal>, <literal>uic</literal>)
+    behave different.</para>
+
+    <section id="install">
+      <title>Install</title>
+
+      <para>Installing it, requires you to copy (or, even better: checkout)
+      the contents of the package's <literal>qt4</literal> folder to</para>
+
+      <orderedlist>
+        <listitem>
+          <para><quote><literal>/path_to_your_project/site_scons/site_tools/qt4</literal></quote>,
+          if you need the Qt4 Tool in one project only, or</para>
+        </listitem>
+
+        <listitem>
+          <para><quote><literal>~/.scons/site_scons/site_tools/qt4</literal></quote>,
+          for a system-wide installation under your current login.</para>
+        </listitem>
+      </orderedlist>
+
+      <para>For more infos about this, please refer to</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>the SCons User's Guide, chap. 17.7 "Where to put your custom
+          Builders and Tools" and</para>
+        </listitem>
+
+        <listitem>
+          <para>the SCons Tools Wiki page at <ulink
+          url="http://scons.org/wiki/ToolsIndex">http://scons.org/wiki/ToolsIndex</ulink>.</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
+    <section id="activation">
+      <title>How to activate</title>
+
+      <para>For activating the tool "qt4", you have to add its name to the
+      Environment constructor, like this</para>
+
+      <screen>env = Environment(tools=['default','qt4'])
+</screen>
+
+      <para>On its startup, the Qt4 tool tries to read the variable
+      <literal>QT4DIR</literal> from the current Environment and
+      <literal>os.environ</literal>. If it is not set, the value of
+      <literal>QTDIR</literal> (in Environment/<literal>os.environ</literal>)
+      is used as a fallback.</para>
+
+      <para>So, you either have to explicitly give the path of your Qt4
+      installation to the Environment with</para>
+
+      <screen>env['QT4DIR'] = '/usr/local/Trolltech/Qt-4.2.3'
+</screen>
+
+      <para>or set the <literal>QT4DIR</literal> as environment variable in
+      your shell.</para>
+    </section>
+
+    <section id="requirements">
+      <title>Requirements</title>
+
+      <para>Under Linux, "qt4" uses the system tool
+      <literal>pkg-config</literal> for automatically setting the required
+      compile and link flags of the single Qt4 modules (like QtCore,
+      QtGui,...). This means that</para>
+
+      <orderedlist>
+        <listitem>
+          <para>you should have <literal>pkg-config</literal> installed,
+          and</para>
+        </listitem>
+
+        <listitem>
+          <para>you additionally have to set
+          <literal>PKG_CONFIG_PATH</literal> in your shell environment, such
+          that it points to $<literal>QT4DIR/lib/pkgconfig</literal> (or
+          $<literal>QT4DIR/lib</literal> for some older versions).</para>
+        </listitem>
+      </orderedlist>
+
+      <para>Based on these two environment variables
+      (<literal>QT4DIR</literal> and <literal>PKG_CONFIG_PATH</literal>), the
+      "qt4" tool initializes all <literal>QT4_*</literal> construction
+      variables listed in the Reference manual. This happens when the tool is
+      "detected" during Environment construction. As a consequence, the setup
+      of the tool gets a two-stage process, if you want to override the values
+      provided by your current shell settings:</para>
+
+      <screen># Stage 1: create plain environment
+qtEnv = Environment()
+# Set new vars
+qtEnv['QT4DIR'] = '/usr/local/Trolltech/Qt-4.2.3
+qtEnv['ENV']['PKG_CONFIG_PATH'] = '/usr/local/Trolltech/Qt-4.2.3/lib/pkgconfig'
+# Stage 2: add qt4 tool
+qtEnv.Tool('qt4')
+</screen>
+    </section>
+  </section>
+
+  <section id="boilerplate">
+    <title>Suggested boilerplate</title>
+
+    <para>Based on the requirements above, we suggest a simple ready-to-go
+    setup as follows:</para>
+
+    <para>SConstruct</para>
+
+    <screen># Detect Qt version
+qtdir = detectLatestQtDir()
+
+# Create base environment
+baseEnv = Environment()
+#...further customization of base env
+
+# Clone Qt environment
+qtEnv = baseEnv.Clone()
+# Set QT4DIR and PKG_CONFIG_PATH
+qtEnv['ENV']['PKG_CONFIG_PATH'] = os.path.join(qtdir, 'lib/pkgconfig')
+qtEnv['QT4DIR'] = qtdir
+# Add qt4 tool
+qtEnv.Tool('qt4')
+#...further customization of qt env
+
+# Export environments
+Export('baseEnv qtEnv')
+
+# Your other stuff...
+# ...including the call to your SConscripts
+</screen>
+
+    <para>In a SConscript</para>
+
+    <screen># Get the Qt4 environment
+Import('qtEnv')
+# Clone it
+env = qtEnv.clone()
+# Patch it
+env.Append(CCFLAGS=['-m32']) # or whatever
+# Use it
+env.StaticLibrary('foo', Glob('*.cpp'))
+</screen>
+
+    <para>The detection of the Qt directory could be as simple as directly
+    assigning a fixed path</para>
+
+    <screen>def detectLatestQtDir():
+    return "/usr/local/qt4.3.2"
+</screen>
+
+    <para>or a little more sophisticated</para>
+
+    <screen># Tries to detect the path to the installation of Qt with
+# the highest version number
+def detectLatestQtDir():
+    if sys.platform.startswith("linux"):
+        # Simple check: inspect only '/usr/local/Trolltech'
+        paths = glob.glob('/usr/local/Trolltech/*')
+        if len(paths):
+            paths.sort()
+            return paths[-1]
+        else:
+            return ""
+    else:
+        # Simple check: inspect only 'C:\Qt'
+        paths = glob.glob('C:\\Qt\\*')
+        if len(paths):
+            paths.sort()
+            return paths[-1]
+        else:
+            return os.environ.get("QTDIR","")
+</screen>
+  </section>
+
+  <section id="firstproject">
+    <title>A first project</title>
+
+    <para>The following SConscript is for a simple project with some cxx
+    files, using the QtCore, QtGui and QtNetwork modules:</para>
+
+    <screen>Import('qtEnv')
+env = qtEnv.Clone()
+env.EnableQt4Modules([
+                      'QtGui',
+                      'QtCore',
+                      'QtNetwork'
+                     ])
+# Add your CCFLAGS and CPPPATHs to env here...
+
+env.Program('foo', Glob('*.cpp')) 
+</screen>
+  </section>
+
+  <section id="mocup">
+    <title>MOC it up</title>
+
+    <para>For the basic support of automocing, nothing needs to be done by the
+    user. The tool usually detects the <literal>Q_OBJECT</literal> macro and
+    calls the <quote><literal>moc</literal></quote> executable
+    accordingly.</para>
+
+    <para>If you don't want this, you can switch off the automocing by
+    a</para>
+
+    <screen>env['QT4_AUTOSCAN'] = 0
+</screen>
+
+    <para>in your SConscript file. Then, you have to moc your files
+    explicitly, using the Moc4 builder.</para>
+
+    <para>You can also switch to an extended automoc strategy with</para>
+
+    <screen>env['QT4_AUTOSCAN_STRATEGY'] = 1
+</screen>
+
+    <para>Please read the description of the
+    <literal>QT4_AUTOSCAN_STRATEGY</literal> variable in the Reference manual
+    for details.</para>
+
+    <para>For debugging purposes, you can set the variable
+    <literal>QT4_DEBUG</literal> with</para>
+
+    <screen>env['QT4_DEBUG'] = 1
+</screen>
+
+    <para>which outputs a lot of messages during automocing.</para>
+  </section>
+
+  <section id="forms">
+    <title>Forms (.ui)</title>
+
+    <para>The header files with setup code for your GUI classes, are not
+    compiled automatically from your <literal>.ui</literal> files. You always
+    have to call the Uic4 builder explicitly like</para>
+
+    <screen>env.Uic4(Glob('*.ui'))
+env.Program('foo', Glob('*.cpp'))
+</screen>
+  </section>
+
+  <section id="resources">
+    <title>Resource files (.qrc)</title>
+
+    <para>Resource files are not built automatically, you always have to add
+    the names of the <literal>.qrc</literal> files to the source list for your
+    program or library:</para>
+
+    <screen>env.Program('foo', Glob('*.cpp')+Glob('*.qrc'))
+</screen>
+
+    <para>For each of the Resource input files, its prefix defines the name of
+    the resulting resource. An appropriate
+    <quote><literal>-name</literal></quote> option is added to the call of the
+    <literal>rcc</literal> executable by default.</para>
+
+    <para>You can also call the Qrc4 builder explicitly as</para>
+
+    <screen>qrccc = env.Qrc4('foo') # ['foo.qrc'] -&gt; ['qrc_foo.cc']
+</screen>
+
+    <para>or (overriding the default suffix)</para>
+
+    <screen>qrccc = env.Qrc4('myprefix_foo.cxx','foo.qrc') # -&gt; ['qrc_myprefix_foo.cxx']
+</screen>
+
+    <para>and then add the resulting cxx file to the sources of your
+    Program/Library:</para>
+
+    <screen>env.Program('foo', Glob('*.cpp') + qrccc)
+</screen>
+  </section>
+
+  <section id="translation">
+    <title>Translation files</title>
+
+    <para>The update of the <literal>.ts</literal> files and the conversion to
+    binary <literal>.qm</literal> files is not done automatically. You have to
+    call the corresponding builders on your own.</para>
+
+    <para>Example for updating a translation file:</para>
+
+    <screen>env.Ts4('foo.ts','.') # -&gt; ['foo.ts']
+</screen>
+
+    <para>By default, the <literal>.ts</literal> files are treated as
+    <emphasis>precious</emphasis> targets. This means that they are not
+    removed prior to a rebuild, but simply get updated. Additionally, they do
+    not get cleaned on a <quote><literal>scons -c</literal></quote>. If you
+    want to delete the translation files on the
+    <quote><literal>-c</literal></quote> SCons command, you can set the
+    variable <quote><literal>QT4_CLEAN_TS</literal></quote> like this</para>
+
+    <screen>env['QT4_CLEAN_TS']=1
+</screen>
+
+    <para>Example for releasing a translation file, i.e. compiling it to a
+    <literal>.qm</literal> binary file:</para>
+
+    <screen>env.Qm4('foo') # ['foo.ts'] -&gt; ['foo.qm']
+</screen>
+
+    <para>or (overriding the output prefix)</para>
+
+    <screen>env.Qm4('myprefix','foo') # ['foo.ts'] -&gt; ['myprefix.qm']
+</screen>
+
+    <para>As an extension both, the Ts4() and Qm4 builder, support the
+    definition of multiple targets. So, calling</para>
+
+    <screen>env.Ts4(['app_en','app_de'], Glob('*.cpp'))
+</screen>
+
+    <para>and</para>
+
+    <screen>env.Qm4(['app','copy'], Glob('*.ts'))
+</screen>
+
+    <para>should work fine.</para>
+
+    <para>Finally, two short notes about the support of directories for the
+    Ts4() builder. You can pass an arbitrary mix of cxx files and subdirs to
+    it, as in</para>
+
+    <screen>env.Ts4('app_en',['sub1','appwindow.cpp','main.cpp']))
+</screen>
+
+    <para>where <literal>sub1</literal> is a folder that gets scanned
+    recursively for cxx files by <literal>lupdate</literal>. But like this,
+    you lose all dependency information for the subdir, i.e. if a file inside
+    the folder changes, the .ts file is not updated automatically! In this
+    case you should tell SCons to always update the target:</para>
+
+    <screen>ts = env.Ts4('app_en',['sub1','appwindow.cpp','main.cpp'])
+env.AlwaysBuild(ts)
+</screen>
+
+    <para>Last note: specifying the current folder
+    <quote><literal>.</literal></quote> as input to Ts4() and storing the
+    resulting .ts file in the same directory, leads to a dependency cycle! You
+    then have to store the .ts and .qm files outside of the current folder, or
+    use <literal>Glob('*.cpp'))</literal> instead.</para>
+  </section>
+</article>

test/Docbook/basic/html/html_cmd.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the HTML builder while using
+the xsltproc executable, if it exists.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+xsltproc = test.where_is('xsltproc')
+if not xsltproc:
+    test.skip_test('No xsltproc executable found, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(arguments=['-f','SConstruct.cmd'])
+test.must_exist(test.workpath('manual.html'))
+
+# Cleanup
+test.run(arguments=['-f','SConstruct.cmd','-c'])
+test.must_not_exist(test.workpath('manual.html'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

test/Docbook/basic/html/image/SConstruct.cmd

+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtml('manual')
+

test/Docbook/basic/htmlchunked/htmlchunked_cmd.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the chunked HTML builder while using
+the xsltproc executable, if it exists.
+"""
+
+import os
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+xsltproc = test.where_is('xsltproc')
+if not xsltproc:
+    test.skip_test('No xsltproc executable found, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(arguments=['-f','SConstruct.cmd'], stderr=None)
+test.must_exist(test.workpath('index.html'))
+
+# Cleanup
+test.run(arguments=['-f','SConstruct.cmd','-c'])
+test.must_not_exist(test.workpath('index.html'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

test/Docbook/basic/htmlchunked/image/SConstruct.cmd

+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtmlChunked('manual')
+

test/Docbook/basic/htmlhelp/htmlhelp_cmd.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the HTMLHELP builder while using
+the xsltproc executable, if it exists.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+xsltproc = test.where_is('xsltproc')
+if not xsltproc:
+    test.skip_test('No xsltproc executable found, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(arguments=['-f','SConstruct.cmd'], stderr=None)
+test.must_exist(test.workpath('index.html'))
+test.must_exist(test.workpath('htmlhelp.hhp'))
+test.must_exist(test.workpath('toc.hhc'))
+
+# Cleanup
+test.run(arguments=['-f','SConstruct.cmd','-c'])
+test.must_not_exist(test.workpath('index.html'))
+test.must_not_exist(test.workpath('htmlhelp.hhp'))
+test.must_not_exist(test.workpath('toc.hhc'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

test/Docbook/basic/htmlhelp/image/SConstruct.cmd

+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtmlhelp('manual')
+

test/Docbook/basic/man/image/SConstruct.cmd

+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookMan('refdb')
+

test/Docbook/basic/man/man_cmd.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the Man builder while using
+the xsltproc executable, if it exists.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+xsltproc = test.where_is('xsltproc')
+if not xsltproc:
+    test.skip_test('No xsltproc executable found, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(arguments=['-f','SConstruct.cmd'], stderr=None)
+test.must_exist(test.workpath('refdb.8'))
+test.must_exist(test.workpath('refdb.sh.8'))
+
+# Cleanup
+test.run(arguments=['-f','SConstruct.cmd','-c'])
+test.must_not_exist(test.workpath('refdb.8'))
+test.must_not_exist(test.workpath('refdb.sh.8'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

test/Docbook/basic/slideshtml/image/SConstruct.cmd

+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookSlidesHtml('virt')
+

test/Docbook/basic/slideshtml/slideshtml_cmd.py

+#!/usr/bin/env python
+#
+# Copyright (c) 2001-2010 The SCons Foundation
+#
+# 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.
+#
+
+"""
+Test the Slides HTML builder while using
+the xsltproc executable, if it exists.
+"""
+
+import os
+import sys
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+xsltproc = test.where_is('xsltproc')
+if not (xsltproc and
+        os.path.isdir('/usr/share/xml/docbook/stylesheet/docbook-xsl/slides') and
+        os.path.isdir('/usr/share/xml/docbook/custom/slides/3.3.1')):
+    test.skip_test('No xsltproc executable or no "slides" stylesheets installed, skipping test.\n')
+
+test.dir_fixture('image')
+
+# Normal invocation
+test.run(arguments=['-f','SConstruct.cmd'], stderr=None)
+test.must_exist(test.workpath('index.html'))
+test.must_exist(test.workpath('toc.html'))
+test.must_exist(test.workpath('foil01.html'))
+test.must_exist(test.workpath('foilgroup01.html'))
+
+# Cleanup
+test.run(arguments=['-f','SConstruct.cmd','-c'])
+test.must_not_exist(test.workpath('index.html'))
+test.must_not_exist(test.workpath('toc.html'))
+test.must_not_exist(test.workpath('foil01.html'))
+test.must_not_exist(test.workpath('foilgroup01.html'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.