summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oberbrunner <garyo@oberbrunner.com>2013-12-28 21:12:34 -0500
committerGary Oberbrunner <garyo@oberbrunner.com>2013-12-28 21:12:34 -0500
commit8985f392bf5429d648345112d5225d4ac6dc9e7a (patch)
treeacc579bee5bd36c930560c4b9203353efe9e069e
parent62877aecf5082b1154e164c67071fdf838c0d0fb (diff)
parent0749634f8f8b24fd11d6501249e3576f66d7e68d (diff)
downloadscons-8985f392bf5429d648345112d5225d4ac6dc9e7a.tar.gz
Merge pull request #97, reduce memory consumption
-rw-r--r--SConstruct5
-rw-r--r--bin/update-release-info.py17
-rw-r--r--doc/generated/builders.gen26
-rw-r--r--doc/generated/builders.mod4
-rw-r--r--doc/generated/functions.gen22
-rw-r--r--doc/generated/functions.mod4
-rw-r--r--doc/generated/tools.gen5
-rw-r--r--doc/generated/variables.gen9
-rw-r--r--doc/generated/variables.mod2
-rw-r--r--doc/man/SConstruct11
-rw-r--r--doc/user/SConstruct11
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Tool/docbook/__init__.py188
-rw-r--r--src/engine/SCons/Tool/docbook/__init__.xml34
-rw-r--r--src/engine/SCons/Tool/gs.py3
-rw-r--r--test/Docbook/basedir/htmlchunked/htmlchunked_cmd.py57
-rw-r--r--test/Docbook/basedir/htmlchunked/image/SConstruct.cmd2
-rw-r--r--test/Docbook/basedir/htmlhelp/htmlhelp_cmd.py61
-rw-r--r--test/Docbook/basedir/htmlhelp/image/SConstruct.cmd3
-rw-r--r--test/Docbook/basedir/slideshtml/image/SConstruct.cmd3
-rw-r--r--test/Docbook/basedir/slideshtml/slideshtml_cmd.py64
-rw-r--r--test/Docbook/basic/epub/epub.py62
-rw-r--r--test/Docbook/basic/epub/image/SConstruct2
-rw-r--r--test/Docbook/basic/epub/image/manual.xml388
-rw-r--r--test/Docbook/basic/html/html_cmd.py54
-rw-r--r--test/Docbook/basic/html/image/SConstruct.cmd3
-rw-r--r--test/Docbook/basic/htmlchunked/htmlchunked_cmd.py55
-rw-r--r--test/Docbook/basic/htmlchunked/image/SConstruct.cmd3
-rw-r--r--test/Docbook/basic/htmlhelp/htmlhelp_cmd.py58
-rw-r--r--test/Docbook/basic/htmlhelp/image/SConstruct.cmd3
-rw-r--r--test/Docbook/basic/man/image/SConstruct.cmd3
-rw-r--r--test/Docbook/basic/man/man_cmd.py56
-rw-r--r--test/Docbook/basic/slideshtml/image/SConstruct.cmd3
-rw-r--r--test/Docbook/basic/slideshtml/slideshtml_cmd.py64
34 files changed, 1236 insertions, 52 deletions
diff --git a/SConstruct b/SConstruct
index f2899473..3f4d703a 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1039,7 +1039,10 @@ for p in [ scons ]:
if dh_builddeb and fakeroot:
# Our Debian packaging builds directly into build/dist,
# so we don't need to Install() the .debs.
- deb = os.path.join(build_dir, 'dist', "%s_%s_all.deb" % (pkg, version))
+ # The built deb is called just x.y.z, not x.y.z.final.0 so strip those off:
+ deb_version = '.'.join(version.split('.')[0:3])
+ deb = os.path.join(build_dir, 'dist', "%s_%s_all.deb" % (pkg, deb_version))
+ # print "Building deb into %s (version=%s)"%(deb, deb_version)
for d in p['debian_deps']:
b = env.SCons_revision(os.path.join(build, d), d)
env.Depends(deb, b)
diff --git a/bin/update-release-info.py b/bin/update-release-info.py
index 338bba91..14894a4f 100644
--- a/bin/update-release-info.py
+++ b/bin/update-release-info.py
@@ -333,17 +333,18 @@ t.replace_assign('deprecated_python_version', str(deprecated_version))
# Update doc/user/main.{in,xml}
docyears = ', '.join(map(str, iter(range(2004, release_date[0] + 1))))
-t = UpdateFile(os.path.join('doc', 'user', 'main.in'))
-if DEBUG: t.file = '/tmp/main.in'
-## TODO debug these
-#t.sub('<pubdate>[^<]*</pubdate>', '<pubdate>' + docyears + '</pubdate>')
-#t.sub('<year>[^<]*</year>', '<year>' + docyears + '</year>')
+if os.path.exists(os.path.join('doc', 'user', 'main.in')):
+ # this is no longer used as of Dec 2013
+ t = UpdateFile(os.path.join('doc', 'user', 'main.in'))
+ if DEBUG: t.file = '/tmp/main.in'
+ ## TODO debug these
+ #t.sub('<pubdate>[^<]*</pubdate>', '<pubdate>' + docyears + '</pubdate>')
+ #t.sub('<year>[^<]*</year>', '<year>' + docyears + '</year>')
t = UpdateFile(os.path.join('doc', 'user', 'main.xml'))
if DEBUG: t.file = '/tmp/main.xml'
-## TODO debug these
-#t.sub('<pubdate>[^<]*</pubdate>', '<pubdate>' + docyears + '</pubdate>')
-#t.sub('<year>[^<]*</year>', '<year>' + docyears + '</year>')
+t.sub('<pubdate>[^<]*</pubdate>', '<pubdate>' + docyears + '</pubdate>')
+t.sub('<year>[^<]*</year>', '<year>' + docyears + '</year>')
# Write out the last update
diff --git a/doc/generated/builders.gen b/doc/generated/builders.gen
index 5cd92f21..41239d4f 100644
--- a/doc/generated/builders.gen
+++ b/doc/generated/builders.gen
@@ -84,6 +84,32 @@ env.CXXFile(target = 'bar', source = 'bar.yy')
</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>
diff --git a/doc/generated/builders.mod b/doc/generated/builders.mod
index b8c7d802..50591b45 100644
--- a/doc/generated/builders.mod
+++ b/doc/generated/builders.mod
@@ -11,6 +11,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
@@ -65,6 +66,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
@@ -129,6 +131,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
@@ -183,6 +186,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen
index 4849ac6d..072b91ca 100644
--- a/doc/generated/functions.gen
+++ b/doc/generated/functions.gen
@@ -3419,6 +3419,28 @@ Progress(['-\r', '\\\r', '|\r', '/\r'], interval=5)
</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>
diff --git a/doc/generated/functions.mod b/doc/generated/functions.mod
index 0f5dd21a..99aaa480 100644
--- a/doc/generated/functions.mod
+++ b/doc/generated/functions.mod
@@ -71,6 +71,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
@@ -158,6 +159,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
@@ -255,6 +257,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
@@ -342,6 +345,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen
index 7d756381..a0a709e9 100644
--- a/doc/generated/tools.gen
+++ b/doc/generated/tools.gen
@@ -222,7 +222,7 @@ accordingly.
</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.
@@ -261,6 +261,7 @@ variables for setting the default XSL name is provided. These are:
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
@@ -272,7 +273,7 @@ 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>
diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen
index ee5a0dd7..efdac8ef 100644
--- a/doc/generated/variables.gen
+++ b/doc/generated/variables.gen
@@ -909,6 +909,15 @@ into a list of Dir instances relative to the target being built.
</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>
diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod
index 8a898ec3..b55b2188 100644
--- a/doc/generated/variables.mod
+++ b/doc/generated/variables.mod
@@ -70,6 +70,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
@@ -651,6 +652,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!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>">
diff --git a/doc/man/SConstruct b/doc/man/SConstruct
index cfdbb2d5..927bfa24 100644
--- a/doc/man/SConstruct
+++ b/doc/man/SConstruct
@@ -62,14 +62,7 @@ if env.WhereIs('gs'):
# 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)
diff --git a/doc/user/SConstruct b/doc/user/SConstruct
index 5d36a5e9..701fb7bc 100644
--- a/doc/user/SConstruct
+++ b/doc/user/SConstruct
@@ -60,14 +60,7 @@ if env.WhereIs('gs'):
# 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)
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 5e3a05bc..978c82c8 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -6,6 +6,9 @@
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.
diff --git a/src/engine/SCons/Tool/docbook/__init__.py b/src/engine/SCons/Tool/docbook/__init__.py
index d6713c69..d14d60bb 100644
--- a/src/engine/SCons/Tool/docbook/__init__.py
+++ b/src/engine/SCons/Tool/docbook/__init__.py
@@ -260,6 +260,34 @@ def __xml_scan(node, env, path, arg):
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
#
@@ -290,9 +318,14 @@ def __build_lxml(target, source, env):
"""
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 = {}
@@ -340,11 +373,13 @@ def __xinclude_lxml(target, source, env):
__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,
@@ -358,9 +393,11 @@ __xinclude_lxml_builder = SCons.Builder.Builder(
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',
@@ -372,6 +409,115 @@ __fop_builder = SCons.Builder.Builder(
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.
@@ -420,11 +566,11 @@ def DocbookHtmlChunked(env, target, source=None, *args, **kw):
# 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
@@ -455,12 +601,12 @@ def DocbookHtmlhelp(env, target, source=None, *args, **kw):
# 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
@@ -605,12 +751,12 @@ def DocbookSlidesHtml(env, target, source=None, *args, **kw):
# 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
@@ -654,19 +800,19 @@ def DocbookXslt(env, target, source=None, *args, **kw):
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 = '',
@@ -693,6 +839,7 @@ def generate(env):
_detect(env)
try:
+ env.AddMethod(DocbookEpub, "DocbookEpub")
env.AddMethod(DocbookHtml, "DocbookHtml")
env.AddMethod(DocbookHtmlChunked, "DocbookHtmlChunked")
env.AddMethod(DocbookHtmlhelp, "DocbookHtmlhelp")
@@ -705,6 +852,7 @@ def generate(env):
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
diff --git a/src/engine/SCons/Tool/docbook/__init__.xml b/src/engine/SCons/Tool/docbook/__init__.xml
index be2f2cab..07487384 100644
--- a/src/engine/SCons/Tool/docbook/__init__.xml
+++ b/src/engine/SCons/Tool/docbook/__init__.xml
@@ -97,7 +97,7 @@ accordingly.
</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.
@@ -136,6 +136,7 @@ variables for setting the default XSL name is provided. These are:
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
@@ -153,6 +154,7 @@ env.DocbookHtml('manual') # now uses html.xsl
<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>
@@ -212,6 +214,15 @@ current environment, if no other XSLT gets specified via keyword.
</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>
@@ -473,6 +484,27 @@ env.DocbookPdf('manual')
</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>
diff --git a/src/engine/SCons/Tool/gs.py b/src/engine/SCons/Tool/gs.py
index a8fdddea..6e31ee27 100644
--- a/src/engine/SCons/Tool/gs.py
+++ b/src/engine/SCons/Tool/gs.py
@@ -70,8 +70,7 @@ def generate(env):
except ImportError, e:
pass
- gsbuilder = SCons.Builder.Builder(action = SCons.Action.Action('$GSCOM', '$GSCOMSTR'),
- env = env)
+ gsbuilder = SCons.Builder.Builder(action = SCons.Action.Action('$GSCOM', '$GSCOMSTR'))
env['BUILDERS']['Gs'] = gsbuilder
env['GS'] = gs
diff --git a/test/Docbook/basedir/htmlchunked/htmlchunked_cmd.py b/test/Docbook/basedir/htmlchunked/htmlchunked_cmd.py
new file mode 100644
index 00000000..b507eb12
--- /dev/null
+++ b/test/Docbook/basedir/htmlchunked/htmlchunked_cmd.py
@@ -0,0 +1,57 @@
+#!/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:
diff --git a/test/Docbook/basedir/htmlchunked/image/SConstruct.cmd b/test/Docbook/basedir/htmlchunked/image/SConstruct.cmd
new file mode 100644
index 00000000..d981b284
--- /dev/null
+++ b/test/Docbook/basedir/htmlchunked/image/SConstruct.cmd
@@ -0,0 +1,2 @@
+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtmlChunked('manual', xsl='html.xsl', base_dir='output/')
diff --git a/test/Docbook/basedir/htmlhelp/htmlhelp_cmd.py b/test/Docbook/basedir/htmlhelp/htmlhelp_cmd.py
new file mode 100644
index 00000000..a0f5e8ac
--- /dev/null
+++ b/test/Docbook/basedir/htmlhelp/htmlhelp_cmd.py
@@ -0,0 +1,61 @@
+#!/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:
diff --git a/test/Docbook/basedir/htmlhelp/image/SConstruct.cmd b/test/Docbook/basedir/htmlhelp/image/SConstruct.cmd
new file mode 100644
index 00000000..8c7c9ca3
--- /dev/null
+++ b/test/Docbook/basedir/htmlhelp/image/SConstruct.cmd
@@ -0,0 +1,3 @@
+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtmlhelp('manual', xsl='htmlhelp.xsl', base_dir='output/')
+
diff --git a/test/Docbook/basedir/slideshtml/image/SConstruct.cmd b/test/Docbook/basedir/slideshtml/image/SConstruct.cmd
new file mode 100644
index 00000000..297aeb59
--- /dev/null
+++ b/test/Docbook/basedir/slideshtml/image/SConstruct.cmd
@@ -0,0 +1,3 @@
+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookSlidesHtml('virt', xsl='slides.xsl', base_dir='output/')
+
diff --git a/test/Docbook/basedir/slideshtml/slideshtml_cmd.py b/test/Docbook/basedir/slideshtml/slideshtml_cmd.py
new file mode 100644
index 00000000..51ed6e4d
--- /dev/null
+++ b/test/Docbook/basedir/slideshtml/slideshtml_cmd.py
@@ -0,0 +1,64 @@
+#!/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:
diff --git a/test/Docbook/basic/epub/epub.py b/test/Docbook/basic/epub/epub.py
new file mode 100644
index 00000000..19e08a0a
--- /dev/null
+++ b/test/Docbook/basic/epub/epub.py
@@ -0,0 +1,62 @@
+#!/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:
diff --git a/test/Docbook/basic/epub/image/SConstruct b/test/Docbook/basic/epub/image/SConstruct
new file mode 100644
index 00000000..16a06996
--- /dev/null
+++ b/test/Docbook/basic/epub/image/SConstruct
@@ -0,0 +1,2 @@
+env = Environment(tools=['docbook'])
+env.DocbookEpub('manual')
diff --git a/test/Docbook/basic/epub/image/manual.xml b/test/Docbook/basic/epub/image/manual.xml
new file mode 100644
index 00000000..ca12e0ed
--- /dev/null
+++ b/test/Docbook/basic/epub/image/manual.xml
@@ -0,0 +1,388 @@
+<?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>
diff --git a/test/Docbook/basic/html/html_cmd.py b/test/Docbook/basic/html/html_cmd.py
new file mode 100644
index 00000000..acb4dad9
--- /dev/null
+++ b/test/Docbook/basic/html/html_cmd.py
@@ -0,0 +1,54 @@
+#!/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:
diff --git a/test/Docbook/basic/html/image/SConstruct.cmd b/test/Docbook/basic/html/image/SConstruct.cmd
new file mode 100644
index 00000000..20b4aa25
--- /dev/null
+++ b/test/Docbook/basic/html/image/SConstruct.cmd
@@ -0,0 +1,3 @@
+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtml('manual')
+
diff --git a/test/Docbook/basic/htmlchunked/htmlchunked_cmd.py b/test/Docbook/basic/htmlchunked/htmlchunked_cmd.py
new file mode 100644
index 00000000..e1ad49a2
--- /dev/null
+++ b/test/Docbook/basic/htmlchunked/htmlchunked_cmd.py
@@ -0,0 +1,55 @@
+#!/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:
diff --git a/test/Docbook/basic/htmlchunked/image/SConstruct.cmd b/test/Docbook/basic/htmlchunked/image/SConstruct.cmd
new file mode 100644
index 00000000..e2406f29
--- /dev/null
+++ b/test/Docbook/basic/htmlchunked/image/SConstruct.cmd
@@ -0,0 +1,3 @@
+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtmlChunked('manual')
+
diff --git a/test/Docbook/basic/htmlhelp/htmlhelp_cmd.py b/test/Docbook/basic/htmlhelp/htmlhelp_cmd.py
new file mode 100644
index 00000000..8e1c1b6b
--- /dev/null
+++ b/test/Docbook/basic/htmlhelp/htmlhelp_cmd.py
@@ -0,0 +1,58 @@
+#!/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:
diff --git a/test/Docbook/basic/htmlhelp/image/SConstruct.cmd b/test/Docbook/basic/htmlhelp/image/SConstruct.cmd
new file mode 100644
index 00000000..29fb4fa6
--- /dev/null
+++ b/test/Docbook/basic/htmlhelp/image/SConstruct.cmd
@@ -0,0 +1,3 @@
+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookHtmlhelp('manual')
+
diff --git a/test/Docbook/basic/man/image/SConstruct.cmd b/test/Docbook/basic/man/image/SConstruct.cmd
new file mode 100644
index 00000000..8b1406b7
--- /dev/null
+++ b/test/Docbook/basic/man/image/SConstruct.cmd
@@ -0,0 +1,3 @@
+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookMan('refdb')
+
diff --git a/test/Docbook/basic/man/man_cmd.py b/test/Docbook/basic/man/man_cmd.py
new file mode 100644
index 00000000..f5127e32
--- /dev/null
+++ b/test/Docbook/basic/man/man_cmd.py
@@ -0,0 +1,56 @@
+#!/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:
diff --git a/test/Docbook/basic/slideshtml/image/SConstruct.cmd b/test/Docbook/basic/slideshtml/image/SConstruct.cmd
new file mode 100644
index 00000000..133cb118
--- /dev/null
+++ b/test/Docbook/basic/slideshtml/image/SConstruct.cmd
@@ -0,0 +1,3 @@
+env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook'])
+env.DocbookSlidesHtml('virt')
+
diff --git a/test/Docbook/basic/slideshtml/slideshtml_cmd.py b/test/Docbook/basic/slideshtml/slideshtml_cmd.py
new file mode 100644
index 00000000..ce5c30ba
--- /dev/null
+++ b/test/Docbook/basic/slideshtml/slideshtml_cmd.py
@@ -0,0 +1,64 @@
+#!/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: