]> granicus.if.org Git - docbook-dsssl/commitdiff
Initial checkin
authorNorman Walsh <ndw@nwalsh.com>
Mon, 2 Apr 2001 13:03:45 +0000 (13:03 +0000)
committerNorman Walsh <ndw@nwalsh.com>
Mon, 2 Apr 2001 13:03:45 +0000 (13:03 +0000)
210 files changed:
xsl/BUGS [new file with mode: 0644]
xsl/Makefile [new file with mode: 0644]
xsl/README.CVS [new file with mode: 0644]
xsl/TODO [new file with mode: 0644]
xsl/VERSION [new file with mode: 0644]
xsl/common/common.xsl [new file with mode: 0644]
xsl/common/gentext.xsl [new file with mode: 0644]
xsl/common/l10n.xml [new file with mode: 0644]
xsl/common/l10n.xsl [new file with mode: 0644]
xsl/common/labels.xsl [new file with mode: 0644]
xsl/common/subtitles.xsl [new file with mode: 0644]
xsl/common/titles.xsl [new file with mode: 0644]
xsl/docsrc/Makefile [new file with mode: 0644]
xsl/docsrc/common/.cvsignore [new file with mode: 0644]
xsl/docsrc/common/Makefile [new file with mode: 0644]
xsl/docsrc/copyright.xml [new file with mode: 0644]
xsl/docsrc/documentation.xml [new file with mode: 0644]
xsl/docsrc/extensions.xml [new file with mode: 0644]
xsl/docsrc/fo/.cvsignore [new file with mode: 0644]
xsl/docsrc/fo/Makefile [new file with mode: 0644]
xsl/docsrc/html/.cvsignore [new file with mode: 0644]
xsl/docsrc/html/Makefile [new file with mode: 0644]
xsl/docsrc/jrefhtml.xsl [new file with mode: 0644]
xsl/docsrc/legalnotice.xml [new file with mode: 0644]
xsl/docsrc/lib/.cvsignore [new file with mode: 0644]
xsl/docsrc/lib/Makefile [new file with mode: 0644]
xsl/docsrc/publishing.xml [new file with mode: 0644]
xsl/docsrc/reference.xml [new file with mode: 0644]
xsl/docsrc/template-example.xml [new file with mode: 0644]
xsl/docsrc/template-example.xsl [new file with mode: 0644]
xsl/docsrc/template/.cvsignore [new file with mode: 0644]
xsl/docsrc/template/Makefile [new file with mode: 0644]
xsl/docsrc/templates.xml [new file with mode: 0644]
xsl/docsrc/warranty.xml [new file with mode: 0644]
xsl/docsrc/xsl2jref.xsl [new file with mode: 0644]
xsl/extensions/.cvsignore [new file with mode: 0644]
xsl/extensions/Makefile [new file with mode: 0644]
xsl/extensions/prj.el [new file with mode: 0644]
xsl/extensions/saxon551/.cvsignore [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/CVS.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/Callout.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/FormatCallout.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/FormatGraphicCallout.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/FormatTextCallout.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/FormatUnicodeCallout.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/Text.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/TextFactory.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/Verbatim.java [new file with mode: 0644]
xsl/extensions/saxon551/com/nwalsh/saxon/package.html [new file with mode: 0644]
xsl/extensions/saxon6/.cvsignore [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/CVS.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/Callout.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/CalloutEmitter.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/ColumnScanEmitter.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/ColumnUpdateEmitter.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/CopyEmitter.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/FormatCallout.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/FormatGraphicCallout.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/FormatTextCallout.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/FormatUnicodeCallout.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/LineCountEmitter.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/NumberLinesEmitter.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/Table.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/Text.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/TextFactory.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/Verbatim.java [new file with mode: 0644]
xsl/extensions/saxon6/com/nwalsh/saxon/package.html [new file with mode: 0644]
xsl/extensions/saxon61/.cvsignore [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/CVS.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/Callout.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/CalloutEmitter.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/ColumnScanEmitter.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/ColumnUpdateEmitter.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/CopyEmitter.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/FormatCallout.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/FormatGraphicCallout.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/FormatTextCallout.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/FormatUnicodeCallout.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/LineCountEmitter.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/NumberLinesEmitter.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/Table.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/Text.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/TextFactory.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/Verbatim.java [new file with mode: 0644]
xsl/extensions/saxon61/com/nwalsh/saxon/package.html [new file with mode: 0644]
xsl/extensions/xalan2/.cvsignore [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/CVS.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/Callout.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/FormatCallout.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/FormatGraphicCallout.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/FormatTextCallout.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/FormatUnicodeCallout.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/Func.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/Params.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/Table.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/Text.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/Verbatim.java [new file with mode: 0644]
xsl/extensions/xalan2/com/nwalsh/xalan/package.html [new file with mode: 0644]
xsl/fo/.cvsignore [new file with mode: 0644]
xsl/fo/Makefile [new file with mode: 0644]
xsl/fo/admon.xsl [new file with mode: 0644]
xsl/fo/autoidx.xsl [new file with mode: 0644]
xsl/fo/autotoc.xsl [new file with mode: 0644]
xsl/fo/biblio.xsl [new file with mode: 0644]
xsl/fo/block.xsl [new file with mode: 0644]
xsl/fo/callout.xsl [new file with mode: 0644]
xsl/fo/component.xsl [new file with mode: 0644]
xsl/fo/division.xsl [new file with mode: 0644]
xsl/fo/docbook.xsl [new file with mode: 0644]
xsl/fo/fo.xsl [new file with mode: 0644]
xsl/fo/footnote.xsl [new file with mode: 0644]
xsl/fo/fop.xsl [new file with mode: 0644]
xsl/fo/formal.xsl [new file with mode: 0644]
xsl/fo/glossary.xsl [new file with mode: 0644]
xsl/fo/graphics.xsl [new file with mode: 0644]
xsl/fo/index.xsl [new file with mode: 0644]
xsl/fo/info.xsl [new file with mode: 0644]
xsl/fo/inline.xsl [new file with mode: 0644]
xsl/fo/keywords.xsl [new file with mode: 0644]
xsl/fo/lists.xsl [new file with mode: 0644]
xsl/fo/math.xsl [new file with mode: 0644]
xsl/fo/pagesetup.xsl [new file with mode: 0644]
xsl/fo/param.xsl [new file with mode: 0644]
xsl/fo/pi.xsl [new file with mode: 0644]
xsl/fo/qandaset.xsl [new file with mode: 0644]
xsl/fo/refentry.xsl [new file with mode: 0644]
xsl/fo/sections.xsl [new file with mode: 0644]
xsl/fo/synop.xsl [new file with mode: 0644]
xsl/fo/table.xsl [new file with mode: 0644]
xsl/fo/titlepage.templates.xml [new file with mode: 0644]
xsl/fo/titlepage.xsl [new file with mode: 0644]
xsl/fo/toc.xsl [new file with mode: 0644]
xsl/fo/verbatim.xsl [new file with mode: 0644]
xsl/fo/xref.xsl [new file with mode: 0644]
xsl/html/.cvsignore [new file with mode: 0644]
xsl/html/Makefile [new file with mode: 0644]
xsl/html/admon.xsl [new file with mode: 0644]
xsl/html/autoidx.xsl [new file with mode: 0644]
xsl/html/autotoc.xsl [new file with mode: 0644]
xsl/html/biblio.xsl [new file with mode: 0644]
xsl/html/block.xsl [new file with mode: 0644]
xsl/html/callout.xsl [new file with mode: 0644]
xsl/html/changebars.xsl [new file with mode: 0644]
xsl/html/chunk-common.xsl [new file with mode: 0644]
xsl/html/chunk.xsl [new file with mode: 0644]
xsl/html/chunker.xsl [new file with mode: 0644]
xsl/html/component.xsl [new file with mode: 0644]
xsl/html/division.xsl [new file with mode: 0644]
xsl/html/docbook.xsl [new file with mode: 0644]
xsl/html/ebnf.xsl [new file with mode: 0644]
xsl/html/footnote.xsl [new file with mode: 0644]
xsl/html/formal.xsl [new file with mode: 0644]
xsl/html/glossary.xsl [new file with mode: 0644]
xsl/html/graphics.xsl [new file with mode: 0644]
xsl/html/html.xsl [new file with mode: 0644]
xsl/html/index.xsl [new file with mode: 0644]
xsl/html/info.xsl [new file with mode: 0644]
xsl/html/inline.xsl [new file with mode: 0644]
xsl/html/keywords.xsl [new file with mode: 0644]
xsl/html/lists.xsl [new file with mode: 0644]
xsl/html/math.xsl [new file with mode: 0644]
xsl/html/param.xsl [new file with mode: 0644]
xsl/html/pi.xsl [new file with mode: 0644]
xsl/html/qandaset.xsl [new file with mode: 0644]
xsl/html/refentry.xsl [new file with mode: 0644]
xsl/html/sections.xsl [new file with mode: 0644]
xsl/html/synop.xsl [new file with mode: 0644]
xsl/html/table.xsl [new file with mode: 0644]
xsl/html/titlepage.templates.xml [new file with mode: 0644]
xsl/html/titlepage.xsl [new file with mode: 0644]
xsl/html/toc.xsl [new file with mode: 0644]
xsl/html/verbatim.xsl [new file with mode: 0644]
xsl/html/xref.xsl [new file with mode: 0644]
xsl/html/xtchunk.xsl [new file with mode: 0644]
xsl/html/xtchunker.xsl [new file with mode: 0644]
xsl/images/callouts/1.png [new file with mode: 0644]
xsl/images/callouts/10.png [new file with mode: 0644]
xsl/images/callouts/2.png [new file with mode: 0644]
xsl/images/callouts/3.png [new file with mode: 0644]
xsl/images/callouts/4.png [new file with mode: 0644]
xsl/images/callouts/5.png [new file with mode: 0644]
xsl/images/callouts/6.png [new file with mode: 0644]
xsl/images/callouts/7.png [new file with mode: 0644]
xsl/images/callouts/8.png [new file with mode: 0644]
xsl/images/callouts/9.png [new file with mode: 0644]
xsl/images/caution.gif [new file with mode: 0644]
xsl/images/caution.png [new file with mode: 0644]
xsl/images/caution.tif [new file with mode: 0644]
xsl/images/home.png [new file with mode: 0644]
xsl/images/important.gif [new file with mode: 0644]
xsl/images/important.png [new file with mode: 0644]
xsl/images/important.tif [new file with mode: 0644]
xsl/images/next.png [new file with mode: 0644]
xsl/images/note.gif [new file with mode: 0644]
xsl/images/note.png [new file with mode: 0644]
xsl/images/note.tif [new file with mode: 0644]
xsl/images/prev.png [new file with mode: 0644]
xsl/images/tip.gif [new file with mode: 0644]
xsl/images/tip.png [new file with mode: 0644]
xsl/images/tip.tif [new file with mode: 0644]
xsl/images/toc-blank.png [new file with mode: 0644]
xsl/images/toc-minus.png [new file with mode: 0644]
xsl/images/toc-plus.png [new file with mode: 0644]
xsl/images/up.png [new file with mode: 0644]
xsl/images/warning.gif [new file with mode: 0644]
xsl/images/warning.png [new file with mode: 0644]
xsl/images/warning.tif [new file with mode: 0644]
xsl/lib/lib.xsl [new file with mode: 0644]
xsl/xhtml/docbook.xsl [new file with mode: 0644]
xsl/xhtml/xtchunk.xsl [new file with mode: 0644]

diff --git a/xsl/BUGS b/xsl/BUGS
new file mode 100644 (file)
index 0000000..5723ffd
--- /dev/null
+++ b/xsl/BUGS
@@ -0,0 +1,6 @@
+The fo stylesheet is probably not in perfect sync with the html stylesheet
+
+Using Equations w/o titles results in incorrectly numbered
+  equations with titles.  Use InformalEquation instead.
+
+The 'char' alignment in tables is not supported
diff --git a/xsl/Makefile b/xsl/Makefile
new file mode 100644 (file)
index 0000000..691f428
--- /dev/null
@@ -0,0 +1,30 @@
+DIFFVER=
+
+.PHONY : distrib clean doc
+
+all:
+       cd html; make
+       cd fo; make
+       cd extensions; make
+       cvs -n update
+
+doc:
+       cd docsrc; make
+       cd doc; make
+
+distrib: all doc
+       dbin/cvs2log -w
+ifeq ($(DIFFVER),)
+       dbin/mergechangelogs > WhatsNew
+else
+       dbin/mergechangelogs -v $(DIFFVER) > WhatsNew
+endif
+
+newversion:
+       dbin/nextversion
+       make DIFFVER=$(DIFFVER) distrib
+
+clean:
+       cd doc; make clean
+       cd test; make clean
+
diff --git a/xsl/README.CVS b/xsl/README.CVS
new file mode 100644 (file)
index 0000000..db102fe
--- /dev/null
@@ -0,0 +1,77 @@
+README.CVS for the DocBook XSL Stylesheets at cvs.docbook.sourceforge.net
+
+These are XSL stylesheets for the DocBook XML DTD. (They would also
+work for the DocBook DTD, modulo certain namecase problems and the
+fact that there aren't any XSL implementations that work with SGML
+source documents.)
+
+CVS Manifest
+------------
+
+README.CVS  this file
+TODO        planned features not yet implemented (may be incomplete :-)
+BUGS        known problems (may also be incomplete :-)
+VERSION     the current version number (note that this is an XSL stylesheet,
+            included by both fo/docbook.xsl and html/docbook.xsl)
+common/            contains code common to both stylesheets
+docsrc/     source files for the stylesheet documentation
+extensions/ Java extension functions
+fo/         stylesheets that produce XSL FO result trees
+html/      stylesheets that produce HTML result trees
+images/     images used by the stylesheets
+lib/        contains schema-independent functions
+xhtml/      stylesheets that produce XHTML result trees
+
+Installation
+------------
+
+*** NOTE: The CVS tree *IS NOT COMPLETE*. In order to run the stylesheets
+directly from the CVS tree, you must checkout several additional trees
+and run some build scripts. This README will be updated to describe how
+sometime real soon now.
+
+Copyright
+---------
+
+Copyright (C) 1999, 2000, 2001 Norman Walsh
+
+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.
+
+Except as contained in this notice, the names of individuals
+credited with contribution to this software shall not be used in
+advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization
+from the individuals in question.
+
+Any stylesheet derived from this Software that is publically
+distributed will be identified with a different name and the
+version strings in any derived Software will be changed so that
+no possibility of confusion between the derived package and this
+Software will exist.
+
+Warranty
+--------
+
+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 NORMAN WALSH OR ANY OTHER
+CONTRIBUTOR 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.
+
+Contacting the Author
+---------------------
+
+These stylesheets are maintained by Norman Walsh, <ndw@nwalsh.com>.
diff --git a/xsl/TODO b/xsl/TODO
new file mode 100644 (file)
index 0000000..526aca8
--- /dev/null
+++ b/xsl/TODO
@@ -0,0 +1,4 @@
+Documentation
+Continued lists
+Bibliography support needs improvement
+
diff --git a/xsl/VERSION b/xsl/VERSION
new file mode 100644 (file)
index 0000000..ac146e1
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+<xsl:variable name="VERSION">1.35</xsl:variable>
+</xsl:stylesheet>
+
diff --git a/xsl/common/common.xsl b/xsl/common/common.xsl
new file mode 100644 (file)
index 0000000..55bf6f3
--- /dev/null
@@ -0,0 +1,919 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     This file contains general templates common to both the HTML and FO
+     versions of the DocBook stylesheets.
+     ******************************************************************** -->
+
+<doc:reference xmlns="">
+<referenceinfo>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<copyright><year>1999</year><year>2000</year>
+<holder>Norman Walsh</holder>
+</copyright>
+</referenceinfo>
+<title>Common Template Reference</title>
+
+<partintro>
+<section><title>Introduction</title>
+
+<para>This is technical reference documentation for the DocBook XSL
+Stylesheets; it documents (some of) the parameters, templates, and
+other elements of the stylesheets.</para>
+
+<para>This is not intended to be <quote>user</quote> documentation.
+It is provided for developers writing customization layers for the
+stylesheets, and for anyone who's interested in <quote>how it
+works</quote>.</para>
+
+<para>Although I am trying to be thorough, this documentation is known
+to be incomplete. Don't forget to read the source, too :-)</para>
+</section>
+</partintro>
+
+</doc:reference>
+
+<!-- ==================================================================== -->
+<!-- Establish strip/preserve whitespace rules -->
+
+<xsl:preserve-space elements="*"/>
+
+<xsl:strip-space elements="
+abstract affiliation anchor answer appendix area areaset areaspec
+artheader article audiodata audioobject author authorblurb authorgroup
+beginpage bibliodiv biblioentry bibliography biblioset blockquote book
+bookbiblio bookinfo callout calloutlist caption caution chapter
+citerefentry cmdsynopsis co collab colophon colspec confgroup
+copyright dedication docinfo editor entry entrytbl epigraph equation
+example figure footnote footnoteref formalpara funcprototype
+funcsynopsis glossary glossdef glossdiv glossentry glosslist graphicco
+group highlights imagedata imageobject imageobjectco important index
+indexdiv indexentry indexterm informalequation informalexample
+informalfigure informaltable inlineequation inlinemediaobject
+itemizedlist itermset keycombo keywordset legalnotice listitem lot
+mediaobject mediaobjectco menuchoice msg msgentry msgexplan msginfo
+msgmain msgrel msgset msgsub msgtext note objectinfo
+orderedlist othercredit part partintro preface printhistory procedure
+programlistingco publisher qandadiv qandaentry qandaset question
+refentry reference refmeta refnamediv refsect1 refsect1info refsect2
+refsect2info refsect3 refsect3info refsynopsisdiv refsynopsisdivinfo
+revhistory revision row sbr screenco screenshot sect1 sect1info sect2
+sect2info sect3 sect3info sect4 sect4info sect5 sect5info section
+sectioninfo seglistitem segmentedlist seriesinfo set setindex setinfo
+shortcut sidebar simplelist simplesect spanspec step subject
+subjectset substeps synopfragment table tbody textobject tfoot tgroup
+thead tip toc tocchap toclevel1 toclevel2 toclevel3 toclevel4
+toclevel5 tocpart varargs variablelist varlistentry videodata
+videoobject void warning subjectset
+
+classsynopsis
+constructorsynopsis
+destructorsynopsis
+fieldsynopsis
+methodparam
+methodsynopsis
+ooclass
+ooexception
+oointerface
+simplemsgentry
+"/>
+
+<!-- ====================================================================== -->
+
+<doc:template name="is.component" xmlns="">
+<refpurpose>Tests if a given node is a component-level element</refpurpose>
+
+<refdescription>
+<para>This template returns '1' if the specified node is a component
+(Chapter, Appendix, etc.), and '0' otherwise.</para>
+</refdescription>
+
+<refparameter>
+<variablelist>
+<varlistentry><term>node</term>
+<listitem>
+<para>The node which is to be tested.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</refparameter>
+
+<refreturn>
+<para>This template returns '1' if the specified node is a component
+(Chapter, Appendix, etc.), and '0' otherwise.</para>
+</refreturn>
+</doc:template>
+
+<xsl:template name="is.component">
+  <xsl:param name="node" select="."/>
+  <xsl:choose>
+    <xsl:when test="local-name($node) = 'appendix'
+                    or local-name($node) = 'article'
+                    or local-name($node) = 'chapter'
+                    or local-name($node) = 'preface'
+                    or local-name($node) = 'bibliography'
+                    or local-name($node) = 'glossary'
+                    or local-name($node) = 'index'">1</xsl:when>
+    <xsl:otherwise>0</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<doc:template name="is.section" xmlns="">
+<refpurpose>Tests if a given node is a section-level element</refpurpose>
+
+<refdescription>
+<para>This template returns '1' if the specified node is a section
+(Section, Sect1, Sect2, etc.), and '0' otherwise.</para>
+</refdescription>
+
+<refparameter>
+<variablelist>
+<varlistentry><term>node</term>
+<listitem>
+<para>The node which is to be tested.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</refparameter>
+
+<refreturn>
+<para>This template returns '1' if the specified node is a section
+(Section, Sect1, Sect2, etc.), and '0' otherwise.</para>
+</refreturn>
+</doc:template>
+
+<xsl:template name="is.section">
+  <xsl:param name="node" select="."/>
+  <xsl:choose>
+    <xsl:when test="local-name($node) = 'section'
+                    or local-name($node) = 'sect1'
+                    or local-name($node) = 'sect2'
+                    or local-name($node) = 'sect3'
+                    or local-name($node) = 'sect4'
+                    or local-name($node) = 'sect5'
+                    or local-name($node) = 'refsect1'
+                    or local-name($node) = 'refsect2'
+                    or local-name($node) = 'refsect3'
+                    or local-name($node) = 'simplesect'">1</xsl:when>
+    <xsl:otherwise>0</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<doc:template name="section.level" xmlns="">
+<refpurpose>Returns the hierarchical level of a section.</refpurpose>
+
+<refdescription>
+<para>This template calculates the hierarchical level of a section.
+Hierarchically, components are <quote>top level</quote>, so a
+<sgmltag>sect1</sgmltag> is at level 2, <sgmltag>sect3</sgmltag> is
+at level 3, etc.</para>
+
+<para>Recursive sections are calculated down to the sixth level.</para>
+</refdescription>
+
+<refparameter>
+<variablelist>
+<varlistentry><term>node</term>
+<listitem>
+<para>The section node for which the level should be calculated.
+Defaults to the context node.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</refparameter>
+
+<refreturn>
+<para>The section level, <quote>2</quote>, <quote>3</quote>, etc.
+</para>
+</refreturn>
+</doc:template>
+
+<xsl:template name="section.level">
+  <xsl:param name="node" select="."/>
+  <xsl:choose>
+    <xsl:when test="name($node)='sect1'">2</xsl:when>
+    <xsl:when test="name($node)='sect2'">3</xsl:when>
+    <xsl:when test="name($node)='sect3'">4</xsl:when>
+    <xsl:when test="name($node)='sect4'">5</xsl:when>
+    <xsl:when test="name($node)='sect5'">6</xsl:when>
+    <xsl:when test="name($node)='section'">
+      <xsl:choose>
+        <xsl:when test="$node/../../../../../section">6</xsl:when>
+        <xsl:when test="$node/../../../../section">5</xsl:when>
+        <xsl:when test="$node/../../../section">4</xsl:when>
+        <xsl:when test="$node/../../section">3</xsl:when>
+        <xsl:otherwise>2</xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="name($node)='simplesect'">
+      <xsl:choose>
+        <xsl:when test="$node/../../sect1">3</xsl:when>
+        <xsl:when test="$node/../../sect2">4</xsl:when>
+        <xsl:when test="$node/../../sect3">5</xsl:when>
+        <xsl:when test="$node/../../sect4">6</xsl:when>
+        <xsl:when test="$node/../../sect5">6</xsl:when>
+        <xsl:when test="$node/../../section">
+          <xsl:choose>
+            <xsl:when test="$node/../../../../../section">6</xsl:when>
+            <xsl:when test="$node/../../../../section">5</xsl:when>
+            <xsl:when test="$node/../../../section">4</xsl:when>
+            <xsl:otherwise>3</xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise>2</xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>2</xsl:otherwise>
+  </xsl:choose>
+</xsl:template><!-- section.level -->
+
+<doc:template name="qanda.section.level" xmlns="">
+<refpurpose>Returns the hierarchical level of a QandASet.</refpurpose>
+
+<refdescription>
+<para>This template calculates the hierarchical level of a QandASet.
+</para>
+</refdescription>
+
+<refreturn>
+<para>The level, <quote>1</quote>, <quote>2</quote>, etc.
+</para>
+</refreturn>
+</doc:template>
+
+<xsl:template name="qanda.section.level">
+  <xsl:variable name="section"
+                select="(ancestor::section
+                         |ancestor::simplesect
+                         |ancestor::sect5
+                         |ancestor::sect4
+                         |ancestor::sect3
+                         |ancestor::sect2
+                         |ancestor::sect1
+                         |ancestor::refsect3
+                         |ancestor::refsect2
+                         |ancestor::refsect1)[last()]"/>
+  <xsl:choose>
+    <xsl:when test="count($section) = '0'">1</xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="section.level">
+        <xsl:with-param name="node" select="$section"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="qandadiv.section.level">
+  <xsl:variable name="section.level">
+    <xsl:call-template name="qanda.section.level"/>
+  </xsl:variable>
+  <xsl:variable name="anc.divs" select="ancestor::qandadiv"/>
+
+  <xsl:value-of select="count($anc.divs) + number($section.level)"/>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<xsl:template name="object.id">
+  <xsl:param name="object" select="."/>
+  <xsl:choose>
+    <xsl:when test="$object/@id">
+      <xsl:value-of select="$object/@id"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="generate-id($object)"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="person.name">
+  <!-- Return a formatted string representation of the contents of
+       the specified node (by default, the current element).
+       Handles Honorific, FirstName, SurName, and Lineage.
+       If %author-othername-in-middle% is #t, also OtherName
+       Handles *only* the first of each.
+       Format is "Honorific. FirstName [OtherName] SurName, Lineage"
+  -->
+  <xsl:param name="node" select="."/>
+
+  <xsl:choose>
+    <!-- handle corpauthor as a special case...-->
+    <xsl:when test="name($node)='corpauthor'">
+      <xsl:apply-templates select="$node"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="h_nl" select="$node//honorific[1]"/>
+      <xsl:variable name="f_nl" select="$node//firstname[1]"/>
+      <xsl:variable name="o_nl" select="$node//othername[1]"/>
+      <xsl:variable name="s_nl" select="$node//surname[1]"/>
+      <xsl:variable name="l_nl" select="$node//lineage[1]"/>
+
+      <xsl:variable name="has_h" select="$h_nl"/>
+      <xsl:variable name="has_f" select="$f_nl"/>
+      <xsl:variable name="has_o"
+                    select="$o_nl and ($author.othername.in.middle != 0)"/>
+      <xsl:variable name="has_s" select="$s_nl"/>
+      <xsl:variable name="has_l" select="$l_nl"/>
+
+      <xsl:if test="$has_h">
+        <xsl:value-of select="$h_nl"/>.
+      </xsl:if>
+
+      <xsl:if test="$has_f">
+        <xsl:if test="$has_h"><xsl:text> </xsl:text></xsl:if>
+        <xsl:value-of select="$f_nl"/>
+      </xsl:if>
+
+      <xsl:if test="$has_o">
+        <xsl:if test="$has_h or $has_f"><xsl:text> </xsl:text></xsl:if>
+        <xsl:value-of select="$o_nl"/>
+      </xsl:if>
+
+      <xsl:if test="$has_s">
+        <xsl:if test="$has_h or $has_f or $has_o">
+          <xsl:text> </xsl:text>
+        </xsl:if>
+        <xsl:value-of select="$s_nl"/>
+      </xsl:if>
+
+      <xsl:if test="$has_l">
+        <xsl:text>, </xsl:text>
+        <xsl:value-of select="$l_nl"/>
+      </xsl:if>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template> <!-- person.name -->
+
+<xsl:template name="person.name.list">
+  <!-- Return a formatted string representation of the contents of
+       the current element. The current element must contain one or
+       more AUTHORs, CORPAUTHORs, OTHERCREDITs, and/or EDITORs.
+
+       John Doe
+     or
+       John Doe and Jane Doe
+     or
+       John Doe, Jane Doe, and A. Nonymous
+  -->
+  <xsl:param name="person.list"
+             select="./author|./corpauthor|./othercredit|./editor"/>
+  <xsl:param name="person.count" select="count($person.list)"/>
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count &gt; $person.count"></xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="person.name">
+        <xsl:with-param name="node" select="$person.list[position()=$count]"/>
+      </xsl:call-template>
+
+      <xsl:choose>
+        <xsl:when test="$person.count = 2 and $count = 1">
+          <xsl:call-template name="gentext.template">
+            <xsl:with-param name="context" select="'authorgroup'"/>
+            <xsl:with-param name="name" select="'sep2'"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:when test="$person.count &gt; 2 and $count+1 = $person.count">
+          <xsl:call-template name="gentext.template">
+            <xsl:with-param name="context" select="'authorgroup'"/>
+            <xsl:with-param name="name" select="'seplast'"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:when test="$count &lt; $person.count">
+          <xsl:call-template name="gentext.template">
+            <xsl:with-param name="context" select="'authorgroup'"/>
+            <xsl:with-param name="name" select="'sep'"/>
+          </xsl:call-template>
+        </xsl:when>
+      </xsl:choose>
+
+      <xsl:call-template name="person.name.list">
+        <xsl:with-param name="person.list" select="$person.list"/>
+        <xsl:with-param name="person.count" select="$person.count"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template><!-- person.name.list -->
+
+<!-- === synopsis ======================================================= -->
+<!-- The following definitions match those given in the reference
+     documentation for DocBook V3.0
+-->
+
+<xsl:variable name="arg.choice.opt.open.str">[</xsl:variable>
+<xsl:variable name="arg.choice.opt.close.str">]</xsl:variable>
+<xsl:variable name="arg.choice.req.open.str">{</xsl:variable>
+<xsl:variable name="arg.choice.req.close.str">}</xsl:variable>
+<xsl:variable name="arg.choice.plain.open.str"><xsl:text> </xsl:text></xsl:variable>
+<xsl:variable name="arg.choice.plain.close.str"><xsl:text> </xsl:text></xsl:variable>
+<xsl:variable name="arg.choice.def.open.str">[</xsl:variable>
+<xsl:variable name="arg.choice.def.close.str">]</xsl:variable>
+<xsl:variable name="arg.rep.repeat.str">...</xsl:variable>
+<xsl:variable name="arg.rep.norepeat.str"></xsl:variable>
+<xsl:variable name="arg.rep.def.str"></xsl:variable>
+<xsl:variable name="arg.or.sep"> | </xsl:variable>
+<xsl:variable name="cmdsynopsis.hanging.indent">4pi</xsl:variable>
+
+<!-- ====================================================================== -->
+
+<!--
+<xsl:template name="xref.g.subst">
+  <xsl:param name="string"></xsl:param>
+  <xsl:param name="target" select="."/>
+  <xsl:variable name="subst">%g</xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="contains($string, $subst)">
+      <xsl:value-of select="substring-before($string, $subst)"/>
+      <xsl:call-template name="gentext.element.name">
+        <xsl:with-param name="element.name" select="name($target)"/>
+      </xsl:call-template>
+      <xsl:call-template name="xref.g.subst">
+        <xsl:with-param name="string"
+                        select="substring-after($string, $subst)"/>
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$string"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="xref.t.subst">
+  <xsl:param name="string"></xsl:param>
+  <xsl:param name="target" select="."/>
+  <xsl:variable name="subst">%t</xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="contains($string, $subst)">
+      <xsl:call-template name="xref.g.subst">
+        <xsl:with-param name="string"
+                        select="substring-before($string, $subst)"/>
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+      <xsl:call-template name="title.xref">
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+      <xsl:call-template name="xref.t.subst">
+        <xsl:with-param name="string"
+                        select="substring-after($string, $subst)"/>
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="xref.g.subst">
+        <xsl:with-param name="string" select="$string"/>
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="xref.n.subst">
+  <xsl:param name="string"></xsl:param>
+  <xsl:param name="target" select="."/>
+  <xsl:variable name="subst">%n</xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="contains($string, $subst)">
+      <xsl:call-template name="xref.t.subst">
+        <xsl:with-param name="string"
+                        select="substring-before($string, $subst)"/>
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+      <xsl:call-template name="number.xref">
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+      <xsl:call-template name="xref.t.subst">
+        <xsl:with-param name="string"
+                        select="substring-after($string, $subst)"/>
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="xref.t.subst">
+        <xsl:with-param name="string" select="$string"/>
+        <xsl:with-param name="target" select="$target"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="subst.xref.text">
+  <xsl:param name="xref.text"></xsl:param>
+  <xsl:param name="target" select="."/>
+
+  <xsl:call-template name="xref.n.subst">
+    <xsl:with-param name="string" select="$xref.text"/>
+    <xsl:with-param name="target" select="$target"/>
+  </xsl:call-template>
+</xsl:template>
+-->
+
+<!-- ====================================================================== -->
+
+<xsl:template name="filename-basename">
+  <!-- We assume all filenames are really URIs and use "/" -->
+  <xsl:param name="filename"></xsl:param>
+  <xsl:param name="recurse" select="false()"/>
+
+  <xsl:choose>
+    <xsl:when test="substring-after($filename, '/') != ''">
+      <xsl:call-template name="filename-basename">
+        <xsl:with-param name="filename"
+                        select="substring-after($filename, '/')"/>
+        <xsl:with-param name="recurse" select="true()"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$filename"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="filename-extension">
+  <xsl:param name="filename"></xsl:param>
+  <xsl:param name="recurse" select="false()"/>
+
+  <!-- Make sure we only look at the base name... -->
+  <xsl:variable name="basefn">
+    <xsl:choose>
+      <xsl:when test="$recurse">
+        <xsl:value-of select="$filename"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="filename-basename">
+          <xsl:with-param name="filename" select="$filename"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="substring-after($basefn, '.') != ''">
+      <xsl:call-template name="filename-extension">
+        <xsl:with-param name="filename"
+                        select="substring-after($basefn, '.')"/>
+        <xsl:with-param name="recurse" select="true()"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$recurse">
+      <xsl:value-of select="$basefn"/>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<doc:template name="select.mediaobject" xmlns="">
+<refpurpose>Selects an appropriate media object from a list</refpurpose>
+
+<refdescription>
+<para>This template examines a list of media objects (usually the
+children of a mediaobject or inlinemediaobject) and processes
+the "right" object.</para>
+
+<para>This template relies on a template named "is.acceptable.mediaobject"
+to determine if a given object is an acceptable graphic. The semantics
+of media objects is that the first acceptable graphic should be used.
+</para>
+
+<para>If no acceptable object is located, nothing happens.</para>
+</refdescription>
+
+<refparameter>
+<variablelist>
+<varlistentry><term>olist</term>
+<listitem>
+<para>The node list of potential objects to examine.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</refparameter>
+
+<refreturn>
+<para>Calls &lt;xsl:apply-templates&gt; on the selected object.</para>
+</refreturn>
+</doc:template>
+
+<xsl:template name="select.mediaobject">
+  <xsl:param name="olist"
+             select="imageobject|imageobjectco
+                     |videoobject|audioobject|textobject"/>
+  <xsl:param name="count">1</xsl:param>
+
+  <xsl:if test="$count &lt;= count($olist)">
+    <xsl:variable name="object" select="$olist[position()=$count]"/>
+
+    <xsl:variable name="useobject">
+      <xsl:choose>
+       <!-- The phrase is never used -->
+        <xsl:when test="name($object)='textobject' and $object/phrase">
+          <xsl:text>0</xsl:text>
+        </xsl:when>
+       <!-- The first textobject is a reasonable fallback -->
+        <xsl:when test="name($object)='textobject'">
+          <xsl:text>1</xsl:text>
+        </xsl:when>
+       <!-- If there's only one object, use it -->
+       <xsl:when test="$count = 1 and count($olist) = 1">
+         <xsl:text>1</xsl:text>
+       </xsl:when>
+       <!-- Otherwise, see if this one is a useable graphic -->
+        <xsl:otherwise>
+          <xsl:choose>
+            <!-- peek inside imageobjectco to simplify the test -->
+            <xsl:when test="local-name($object) = 'imageobjectco'">
+              <xsl:call-template name="is.acceptable.mediaobject">
+                <xsl:with-param name="object" select="$object/imageobject"/>
+              </xsl:call-template>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:call-template name="is.acceptable.mediaobject">
+                <xsl:with-param name="object" select="$object"/>
+              </xsl:call-template>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$useobject='1'">
+        <xsl:apply-templates select="$object"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="select.mediaobject">
+          <xsl:with-param name="olist" select="$olist"/>
+          <xsl:with-param name="count" select="$count + 1"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:if>
+</xsl:template>
+
+<doc:template name="is.acceptable.mediaobject" xmlns="">
+<refpurpose>Returns '1' if the specified media object is recognized.</refpurpose>
+
+<refdescription>
+<para>This template examines a media object and returns '1' if the
+object is recognized as a graphic.</para>
+</refdescription>
+
+<refparameter>
+<variablelist>
+<varlistentry><term>object</term>
+<listitem>
+<para>The media object to consider.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</refparameter>
+
+<refreturn>
+<para>0 or 1</para>
+</refreturn>
+</doc:template>
+
+<xsl:template name="is.acceptable.mediaobject">
+  <xsl:param name="object"></xsl:param>
+
+  <xsl:variable name="filename">
+    <xsl:call-template name="mediaobject.filename">
+      <xsl:with-param name="object" select="$object"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:variable name="ext">
+    <xsl:call-template name="filename-extension">
+      <xsl:with-param name="filename" select="$filename"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <!-- there will only be one -->
+  <xsl:variable name="data" select="$object/videodata
+                                    |$object/imagedata
+                                    |$object/audiodata"/>
+
+  <xsl:variable name="format" select="$data/@format"/>
+
+  <xsl:variable name="graphic.format">
+    <xsl:if test="$format">
+      <xsl:call-template name="is.graphic.format">
+        <xsl:with-param name="format" select="$format"/>
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:variable name="graphic.ext">
+    <xsl:if test="$ext">
+      <xsl:call-template name="is.graphic.extension">
+        <xsl:with-param name="ext" select="$ext"/>
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$graphic.format = '1'">1</xsl:when>
+    <xsl:when test="$graphic.ext = '1'">1</xsl:when>
+    <xsl:otherwise>0</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="is.graphic.format">
+  <xsl:param name="format"></xsl:param>
+  <xsl:if test="$format = 'PNG'
+                or $format = 'JPG'
+                or $format = 'JPEG'
+                or $format = 'linespecific'
+                or $format = 'GIF'
+                or $format = 'GIF87a'
+                or $format = 'GIF89a'
+                or $format = 'BMP'">1</xsl:if>
+</xsl:template>
+
+<xsl:template name="is.graphic.extension">
+  <xsl:param name="ext"></xsl:param>
+  <xsl:if test="$ext = 'png'
+                or $ext = 'jpeg'
+                or $ext = 'jpg'
+                or $ext = 'avi'
+                or $ext = 'mpg'
+                or $ext = 'mpeg'
+                or $ext = 'qt'
+                or $ext = 'gif'
+                or $ext = 'bmp'">1</xsl:if>
+</xsl:template>
+
+<xsl:template name="mediaobject.filename">
+  <xsl:param name="object"></xsl:param>
+
+  <xsl:variable name="data" select="$object/videodata
+                                    |$object/imagedata
+                                    |$object/audiodata"/>
+
+  <xsl:variable name="filename">
+    <xsl:choose>
+      <xsl:when test="$data[@fileref]">
+        <xsl:value-of select="$data/@fileref"/>
+      </xsl:when>
+      <xsl:when test="$data[@entityref]">
+        <xsl:value-of select="unparsed-entity-uri($data/@entityref)"/>
+      </xsl:when>
+      <xsl:otherwise></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="has.ext" select="contains($filename, '.') != ''"/>
+
+  <xsl:variable name="ext">
+    <xsl:choose>
+      <xsl:when test="contains($filename, '.')">
+        <xsl:call-template name="filename-extension">
+          <xsl:with-param name="filename" select="$filename"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$graphic.default.extension"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="graphic.ext">
+    <xsl:call-template name="is.graphic.extension">
+      <xsl:with-param name="ext" select="$ext"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="not($has.ext)">
+      <xsl:choose>
+        <xsl:when test="$ext != ''">
+          <xsl:value-of select="$filename"/>
+          <xsl:text>.</xsl:text>
+          <xsl:value-of select="$ext"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$filename"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="not($graphic.ext)">
+      <xsl:choose>
+        <xsl:when test="$graphic.default.extension != ''">
+          <xsl:value-of select="$filename"/>
+          <xsl:text>.</xsl:text>
+          <xsl:value-of select="$graphic.default.extension"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$filename"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$filename"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<doc:template name="check.id.unique" xmlns="">
+<refpurpose>Warn users about references to non-unique IDs</refpurpose>
+<refdescription>
+<para>If passed an ID in <varname>linkend</varname>,
+<function>check.id.unique</function> prints
+a warning message to the user if either the ID does not exist or
+the ID is not unique.</para>
+</refdescription>
+</doc:template>
+
+<xsl:template name="check.id.unique">
+  <xsl:param name="linkend"></xsl:param>
+  <xsl:if test="$linkend != ''">
+    <xsl:variable name="targets" select="id($linkend)"/>
+    <xsl:variable name="target" select="$targets[1]"/>
+
+    <xsl:if test="count($targets)=0">
+      <xsl:message>
+       <xsl:text>Error: no ID for constraint linkend: </xsl:text>
+       <xsl:value-of select="$linkend"/>
+       <xsl:text>.</xsl:text>
+      </xsl:message>
+      <!--
+      <xsl:message>
+       <xsl:text>If the ID exists in your document, did your </xsl:text>
+        <xsl:text>XSLT Processor load the DTD?</xsl:text>
+      </xsl:message>
+      -->
+    </xsl:if>
+
+    <xsl:if test="count($targets)>1">
+      <xsl:message>
+       <xsl:text>Warning: multiple "IDs" for constraint linkend: </xsl:text>
+       <xsl:value-of select="$linkend"/>
+       <xsl:text>.</xsl:text>
+      </xsl:message>
+    </xsl:if>
+  </xsl:if>
+</xsl:template>
+
+<doc:template name="check.idref.targets" xmlns="">
+<refpurpose>Warn users about incorrectly typed references</refpurpose>
+<refdescription>
+<para>If passed an ID in <varname>linkend</varname>,
+<function>check.idref.targets</function> makes sure that the element
+pointed to by the link is one of the elements listed in
+<varname>element-list</varname> and warns the user otherwise.</para>
+</refdescription>
+</doc:template>
+
+<xsl:template name="check.idref.targets">
+  <xsl:param name="linkend"></xsl:param>
+  <xsl:param name="element-list"></xsl:param>
+  <xsl:if test="$linkend != ''">
+    <xsl:variable name="targets" select="id($linkend)"/>
+    <xsl:variable name="target" select="$targets[1]"/>
+
+    <xsl:if test="count($target) &gt; 0">
+      <xsl:if test="not(contains(concat(' ', $element-list, ' '), name($target)))">
+       <xsl:message>
+         <xsl:text>Error: linkend (</xsl:text>
+         <xsl:value-of select="$linkend"/>
+         <xsl:text>) points to "</xsl:text>
+         <xsl:value-of select="name($target)"/>
+         <xsl:text>" not (one of): </xsl:text>
+         <xsl:value-of select="$element-list"/>
+       </xsl:message>
+      </xsl:if>
+    </xsl:if>
+  </xsl:if>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/common/gentext.xsl b/xsl/common/gentext.xsl
new file mode 100644 (file)
index 0000000..847032e
--- /dev/null
@@ -0,0 +1,335 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ============================================================ -->
+
+<xsl:template match="*" mode="object.title.template">
+  <xsl:call-template name="gentext.template">
+    <xsl:with-param name="context" select="'title'"/>
+    <xsl:with-param name="name" select="local-name(.)"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="section|sect1|sect2|sect3|sect4|sect5|simplesect"
+              mode="object.title.template">
+  <xsl:choose>
+    <xsl:when test="$section.autolabel != 0">
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'section-title-numbered'"/>
+        <xsl:with-param name="name" select="local-name(.)"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'section-title'"/>
+        <xsl:with-param name="name" select="local-name(.)"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template match="*" mode="object.subtitle.template">
+  <xsl:call-template name="gentext.template">
+    <xsl:with-param name="context" select="'subtitle'"/>
+    <xsl:with-param name="name" select="local-name(.)"/>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template match="*" mode="object.xref.template">
+  <xsl:call-template name="gentext.template">
+    <xsl:with-param name="context" select="'xref'"/>
+    <xsl:with-param name="name" select="local-name(.)"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="section|simplesect
+                     |sect1|sect2|sect3|sect4|sect5
+                     |refsect1|refsect2|refsect3"
+              mode="object.xref.template">
+  <xsl:choose>
+    <xsl:when test="$section.autolabel != 0">
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'section-xref-numbered'"/>
+        <xsl:with-param name="name" select="local-name(.)"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'section-xref'"/>
+        <xsl:with-param name="name" select="local-name(.)"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template match="*" mode="object.title.markup">
+  <xsl:variable name="template">
+    <xsl:apply-templates select="." mode="object.title.template"/>
+  </xsl:variable>
+
+  <xsl:call-template name="substitute-markup">
+    <xsl:with-param name="allow-anchors" select="1"/>
+    <xsl:with-param name="template" select="$template"/>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template match="*" mode="object.subtitle.markup">
+  <xsl:variable name="template">
+    <xsl:apply-templates select="." mode="object.subtitle.template"/>
+  </xsl:variable>
+
+  <xsl:call-template name="substitute-markup">
+    <xsl:with-param name="template" select="$template"/>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template match="*" mode="object.xref.markup">
+  <xsl:variable name="template">
+    <xsl:apply-templates select="." mode="object.xref.template"/>
+  </xsl:variable>
+
+  <xsl:message>
+    <xsl:text>object.xref.markup: </xsl:text>
+    <xsl:value-of select="local-name(.)"/>
+    <xsl:text>: </xsl:text>
+    <xsl:value-of select="$template"/>
+  </xsl:message>
+
+  <xsl:call-template name="substitute-markup">
+    <xsl:with-param name="template" select="$template"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="section|simplesect
+                     |sect1|sect2|sect3|sect4|sect5
+                     |refsect1|refsect2|refsect3"
+              mode="object.xref.markup">
+  <xsl:variable name="template">
+    <xsl:apply-templates select="." mode="object.xref.template"/>
+  </xsl:variable>
+
+  <xsl:message>
+    <xsl:text>object.xref.markup: </xsl:text>
+    <xsl:value-of select="local-name(.)"/>
+    <xsl:text>: </xsl:text>
+    <xsl:value-of select="$template"/>
+  </xsl:message>
+
+  <xsl:call-template name="substitute-markup">
+    <xsl:with-param name="template" select="$template"/>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template name="substitute-markup">
+  <xsl:param name="template" select="''"/>
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="bef-n" select="substring-before($template, '%n')"/>
+  <xsl:variable name="bef-s" select="substring-before($template, '%s')"/>
+  <xsl:variable name="bef-t" select="substring-before($template, '%t')"/>
+
+  <xsl:choose>
+    <!-- n=1 -->
+    <xsl:when test="starts-with($template, '%n')">
+      <xsl:apply-templates select="." mode="label.markup"/>
+      <xsl:call-template name="substitute-markup">
+        <xsl:with-param name="template"
+                        select="substring-after($template, '%n')"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- t=1 -->
+    <xsl:when test="starts-with($template, '%t')">
+      <xsl:apply-templates select="." mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+      <xsl:call-template name="substitute-markup">
+        <xsl:with-param name="template"
+                        select="substring-after($template, '%t')"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- s=1 -->
+    <xsl:when test="starts-with($template, '%s')">
+      <xsl:apply-templates select="." mode="subtitle.content"/>
+      <xsl:call-template name="substitute-markup">
+        <xsl:with-param name="template"
+                        select="substring-after($template, '%s')"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- n and t and s -->
+    <xsl:when test="contains($template, '%n')
+                    and contains($template, '%t')
+                    and contains($template, '%s')">
+      <xsl:choose>
+        <!-- n is first -->
+        <xsl:when test="string-length($bef-n) &lt; string-length($bef-s)
+                        and string-length($bef-n) &lt; string-length($bef-t)">
+          <xsl:value-of select="$bef-n"/>
+          <xsl:apply-templates select="." mode="label.markup"/>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%n')"/>
+          </xsl:call-template>
+        </xsl:when>
+        <!-- s is first -->
+        <xsl:when test="string-length($bef-s) &lt; string-length($bef-n)
+                        and string-length($bef-s) &lt; string-length($bef-t)">
+          <xsl:value-of select="$bef-s"/>
+          <xsl:apply-templates select="." mode="subtitle.content"/>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%s')"/>
+          </xsl:call-template>
+        </xsl:when>
+        <!-- t must be first -->
+        <xsl:otherwise>
+          <xsl:value-of select="$bef-t"/>
+          <xsl:apply-templates select="." mode="title.markup">
+            <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+          </xsl:apply-templates>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%t')"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <!-- n and t -->
+    <xsl:when test="contains($template, '%n')
+                    and contains($template, '%t')">
+      <xsl:choose>
+        <!-- n is first -->
+        <xsl:when test="string-length($bef-n) &lt; string-length($bef-t)">
+          <xsl:value-of select="$bef-n"/>
+          <xsl:apply-templates select="." mode="label.markup"/>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%n')"/>
+          </xsl:call-template>
+        </xsl:when>
+        <!-- t is first -->
+        <xsl:otherwise>
+          <xsl:value-of select="$bef-t"/>
+          <xsl:apply-templates select="." mode="title.markup">
+            <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+          </xsl:apply-templates>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%t')"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <!-- n and s -->
+    <xsl:when test="contains($template, '%n')
+                    and contains($template, '%s')">
+      <xsl:choose>
+        <!-- n is first -->
+        <xsl:when test="string-length($bef-n) &lt; string-length($bef-s)">
+          <xsl:value-of select="$bef-n"/>
+          <xsl:apply-templates select="." mode="label.markup"/>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%n')"/>
+          </xsl:call-template>
+        </xsl:when>
+        <!-- s is first -->
+        <xsl:otherwise>
+          <xsl:value-of select="$bef-s"/>
+          <xsl:apply-templates select="." mode="subtitle.content"/>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%s')"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <!-- t and s -->
+    <xsl:when test="contains($template, '%t')
+                    and contains($template, '%s')">
+      <xsl:choose>
+        <!-- t is first -->
+        <xsl:when test="string-length($bef-t) &lt; string-length($bef-s)">
+          <xsl:value-of select="$bef-t"/>
+          <xsl:apply-templates select="." mode="title.markup">
+            <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+          </xsl:apply-templates>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%t')"/>
+          </xsl:call-template>
+        </xsl:when>
+        <!-- s is first -->
+        <xsl:otherwise>
+          <xsl:value-of select="$bef-s"/>
+          <xsl:apply-templates select="." mode="subtitle.content"/>
+          <xsl:call-template name="substitute-markup">
+            <xsl:with-param name="template"
+                            select="substring-after($template, '%s')"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <!-- n -->
+    <xsl:when test="contains($template, '%n')">
+      <xsl:value-of select="$bef-n"/>
+      <xsl:apply-templates select="." mode="label.markup"/>
+      <xsl:call-template name="substitute-markup">
+        <xsl:with-param name="template"
+                        select="substring-after($template, '%n')"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- t -->
+    <xsl:when test="contains($template, '%t')">
+      <xsl:value-of select="$bef-t"/>
+      <xsl:apply-templates select="." mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+      <xsl:call-template name="substitute-markup">
+        <xsl:with-param name="template"
+                        select="substring-after($template, '%t')"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- s -->
+    <xsl:when test="contains($template, '%s')">
+      <xsl:value-of select="$bef-s"/>
+      <xsl:apply-templates select="." mode="subtitle.content"/>
+      <xsl:call-template name="substitute-markup">
+        <xsl:with-param name="template"
+                        select="substring-after($template, '%s')"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- neither n nor t nor s -->
+    <xsl:otherwise>
+      <xsl:value-of select="$template"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/common/l10n.xml b/xsl/common/l10n.xml
new file mode 100644 (file)
index 0000000..a7ef90e
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version='1.0'?>
+<!DOCTYPE internationalization SYSTEM "l10n.dtd" [
+<!ENTITY ca SYSTEM "ca.xml">
+<!ENTITY cs SYSTEM "cs.xml">
+<!ENTITY da SYSTEM "da.xml">
+<!ENTITY de SYSTEM "de.xml">
+<!ENTITY el SYSTEM "el.xml">
+<!ENTITY en SYSTEM "en.xml">
+<!ENTITY es SYSTEM "es.xml">
+<!ENTITY et SYSTEM "et.xml">
+<!ENTITY fi SYSTEM "fi.xml">
+<!ENTITY fr SYSTEM "fr.xml">
+<!ENTITY hu SYSTEM "hu.xml">
+<!ENTITY id SYSTEM "id.xml">
+<!ENTITY it SYSTEM "it.xml">
+<!ENTITY ja SYSTEM "ja.xml">
+<!ENTITY ko SYSTEM "ko.xml">
+<!ENTITY nl SYSTEM "nl.xml">
+<!ENTITY no SYSTEM "no.xml">
+<!ENTITY pl SYSTEM "pl.xml">
+<!ENTITY pt SYSTEM "pt.xml">
+<!ENTITY pt_br SYSTEM "pt_br.xml">
+<!ENTITY ro SYSTEM "ro.xml">
+<!ENTITY ru SYSTEM "ru.xml">
+<!ENTITY sk SYSTEM "sk.xml">
+<!ENTITY sl SYSTEM "sl.xml">
+<!ENTITY sv SYSTEM "sv.xml">
+<!ENTITY zh_cn SYSTEM "zh_cn.xml">
+<!ENTITY zh_tw SYSTEM "zh_tw.xml">
+]>
+<internationalization>
+&ca;
+&cs;
+&da;
+&de;
+&el;
+&en;
+&es;
+&et;
+&fi;
+&fr;
+&hu;
+&id;
+&it;
+&ja;
+&ko;
+&nl;
+&no;
+&pl;
+&pt;
+&pt_br;
+&ro;
+&ru;
+&sk;
+&sl;
+&sv;
+&zh_cn;
+&zh_tw;
+</internationalization>
diff --git a/xsl/common/l10n.xsl b/xsl/common/l10n.xsl
new file mode 100644 (file)
index 0000000..23138ab
--- /dev/null
@@ -0,0 +1,295 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     This file contains localization templates (for internationalization)
+     ******************************************************************** -->
+
+<xsl:param name="l10n.xml" select="document('../common/l10n.xml')"/>
+
+<xsl:param name="l10n.gentext.language" select="''"/>
+<xsl:param name="l10n.gentext.default.language" select="'en'"/>
+<xsl:param name="l10n.gentext.use.xref.language" select="false()"/>
+
+<xsl:template name="l10n.language">
+  <xsl:param name="target" select="."/>
+  <xsl:param name="xref-context" select="false()"/>
+
+  <xsl:variable name="language">
+    <xsl:choose>
+      <xsl:when test="$l10n.gentext.language != ''">
+        <xsl:value-of select="$l10n.gentext.language"/>
+      </xsl:when>
+
+      <xsl:when test="$xref-context or $l10n.gentext.use.xref.language">
+        <xsl:variable name="lang-attr"
+                      select="($target/ancestor-or-self::*/@lang
+                               |$target/ancestor-or-self::*/@xml:lang)[last()]"/>
+        <xsl:choose>
+          <xsl:when test="string($lang-attr) = ''">
+            <xsl:value-of select="$l10n.gentext.default.language"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$lang-attr"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <xsl:variable name="lang-attr" 
+                      select="(ancestor-or-self::*/@lang
+                               |ancestor-or-self::*/@xml:lang)[last()]"/>
+        <xsl:choose>
+          <xsl:when test="string($lang-attr) = ''">
+            <xsl:value-of select="$l10n.gentext.default.language"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$lang-attr"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="contains($language,'-')">
+      <xsl:value-of select="substring-before($language,'-')"/>
+      <xsl:text>_</xsl:text>
+      <xsl:value-of select="substring-after($language,'-')"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$language"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="gentext.xref.text">
+  <xsl:param name="element.name" select="name(.)"/>
+  <xsl:param name="default"></xsl:param>
+  <xsl:param name="lang">
+    <xsl:call-template name="l10n.language"/>
+  </xsl:param>
+
+  <xsl:variable name="l10n.text">
+    <xsl:value-of select="($l10n.xml/internationalization/localization[@language=$lang]/xref[@element=$element.name])[1]/@text"/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$l10n.text=''">
+      <xsl:choose>
+        <xsl:when test="$default=''">
+          <xsl:message>
+            <xsl:text>No "</xsl:text>
+            <xsl:value-of select="$lang"/>
+            <xsl:text>" cross reference text for "</xsl:text>
+            <xsl:value-of select="$element.name"/>
+            <xsl:text>" exists and no default specified.</xsl:text>
+          </xsl:message>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$default"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$l10n.text"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="gentext">
+  <xsl:param name="key" select="local-name(.)"/>
+  <xsl:param name="lang">
+    <xsl:call-template name="l10n.language"/>
+  </xsl:param>
+
+  <xsl:variable name="l10n.gentext"
+                select="($l10n.xml/internationalization/localization[@language=$lang]/gentext[@key=$key])[1]"/>
+
+  <xsl:variable name="l10n.name">
+    <xsl:value-of select="$l10n.gentext/@text"/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="count($l10n.gentext)=0">
+      <xsl:message>
+        <xsl:text>No "</xsl:text>
+        <xsl:value-of select="$lang"/>
+        <xsl:text>" localization of "</xsl:text>
+        <xsl:value-of select="$key"/>
+        <xsl:text>" exists; using "en".</xsl:text>
+      </xsl:message>
+
+      <xsl:value-of select="($l10n.xml/internationalization/localization[@language='en']/gentext[@key=$key])[1]/@text"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$l10n.name"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="gentext.element.name">
+  <xsl:param name="element.name" select="name(.)"/>
+  <xsl:param name="lang">
+    <xsl:call-template name="l10n.language"/>
+  </xsl:param>
+
+  <xsl:call-template name="gentext">
+    <xsl:with-param name="key" select="$element.name"/>
+    <xsl:with-param name="lang" select="$lang"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.space">
+  <xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template name="gentext.edited.by">
+  <xsl:call-template name="gentext.element.name">
+    <xsl:with-param name="element.name">Editedby</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.by">
+  <xsl:call-template name="gentext.element.name">
+    <xsl:with-param name="element.name">by</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.dingbat">
+  <xsl:param name="dingbat">bullet</xsl:param>
+  <xsl:param name="lang">
+    <xsl:call-template name="l10n.language"/>
+  </xsl:param>
+
+  <xsl:variable name="l10n.dingbat">
+    <xsl:value-of select="($l10n.xml/internationalization/localization[@language=$lang]/dingbat[@key=$dingbat])[1]/@text"/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$l10n.dingbat=''">
+      <xsl:message>
+        <xsl:text>No "</xsl:text>
+        <xsl:value-of select="$lang"/>
+        <xsl:text>" localization of dingbat </xsl:text>
+        <xsl:value-of select="$dingbat"/>
+        <xsl:text> exists; using "en".</xsl:text>
+      </xsl:message>
+
+      <xsl:value-of select="($l10n.xml/internationalization/localization[@language='en']/dingbat[@key=$dingbat])[1]/@text"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$l10n.dingbat"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="gentext.startquote">
+  <xsl:call-template name="gentext.dingbat">
+    <xsl:with-param name="dingbat">startquote</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.endquote">
+  <xsl:call-template name="gentext.dingbat">
+    <xsl:with-param name="dingbat">endquote</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.nestedstartquote">
+  <xsl:call-template name="gentext.dingbat">
+    <xsl:with-param name="dingbat">nestedstartquote</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.nestedendquote">
+  <xsl:call-template name="gentext.dingbat">
+    <xsl:with-param name="dingbat">nestedendquote</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.nav.prev">
+  <xsl:call-template name="gentext.element.name">
+    <xsl:with-param name="element.name">nav-prev</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.nav.next">
+  <xsl:call-template name="gentext.element.name">
+    <xsl:with-param name="element.name">nav-next</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.nav.home">
+  <xsl:call-template name="gentext.element.name">
+    <xsl:with-param name="element.name">nav-home</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="gentext.nav.up">
+  <xsl:call-template name="gentext.element.name">
+    <xsl:with-param name="element.name">nav-up</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template name="gentext.template">
+  <xsl:param name="context" select="'default'"/>
+  <xsl:param name="name" select="'default'"/>
+  <xsl:param name="lang">
+    <xsl:call-template name="l10n.language"/>
+  </xsl:param>
+
+  <xsl:variable name="localization.node"
+                select="($l10n.xml/internationalization/localization[@language=$lang])[1]"/>
+
+  <xsl:if test="count($localization.node) = 0">
+    <xsl:message>
+      <xsl:text>No "</xsl:text>
+      <xsl:value-of select="$lang"/>
+      <xsl:text>" localization exists.</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <xsl:variable name="context.node"
+                select="$localization.node/context[@name=$context]"/>
+
+  <xsl:if test="count($context.node) = 0">
+    <xsl:message>
+      <xsl:text>No context named "</xsl:text>
+      <xsl:value-of select="$context"/>
+      <xsl:text>" exists in the "</xsl:text>
+      <xsl:value-of select="$lang"/>
+      <xsl:text>" localization.</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <xsl:variable name="template.node"
+                select="$context.node/template[@name=$name][1]"/>
+
+  <xsl:if test="count($template.node) = 0">
+    <xsl:message>
+      <xsl:text>No template named "</xsl:text>
+      <xsl:value-of select="$name"/>
+      <xsl:text>" exists in the context named "</xsl:text>
+      <xsl:value-of select="$context"/>
+      <xsl:text>" in the "</xsl:text>
+      <xsl:value-of select="$lang"/>
+      <xsl:text>" localization.</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <xsl:value-of select="$template.node/@text"/>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/common/labels.xsl b/xsl/common/labels.xsl
new file mode 100644 (file)
index 0000000..e1b8c6e
--- /dev/null
@@ -0,0 +1,510 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ============================================================ -->
+<!-- label markup -->
+
+<doc:mode mode="label.markup" xmlns="">
+<refpurpose>Provides access to element labels</refpurpose>
+<refdescription>
+<para>Processing an element in the
+<literal role="mode">label.markup</literal> mode produces the
+element label.</para>
+<para>Trailing punctuation is not added to the label.
+</para>
+</refdescription>
+</doc:mode>
+
+<xsl:param name="label.from.part" select="'1'"/>
+
+<xsl:template match="*" mode="intralabel.punctuation">
+  <xsl:text>.</xsl:text>
+</xsl:template>
+
+<xsl:template match="*" mode="label.markup">
+  <xsl:message>
+    <xsl:text>Request for label of unexpected element: </xsl:text>
+    <xsl:value-of select="name(.)"/>
+  </xsl:message>
+</xsl:template>
+
+<xsl:template match="set|book" mode="label.markup">
+  <xsl:if test="@label">
+    <xsl:value-of select="@label"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="part" mode="label.markup">
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$part.autolabel != 0">
+      <xsl:number from="book" count="part" format="I"/>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="preface" mode="label.markup">
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$preface.autolabel != 0">
+      <xsl:choose>
+        <xsl:when test="$label.from.part != 0">
+          <xsl:number from="part" count="preface" format="1" level="any"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:number from="book" count="preface" format="1" level="any"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="chapter" mode="label.markup">
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$chapter.autolabel != 0">
+      <xsl:choose>
+        <xsl:when test="$label.from.part != 0">
+          <xsl:number from="part" count="chapter" format="1" level="any"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:number from="book" count="chapter" format="1" level="any"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="appendix" mode="label.markup">
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$appendix.autolabel != 0">
+      <xsl:choose>
+        <xsl:when test="$label.from.part != 0">
+          <xsl:number from="part" count="appendix" format="A" level="any"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:number from="book" count="appendix" format="A" level="any"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="article" mode="label.markup">
+  <xsl:if test="@label">
+    <xsl:value-of select="@label"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="dedication|colophon" mode="label.markup">
+  <xsl:if test="@label">
+    <xsl:value-of select="@label"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="reference" mode="label.markup">
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$part.autolabel != 0">
+      <xsl:number from="book" count="reference" format="I" level="any"/>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="refentry" mode="label.markup">
+  <xsl:if test="@label">
+    <xsl:value-of select="@label"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="section" mode="label.markup">
+  <!-- if this is a nested section, label the parent -->
+  <xsl:if test="local-name(..) = 'section'">
+    <xsl:variable name="parent.section.label">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+    </xsl:variable>
+    <xsl:if test="$parent.section.label != ''">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+      <xsl:apply-templates select=".." mode="intralabel.punctuation"/>
+    </xsl:if>
+  </xsl:if>
+
+  <!-- if the parent is a component, maybe label that too -->
+  <xsl:variable name="parent.is.component">
+    <xsl:call-template name="is.component">
+      <xsl:with-param name="node" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <!-- does this section get labelled? -->
+  <xsl:variable name="label">
+    <xsl:call-template name="label.this.section">
+      <xsl:with-param name="section" select="."/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:if test="$section.label.includes.component.label != 0
+                and $parent.is.component != 0">
+    <xsl:variable name="parent.label">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+    </xsl:variable>
+    <xsl:if test="$parent.label != ''">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+      <xsl:apply-templates select=".." mode="intralabel.punctuation"/>
+    </xsl:if>
+  </xsl:if>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$label != 0">
+      <xsl:number count="section"/>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="sect1" mode="label.markup">
+  <!-- if the parent is a component, maybe label that too -->
+  <xsl:variable name="parent.is.component">
+    <xsl:call-template name="is.component">
+      <xsl:with-param name="node" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:if test="$section.label.includes.component.label != 0
+                and $parent.is.component">
+    <xsl:variable name="parent.label">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+    </xsl:variable>
+    <xsl:if test="$parent.label != ''">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+      <xsl:apply-templates select=".." mode="intralabel.punctuation"/>
+    </xsl:if>
+  </xsl:if>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$section.autolabel != 0">
+      <xsl:number count="sect1"/>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="sect2|sect3|sect4|sect5" mode="label.markup">
+  <!-- label the parent -->
+  <xsl:variable name="parent.label">
+    <xsl:apply-templates select=".." mode="label.markup"/>
+  </xsl:variable>
+  <xsl:if test="$parent.label != ''">
+    <xsl:apply-templates select=".." mode="label.markup"/>
+    <xsl:apply-templates select=".." mode="intralabel.punctuation"/>
+  </xsl:if>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$section.autolabel != 0">
+      <xsl:choose>
+        <xsl:when test="local-name(.) = 'sect2'">
+         <xsl:number count="sect2"/>
+       </xsl:when>
+       <xsl:when test="local-name(.) = 'sect3'">
+         <xsl:number count="sect3"/>
+       </xsl:when>
+       <xsl:when test="local-name(.) = 'sect4'">
+         <xsl:number count="sect4"/>
+       </xsl:when>
+       <xsl:when test="local-name(.) = 'sect5'">
+         <xsl:number count="sect5"/>
+       </xsl:when>
+       <xsl:otherwise>
+         <xsl:message>label.markup: this can't happen!</xsl:message>
+       </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="refsect1" mode="label.markup">
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$section.autolabel != 0">
+      <xsl:number count="refsect1"/>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="refsect2|refsect3" mode="label.markup">
+  <!-- label the parent -->
+  <xsl:variable name="parent.label">
+    <xsl:apply-templates select=".." mode="label.markup"/>
+  </xsl:variable>
+  <xsl:if test="$parent.label != ''">
+    <xsl:apply-templates select=".." mode="label.markup"/>
+    <xsl:apply-templates select=".." mode="intralabel.punctuation"/>
+  </xsl:if>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$section.autolabel != 0">
+      <xsl:choose>
+        <xsl:when test="local-name(.) = 'refsect2'">
+         <xsl:number count="refsect2"/>
+       </xsl:when>
+        <xsl:otherwise>
+         <xsl:number count="refsect3"/>
+       </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="simplesect" mode="label.markup">
+  <!-- if this is a nested section, label the parent -->
+  <xsl:if test="local-name(..) = 'section'
+                or local-name(..) = 'sect1'
+                or local-name(..) = 'sect2'
+                or local-name(..) = 'sect3'
+                or local-name(..) = 'sect4'
+                or local-name(..) = 'sect5'">
+    <xsl:variable name="parent.section.label">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+    </xsl:variable>
+    <xsl:if test="$parent.section.label != ''">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+      <xsl:apply-templates select=".." mode="intralabel.punctuation"/>
+    </xsl:if>
+  </xsl:if>
+
+  <!-- if the parent is a component, maybe label that too -->
+  <xsl:variable name="parent.is.component">
+    <xsl:call-template name="is.component">
+      <xsl:with-param name="node" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <!-- does this section get labelled? -->
+  <xsl:variable name="label">
+    <xsl:call-template name="label.this.section">
+      <xsl:with-param name="section" select="."/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:if test="$section.label.includes.component.label != 0
+                and $parent.is.component != 0">
+    <xsl:variable name="parent.label">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+    </xsl:variable>
+    <xsl:if test="$parent.label != ''">
+      <xsl:apply-templates select=".." mode="label.markup"/>
+      <xsl:apply-templates select=".." mode="intralabel.punctuation"/>
+    </xsl:if>
+  </xsl:if>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$label != 0">
+      <xsl:number count="simplesect"/>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="qandadiv" mode="label.markup">
+  <xsl:variable name="lparent" select="(ancestor::set
+                                       |ancestor::book
+                                       |ancestor::chapter
+                                       |ancestor::appendix
+                                       |ancestor::preface
+                                       |ancestor::section
+                                       |ancestor::simplesect
+                                       |ancestor::sect1
+                                       |ancestor::sect2
+                                       |ancestor::sect3
+                                       |ancestor::sect4
+                                       |ancestor::sect5
+                                       |ancestor::refsect1
+                                       |ancestor::refsect2
+                                       |ancestor::refsect3)[last()]"/>
+
+  <xsl:variable name="lparent.prefix">
+    <xsl:apply-templates select="$lparent" mode="label.markup"/>
+  </xsl:variable>
+
+  <xsl:variable name="prefix">
+    <xsl:if test="$qanda.inherit.numeration != 0">
+      <xsl:if test="$lparent.prefix != ''">
+        <xsl:apply-templates select="$lparent" mode="label.markup"/>
+        <xsl:apply-templates select="$lparent" mode="intralabel.punctuation"/>
+      </xsl:if>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="$prefix"/>
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:when test="$qandadiv.autolabel != 0">
+      <xsl:value-of select="$prefix"/>
+      <xsl:number level="multiple" count="qandadiv" format="1"/>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="question|answer" mode="label.markup">
+  <xsl:variable name="lparent" select="(ancestor::set
+                                       |ancestor::book
+                                       |ancestor::chapter
+                                       |ancestor::appendix
+                                       |ancestor::preface
+                                       |ancestor::section
+                                       |ancestor::simplesect
+                                       |ancestor::sect1
+                                       |ancestor::sect2
+                                       |ancestor::sect3
+                                       |ancestor::sect4
+                                       |ancestor::sect5
+                                       |ancestor::refsect1
+                                       |ancestor::refsect2
+                                       |ancestor::refsect3)[last()]"/>
+
+  <xsl:variable name="lparent.prefix">
+    <xsl:apply-templates select="$lparent" mode="label.markup"/>
+  </xsl:variable>
+
+  <xsl:variable name="prefix">
+    <xsl:if test="$qanda.inherit.numeration != 0">
+      <xsl:if test="$lparent.prefix != ''">
+        <xsl:apply-templates select="$lparent" mode="label.markup"/>
+        <xsl:apply-templates select="$lparent" mode="intralabel.punctuation"/>
+      </xsl:if>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:variable name="inhlabel"
+                select="ancestor-or-self::qandaset/@defaultlabel[1]"/>
+
+  <xsl:variable name="deflabel">
+    <xsl:choose>
+      <xsl:when test="$inhlabel != ''">
+        <xsl:value-of select="$inhlabel"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$qanda.defaultlabel"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="label" select="label"/>
+
+  <xsl:choose>
+    <xsl:when test="count($label)>0">
+      <xsl:value-of select="$prefix"/>
+      <xsl:apply-templates select="$label"/>
+    </xsl:when>
+
+    <xsl:when test="$deflabel = 'qanda' and local-name(.) = 'question'">
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'Question'"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <xsl:when test="$deflabel = 'qanda' and local-name(.) = 'answer'">
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'Answer'"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <xsl:when test="$deflabel = 'number'">
+      <xsl:if test="name(.) = 'question'">
+        <xsl:value-of select="$prefix"/>
+        <xsl:number level="multiple" count="qandaentry" format="1"/>
+      </xsl:if>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="bibliography|glossary|index" mode="label.markup">
+  <xsl:if test="@label">
+    <xsl:value-of select="@label"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="figure|table|example|equation" mode="label.markup">
+  <xsl:variable name="pchap"
+                select="ancestor::chapter|ancestor::appendix"/>
+
+  <xsl:variable name="prefix">
+    <xsl:if test="count($pchap) &gt; 0">
+      <xsl:apply-templates select="$pchap" mode="label.markup"/>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:choose>
+        <xsl:when test="count($pchap)>0">
+          <xsl:if test="$prefix != ''">
+            <xsl:apply-templates select="$pchap" mode="label.markup"/>
+            <xsl:apply-templates select="$pchap" mode="intralabel.punctuation"/>
+          </xsl:if>
+          <xsl:number format="1" from="chapter|appendix" level="any"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:number format="1" from="book|article" level="any"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="abstract" mode="label.markup">
+  <!-- nop -->
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template name="label.this.section">
+  <xsl:param name="section" select="."/>
+  <xsl:value-of select="$section.autolabel"/>
+</xsl:template>
+
+<doc:template name="label.this.section" xmlns="">
+<refpurpose>Returns true if $section should be labelled</refpurpose>
+<refdescription>
+<para>Returns true if the specified section should be labelled.
+By default, this template simply returns $section.autolabel, but
+custom stylesheets may override it to get more selective behavior.</para>
+</refdescription>
+</doc:template>
+
+<!-- ============================================================ -->
+
+</xsl:stylesheet>
diff --git a/xsl/common/subtitles.xsl b/xsl/common/subtitles.xsl
new file mode 100644 (file)
index 0000000..7c7f2cb
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ============================================================ -->
+<!-- subtitle markup -->
+
+<doc:mode mode="subtitle.markup" xmlns="">
+<refpurpose>Provides access to element subtitles</refpurpose>
+<refdescription>
+<para>Processing an element in the
+<literal role="mode">subtitle.markup</literal> mode produces the
+subtitle of the element.
+</para>
+</refdescription>
+</doc:mode>
+
+<xsl:template match="*" mode="subtitle.markup">
+  <xsl:message>
+    <xsl:text>Request for subtitle of unexpected element: </xsl:text>
+    <xsl:value-of select="name(.)"/>
+  </xsl:message>
+  <xsl:text>???SUBTITLE???</xsl:text>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="set" mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(setinfo/subtitle|subtitle)[1]"
+                       mode="subtitle.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="book" mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(bookinfo/subtitle|subtitle)[1]"
+                       mode="subtitle.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="part" mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(partinfo/subtitle
+                                |docinfo/subtitle
+                                |subtitle)[1]"
+                       mode="subtitle.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="preface|chapter|appendix" mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(docinfo/subtitle
+                                |prefaceinfo/subtitle
+                                |chapterinfo/subtitle
+                                |appendixinfo/subtitle
+                                |subtitle)[1]"
+                       mode="subtitle.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="dedication|colophon" mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="subtitle"
+                       mode="subtitle.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="reference" mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(referenceinfo/subtitle
+                                |docinfo/subtitle
+                                |subtitle)[1]"
+                       mode="subtitle.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="refentry" mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(refentryinfo/subtitle
+                                |docinfo/subtitle)[1]"
+                       mode="subtitle.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="section
+                     |sect1|sect2|sect3|sect4|sect5
+                     |refsect1|refsect2|refsect3
+                     |simplesect"
+              mode="subtitle.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(sectioninfo/subtitle
+                                |sect1info/subtitle
+                                |sect2info/subtitle
+                                |sect3info/subtitle
+                                |sect4info/subtitle
+                                |sect5info/subtitle
+                                |refsect1info/subtitle
+                                |refsect2info/subtitle
+                                |refsect3info/subtitle
+                                |subtitle)[1]"
+                       mode="subtitle.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/common/titles.xsl b/xsl/common/titles.xsl
new file mode 100644 (file)
index 0000000..4af1cc3
--- /dev/null
@@ -0,0 +1,292 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ============================================================ -->
+<!-- title markup -->
+
+<doc:mode mode="title.markup" xmlns="">
+<refpurpose>Provides access to element titles</refpurpose>
+<refdescription>
+<para>Processing an element in the
+<literal role="mode">title.markup</literal> mode produces the
+title of the element. This does not include the label.
+</para>
+</refdescription>
+</doc:mode>
+
+<xsl:template match="*" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:choose>
+    <xsl:when test="title">
+      <xsl:apply-templates select="title[1]" mode="title.markup">
+       <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:when test="local-name(.) = 'partintro'">
+      <!-- partintro's don't have titles, use the parent (part or reference)
+           title instead. -->
+      <xsl:apply-templates select="parent::*" mode="title.markup"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message>
+       <xsl:text>Request for title of unexpected element: </xsl:text>
+       <xsl:value-of select="name(.)"/>
+      </xsl:message>
+      <xsl:text>???TITLE???</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="title" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:choose>
+    <xsl:when test="$allow-anchors != 0">
+      <xsl:apply-templates/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates mode="no.anchor.mode"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="set" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(setinfo/title|title)[1]"
+                       mode="title.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="book" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(bookinfo/title|title)[1]"
+                       mode="title.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="part" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(partinfo/title|docinfo/title|title)[1]"
+                       mode="title.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="preface|chapter|appendix" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="title" select="(docinfo/title
+                                      |prefaceinfo/title
+                                      |chapterinfo/title
+                                      |appendixinfo/title
+                                      |title)[1]"/>
+  <xsl:apply-templates select="$title" mode="title.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="dedication" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:choose>
+    <xsl:when test="title">
+      <xsl:apply-templates select="title" mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'Dedication'"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="colophon" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:choose>
+    <xsl:when test="title">
+      <xsl:apply-templates select="title" mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'Colophon'"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="article" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="title" select="(artheader/title
+                                      |articleinfo/title
+                                      |title)[1]"/>
+
+  <xsl:apply-templates select="$title" mode="title.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="reference" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="(referenceinfo/title|docinfo/title|title)[1]"
+                       mode="title.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="refentry" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="refmeta" select=".//refmeta"/>
+  <xsl:variable name="refentrytitle" select="$refmeta//refentrytitle"/>
+  <xsl:variable name="refnamediv" select=".//refnamediv"/>
+  <xsl:variable name="refname" select="$refnamediv//refname"/>
+
+  <xsl:variable name="title">
+    <xsl:choose>
+      <xsl:when test="$refentrytitle">
+        <xsl:apply-templates select="$refentrytitle[1]" mode="title.markup"/>
+      </xsl:when>
+      <xsl:when test="$refname">
+        <xsl:apply-templates select="$refname[1]" mode="title.markup"/>
+      </xsl:when>
+      <xsl:otherwise>REFENTRY WITHOUT TITLE???</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:copy-of select="$title"/>
+</xsl:template>
+
+<xsl:template match="refentrytitle|refname" mode="title.markup">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="section
+                     |sect1|sect2|sect3|sect4|sect5
+                     |refsect1|refsect2|refsect3
+                     |simplesect"
+              mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="title" select="(sectioninfo/title
+                                      |sect1info/title
+                                      |sect2info/title
+                                      |sect3info/title
+                                      |sect4info/title
+                                      |sect5info/title
+                                      |refsect1info/title
+                                      |refsect2info/title
+                                      |refsect3info/title
+                                      |title)[1]"/>
+
+  <xsl:apply-templates select="$title" mode="title.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="bibliography" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="title" select="(bibliographyinfo/title|title)[1]"/>
+  <xsl:choose>
+    <xsl:when test="$title">
+      <xsl:apply-templates select="$title" mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'Bibliography'"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="glossary" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="title" select="(glossaryinfo/title|title)[1]"/>
+  <xsl:choose>
+    <xsl:when test="$title">
+      <xsl:apply-templates select="$title" mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext.element.name">
+        <xsl:with-param name="element.name" select="name(.)"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="index" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="title" select="(indexinfo/title|title)[1]"/>
+  <xsl:choose>
+    <xsl:when test="$title">
+      <xsl:apply-templates select="$title" mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'Index'"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="figure|table|example|equation" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:apply-templates select="title" mode="title.markup">
+    <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="abstract" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:choose>
+    <xsl:when test="title">
+      <xsl:apply-templates select="title" mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext.element.name">
+        <xsl:with-param name="element.name" select="name(.)"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="caution|tip|warning|important|note" mode="title.markup">
+  <xsl:param name="allow-anchors" select="'0'"/>
+  <xsl:variable name="title" select="title[1]"/>
+  <xsl:choose>
+    <xsl:when test="$title">
+      <xsl:apply-templates select="$title" mode="title.markup">
+        <xsl:with-param name="allow-anchors" select="$allow-anchors"/>
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key">
+          <xsl:choose>
+            <xsl:when test="local-name(.)='note'">Note</xsl:when>
+            <xsl:when test="local-name(.)='important'">Important</xsl:when>
+            <xsl:when test="local-name(.)='caution'">Caution</xsl:when>
+            <xsl:when test="local-name(.)='warning'">Warning</xsl:when>
+            <xsl:when test="local-name(.)='tip'">Tip</xsl:when>
+          </xsl:choose>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/docsrc/Makefile b/xsl/docsrc/Makefile
new file mode 100644 (file)
index 0000000..51a77ed
--- /dev/null
@@ -0,0 +1,6 @@
+all:
+       cd common; make
+       cd lib; make
+       cd html; make
+       cd fo; make
+       cd template; make
diff --git a/xsl/docsrc/common/.cvsignore b/xsl/docsrc/common/.cvsignore
new file mode 100644 (file)
index 0000000..6722cd9
--- /dev/null
@@ -0,0 +1 @@
+*.xml
diff --git a/xsl/docsrc/common/Makefile b/xsl/docsrc/common/Makefile
new file mode 100644 (file)
index 0000000..c91756b
--- /dev/null
@@ -0,0 +1,10 @@
+JSTYLE=../../docsrc/xsl2jref.xsl
+VPATH=../../common
+
+XMLFILES = common.xml
+
+all: $(XMLFILES)
+
+%.xml : %.xsl $(JSTYLE) ../../docsrc/legalnotice.xml
+       saxon -6 $< $(JSTYLE) /dev/null output-file=$@
+       xnsgmls -E 5 -sv -c /share/doctypes/catalog $@
diff --git a/xsl/docsrc/copyright.xml b/xsl/docsrc/copyright.xml
new file mode 100644 (file)
index 0000000..8fac2ef
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice
+  PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+  "http://www.oasis-open.org/xml/4.1.2/docbookx.dtd">
+<legalnotice><title>Copyright</title>
+
+<para>Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the <quote>Software</quote>), 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:
+</para>
+
+<para>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.</para>
+
+<para>Except as contained in this notice, the names of individuals
+credited with contribution to this software shall not be used in
+advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization from the individuals
+in question.</para>
+
+<para>Any stylesheet derived from this Software that is publically
+distributed will be identified with a different name and the version
+strings in any derived Software will be changed so that no possibility
+of confusion between the derived package and this Software will
+exist.</para>
+</legalnotice>
diff --git a/xsl/docsrc/documentation.xml b/xsl/docsrc/documentation.xml
new file mode 100644 (file)
index 0000000..ef46dd8
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE book
+  PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+  "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY reference.xml SYSTEM "reference.xml" NDATA SGML>
+<!ENTITY publishing.xml SYSTEM "publishing.xml">
+<!ENTITY extensions.xml SYSTEM "extensions.xml">
+<!ENTITY templates.xml SYSTEM "templates.xml">
+<!ENTITY html-param.xml SYSTEM "html/param.xml" NDATA SGML>
+]>
+<book>
+<bookinfo>
+<title>DocBook XSL Stylesheet Documentation</title>
+<!-- $Id$ -->
+
+<authorgroup>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<othercredit><surname>Stayton</surname>
+<firstname>Bob</firstname></othercredit>
+</authorgroup>
+
+<copyright><year>1999</year><year>2000</year><year>2001</year>
+<holder>Norman Walsh</holder>
+</copyright>
+</bookinfo>
+
+<preface><title>Preface</title>
+
+<para>This is the beginnings of documentation for the DocBook XSL
+Stylesheets.</para>
+
+</preface>
+
+&publishing.xml;
+&extensions.xml;
+
+<chapter>
+<title>Reference Documentation</title>
+
+<para>Reference documentation is also available:</para>
+
+<itemizedlist>
+<listitem><para><olink type="title" localinfo="reference.html"
+                       targetdocent="reference.xml"/></para>
+</listitem>
+</itemizedlist>
+</chapter>
+
+&templates.xml;
+</book>
+
diff --git a/xsl/docsrc/extensions.xml b/xsl/docsrc/extensions.xml
new file mode 100644 (file)
index 0000000..5122eff
--- /dev/null
@@ -0,0 +1,96 @@
+<chapter>
+<title>Saxon Extensions</title>
+<?dbhtml filename="extensions.html"?>
+
+<para>Beginning with release 1.25, the DocBook XSL Stylesheets include
+a set of Java extensions for Saxon.</para>
+
+<para>These extensions enable callouts, numbered program listings, and
+the direct inclusion of text:</para>
+
+<programlistingco>
+<areaspec>
+<area coords="1" id="prologue"/>
+<area coords="4" id="skipeof"/>
+<areaset coords="" id="xreq">
+<area coords="9" id="require1"/>
+<area coords="10" id="require2"/>
+</areaset>
+<area coords="11 12" id="use"/>
+<area coords="27" id="funccall"/>
+</areaspec>
+<programlisting linenumbering='numbered'>@rem = '--*-Perl-*--
+@echo off
+perl.exe %_batchname %$
+goto endofperl
+@rem ';
+
+# Compress mail...
+
+require 'n:/home/nwalsh/lib/cygnus.pl';
+require 'timelocal.pl';
+use Cwd;
+
+select (STDERR); $| = 1;
+select (STDOUT); $| = 1;
+
+@DIRS = ("/home/nwalsh/Mail");
+while (@DIRS) {
+    $dir = shift @DIRS;
+    opendir (DIR, $dir);
+    while ($fname = readdir(DIR)) {
+        $file = "$dir/$fname";
+        next if ! -d $file;
+        next if $fname =~ /^\.\.?$/;
+
+        print "$file\n";
+        push (@DIRS, $file);
+        &amp;compress ($file);
+    }
+}
+
+exit;</programlisting>
+<calloutlist>
+<callout arearefs="prologue">
+<para>The prologue handles embedding a Perl script in a DOS batch file.</para>
+</callout>
+<callout arearefs="skipeof">
+<para>The <literal>goto</literal> statement, interpreted by the DOS batch
+file interpreter, skips over the body of the Perl script.</para>
+</callout>
+<callout arearefs="require1">
+<para>The <literal>require</literal> statement sources in external program
+fragments.</para>
+</callout>
+<callout arearefs="use">
+<para>The <literal>use</literal> statement is similar, but has additional
+utility.  It is a Perl5 function.  (Note that this callout area specifies
+both a line and a column.)</para>
+</callout>
+<callout arearefs="funccall">
+<para>This is a user subroutine call.</para>
+</callout>
+</calloutlist>
+</programlistingco>
+
+<section><title>Installation</title>
+
+<para>The extensions are included in the distribution in
+<filename>extensions/nwalsh.jar</filename>. Just make sure that jar
+file is in your CLASSPATH when you run Saxon.</para>
+
+</section>
+
+<section><title>Using the Extensions</title>
+
+<para>For compatibility with other processors, the extensions are disabled
+by default. To enable the extensions, turn on
+<literal>$saxon.extensions</literal>, for example by passing
+<literal>saxon.extensions=1</literal> to Saxon.</para>
+
+<para>For more control over the specific extensions, see
+<olink type="title" localinfo="html/param.html"
+                    targetdocent="html-param.xml"/>.</para>
+</section>
+
+</chapter>
diff --git a/xsl/docsrc/fo/.cvsignore b/xsl/docsrc/fo/.cvsignore
new file mode 100644 (file)
index 0000000..6722cd9
--- /dev/null
@@ -0,0 +1 @@
+*.xml
diff --git a/xsl/docsrc/fo/Makefile b/xsl/docsrc/fo/Makefile
new file mode 100644 (file)
index 0000000..2b38ace
--- /dev/null
@@ -0,0 +1,9 @@
+JSTYLE=../../docsrc/xsl2jref.xsl
+VPATH=../../fo
+
+XMLFILES = param.xml table.xml
+
+all: $(XMLFILES)
+
+%.xml : %.xsl $(JSTYLE)
+       saxon -6 $< $(JSTYLE) - output-file=$@
diff --git a/xsl/docsrc/html/.cvsignore b/xsl/docsrc/html/.cvsignore
new file mode 100644 (file)
index 0000000..6722cd9
--- /dev/null
@@ -0,0 +1 @@
+*.xml
diff --git a/xsl/docsrc/html/Makefile b/xsl/docsrc/html/Makefile
new file mode 100644 (file)
index 0000000..f8304a7
--- /dev/null
@@ -0,0 +1,9 @@
+JSTYLE=../../docsrc/xsl2jref.xsl
+VPATH=../../html
+
+XMLFILES = param.xml ebnf.xml
+
+all: $(XMLFILES)
+
+%.xml : %.xsl $(JSTYLE)
+       saxon -6 $< $(JSTYLE) /dev/null output-file=$@
diff --git a/xsl/docsrc/jrefhtml.xsl b/xsl/docsrc/jrefhtml.xsl
new file mode 100644 (file)
index 0000000..b176fca
--- /dev/null
@@ -0,0 +1,174 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="lxslt"
+                version='1.0'>
+
+<xsl:import href="../html/docbook.xsl"/>
+
+<xsl:output
+  method="html"
+  indent="yes"
+  encoding="ISO-8859-1"/>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="lxslt:component"/>
+
+<xsl:param name="part.autolabel" select="0"/>
+
+<xsl:template match="refentry">
+  <hr/>
+  <xsl:apply-imports/>
+</xsl:template>
+
+<xsl:template match="refdescription">
+  <div class="{name(.)}">
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id"/>
+      </xsl:attribute>
+    </a>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refauthor">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>Author</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refversion">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>Version</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refparameter">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>Parameters</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refreturn">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>Returns</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refexception|refthrows">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>Exceptions</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refsee">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>See</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refsince">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>Since</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refserial">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>Serial</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refdeprecated">
+  <div class="{name(.)}">
+    <b>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:text>Deprecated</xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/docsrc/legalnotice.xml b/xsl/docsrc/legalnotice.xml
new file mode 100644 (file)
index 0000000..06bb669
--- /dev/null
@@ -0,0 +1,37 @@
+<legalnotice><title>Copyright Statement</title>
+
+<para>Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the <quote>Software</quote>), 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:
+</para>
+
+<para>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.</para>
+
+<para>Except as contained in this notice, the names of individuals
+credited with contribution to this software shall not be used in
+advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization from the individuals
+in question.</para>
+
+<para>Any stylesheet derived from this Software that is publically
+distributed will be identified with a different name and the version
+strings in any derived Software will be changed so that no possibility
+of confusion between the derived package and this Software will
+exist.</para>
+</legalnotice>
+
+<legalnotice><title>Warranty</title>
+<para>THE SOFTWARE IS PROVIDED <quote>AS IS</quote>,
+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 NORMAN WALSH OR ANY
+OTHER CONTRIBUTOR 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.</para>
+</legalnotice>
diff --git a/xsl/docsrc/lib/.cvsignore b/xsl/docsrc/lib/.cvsignore
new file mode 100644 (file)
index 0000000..6722cd9
--- /dev/null
@@ -0,0 +1 @@
+*.xml
diff --git a/xsl/docsrc/lib/Makefile b/xsl/docsrc/lib/Makefile
new file mode 100644 (file)
index 0000000..e4c522c
--- /dev/null
@@ -0,0 +1,9 @@
+JSTYLE=../../docsrc/xsl2jref.xsl
+VPATH=../../lib
+
+XMLFILES = lib.xml
+
+all: $(XMLFILES)
+
+%.xml : %.xsl $(JSTYLE)
+       saxon -6 $< $(JSTYLE) /dev/null output-file=$@
diff --git a/xsl/docsrc/publishing.xml b/xsl/docsrc/publishing.xml
new file mode 100644 (file)
index 0000000..977db45
--- /dev/null
@@ -0,0 +1,1019 @@
+<chapter>
+<chapterinfo>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Stayton</surname>
+<firstname>Bob</firstname></author>
+<copyright><year>2000</year><holder>Bob Stayton</holder>
+</copyright>
+</chapterinfo>
+<title>DocBook XSL</title>
+<?dbhtml filename="publishing.html"?>
+ <sect1>
+  <title>Using XSL tools to publish DocBook
+   documents</title>
+  <para>There is a growing list of tools to process DocBook
+   documents using XSL stylesheets. Each tool implements parts
+   or all of the XSL standard, which actually has several
+   components:
+   <variablelist>
+    <varlistentry>
+     <term>Extensible Stylesheet Language (XSL)</term>
+     <listitem>
+      <para>A language for expressing stylesheets written
+       in XML. It includes the formatting object language, but
+       refers to separate documents for the transformation
+       language and the path language.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+   <term>XSL Transformation (XSLT)</term>
+   <listitem>
+    <para>The part of XSL for transforming XML documents
+       into other XML documents, HTML, or text. It can be used to
+       rearrange the content and generate new content.</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>XML Path Language (XPath)</term>
+  <listitem>
+   <para>A language for addressing parts of an XML
+       document. It is used to find the parts of your document to
+       apply different styles to. All XSL processors use this
+       component.</para>
+ </listitem>
+</varlistentry>
+</variablelist></para>
+<para>To publish HTML from your XML documents, you just
+   need an XSLT engine. To get to print, you need an XSLT
+   engine to produce formatting objects (FO), which then must
+   be processed with a formatting object processor to produce
+   PostScript or PDF output.</para>
+<para>James Clark's XT was the first useful XSLT engine,
+   and it is still in wide use. It is written in Java, so it
+   runs on many platforms, and it is free (
+   <ulink url="http://www.jclark.com">http://www.jclark.com</ulink>).
+   XT comes with James Clark's nonvalidating parser XP, but
+   you can substitute a different Java parser. Here is a
+   simple example of using XT from the Unix command line to
+   produce HTML: You'll need to alter your
+   <parameter>CLASSPATH</parameter> environment variable to
+   include the path to where you put the
+   <filename>.jar</filename> files from the XT
+   distribution.</para>
+<screen>CLASSPATH=xt.jar:xp.jar:sax.jar
+export CLASSPATH
+java  com.jclark.xsl.sax.Driver <replaceable>filename.xml</replaceable> <replaceable>docbook/html/docbook.xsl</replaceable> &gt; <replaceable>output.html</replaceable></screen>
+<para>If you replace the HTML stylesheet with a
+   formatting object stylesheet, XT will produce a formatting
+   object file. Then you can convert that to PDF using FOP, a
+   formatting object processor available for free from the
+   Apache XML Project (
+   <ulink url="http://xml.apache.org">http://xml.apache.org</ulink>).
+   Here is an example of that two stage processing:</para>
+<screen>CLASSPATH=xt.jar:xp.jar:sax.jar:fop.jar
+export CLASSPATH
+java  com.jclark.xsl.sax.Driver <replaceable>filename.xml</replaceable> <replaceable>docbook/fo/docbook.xsl</replaceable> &gt; <replaceable>output.fo</replaceable>
+java  org.apache.fop.apps.CommandLine <replaceable>output.fo</replaceable> <replaceable>output.pdf</replaceable></screen>
+<para>As of this writing, some other XSLT processors to
+   choose from include:</para>
+<itemizedlist>
+<listitem>
+ <para>4XSLT, written in Python, from FourThought LLC (
+     <ulink url="http://www.fourthought.com">http://www.fourthought.com</ulink>)</para>
+</listitem>
+<listitem>
+<para>Sablotron, written in C++, from Ginger Alliance (
+
+     <ulink url="http://www.gingerall.com">http://www.gingerall.com</ulink>)</para>
+</listitem>
+<listitem>
+<para>Saxon, written in Java, from Michael Kay (
+     <ulink url="http://users.iclway.co.uk/mhkay/saxon">http://users.iclway.co.uk/mhkay/saxon</ulink>)</para>
+</listitem>
+<listitem>
+<para>Xalan, written in Java, from the Apache XML
+     Project (
+     <ulink url="http://xml.apache.org">http://xml.apache.org</ulink>)</para>
+</listitem>
+<listitem>
+<para>XML::XSLT,written in Perl, from Geert Josten and
+     Egon Willighagen (
+     <ulink url="http://www.cpan.org">http://www.cpan.org</ulink>)</para>
+</listitem>
+</itemizedlist>
+<para>For print output, these additional tools are available for processing formatting objects:</para>
+<itemizedlist><listitem><para>XEP (written in Java) from
+   RenderX (
+  <ulink url="http://www.renderx.com">http://www.renderx.com</ulink>).</para></listitem><listitem><para>PassiveTeX from Sebastian Rahtz (<ulink url="http://users.ox.ac.uk/~rahtz/passivetex/">http://users.ox.ac.uk/~rahtz/passivetex/</ulink>).</para></listitem></itemizedlist></sect1>
+<sect1>
+<title>A brief introduction to XSL</title>
+<para>XSL is both a transformation language and a
+ formatting language. The XSLT transformation part lets you
+ scan through a document's structure and rearrange its
+ content any way you like. You can write out the content
+ using a different set of XML tags, and generate text as
+ needed. For example, you can scan through a document to
+ locate all headings and then insert a generated table of
+ contents at the beginning of the document, at the same time
+ writing out the content marked up as HTML. XSL is also a
+ rich formatting language, letting you apply typesetting
+ controls to all components of your output. With a good
+ formatting backend, it is capable of producing high quality
+ printed pages.</para>
+<para>An XSL stylesheet is written using XML syntax, and is
+ itself a well-formed XML document. That makes the basic
+ syntax familiar, and enables an XML processor to check for
+ basic syntax errors. The stylesheet instructions use
+ special element names, which typically begin with
+ <literal>xsl:</literal> to distinguish them from any XML
+ tags you want to appear in the output. The XSL namespace is
+ identified at the top of the stylesheet file. As with other
+ XML, any XSL elements that are not empty will require a
+ closing tag. And some XSL elements have specific attributes
+ that control their behavior. It helps to keep a good XSL
+ reference book handy.</para>
+<para>Here is an example of a simple XSL stylesheet applied
+ to a simple XML file to generate HTML output.</para>
+<example>
+<title>Simple XML file</title>
+<programlisting>&lt;?xml version="1.0"?&gt;
+&lt;document&gt;
+&lt;title&gt;Using a mouse&lt;/title&gt;
+&lt;para&gt;It's easy to use a mouse. Just roll it
+around and click the buttons.&lt;/para&gt;
+&lt;/document&gt;</programlisting>
+</example>
+<example>
+<title>Simple XSL stylesheet</title>
+<programlisting>&lt;?xml version='1.0'?&gt;
+&lt;xsl:stylesheet
+          xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'&gt;
+&lt;xsl:output method="html"/&gt;
+
+&lt;xsl:template match="document"&gt;
+  &lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;
+    &lt;xsl:value-of select="./title"/&gt;
+  &lt;/TITLE&gt;
+  &lt;/HEAD&gt;
+  &lt;BODY&gt;
+    &lt;xsl:apply-templates/&gt;
+  &lt;/BODY&gt;
+  &lt;/HTML&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template match="title"&gt;
+  &lt;H1&gt;&lt;xsl:apply-templates/&gt;&lt;/H1&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template match="para"&gt;
+  &lt;P&gt;&lt;xsl:apply-templates/&gt;&lt;/P&gt;
+&lt;/xsl:template&gt;
+
+&lt;/xsl:stylesheet&gt;
+</programlisting>
+</example>
+<example>
+<title>HTML output</title>
+<programlisting>&lt;HTML&gt;
+&lt;HEAD&gt;
+&lt;TITLE&gt;Using a mouse&lt;/TITLE&gt;
+&lt;/HEAD&gt;
+&lt;BODY&gt;
+&lt;H1&gt;Using a mouse&lt;/H1&gt;
+&lt;P&gt;It's easy to use a mouse. Just roll it
+around and click the buttons.&lt;/P&gt;
+&lt;/BODY&gt;
+&lt;/HTML&gt;
+</programlisting>
+</example>
+</sect1>
+<sect1>
+<title>XSL processing model</title>
+<para>XSL is a template language, not a procedural
+language. That means a stylesheet specifies a sample of the
+output, not a sequence of programming steps to generate it.
+A stylesheet consists of a mixture of output samples with
+instructions of what to put in each sample. Each bit of
+output sample and instructions is called
+a  <emphasis>template</emphasis>.</para>
+<para>In general, you write a template for each element
+type in your document. That lets you concentrate on
+handling just one element at a time, and keeps a stylesheet
+modular. The power of XSL comes from processing the
+templates recursively. That is, each template handles the
+processing of its own element, and then calls other
+templates to process its children, and so on. Since an XML
+document is always a single root element at the top level
+that contains all of the nested descendent elements, the
+XSL templates also start at the top and work their way down
+through the hierarchy of elements.</para>
+<para>Take the
+DocBook <literal>&lt;para&gt;</literal> paragraph element as
+an example. To convert this to HTML, you want to wrap the
+paragraph content with the HTML
+tags <literal>&lt;p&gt;</literal> and <literal>&lt;/p&gt;</literal>.
+But a DocBook <literal>&lt;para&gt;</literal>  can contain
+any number of in-line DocBook elements marking up the text.
+Fortunately, you can let other templates take care of those
+elements, so your XSL template
+for <literal>&lt;para&gt;</literal> can be quite
+simple:</para>
+<programlisting>&lt;xsl:template match="para"&gt;
+  &lt;p&gt;
+    &lt;xsl:apply-templates/&gt;
+  &lt;/p&gt;
+&lt;/xsl:template&gt;
+</programlisting>
+<para>The <literal>&lt;xsl:template&gt;</literal> element
+starts a new template, and
+its <literal>match</literal> attribute indicates where to
+apply the template, in this case to
+any <literal>&lt;para&gt;</literal> elements. The template
+says to output a literal <literal>&lt;p&gt;</literal> string
+and then execute
+the <literal>&lt;xsl:apply-templates/&gt;</literal> instruction.
+This tells the XSL processor to look among all the
+templates in the stylesheet for any that should be applied
+to the content of the paragraph. If each template in the
+stylesheet includes
+an <literal>&lt;xsl:apply-templates/&gt;</literal> instruction,
+then all descendents will eventually be processed. When it
+is through recursively applying templates to the paragraph
+content, it outputs the <literal>&lt;/p&gt;</literal> closing
+tag.</para>
+<sect2>
+<title>Context is important</title>
+<para>Since you aren't writing a linear procedure to
+process your document, the context of where and how to
+apply each modular template is important.
+The <literal>match</literal> attribute
+of <literal>&lt;xsl:template&gt;</literal> provides that
+context for most templates. There is an entire expression
+language, XPath, for identifying what parts of your
+document should be handled by each template. The simplest
+context is just an element name, as in the example above.
+But you can also specify elements as children of other
+elements, elements with certain attribute values, the first
+or last elements in a sequence, and so on. Here is how the
+DocBook <literal>&lt;formalpara&gt;</literal> element is
+handled:</para>
+<programlisting>&lt;xsl:template match="formalpara"&gt;
+  &lt;p&gt;
+    &lt;xsl:apply-templates/&gt;
+  &lt;/p&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template match="formalpara/title"&gt;
+  &lt;b&gt;&lt;xsl:apply-templates/&gt;&lt;/b&gt;
+  &lt;xsl:text&gt; &lt;/xsl:text&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template match="formalpara/para"&gt;
+  &lt;xsl:apply-templates/&gt;
+&lt;/xsl:template&gt;
+</programlisting>
+<para>There are three templates defined, one for
+the <literal>&lt;formalpara&gt;</literal> element itself,
+ and one for each of its children elements. The <literal>match</literal> attribute
+value <literal>formalpara/title</literal>    in the second
+template is an XPath expression indicating
+a <literal>&lt;title&gt;</literal> element that is an
+immediate child of
+a <literal>&lt;formalpara&gt;</literal> element. This
+distinguishes such titles from
+other <literal>&lt;title&gt;</literal> elements used in
+DocBook. XPath expressions are the key to controlling how
+your templates are applied.</para>
+<para>In general, the XSL processor has internal rules that
+apply templates that are more specific before templates
+that are less specific. That lets you control the details,
+but also provides a fallback mechanism to a less specific
+template when you don't supply the full context for every
+combination of elements. This feature is illustrated by the
+third template, for <literal>formalpara/para</literal>. By
+including this template, the stylesheet processes a <literal>&lt;para&gt;</literal> within <literal>&lt;formalpara&gt;</literal> in
+a special way, in this case by not outputting the HTML <literal>&lt;p&gt;</literal> tags already output by its parent. If this template had not been included, then the processor would have fallen back to the template
+specified by <literal>match="para"</literal> described
+above, which would have output a second set of <literal>&lt;p&gt;</literal> tags.</para>
+<para>You can also control template context with
+XSL <emphasis>modes</emphasis>, which are used extensively
+in the DocBook stylesheets. Modes let you process the same
+input more than once in different ways.
+A <literal>mode</literal> attribute in
+an <literal>&lt;xsl:template&gt;</literal> definition adds a
+specific mode name to that template. When the same mode
+name is used
+in <literal>&lt;xsl:apply-templates/&gt;</literal>, it acts
+as a filter to narrow the selection of templates to only
+those selected by
+the <literal>match</literal> expression <emphasis>and</emphasis> that
+have that mode name. This lets you define two different
+templates for the same element match that are applied under
+different contexts. For example, there are two templates
+defined for
+DocBook <literal>&lt;listitem&gt;</literal>  elements:</para>
+<programlisting>&lt;xsl:template match="listitem"&gt;
+  &lt;li&gt;&lt;xsl:apply-templates/&gt;&lt;/li&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template match="listitem" mode="xref"&gt;
+  &lt;xsl:number format="1"/&gt;
+&lt;/xsl:template&gt;
+</programlisting>
+<para>The first template is for the normal list item
+context where you want to output the
+HTML <literal>&lt;li&gt;</literal> tags. The second template
+is called with <literal>&lt;xsl:apply-templates
+select="$target" mode="xref"/&gt;</literal> in the context
+of processing <literal>&lt;xref&gt;</literal> elements. In
+this case the <literal>select</literal> attribute locates
+the ID of the specific list item and
+the <literal>mode</literal> attribute selects the second
+template, whose effect is to output its item number when it
+is in an ordered list. Because there are many such special
+needs when
+processing <literal>&lt;xref&gt;</literal> elements, it is
+convenient to define a mode name <literal>xref</literal> to
+handle them all. Keep in mind that mode settings
+do <emphasis>not</emphasis> automatically get passed down to
+other templates
+through <literal>&lt;xsl:apply-templates/&gt;</literal>.</para>
+</sect2>
+<sect2>
+<title>Programming features</title>
+<para>Although XSL is template-driven, it also has some
+features of traditional programming languages. Here are
+some examples from the DocBook stylesheets. </para>
+<programlisting><lineannotation>Assign a value to a variable:</lineannotation>
+&lt;xsl:variable name="refelem" select="name($target)"/&gt;
+
+<lineannotation>If statement:</lineannotation>
+&lt;xsl:if test="$show.comments"&gt;
+    &lt;i&gt;&lt;xsl:call-template name="inline.charseq"/&gt;&lt;/i&gt;
+&lt;/xsl:if&gt;
+
+<lineannotation>Case statement:</lineannotation>
+&lt;xsl:choose&gt;
+    &lt;xsl:when test="@columns"&gt;
+        &lt;xsl:value-of select="@columns"/&gt;
+    &lt;/xsl:when&gt;
+    &lt;xsl:otherwise&gt;1&lt;/xsl:otherwise&gt;
+&lt;/xsl:choose&gt;
+
+<lineannotation>Call a template by name like a subroutine, passing parameter values and accepting a return value:</lineannotation>
+&lt;xsl:call-template name="xref.xreflabel"&gt;
+   &lt;xsl:with-param name="target" select="$target"/&gt;
+&lt;/xsl:call-template&gt;
+</programlisting>
+<para>However, you can't always use these constructs as you
+do in other programming languages. Variables in particular
+have very different behavior.</para>
+<sect3>
+<title>Using variables and parameters</title>
+<para>XSL provides two elements that let you assign a value
+to a
+name: <literal>&lt;xsl:variable&gt;</literal> and <literal>&lt;xsl:param&gt;</literal>.
+These share the same name space and syntax for assigning
+names and values. Both can be referred to using
+the <literal>$name</literal> syntax. The main difference
+between these two elements is that a param's value acts as
+a default value that can be overridden when a template is
+called using
+a <literal>&lt;xsl:with-param&gt;</literal> element as in the
+last example above.</para>
+<para>Here are two examples from DocBook:</para>
+<programlisting>&lt;xsl:param name="cols"&gt;1&lt;/xsl:param&gt;
+&lt;xsl:variable name="segnum" select="position()"/&gt;
+</programlisting>
+<para>In both elements, the name of the parameter or
+variable is specified with
+the <literal>name</literal> attribute. So the name of
+the <literal>param</literal> here
+is <literal>cols</literal> and the name of
+the <literal>variable</literal> is <literal>segnum</literal>.
+The value of either can be supplied in two ways. The value
+of the first example is the text node "1" and is supplied
+as the content of the element. The value of the second
+example is supplied as the result of the expression in
+its <literal>select</literal> attribute, and the element
+itself has no content.</para>
+<para>The feature of XSL variables that is odd to new users
+is that once you assign a value to a variable, you cannot
+assign a new value within the same scope. Doing so will
+generate an error. So variables are not used as dynamic
+storage bins they way they are in other languages. They
+hold a fixed value within their scope of application, and
+then disappear when the scope is exited. This feature is a
+result of the design of XSL, which is template-driven and
+not procedural. This means there is no definite order of
+processing, so you can't rely on the values of changing
+variables. To use variables in XSL, you need to understand
+how their scope is defined.</para>
+<para>Variables defined outside of all templates are
+considered global variables, and they are readable within
+all templates. The value of a global variable is fixed, and
+its global value can't be altered from within any template.
+However, a template can create a local variable of the same
+name and give it a different value. That local value
+remains in effect only within the scope of the local
+variable.</para>
+<para>Variables defined within a template remain in effect
+only within their permitted scope, which is defined as all
+following siblings and their descendants. To understand
+such a scope, you have to remember that XSL instructions
+are true XML elements that are embedded in an XML family
+hierarchy of XSL elements, often referred to as parents,
+children, siblings, ancestors and descendants. Taking the
+family analogy a step further, think of a variable
+assignment as a piece of advice that you are allowed to
+give to certain family members. You can give your advice
+only to your younger siblings (those that follow you) and
+their descendents. Your older siblings won't listen,
+neither will your parents or any of your ancestors. To
+stretch the analogy a bit, it is an error to try to give
+different advice under the same name to the same group of
+listeners (in other words, to redefine the variable). Keep
+in mind that this family is not the elements of your
+document, but just the XSL instructions in your stylesheet.
+To help you keep track of such scopes in hand-written
+stylesheets, it helps to indent nested XSL elements. Here
+is an edited snippet from the DocBook stylesheet
+file <filename>pi.xsl</filename> that illustrates different
+scopes for two variables:</para>
+<programlisting>
+ 1 &lt;xsl:template name="dbhtml-attribute"&gt;
+ 2 ...
+ 3    &lt;xsl:choose&gt;
+ 4       &lt;xsl:when test="$count&gt;count($pis)"&gt;
+ 5          &lt;!-- not found --&gt;
+ 6       &lt;/xsl:when&gt;
+ 7       &lt;xsl:otherwise&gt;
+ 8          &lt;xsl:variable name="pi"&gt;
+ 9             &lt;xsl:value-of select="$pis[$count]"/&gt;
+10          &lt;/xsl:variable&gt;
+11          &lt;xsl:choose&gt;
+12             &lt;xsl:when test="contains($pi,concat($attribute, '='))"&gt;
+13                &lt;xsl:variable name="rest" select="substring-after($pi,concat($attribute,'='))"/&gt;
+14                &lt;xsl:variable name="quote" select="substring($rest,1,1)"/&gt;
+15                &lt;xsl:value-of select="substring-before(substring($rest,2),$quote)"/&gt;
+16             &lt;/xsl:when&gt;
+17             &lt;xsl:otherwise&gt;
+18             ...
+19             &lt;/xsl:otherwise&gt;
+20          &lt;/xsl:choose&gt;
+21       &lt;/xsl:otherwise&gt;
+22    &lt;/xsl:choose&gt;
+23 &lt;/xsl:template&gt;
+
+</programlisting>
+<para>The scope of the variable <literal>pi</literal> begins
+on line 8 where it is defined in this template, and ends on
+line 20 when its last sibling ends.<footnote><para>Technically, the scope extends to the end tag of the parent of the <literal>&lt;xsl:variable&gt;</literal> element. That is effectively the last sibling.</para></footnote>     The scope of the
+variable <literal>rest</literal> begins on line 13 and ends
+on line 15. Fortunately, line 15 outputs an expression
+using the value before it goes out of scope.</para>
+<para>What happens when
+an <literal>&lt;xsl:apply-templates/&gt;</literal> element
+is used within the scope of a local variable? Do the
+templates that are applied to the document children get the
+variable? The answer is no. The templates that are applied
+are not actually within the scope of the variable. They
+exist elsewhere in the stylesheet and are not following
+siblings or their descendants. </para>
+<para>To pass a value to another template, you pass a
+parameter using
+the <literal>&lt;xsl:with-param&gt;</literal> element. This
+parameter passing is usually done with calls to a specific
+named template
+using <literal>&lt;xsl:call-template&gt;</literal>, although
+it works
+with <literal>&lt;xsl:apply-templates&gt;</literal> too.
+That's because the called template must be expecting the
+parameter by defining it using
+a <literal>&lt;xsl:param&gt;</literal> element with the same
+parameter name. Any passed parameters whose names are not
+defined in the called template are ignored.</para>
+<para>Here is an example of parameter passing
+from <filename>docbook.xsl</filename>:</para>
+<programlisting>&lt;xsl:call-template name="head.content"&gt;
+   &lt;xsl:with-param name="node" select="$doc"/&gt;
+&lt;/xsl:call-template&gt;
+</programlisting>
+<para>Here a template
+named <literal>head.content</literal> is being called and
+passed a parameter named <literal>node</literal> whose
+content is the value of the <literal>$doc</literal> variable
+in the current context. The top of that template looks like
+this:</para>
+<programlisting>&lt;xsl:template name="head.content"&gt;
+   &lt;xsl:param name="node" select="."/&gt;
+</programlisting>
+<para>The template is expecting the parameter because it
+has a <literal>&lt;xsl:param&gt;</literal> defined with the
+same name. The value in this definition is the default
+value. This would be the parameter value used in the
+template if the template was called without passing that
+parameter.</para>
+</sect3>
+</sect2>
+<sect2>
+<title>Generating HTML output.</title>
+<para>You generate HTML from your DocBook XML files by
+applying the HTML version of the stylesheets. This is done
+by using the HTML driver
+file <filename>docbook/html/docbook.xsl</filename> as your
+stylesheet. That is the master stylesheet file that
+uses <literal>&lt;xsl:include&gt;</literal> to pull in the
+component files it needs to assemble a complete stylesheet
+for producing HTML. </para>
+<para>The way the DocBook stylesheet generates HTML is to
+apply templates that output a mix of text content and HTML
+elements. Starting at the top level in the main
+file <filename>docbook.xsl</filename>:</para>
+<programlisting>&lt;xsl:template match="/"&gt;
+  &lt;xsl:variable name="doc" select="*[1]"/&gt;
+  &lt;html&gt;
+  &lt;head&gt;
+    &lt;xsl:call-template name="head.content"&gt;
+      &lt;xsl:with-param name="node" select="$doc"/&gt;
+    &lt;/xsl:call-template&gt;
+  &lt;/head&gt;
+  &lt;body&gt;
+    &lt;xsl:apply-templates/&gt;
+  &lt;/body&gt;
+  &lt;/html&gt;
+&lt;/xsl:template&gt;
+</programlisting>
+<para>This template matches the root element of your input
+document, and starts the process of recursively applying
+templates. It first defines a variable
+named <literal>doc</literal> and then outputs two literal
+HTML elements <literal>&lt;html&gt;</literal> and <literal>&lt;head&gt;</literal>.
+Then it calls a named
+template <literal>head.content</literal> to process the
+content of the HTML <literal>&lt;head&gt;</literal>, closes
+the <literal>&lt;head&gt;</literal> and starts
+the <literal>&lt;body&gt;</literal>. There it
+uses <literal>&lt;xsl:apply-templates/&gt;</literal> to
+recursively process the entire input document. Then it just
+closes out the HTML file.</para>
+<para>Simple HTML elements can generated as literal
+elements as shown here. But if the HTML being output
+depends on the context, you need something more powerful to
+select the element name and possibly add attributes and
+their values. Here is a fragment
+from <filename>sections.xsl</filename> that shows how a
+heading tag is generated using
+the <literal>&lt;xsl:element&gt;</literal> and <literal>&lt;xsl:attribute&gt;</literal> elements:</para>
+<programlisting>
+ 1 &lt;xsl:element name="h{$level}"&gt;
+ 2   &lt;xsl:attribute name="class"&gt;title&lt;/xsl:attribute&gt;
+ 3   &lt;xsl:if test="$level&lt;3"&gt;
+ 4     &lt;xsl:attribute name="style"&gt;clear: all&lt;/xsl:attribute&gt;
+ 5   &lt;/xsl:if&gt;
+ 6   &lt;a&gt;
+ 7     &lt;xsl:attribute name="name"&gt;
+ 8       &lt;xsl:call-template name="object.id"/&gt;
+ 9     &lt;/xsl:attribute&gt;
+10     &lt;b&gt;&lt;xsl:copy-of select="$title"/&gt;&lt;/b&gt;
+11   &lt;/a&gt;
+12 &lt;/xsl:element&gt;
+</programlisting>
+<para>This whole example is generating a single HTML
+heading element. Line 1 begins the HTML element definition
+by identifying the name of the element. In this case, the
+name is an expression that includes the
+variable <literal>$level</literal> passed as a parameter to
+this template. Thus a single template can
+generate <literal>&lt;h1&gt;</literal>, <literal>&lt;h2&gt;</literal>,
+etc. depending on the context in which it is called. Line 2
+defines a <literal>class="title"</literal> attribute that is
+added to this element. Lines 3 to 5 add
+a <literal>style="clear all"</literal> attribute, but only
+if the heading level is less than 3. Line 6 opens
+an <literal>&lt;a&gt;</literal> anchor element. Although this
+looks like a literal output string, it is actually modified
+by lines 7 to 9 that insert
+the <literal>name</literal> attribute into
+the <literal>&lt;a&gt;</literal> element. This illustrates
+that XSL is managing output elements as active element
+nodes, not just text strings. Line 10 outputs the text of
+the heading title, also passed as a parameter to the
+template, enclosed in HTML boldface tags. Line 11 closes
+the anchor tag with the
+literal <literal>&lt;/a&gt;</literal> syntax, while line 12
+closes the heading tag by closing the element definition.
+Since the actual element name is a variable, it couldn't
+use the literal syntax.</para>
+<para>As you follow the sequence of nested templates
+processing elements, you might be wondering how the
+ordinary text of your input document gets to the output. In
+the file <filename>docbook.xsl</filename> you will find
+this template that handles any text not processed by any
+other template:</para>
+<programlisting>&lt;xsl:template match="text()"&gt;
+  &lt;xsl:value-of select="."/&gt;
+&lt;/xsl:template&gt;
+</programlisting>
+<para>This template's body consists of the "value" of the text node,
+which is just its text. In general, all XSL processors have
+some built-in templates to handle any content for which
+your stylesheet doesn't supply a matching template. This
+template serves the same function but appears explicitly in
+the stylesheet.</para>
+</sect2>
+<sect2>
+<title>Generating formatting objects.</title>
+<para>You generate formatting objects from your DocBook XML
+files by applying the fo version of the stylesheets. This
+is done by using the fo driver
+file <filename>docbook/fo/docbook.xsl</filename> as your
+stylesheet. That is the master stylesheet file that
+uses <literal>&lt;xsl:include&gt;</literal> to pull in the
+component files it needs to assemble a complete stylesheet
+for producing formatting objects. Generating a formatting
+objects file is only half the process of producing typeset
+output. You also need a formatting object processor such as
+the Apache XML Project's FOP as described in an earlier
+section.</para>
+<para>The DocBook fo stylesheet works in a similar manner
+to the HTML stylesheet. Instead of outputting HTML tags, it
+outputs text marked up
+with <literal>&lt;fo:<replaceable>something</replaceable>&gt;</literal> tags.
+For example, to indicate that some text should be kept
+in-line and typeset with a monospace font, it might look
+like this:</para>
+<programlisting>&lt;fo:inline-sequence font-family="monospace"&gt;/usr/man&lt;/fo:inline-sequence&gt;</programlisting>
+<para>The templates
+in <filename>docbook/fo/inline.xsl</filename>      that produce
+this output for a
+DocBook   <literal>&lt;filename&gt;</literal>     element look
+like this:</para>
+<programlisting>&lt;xsl:template match="filename"&gt;
+  &lt;xsl:call-template name="inline.monoseq"/&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template name="inline.monoseq"&gt;
+  &lt;xsl:param name="content"&gt;
+    &lt;xsl:apply-templates/&gt;
+  &lt;/xsl:param&gt;
+  &lt;fo:inline-sequence font-family="monospace"&gt;
+    &lt;xsl:copy-of select="$content"/&gt;
+  &lt;/fo:inline-sequence&gt;
+&lt;/xsl:template&gt;
+</programlisting>
+<para>There are dozens of fo tags and attributes specified
+in the XSL standard. It is beyond the scope of this
+document to cover how all of them are used in the DocBook
+stylesheets. Fortunately, this is only an intermediate
+format that you probably won't have to deal with very much
+directly unless you are writing your own
+stylesheets.</para>
+</sect2>
+</sect1>
+<sect1>
+<title>Customizing DocBook XSL stylesheets</title>
+<para>The DocBook XSL stylesheets are written in a modular
+fashion. Each of the HTML and FO stylesheets starts with a
+driver file that assembles a collection of component files
+into a complete stylesheet. This modular design puts similar things together into smaller files that are easier to write and maintain than one big stylesheet. The modular stylesheet files
+are distributed among four directories:</para>
+
+<variablelist>
+<varlistentry><term>common/</term>
+<listitem>
+<para>contains code common to both stylesheets, including localization data
+</para>
+</listitem>
+</varlistentry>
+<varlistentry><term>fo/</term>
+<listitem>
+<para>a stylesheet that produces XSL FO result trees
+</para>
+</listitem>
+</varlistentry>
+<varlistentry><term>html/</term>
+<listitem>
+<para>a stylesheet that produces HTML/XHTML result trees
+</para>
+</listitem>
+</varlistentry>
+<varlistentry><term>lib/</term>
+<listitem>
+<para>contains schema-independent functions
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+<para>The driver files for each of HTML and FO stylesheets
+are <filename>html/docbook.xsl</filename> and <filename>fo/docbook.xsl</filename>,
+respectively. A driver file consists mostly of a bunch
+of <literal>&lt;xsl:include&gt;</literal> instructions to
+pull in the component templates, and then defines some
+top-level templates. For example:</para>
+<programlisting>&lt;xsl:include href="../VERSION"/&gt;
+&lt;xsl:include href="../lib/lib.xsl"/&gt;
+&lt;xsl:include href="../common/l10n.xsl"/&gt;
+&lt;xsl:include href="../common/common.xsl"/&gt;
+&lt;xsl:include href="autotoc.xsl"/&gt;
+&lt;xsl:include href="lists.xsl"/&gt;
+&lt;xsl:include href="callout.xsl"/&gt;
+...
+&lt;xsl:include href="param.xsl"/&gt;
+&lt;xsl:include href="pi.xsl"/&gt;
+</programlisting>
+<para>The first four modules are shared with the FO
+stylesheet and are referenced using relative pathnames to
+the common directories. Then the long list of component
+stylesheets starts. Pathnames in include statements are
+always taken to be relative to the including file. Each
+included file must be a valid XSL stylesheet, which means
+its root element must
+be <literal>&lt;xsl:stylesheet&gt;</literal>.</para>
+<sect2>
+<title>Stylesheet inclusion vs. importing</title>
+<para>XSL actually provides two inclusion
+mechanisms: <literal>&lt;xsl:include&gt;</literal> and <literal>&lt;xsl:import&gt;</literal>.
+Of the two, <literal>&lt;xsl:include&gt;</literal> is
+the simpler. It treats the included content as if it were
+actually typed into the file at that point, and doesn't
+give it any more or less precedence relative to the
+surrounding text. It is best used when assembling
+dissimilar templates that don't overlap what they match.
+The DocBook driver files use this instruction to assemble a
+set of modules into a stylesheet.</para>
+<para>In contrast, <literal>&lt;xsl:import&gt;</literal> lets
+you manage the precedence of templates and variables. It is
+the preferred mode of customizing another stylesheet because
+it lets you override definitions in the distributed
+stylesheet with your own, without altering the distribution
+files at all. You simply import the whole stylesheet and
+add whatever changes you want.</para>
+<para>The precedence rules for import are detailed and
+rigorously defined in the XSL standard. The basic rule is
+that any templates and variables in the importing
+stylesheet have precedence over equivalent templates and
+variables in the imported stylesheet. Think of the imported stylesheet elements as a fallback collection, to be used only if a match is not found in the current stylesheet. You can customize the templates you want to change in your stylesheet file, and let the imported stylesheet handle the rest.</para>
+<note>
+<para>Customizing a DocBook XSL stylesheet is the opposite
+of customizing a DocBook DTD. When you customize a DocBook
+DTD, the rules of XML and SGML dictate that
+the <emphasis>first</emphasis> of any duplicate declarations
+wins. Any subsequent declarations of the same element or
+entity are ignored. The architecture of the DTD provides
+slots for inserting your own custom declarations early
+enough in the DTD for them to override the standard
+declarations. In contrast, customizing an XSL stylesheet is
+simpler because your definitions have precedence over imported ones.</para>
+</note>
+<para>You can carry modularization to deeper levels because
+module files can also include or import other modules.
+You'll need to be careful to maintain the precedence that
+you want as the modules get rolled up into a complete
+stylesheet. </para>
+</sect2>
+<sect2>
+<title>Customizing
+with <literal>&lt;xsl:import&gt;</literal></title>
+<para>There is currently one example of customizing
+with <literal>&lt;xsl:import&gt;</literal> in the HTML
+version of the DocBook stylesheets.
+The <filename>xtchunk.xsl</filename> stylesheet modifies the
+HTML processing to output many smaller HTML files rather
+than a single large file per input document. It uses XSL
+extensions defined only in the XSL
+processor <command>XT</command>. In the driver
+file <filename>xtchunk.xsl</filename>, the first instruction
+is <literal>&lt;xsl:import
+href="docbook.xsl"/&gt;</literal>. That instruction imports
+the original driver file, which in turn uses
+many <literal>&lt;xsl:include&gt;</literal> instructions to
+include all the modules. That single import instruction
+gives the new stylesheet the complete set of DocBook
+templates to start with.</para>
+<para>After the
+import, <filename>xtchunk.xsl</filename> redefines some of
+the templates and adds some new ones. Here is one example
+of a redefined template:</para>
+<programlisting><lineannotation>Original template in autotoc.xsl</lineannotation>
+&lt;xsl:template name="href.target"&gt;
+  &lt;xsl:param name="object" select="."/&gt;
+  &lt;xsl:text&gt;#&lt;/xsl:text&gt;
+  &lt;xsl:call-template name="object.id"&gt;
+    &lt;xsl:with-param name="object" select="$object"/&gt;
+  &lt;/xsl:call-template&gt;
+&lt;/xsl:template&gt;
+
+<lineannotation>New template in xtchunk.xsl</lineannotation>
+&lt;xsl:template name="href.target"&gt;
+  &lt;xsl:param name="object" select="."/&gt;
+  &lt;xsl:variable name="ischunk"&gt;
+    &lt;xsl:call-template name="chunk"&gt;
+      &lt;xsl:with-param name="node" select="$object"/&gt;
+    &lt;/xsl:call-template&gt;
+  &lt;/xsl:variable&gt;
+
+  &lt;xsl:apply-templates mode="chunk-filename" select="$object"/&gt;
+
+  &lt;xsl:if test="$ischunk='0'"&gt;
+    &lt;xsl:text&gt;#&lt;/xsl:text&gt;
+    &lt;xsl:call-template name="object.id"&gt;
+      &lt;xsl:with-param name="object" select="$object"/&gt;
+    &lt;/xsl:call-template&gt;
+  &lt;/xsl:if&gt;
+&lt;/xsl:template&gt;
+</programlisting>
+<para>The new template handles the more complex processing
+of HREFs when the output is split into many HTML files.
+Where the old template could simply
+output <literal>#<replaceable>object.id</replaceable></literal>,
+the new one outputs <literal><replaceable>filename</replaceable>#<replaceable>object.id</replaceable></literal>.</para>
+</sect2>
+<sect2>
+<title>Setting stylesheet variables</title>
+<para>You may not have to define any new templates,
+however. The DocBook stylesheets are parameterized using
+XSL variables rather than hard-coded values for many of the
+formatting features. Since
+the <literal>&lt;xsl:import&gt;</literal> mechanism also
+lets you redefine global variables, this gives you an easy
+way to customize many features of the DocBook
+stylesheets. Over time, more features will be parameterized to permit customization. If you find hardcoded values in the stylesheets that would be useful to customize, please let the maintainer know.</para>
+<para>Near the end of the list of includes in the main
+DocBook driver file is the
+instruction <literal>&lt;xsl:include
+href="param.xsl"/&gt;</literal>.
+The <filename>param.xsl</filename> file is the most
+important module for customizing a DocBook XSL stylesheet.
+This module contains no templates, only definitions of
+stylesheet variables. Since these variables are defined
+outside of any template, they are global variables and
+apply to the entire stylesheet. By redefining these
+variables in an importing stylesheet, you can change the
+behavior of the stylesheet.</para>
+<para>To create a customized DocBook stylesheet, you simply
+create a new stylesheet file such
+as <filename>mystyle.xsl</filename> that imports the standard
+stylesheet and adds your own new variable definitions. Here
+is an example of a complete custom stylesheet that changes
+the depth of sections listed in the table of contents from
+two to three:</para>
+<programlisting>&lt;?xml version='1.0'?&gt;
+&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'
+                xmlns="http://www.w3.org/TR/xhtml1/transitional"
+                exclude-result-prefixes="#default"&gt;
+
+&lt;xsl:import href="docbook.xsl"/&gt;
+
+&lt;xsl:variable name="toc.section.depth"&gt;3&lt;/xsl:variable&gt;
+&lt;!-- Add other variable definitions here --&gt;
+
+&lt;/xsl:stylesheet&gt;
+</programlisting>
+<para>Following the opening stylesheet element are the
+import instruction and one variable definition. The
+variable <literal>toc.section.depth</literal> was defined
+in <filename>param.xsl</filename> with value "2", and here
+it is defined as "3". Since the importing stylesheet takes
+precedence, this new value is used. Thus documents
+processed with <filename>mystyle.xsl</filename> instead
+of <filename>docbook.xsl</filename> will have three levels
+of sections in the tables of contents, and all other
+processing will be the same.</para>
+<para>Use the list of variables
+in <filename>param.xsl</filename> as your guide for creating
+a custom stylesheet. If the changes you want are controlled
+by a variable there, then customizing is easy. </para>
+
+</sect2>
+<sect2>
+<title>Writing your own templates</title>
+<para>If the changes you want are more extensive than what
+is supported by variables, you can write new templates. You
+can put your new templates directly in your importing
+stylesheet, or you can modularize your importing stylesheet
+as well. You can write your own stylesheet module
+containing a collection of templates for processing lists,
+for example, and put them in a file
+named <filename>mylists.xsl</filename>. Then your importing
+stylesheet can pull in your list templates with
+a <literal>&lt;xsl:include
+href="mylists.xsl"/&gt;</literal> instruction. Since your
+included template definitions appear after the main import
+instruction, your templates will take precedence.</para>
+<para>You'll need to make sure your new templates are
+compatible with the remaining modules, which means:</para>
+<itemizedlist>
+<listitem>
+<para>Any named templates should use the same name so
+calling templates in other modules can find them.</para>
+</listitem>
+<listitem>
+<para>Your template set should process the same elements
+matched by templates in the original module, to ensure
+complete coverage.</para>
+</listitem>
+<listitem>
+<para>Include the same set
+of <literal>&lt;xsl:param&gt;</literal> elements in each
+template to interface properly with any calling templates,
+although you can set different values for your
+parameters.</para>
+</listitem>
+<listitem>
+<para>Any templates that are used like subroutines to
+return a value should return the same data type.</para>
+</listitem>
+</itemizedlist>
+</sect2>
+<sect2>
+<title>Writing your own driver</title>
+<para>Another approach to customizing the stylesheets is to
+write your own driver file. Instead of
+using <literal>&lt;xsl:import
+href="docbook.xsl"/&gt;</literal>, you copy that file to a
+new name and rewrite any of
+the <literal>&lt;xsl:include/&gt;</literal> instructions to
+assemble a custom collection of stylesheet modules. One
+reason to do this is to speed up processing by reducing the
+size of the stylesheet. If you are using a customized
+DocBook DTD that omits many elements you never use, you
+might be able to omit those modules of the
+stylesheet.</para>
+</sect2>
+<sect2>
+<title>Localization</title>
+<para>The DocBook stylesheets include features for
+localizing generated text, that is, printing any generated
+text in a language other than the default English. In
+general, the stylesheets will switch to the language
+identified by a <literal>lang</literal> attribute when
+processing elements in your documents. If your documents
+use the <literal>lang</literal> attribute, then you don't
+need to customize the stylesheets at all for
+localization.</para>
+<para>As far as the stylesheets go,
+a <literal>lang</literal> attribute is inherited by the
+descendents of a document element. The stylesheet searches
+for a <literal>lang</literal> attribute using this XPath
+expression:</para>
+<programlisting>&lt;xsl:variable name="lang-attr"
+         select="($target/ancestor-or-self::*/@lang
+                  |$target/ancestor-or-self::*/@xml:lang)[last()]"/&gt;</programlisting>
+
+<para>This locates the attribute on the current element or
+its most recent ancestor. Thus
+a <literal>lang</literal> attribute is in effect for an
+element and all of its descendents, unless it is reset in
+one of those descendents. If you define it in only your
+document root element, then it applies to the whole
+document:</para>
+<programlisting>&lt;?xml version="1.0"?&gt;
+&lt;!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN" "docbook.dtd"&gt;
+&lt;book lang="fr"&gt;
+...
+&lt;/book&gt;</programlisting>
+<para>When text is being generated, the stylesheet checks
+the most recent <literal>lang</literal> attribute and looks
+up the generated text strings for that language in a
+localization XML file. These are located in
+the <filename>common</filename> directory of the
+stylesheets, one file per language. Here is the top of the
+file <filename>fr.xml</filename>:</para>
+<programlisting>&lt;localization language="fr"&gt;
+
+&lt;gentext key="abstract"                 text="R&amp;#x00E9;sum&amp;#x00E9;"/&gt;
+&lt;gentext key="answer"                   text="R:"/&gt;
+&lt;gentext key="appendix"                 text="Annexe"/&gt;
+&lt;gentext key="article"                  text="Article"/&gt;
+&lt;gentext key="bibliography"             text="Bibliographie"/&gt;
+...
+</programlisting>
+<para>The stylesheet templates use the gentext key names,
+and then the stylesheet looks up the associated text value
+when the document is processed with that lang setting. The
+file <filename>l10n.xml</filename> (note
+the <filename>.xml</filename> suffix) lists the filenames of
+all the supported languages.</para>
+<para>You can also create a custom stylesheet that sets the
+language. That might be useful if your documents don't make
+appropriate use of the <literal>lang</literal> attribute.
+The module <filename>l10n.xsl</filename> defines two global
+variables that can be overridden with an importing
+stylesheet as described above. Here are their default
+definitions:</para>
+<programlisting>&lt;xsl:variable name="l10n.gentext.language"&gt;&lt;/xsl:variable&gt;
+&lt;xsl:variable name="l10n.gentext.default.language"&gt;en&lt;/xsl:variable&gt;
+</programlisting>
+<para>The first one sets the language for all elements,
+regardless of an element's <literal>lang</literal> attribute
+value. The second just sets a default language for any
+elements that haven't got a <literal>lang</literal> setting
+of their own (or their ancestors).</para>
+</sect2>
+</sect1>
+</chapter>
diff --git a/xsl/docsrc/reference.xml b/xsl/docsrc/reference.xml
new file mode 100644 (file)
index 0000000..ce742bc
--- /dev/null
@@ -0,0 +1,66 @@
+<!DOCTYPE book
+  PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+  "http://www.oasis-open.org/xml/4.1.2/docbookx.dtd" [
+<!ENTITY common.xml SYSTEM "common/common.xml" NDATA SGML>
+<!ENTITY lib.xml SYSTEM "lib/lib.xml" NDATA SGML>
+<!ENTITY html-param.xml SYSTEM "html/param.xml" NDATA SGML>
+<!ENTITY html-ebnf.xml SYSTEM "html/ebnf.xml" NDATA SGML>
+<!ENTITY fo-param.xml SYSTEM "fo/param.xml" NDATA SGML>
+<!ENTITY fo-table.xml SYSTEM "fo/table.xml" NDATA SGML>
+<!ENTITY titlepage.xml SYSTEM "template/titlepage.xml" NDATA SGML>
+]>
+<book>
+<bookinfo>
+<title>DocBook XSL Stylesheet Reference Documentation</title>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<copyright><year>1999</year><year>2000</year>
+<holder>Norman Walsh</holder>
+</copyright>
+</bookinfo>
+
+<preface><title>Preface</title>
+
+<para>This constitutes only the most rudimentary beginnings of
+documentation for these stylesheets.</para>
+
+<para>At present, the only documentation available is the set
+of references generated from the stylesheet sources:</para>
+
+<itemizedlist>
+<listitem><para><olink type="title" localinfo="lib/lib.html"
+                       targetdocent="lib.xml"/></para>
+</listitem>
+<listitem><para><olink type="title" localinfo="common/common.html"
+                       targetdocent="common.xml"/></para>
+</listitem>
+<listitem><para><olink type="title" localinfo="html/param.html"
+                       targetdocent="html-param.xml"/></para>
+</listitem>
+<listitem><para><olink type="title" localinfo="html/ebnf.html"
+                       targetdocent="html-ebnf.xml"/></para>
+</listitem>
+<listitem><para><olink type="title" localinfo="fo/param.html"
+                       targetdocent="fo-param.xml"/></para>
+</listitem>
+<listitem><para><olink type="title" localinfo="fo/table.html"
+                       targetdocent="fo-table.xml"/></para>
+</listitem>
+</itemizedlist>
+
+<para>The reference to the template system is also available,
+but at this point it's probably even less useful than the preceding
+references.</para>
+
+<itemizedlist>
+<listitem><para><olink type="title" localinfo="template/titlepage.html"
+                       targetdocent="titlepage.xml"/></para>
+</listitem>
+</itemizedlist>
+
+</preface>
+</book>
+
diff --git a/xsl/docsrc/template-example.xml b/xsl/docsrc/template-example.xml
new file mode 100644 (file)
index 0000000..abb3dbd
--- /dev/null
@@ -0,0 +1,12 @@
+<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
+             xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+             base-stylesheet="/path/to/html/docbook.xsl">
+
+<t:titlepage element="article" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto" order="document">
+    <title predicate="[1]"/>
+    <author/>
+    <edition/>
+  </t:titlepage-content>
+</t:titlepage>
+</t:templates>
diff --git a/xsl/docsrc/template-example.xsl b/xsl/docsrc/template-example.xsl
new file mode 100644 (file)
index 0000000..b4bd9d6
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!-- This stylesheet was created by titlepage.xsl; do not edit it by hand. -->
+
+<xsl:import href="/path/to/html/docbook.xsl"/>
+
+<xsl:template name="article.titlepage.recto"><xsl:apply-templates mode="article.titlepage.recto.mode" select="(articleinfo/title|artheader/title|title)[1]|articleinfo/author|artheader/author|articleinfo/edition|artheader/edition"/>
+</xsl:template>
+
+<xsl:template name="article.titlepage">
+  <div class="titlepage">
+    <xsl:call-template name="article.titlepage.before.recto"/>
+    <xsl:call-template name="article.titlepage.recto"/>
+    <xsl:call-template name="article.titlepage.before.verso"/>
+    <xsl:call-template name="article.titlepage.verso"/>
+    <xsl:call-template name="article.titlepage.separator"/>
+  </div>
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/xsl/docsrc/template/.cvsignore b/xsl/docsrc/template/.cvsignore
new file mode 100644 (file)
index 0000000..6722cd9
--- /dev/null
@@ -0,0 +1 @@
+*.xml
diff --git a/xsl/docsrc/template/Makefile b/xsl/docsrc/template/Makefile
new file mode 100644 (file)
index 0000000..30b891e
--- /dev/null
@@ -0,0 +1,10 @@
+JSTYLE=../../docsrc/xsl2jref.xsl
+VPATH=../../template
+
+XMLFILES = titlepage.xml
+
+all: $(XMLFILES)
+
+%.xml : %.xsl $(JSTYLE)
+       saxon -6 $< $(JSTYLE) /dev/null output-file=$@
+       xnsgmls -E 5 -sv -c /share/doctypes/catalog $@
diff --git a/xsl/docsrc/templates.xml b/xsl/docsrc/templates.xml
new file mode 100644 (file)
index 0000000..2e93637
--- /dev/null
@@ -0,0 +1,104 @@
+<chapter>
+<chapterinfo>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<copyright><year>2000</year><holder>Norman Walsh</holder>
+</copyright>
+</chapterinfo>
+<title>The Template System</title>
+
+<para>Some parts of the DocBook XSL Stylesheets are actually generated
+using XSL Stylesheets. In particular, the formatting of title pages
+is generated using a special template system. The same template system
+will eventually allow you to easily customize bibliography entries and
+perhaps other parts of the system as well.</para>
+
+<para>FIXME: there needs to be more introductory/explanatory text
+here!</para>
+
+<section><title>Changing the Article Title Page</title>
+
+<para>In order to demonstrate how this system works, let's consider
+how we can use it to change the format of article title pages.</para>
+
+<para>By default, the stylesheets print the following elements on the
+article title page, in this order: <simplelist type="inline">
+<member><sgmltag>title</sgmltag></member>
+<member><sgmltag>subtitle</sgmltag></member>
+<member><sgmltag>corpauthor</sgmltag></member>
+<member><sgmltag>authorgroup</sgmltag></member>
+<member><sgmltag>author</sgmltag></member>
+<member><sgmltag>releaseinfo</sgmltag></member>
+<member><sgmltag>copyright</sgmltag></member>
+<member><sgmltag>legalnotice</sgmltag></member>
+<member><sgmltag>pubdate</sgmltag></member>
+<member><sgmltag>revision</sgmltag></member>
+<member><sgmltag>revhistory</sgmltag></member>
+<member><sgmltag>abstract</sgmltag></member>
+</simplelist>. Suppose we want to put only the
+<sgmltag>title</sgmltag>, <sgmltag>author</sgmltag>, and
+<sgmltag>edition</sgmltag> elements on the title page, in the order
+that they appear in the <sgmltag>articleinfo</sgmltag>.
+</para>
+
+<para>The <quote>hard</quote> (and wrong!) way to do it would be to
+edit <filename>titlepage.templates.xsl</filename> and make the changes
+by hand.</para>
+
+<para>The easy and right way is to construct a template document that
+describes the order and sequence of elements that you want:</para>
+
+<screen><![CDATA[
+<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
+             xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+             base-stylesheet="/path/to/html/docbook.xsl">
+
+<t:titlepage element="article" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto" order="document">
+    <title predicate="[1]"/>
+    <author/>
+    <edition/>
+  </t:titlepage-content>
+</t:titlepage>
+</t:templates>
+]]></screen>
+
+<para>Then process this document with the
+<filename>template/titlepage.xsl</filename> stylesheet. This will
+produce the following somewhat cryptic stylesheet:</para>
+
+<screen><![CDATA[
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!-- This stylesheet was created by titlepage.xsl; do not edit it by hand. -->
+
+<xsl:import href="/path/to/html/docbook.xsl"/>
+
+<xsl:template name="article.titlepage.recto"><xsl:apply-templates mode="article.titlepage.recto.mode" select="(articleinfo/title|artheader/title|title)[1]|articleinfo/author|artheader/author|articleinfo/edition|artheader/edition"/>
+</xsl:template>
+
+<xsl:template name="article.titlepage">
+  <div class="titlepage">
+    <xsl:call-template name="article.titlepage.before.recto"/>
+    <xsl:call-template name="article.titlepage.recto"/>
+    <xsl:call-template name="article.titlepage.before.verso"/>
+    <xsl:call-template name="article.titlepage.verso"/>
+    <xsl:call-template name="article.titlepage.separator"/>
+  </div>
+</xsl:template>
+
+</xsl:stylesheet>
+]]></screen>
+
+<para>Despite its cryptic appearance, it has the desired result.
+If you want to change <emphasis>how</emphasis> the titlepage elements
+are formatted (as opposed to which ones are formatted), you have to
+write your own customization layer that overrides the template for
+the element in question in the <quote>titlepage.mode</quote> mode.</para>
+</section>
+
+</chapter>
diff --git a/xsl/docsrc/warranty.xml b/xsl/docsrc/warranty.xml
new file mode 100644 (file)
index 0000000..534b8f9
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice
+  PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+  "http://www.oasis-open.org/xml/4.1.2/docbookx.dtd">
+<legalnotice><title>Warranty</title>
+<para>THE SOFTWARE IS PROVIDED <quote>AS IS</quote>,
+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 NORMAN WALSH OR ANY
+OTHER CONTRIBUTOR 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.</para>
+</legalnotice>
diff --git a/xsl/docsrc/xsl2jref.xsl b/xsl/docsrc/xsl2jref.xsl
new file mode 100644 (file)
index 0000000..7fe1046
--- /dev/null
@@ -0,0 +1,356 @@
+<?xml version='1.0'?>
+<!DOCTYPE xsl:stylesheet [
+<!ENTITY RE "<xsl:text>&#10;</xsl:text>">
+]>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'
+                xmlns:docbook="http://www.oasis-open.org/docbook/xml/4.0"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                xmlns:xt="http://www.jclark.com/xt"
+                xmlns:saxon="http://icl.com/saxon"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                xmlns:xalanredirect="org.apache.xalan.xslt.extensions.Redirect"
+                exclude-result-prefixes="doc docbook xsl"
+                extension-element-prefixes="xt saxon xalanredirect lxslt">
+
+<xsl:output
+     method="xml"
+     doctype-public="-//Norman Walsh//DTD JRefEntry V1.0//EN"
+     doctype-system="http://nwalsh.com/docbook/jrefentry/1.0/jrefentry.dtd"
+/>
+
+<xsl:preserve-space elements="xsl:variable"/>
+<xsl:strip-space elements="xsl:stylesheet"/>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:param name="output-file" select="''"/>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="/">
+  <xsl:choose>
+    <xsl:when test="$output-file = ''">
+      <xsl:message terminate='yes'>
+        <xsl:text>You must set the output-file parameter!</xsl:text>
+      </xsl:message>
+    </xsl:when>
+    <xsl:when test="/xsl:stylesheet/doc:*">
+      <xt:document method="xml" href="{$output-file}">
+        <xsl:apply-templates/>
+        <xsl:fallback>
+          <xalanredirect:write file="{$output-file}">
+            <xsl:apply-templates/>
+            <xsl:fallback>
+              <saxon:output method="xml" file="{$output-file}">
+                <xsl:apply-templates/>
+                <xsl:fallback>
+                  <xsl:apply-templates/>
+                </xsl:fallback>
+              </saxon:output>
+            </xsl:fallback>
+          </xalanredirect:write>
+        </xsl:fallback>
+      </xt:document>
+    </xsl:when>
+    <xsl:otherwise>
+      <!-- nop -->
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*">
+  <xsl:variable name="block-element" select="name(.) = 'para'
+                                             or name(.) = 'sidebar'
+                                             or name(.) = 'variablelist'
+                                             or name(.) = 'itemizedlist'"/>
+  <xsl:if test="$block-element">&RE;</xsl:if>
+  <xsl:element namespace="" name="{name(.)}">
+    <xsl:apply-templates select="@*" mode="copy-attr"/>
+    <xsl:apply-templates/>
+  </xsl:element>
+  <xsl:if test="$block-element">&RE;</xsl:if>
+</xsl:template>
+
+<xsl:template match="@*" mode="copy-attr">
+  <xsl:attribute name="{name(.)}">
+    <xsl:value-of select="."/>
+  </xsl:attribute>
+</xsl:template>
+
+<xsl:template match="xsl:*"></xsl:template>
+
+<xsl:template match="xsl:stylesheet">
+  <xsl:choose>
+    <xsl:when test="doc:reference">
+      <reference>
+        <xsl:apply-templates/>
+      </reference>
+      &RE;
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="xsl:include">
+  <xsl:apply-templates select="document(@href)/*"/>
+</xsl:template>
+
+<xsl:template match="@*" mode="copy">
+  <xsl:text> </xsl:text>
+  <xsl:value-of select="name(.)"/>
+  <xsl:text>="</xsl:text>
+  <xsl:value-of select="."/>
+  <xsl:text>"</xsl:text>
+</xsl:template>
+
+<xsl:template match="*" mode="copy">
+  <xsl:variable name="content">
+    <xsl:apply-templates mode="copy"/>
+  </xsl:variable>
+
+  <xsl:text>&lt;</xsl:text>
+  <xsl:value-of select="name(.)"/>
+  <xsl:apply-templates select="@*" mode="copy"/>
+  <xsl:choose>
+    <xsl:when test="$content = ''">
+      <xsl:text>/</xsl:text>
+      <xsl:text>&gt;</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>&gt;</xsl:text>
+      <xsl:copy-of select="$content"/>
+      <xsl:text>&lt;/</xsl:text>
+      <xsl:value-of select="name(.)"/>
+      <xsl:text>&gt;</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="comment()" mode="copy">
+  <xsl:text>&lt;!--</xsl:text>
+  <xsl:value-of select="."/>
+  <xsl:text>--&gt;</xsl:text>
+</xsl:template>
+
+<xsl:template match="processing-instruction()" mode="copy">
+  <xsl:text>&lt;?</xsl:text>
+  <xsl:value-of select="name(.)"/>
+  <xsl:text> </xsl:text>
+  <xsl:value-of select="."/>
+  <xsl:text>?&gt;</xsl:text>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="doc:reference">
+  <!-- only process the children; doc:reference logically wraps the entire
+       stylesheet, even if it can't syntactically do so. -->
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="doc:variable">
+  <xsl:variable name="name" select="@name"/>
+
+  &RE;
+  <refentry id="var.{$name}">
+    &RE;
+    <refnamediv>
+      &RE;
+      <refname><xsl:value-of select="$name"/></refname>
+      &RE;
+      <xsl:apply-templates select="refpurpose"/>
+      &RE;
+    </refnamediv>
+    &RE;
+    <refsynopsisdiv>
+      &RE;
+      <synopsis>
+        <xsl:apply-templates select="../xsl:variable[@name=$name]"
+                             mode="copy-template"/>
+      </synopsis>
+      &RE;
+    </refsynopsisdiv>
+    &RE;
+    <xsl:apply-templates select="*[name(.)!='refpurpose']"/>
+  </refentry>
+  &RE;
+</xsl:template>
+
+<xsl:template match="doc:param">
+  <xsl:variable name="name" select="@name"/>
+
+  &RE;
+  <refentry id="param.{$name}">
+    &RE;
+    <refnamediv>
+      &RE;
+      <refname><xsl:value-of select="$name"/></refname>
+      &RE;
+      <xsl:apply-templates select="refpurpose"/>
+      &RE;
+    </refnamediv>
+    &RE;
+    <refsynopsisdiv>
+      &RE;
+      <synopsis>
+        <xsl:apply-templates select="../xsl:param[@name=$name]"
+                             mode="copy-template"/>
+      </synopsis>
+      &RE;
+    </refsynopsisdiv>
+    &RE;
+    <xsl:apply-templates select="*[name(.)!='refpurpose']"/>
+  </refentry>
+  &RE;
+</xsl:template>
+
+<xsl:template match="doc:template[@name]">
+  <xsl:variable name="name" select="@name"/>
+
+  &RE;
+  <refentry id="template.{$name}">
+    &RE;
+    <refnamediv>
+      &RE;
+      <refname><xsl:value-of select="$name"/></refname>
+      &RE;
+      <xsl:apply-templates select="refpurpose"/>
+      &RE;
+    </refnamediv>
+    &RE;
+    <refsynopsisdiv>
+      &RE;
+      <synopsis>
+        <xsl:apply-templates select="../xsl:template[@name=$name]"
+                             mode="copy-template"/>
+      </synopsis>
+      &RE;
+    </refsynopsisdiv>
+    &RE;
+    <xsl:apply-templates select="*[name(.)!='refpurpose']"/>
+  </refentry>
+  &RE;
+</xsl:template>
+
+<xsl:template match="doc:template[@match]">
+  <xsl:variable name="match" select="@match"/>
+  <xsl:variable name="mode" select="@mode"/>
+
+  &RE;
+  <refentry>
+    &RE;
+    <refnamediv>
+      &RE;
+      <refname>
+        <xsl:value-of select="$match"/>
+        <xsl:if test="@mode">
+          <xsl:text> (in </xsl:text>
+          <xsl:value-of select="$mode"/>
+          <xsl:text> mode)</xsl:text>
+        </xsl:if>
+      </refname>
+      &RE;
+      <xsl:apply-templates select="refpurpose"/>
+      &RE;
+    </refnamediv>
+    &RE;
+    <refsynopsisdiv>
+      &RE;
+      <synopsis>
+        <xsl:choose>
+          <xsl:when test="@mode">
+            <xsl:apply-templates select="../xsl:template[@match=$match and @mode=$mode]"
+                                 mode="copy-template"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:apply-templates select="../xsl:template[@match=$match]"
+                                 mode="copy-template"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </synopsis>
+      &RE;
+    </refsynopsisdiv>
+    &RE;
+    <xsl:apply-templates select="*[name(.)!='refpurpose']"/>
+  </refentry>
+  &RE;
+</xsl:template>
+
+<xsl:template match="doc:mode">
+  <xsl:variable name="name" select="@mode"/>
+
+  <refentry id="mode.{$name}">
+    <refnamediv>
+      <refname><xsl:value-of select="$name"/> mode</refname>
+      <xsl:apply-templates select="refpurpose"/>
+    </refnamediv>
+    <xsl:apply-templates select="*[name(.)!='refpurpose']"/>
+  </refentry>
+</xsl:template>
+
+<xsl:template match="doc:attribute-set">
+  <xsl:variable name="name" select="@mode"/>
+
+  <refentry id="attrset.{$name}">
+    <refnamediv>
+      <refname><xsl:value-of select="$name"/> mode</refname>
+      <xsl:apply-templates select="refpurpose"/>
+    </refnamediv>
+    <xsl:apply-templates select="*[name(.)!='refpurpose']"/>
+  </refentry>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*|text()|comment()|processing-instruction()"
+              mode="copy-template">
+  <!-- suppress -->
+</xsl:template>
+
+<xsl:template match="xsl:param" mode="copy-template">
+  &RE;
+  <xsl:apply-templates select="." mode="copy"/>
+</xsl:template>
+
+<xsl:template match="xsl:template" mode="copy-template">
+  <xsl:variable name="content">
+    <xsl:apply-templates mode="copy-template"/>
+  </xsl:variable>
+
+  <xsl:text>&lt;</xsl:text>
+  <xsl:value-of select="name(.)"/>
+  <xsl:apply-templates select="@*" mode="copy"/>
+  <xsl:choose>
+    <xsl:when test="$content = ''">
+      <xsl:text>/</xsl:text>
+      <xsl:text>&gt;</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>&gt;</xsl:text>
+      <xsl:copy-of select="$content"/>
+      &RE;
+      <xsl:text>  ...</xsl:text>
+      &RE;
+      <xsl:text>&lt;/</xsl:text>
+      <xsl:value-of select="name(.)"/>
+      <xsl:text>&gt;</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/extensions/.cvsignore b/xsl/extensions/.cvsignore
new file mode 100644 (file)
index 0000000..2c22042
--- /dev/null
@@ -0,0 +1,3 @@
+doc
+*.jar
+
diff --git a/xsl/extensions/Makefile b/xsl/extensions/Makefile
new file mode 100644 (file)
index 0000000..9d1b722
--- /dev/null
@@ -0,0 +1,27 @@
+.PHONY: doc saxon551 saxon6 saxon61 xalan2
+
+all: saxon551 saxon6 saxon61 xalan2
+
+saxon551:
+       cd saxon551/.classes && make
+
+saxon6:
+       cd saxon6/.classes && make
+
+saxon61:
+       cd saxon61/.classes && make
+
+xalan2:
+       cd xalan2/.classes && make
+
+jars: saxon551 saxon6 saxon61 xalan2
+       cd saxon551/.classes && make jar
+       cd saxon6/.classes && make jar
+       cd saxon61/.classes && make jar
+       cd xalan2/.classes && make jar
+
+clean:
+       cd saxon551/.classes && make clean
+       cd saxon6/.classes && make clean
+       cd saxon61/.classes && make clean
+       cd xalan2/.classes && make clean
diff --git a/xsl/extensions/prj.el b/xsl/extensions/prj.el
new file mode 100644 (file)
index 0000000..2174d3e
--- /dev/null
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+(jde-set-project-name "xalan")
+(jde-set-variables 
+ '(jde-gen-session-bean-template (quote ("(jde-import-insert-imports-into-buffer (list \"javax.ejb.*\"
+\"java.rmi.RemoteException\"))" "(jde-wiz-update-implements-clause \"SessionBean\")" "'> \"public void ejbActivate() throws RemoteException {\"'>'n \"}\"'>'n
+'>'n" "'> \"public void ejbPassivate() throws RemoteException {\"'>'n \"}\"'>'n
+'>'n" "'> \"public void ejbRemove() throws RemoteException {\"'>'n \"}\"'>'n '>'n" "'> \"public void setSessionContext(SessionContext ctx) throws
+RemoteException {\"" "'>'n \"}\"'>'n '>'n" "'> \"public void unsetSessionContext() throws RemoteException {\"'>'n
+\"}\"'>'n '>'n'>")))
+ '(jde-gen-beep (quote ("(end-of-line) '&" "\"Toolkit.getDefaultToolkit().beep();\"'>'n'>")))
+ '(jde-which-method-format (quote ("[" jde-which-method-current "]")))
+ '(jde-run-classic-mode-vm nil)
+ '(jde-javadoc-gen-nodeprecatedlist nil)
+ '(jde-which-method-max-length 20)
+ '(jde-imenu-include-classdef t)
+ '(jde-javadoc-gen-link-online nil)
+ '(jde-gen-code-templates (quote (("Get Set Pair" . jde-gen-get-set) ("toString method" . jde-gen-to-string-method) ("Action Listener" . jde-gen-action-listener) ("Window Listener" . jde-gen-window-listener) ("Mouse Listener" . jde-gen-mouse-listener) ("Mouse Motion Listener" . jde-gen-mouse-motion-listener) ("Inner Class" . jde-gen-inner-class) ("println" . jde-gen-println) ("beep" . jde-gen-beep) ("property change support" . jde-gen-property-change-support) ("EJB Entity Bean" . jde-gen-entity-bean) ("EJB Session Bean" . jde-gen-session-bean))))
+ '(jde-gen-cflow-else (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"else\")" "'(l '> \"else \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'>'r'n" "\"} // end of else\"'>'n'>)" ")")))
+ '(jde-make-args "")
+ '(jde-javadoc-gen-destination-directory "JavaDoc")
+ '(jde-mode-line-format (quote ("-" mode-line-mule-info mode-line-modified mode-line-frame-identification mode-line-buffer-identification "   " global-mode-string "   %[(" mode-name mode-line-process minor-mode-alist "%n" ")%]--" (line-number-mode "L%l--") (column-number-mode "C%c--") (-3 . "%p") (jde-which-method-mode ("--" jde-which-method-format "--")) "-%-")))
+ '(jde-mode-abbreviations (quote (("ab" . "abstract") ("bo" . "boolean") ("br" . "break") ("by" . "byte") ("byv" . "byvalue") ("cas" . "cast") ("ca" . "catch") ("ch" . "char") ("cl" . "class") ("co" . "const") ("con" . "continue") ("de" . "default") ("dou" . "double") ("el" . "else") ("ex" . "extends") ("fa" . "false") ("fi" . "final") ("fin" . "finally") ("fl" . "float") ("fo" . "for") ("fu" . "future") ("ge" . "generic") ("go" . "goto") ("impl" . "implements") ("impo" . "import") ("ins" . "instanceof") ("in" . "int") ("inte" . "interface") ("lo" . "long") ("na" . "native") ("ne" . "new") ("nu" . "null") ("pa" . "package") ("pri" . "private") ("pro" . "protected") ("pu" . "public") ("re" . "return") ("sh" . "short") ("st" . "static") ("su" . "super") ("sw" . "switch") ("sy" . "synchronized") ("th" . "this") ("thr" . "throw") ("throw" . "throws") ("tra" . "transient") ("tr" . "true") ("vo" . "void") ("vol" . "volatile") ("wh" . "while"))))
+ '(jde-imenu-enable t)
+ '(jde-compile-option-verbose nil)
+ '(jde-db-option-heap-size (quote ((1 . "megabytes") (16 . "megabytes"))))
+ '(jde-bug-debugger-host-address "localhost" t)
+ '(jde-make-working-directory "")
+ '(jde-bug-breakpoint-marker-colors (quote ("red" . "yellow")))
+ '(jde-javadoc-gen-use nil)
+ '(jde-gen-buffer-boilerplate nil)
+ '(jde-bug-raise-frame-p t)
+ '(jde-db-option-application-args (quote ("-IN" "/share/xsl/docbook/test/exttest.xml" "-XSL " "/share/xsl/docbook/test/exttest.xsl")) t)
+ '(jde-javadoc-gen-nonavbar nil)
+ '(jde-javadoc-gen-nohelp nil)
+ '(jde-bug-vm-includes-jpda-p nil)
+ '(jde-gen-jfc-app-buffer-template (quote ("(funcall jde-gen-boilerplate-function) '>'n" "\"import java.awt.Dimension;\" '>'n" "\"import java.awt.Graphics;\" '>'n" "\"import java.awt.Graphics2D;\" '>'n" "\"import java.awt.Color;\" '>'n" "\"import java.awt.geom.Ellipse2D;\" '>'n" "\"import java.awt.event.WindowAdapter;\" '>'n" "\"import java.awt.event.WindowEvent;\" '>'n" "\"import javax.swing.JFrame;\" '>'n" "\"import javax.swing.JPanel;\" '>'n" "\"import javax.swing.JScrollPane;\" '>'n" "\"import javax.swing.JMenuBar;\" '>'n" "\"import javax.swing.JMenu;\" '>'n" "\"import java.awt.event.ActionEvent;\" '>'n" "\"import javax.swing.AbstractAction;\" '>'n '>'n" "\"/**\" '>'n" "\" * \"" "(file-name-nondirectory buffer-file-name) '>'n" "\" *\" '>'n" "\" *\" '>'n" "\" * Created: \" (current-time-string) '>'n" "\" *\" '>'n" "\" * @author <a href=\\\"mailto: \\\"\" (user-full-name) \"</a>\"'>'n" "\" * @version\" '>'n" "\" */\" '>'n" "'>'n" "\"public class \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" extends JFrame\"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"class Canvas extends JPanel\"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"public Canvas () \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"setSize(getPreferredSize());\" '>'n" "\"Canvas.this.setBackground(Color.white);\" '>'n" "\"}\"'>'n '>'n" "\"public Dimension getPreferredSize() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"return new Dimension(600, 600);\" '>'n" "\"}\"'>'n '>'n" "\"public void paintComponent(Graphics g) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"super.paintComponent(g);\" '>'n" "\"Graphics2D g2d = (Graphics2D) g;\" '>'n" "\"Ellipse2D circle = new Ellipse2D.Double(0d, 0d, 100d, 100d);\" '>'n" "\"g2d.setColor(Color.red);\" '>'n" "\"g2d.translate(10, 10);\" '>'n" "\"g2d.draw(circle);\" '>'n" "\"g2d.fill(circle);\" '>'n" "\"}\"'>'n " "\"}\"'>'n '>'n" "\"public \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\"()\"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"super(\\\"\" (P \"Enter app title: \") \"\\\");\" '>'n" "\"setSize(300, 300);\" '>'n" "\"addWindowListener(new WindowAdapter() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"public void windowClosing(WindowEvent e) {System.exit(0);}\" '>'n" "\"public void windowOpened(WindowEvent e) {}\" '>'n" "\"});\"'>'n" "\"setJMenuBar(createMenu());\" '>'n" "\"getContentPane().add(new JScrollPane(new Canvas()));\" '>'n" "\"}\"'>'n" "'>'n" "\"public static void main(String[] args) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'n" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" f = new \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\"();\" '>'n" "\"f.show();\" '>'n" "\"}\"'>'n '>'n" "\"protected JMenuBar createMenu() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"JMenuBar mb = new JMenuBar();\" '>'n" "\"JMenu menu = new JMenu(\\\"File\\\");\" '>'n" "\"menu.add(new AbstractAction(\\\"Exit\\\") \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"public void actionPerformed(ActionEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"System.exit(0);\" '>'n" "\"}\" '>'n" "\"});\" '>'n" "\"mb.add(menu);\" '>'n" "\"return mb;\" '>'n" "\"}\"'>'n " "\"} // \"'>" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "'>'n")))
+ '(jde-bug-key-bindings (quote (("[?\ 3 ?\1a ?\13]" . jde-bug-step-over) ("[?\ 3 ?\1a ?\18]" . jde-bug-step-into) ("[?\ 3 ?\1a ?\ 1]" . jde-bug-step-into-all) ("[?\ 3 ?\1a ?\17]" . jde-bug-step-out) ("[?\ 3 ?\1a ?\ 3]" . jde-bug-continue) ("[?\ 3 ?\1a ?\ 2]" . jde-bug-toggle-breakpoint))))
+ '(jde-compile-finish-hook (quote (jde-compile-finish-refresh-speedbar jde-compile-finish-flush-completion-cache)))
+ '(jde-compile-option-nowarn nil)
+ '(jde-setnu-mode-threshold 20000)
+ '(jde-run-java-vm-w "javaw")
+ '(jde-compile-option-encoding nil)
+ '(jde-run-option-java-profile (quote (nil . "./java.prof")))
+ '(jde-bug-jpda-directory "/usr/local/jdk1.2.2" t)
+ '(jde-read-compile-args nil)
+ '(jde-run-java-vm "java")
+ '(jde-db-option-verbose (quote (nil nil nil)))
+ '(jde-which-method-class-min-length 4)
+ '(jde-db-read-app-args nil)
+ '(jde-javadoc-gen-nodeprecated nil)
+ '(jde-run-option-heap-profile (quote (nil "./java.hprof" 5 20 "Allocation objects")))
+ '(jde-gen-println (quote ("(end-of-line) '&" "\"System.out.println(\" (P \"Print out: \") \");\" '>'n'>")))
+ '(jde-enable-abbrev-mode nil)
+ '(jde-auto-parse-max-buffer-size 50000)
+ '(jde-gen-cflow-main (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"main\")" "'(l '> \"public static void main (String[] args) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'>'r'n" "\"} // end of main ()\"'>'n'>)" ")")))
+ '(jde-javadoc-exception-tag-template "\"* @exception \" type \" if an error occurs\"")
+ '(jde-global-classpath nil t)
+ '(jde-gen-window-listener-template (quote ("(end-of-line) '& (P \"Window name: \")" "\".addWindowListener(new WindowAdapter() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'> \"public void windowActivated(WindowEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"" "'>'n \"public void windowClosed(WindowEvent e)\"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'n \"}\"" "'>'n \"public void windowClosing(WindowEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'n \"System.exit(0);\" '>'n \"}\"" "'>'n \"public void windowDeactivated(WindowEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'n \"}\"" "'>'n \"public void windowDeiconified(WindowEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'n \"}\"" "'>'n \"public void windowIconified(WindowEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'n \"}\"" "'>'n \"public void windowOpened(WindowEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'n \"}\"" "'>'n \"});\" '>'n'>")))
+ '(jde-run-working-directory "/share/xsl/docbook/extensions" t)
+ '(jde-gen-property-change-support (quote ("(end-of-line) '&" "\"protected PropertyChangeSupport pcs =  new PropertyChangeSupport(this);\" '>'n '>'n" "\"/**\" '>'n" "\"* Adds a PropertyChangeListener to the listener list.\" '>'n" "\"* The listener is registered for all properties.\" '>'n" "\"*\" '>'n" "\"* @param listener The PropertyChangeListener to be added\" '>'n" "\"*/\" '>'n" "\"public void addPropertyChangeListener(PropertyChangeListener listener) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"pcs.addPropertyChangeListener(listener);\" '>'n \"}\" '>'n '>'n" "\"/**\" '>'n" "\"* Removes a PropertyChangeListener from the listener list.\" '>'n" "\"* This removes a PropertyChangeListener that was registered for all properties.\" '>'n" "\"*\" '>'n " "\"* @param listener The PropertyChangeListener to be removed\" '>'n" "\"*/\" '>'n" "\"public void removePropertyChangeListener(PropertyChangeListener listener) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>\"pcs.removePropertyChangeListener(listener);\" '>'n \"}\" '>'n '>'n" "\"/**\" '>'n\"* Adds a PropertyChangeListener for a specific property.\" '>'n" "\"* The listener will be invoked only when a call on firePropertyChange\" '>'n" "\"* names that specific property.\" '>'n" "\"*\" '>'n \"* @param propertyName The name of the property to listen on\" '>'n" "\"* @param listener The PropertyChangeListener to be added\" '>'n \"*/\" '>'n" "\"public void addPropertyChangeListener(String propertyName,\" '>'n" "\"PropertyChangeListener listener) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'> \"pcs.addPropertyChangeListener(propertyName, listener);\" '>'n \"}\" '>'n '>'n" "\"/**\" '>'n\"* Removes a PropertyChangeListener for a specific property.\" '>'n" "\"*\" '>'n \"* @param propertyName The name of the property that was listened on\" '>'n" "\"* @param listener The PropertyChangeListener to be removed\" '>'n \"*/\" '>'n" "\"public void removePropertyChangeListener(String propertyName,\" '>'n" "\"PropertyChangeListener listener) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'> \"pcs.removePropertyChangeListener(propertyName, listener);\" '>'n \"}\" '>'n '>'n" "\"/**\" '>'n\"* Reports a bound property update to any registered listeners. \" '>'n" "\"* No event is fired if old and new are equal and non-null.\" '>'n" "\"*\" '>'n \"* @param propertyName The programmatic name of the property that was changed\" '>'n" "\"* @param oldValue The old value of the property\" '>'n" "\"* @param newValue The new value of the property.\" '>'n \"*/\" '>'n" "\"public void firePropertyChange(String propertyName, Object oldValue, Object newValue) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'> \"pcs.firePropertyChange(propertyName, oldValue, newValue);\" '>'n \"}\" '>'n '>'n" "\"/**\" '>'n\"* Reports a bound property update to any registered listeners. \" '>'n" "\"* No event is fired if old and new are equal and non-null.\" '>'n" "\"* This is merely a convenience wrapper around the more general\" '>'n" "\"* firePropertyChange method that takes Object values.\" '>'n" "\"* No event is fired if old and new are equal and non-null.\" '>'n" "\"*\" '>'n \"* @param propertyName The programmatic name of the property that was changed\" '>'n" "\"* @param oldValue The old value of the property\" '>'n" "\"* @param newValue The new value of the property.\" '>'n \"*/\" '>'n" "\"public void firePropertyChange(String propertyName, int oldValue, int newValue) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'> \"pcs.firePropertyChange(propertyName, oldValue, newValue);\" '>'n \"}\" '>'n '>'n" "\"/**\" '>'n\"* Reports a bound property update to any registered listeners. \" '>'n" "\"* No event is fired if old and new are equal and non-null.\" '>'n" "\"* This is merely a convenience wrapper around the more general\" '>'n" "\"* firePropertyChange method that takes Object values.\" '>'n" "\"* No event is fired if old and new are equal and non-null.\" '>'n" "\"*\" '>'n \"* @param propertyName The programmatic name of the property that was changed\" '>'n" "\"* @param oldValue The old value of the property\" '>'n" "\"* @param newValue The new value of the property.\" '>'n \"*/\" '>'n" "\"public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'> \"pcs.firePropertyChange(propertyName, oldValue, newValue);\" '>'n \"}\" '>'n '>'n" "\"/**\" '>'n\"* Fires an existing PropertyChangeEvent to any registered listeners.\" '>'n" "\"* No event is fired if the given event's old and new values are equal and non-null. \" '>'n" "\"*\" '>'n \"* @param evt The PropertyChangeEvent object.\" '>'n\"*/\" '>'n" "\"public void firePropertyChange(PropertyChangeEvent evt) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'> \"pcs.firePropertyChange(evt);\" '>'n \"}\" '>'n '>'n" "\"/**\" '>'n\"* Checks if there are any listeners for a specific property.\" '>'n" "\"*\" '>'n \"* @param evt The PropertyChangeEvent object.\" '>'n" "\"* @return <code>true</code>if there are one or more listeners for the given property\" '>'n" "\"*/\" '>'n" "\"public boolean hasListeners(String propertyName) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'> \"return pcs.hasListeners(propertyName);\" '>'n \"}\" '>'n '>'n'>")))
+ '(jde-javadoc-describe-interface-template "\"* Describe interface \" (jde-javadoc-code name) \" here.\"")
+ '(jde-imenu-include-signature t)
+ '(jde-db-marker-regexp "^.*: thread=.*, \\(\\(.*[.]\\)*\\)\\([^$]*\\)\\($.*\\)*[.].+(), line=\\([0-9]*\\),")
+ '(jde-gen-mouse-motion-listener-template (quote ("(end-of-line) '& (P \"Component name: \")" "\".addMouseMotionListener(new MouseMotionAdapter() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>" "'>'n \"public void mouseDragged(MouseEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>" "'>'n \"public void mouseMoved(MouseEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>" "'>'n \"});\"'>'n'>")))
+ '(jde-key-bindings (quote (("[?\ 3 ?\16 ?\ 1]" . jde-run-menu-run-applet) ("[?\ 3 ?\16 ?\ 2]" . jde-build) ("[?\ 3 ?\16 ?\ 3]" . jde-compile) ("[?\ 3 ?\16 ?\ 4]" . jde-debug) ("[?\ 3 ?\16 ?\ 6]" . jde-wiz-implement-interface) ("[?\ 3 ?\16 ?j]" . jde-javadoc-generate-javadoc-template) ("[?\ 3 ?\16 ?\v]" . bsh) ("[?\ 3 ?\16 ?\f]" . jde-gen-println) ("[?\ 3 ?\16 ?\ e]" . jde-browse-jdk-doc) ("[?\ 3 ?\16 ?\10]" . jde-save-project) ("[?\ 3 ?\16 ?\11]" . jde-wiz-update-class-list) ("[?\ 3 ?\16 ?\12]" . jde-run) ("[?\ 3 ?\16 ?\13]" . speedbar-frame-mode) ("[?\ 3 ?\16 ?\14]" . jde-db-menu-debug-applet) ("[?\ 3 ?\16 ?\17]" . jde-help-symbol) ("[?\ 3 ?\16 ?\19]" . jde-show-class-source) ("[?\ 3 ?\16 ?\1a]" . jde-import-find-and-import) ("[(control c) (control v) (control ?.)]" . jde-complete-at-point-menu) ("[(control c) (control v) ?.]" . jde-complete-at-point))))
+ '(jde-gen-cflow-for-i (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"fori\")" "'(l '> \"for (int \" (p \"variable: \" var) \" = 0; \"" "(s var)" "\" < \"(p \"upper bound: \" ub)\"; \" (s var) \"++) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'>'r'n" "\"} // end of for (int \" (s var) \" = 0; \"" "(s var) \" < \" (s ub) \"; \" (s var) \"++)\"'>'n'>)" ")")))
+ '(jde-run-option-classpath (quote ("/share/xsl/docbook/extensions/xalan2/.classes" "/projects/apache/xml-xalan/java/build/classes" "/projects/apache/xml-xalan/java/bin/bsf.jar" "/projects/apache/xml-xalan/java/bin/xerces.jar" "/projects/sun/resolver/.classes" "/projects/apache/xml-xerces/java/build/classes" "/home/ndw/java")) t)
+ '(jde-javadoc-gen-detail-switch (quote ("-protected")))
+ '(jde-bug-sio-connect-delay 1)
+ '(jde-javadoc-param-tag-template "\"* @param \" name \" \" (jde-javadoc-a type)
+ \" \" (jde-javadoc-code type) \" value\"")
+ '(jde-compile-option-verbose-path nil)
+ '(jde-javadoc-display-doc t)
+ '(jde-imenu-modifier-abbrev-alist (quote (("public" . 43) ("protected" . 177) ("private" . 172) ("static" . 2215) ("transient" . 35) ("volatile" . 126) ("abstract" . 170) ("final" . 182) ("native" . 36) ("synchronized" . 64) ("strictfp" . 37))))
+ '(jde-db-debugger (quote ("JDEbug" "/usr/local/jdk1.2.2/lib/i386" . "Executable")) t)
+ '(jde-jdk-doc-url "http://www.javasoft.com/products/jdk/1.1/docs/index.html")
+ '(jde-gen-cflow-enable t)
+ '(jde-compiler "javac")
+ '(jde-javadoc-gen-verbose nil)
+ '(jde-javadoc-describe-method-template "\"* Describe \" (jde-javadoc-code name) \" method here.\"")
+ '(jde-gen-class-buffer-template (quote ("(funcall jde-gen-boilerplate-function) '>'n" "\"/**\" '>'n" "\" * \"" "(file-name-nondirectory buffer-file-name) '>'n" "\" *\" '>'n" "\" *\" '>'n" "\" * Created: \" (current-time-string) '>'n" "\" *\" '>'n" "\" * @author <a href=\\\"mailto: \\\"\" (user-full-name) \"</a>\"'>'n" "\" * @version\" '>'n" "\" */\" '>'n'" "'>'n" "\"public class \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" \" (jde-gen-get-super-class)" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"public \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" ()\"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'p'n" "\"}\">" "'>'n" "\"}\">" "\"// \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "'>'n")))
+ '(jde-javadoc-checker-level (quote protected))
+ '(jde-appletviewer-option-vm-args nil)
+ '(jde-run-executable-args nil)
+ '(jde-db-option-garbage-collection (quote (t t)))
+ '(jde-javadoc-gen-stylesheetfile "")
+ '(jde-use-font-lock t)
+ '(jde-compile-option-bootclasspath nil)
+ '(jde-make-program "make")
+ '(jde-javadoc-gen-group nil)
+ '(jde-javadoc-gen-link-offline nil)
+ '(jde-entering-java-buffer-hook (quote (jde-reload-project-file jde-which-method-update-on-entering-buffer)))
+ '(jde-javadoc-gen-doc-title "")
+ '(jde-javadoc-gen-header "")
+ '(jde-run-option-vm-args nil)
+ '(jde-javadoc-gen-window-title "")
+ '(jde-compile-option-directory "" t)
+ '(jde-imenu-create-index-function (quote semantic-create-imenu-index))
+ '(jde-gen-console-buffer-template (quote ("(funcall jde-gen-boilerplate-function) '>'n" "\"/**\" '>'n" "\" * \"" "(file-name-nondirectory buffer-file-name) '>'n" "\" *\" '>'n" "\" *\" '>'n" "\" * Created: \" (current-time-string) '>'n" "\" *\" '>'n" "\" * @author <a href=\\\"mailto: \\\"\" (user-full-name) \"</a>\"'>'n" "\" * @version\" '>'n" "\" */\" '>'n" "'>'n" "\"public class \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"public \"" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "\" ()\"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'n" "\"}\"'>'n" "'>'n" "\"public static void main(String[] args)\"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "'>'p'n" "\"}\"'>'n" "\"} // \"'>" "(file-name-sans-extension (file-name-nondirectory buffer-file-name))" "'>'n")))
+ '(jde-read-make-args nil)
+ '(jde-javadoc-gen-noindex nil)
+ '(jde-gen-mouse-listener-template (quote ("(end-of-line) '& (P \"Component name: \")" "\".addMouseListener(new MouseAdapter() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'> " "'>'n \"public void mouseClicked(MouseEvent e) \" " "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\" '>" "'>'n \"public void mouseEntered(MouseEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\" '>" "'>'n \"public void mouseExited(MouseEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>" "'>'n \"public void mousePressed(MouseEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\" '>" "'>'n \"public void mouseReleased(MouseEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>" "'>'n \"});\"'>'n'>")))
+ '(jde-run-option-application-args (quote ("-IN" "test.xml" "-XSL" "test.xsl")) t)
+ '(jde-bug-vm-executable (quote ("java")))
+ '(jde-db-set-initial-breakpoint t)
+ '(jde-bug-debugger-command-timeout 10)
+ '(jde-db-option-stack-size (quote ((128 . "kilobytes") (400 . "kilobytes"))))
+ '(jde-db-option-properties nil t)
+ '(jde-db-source-directories (quote ("/share/xsl/docbook/extensions/xalan2/" "/projects/apache/xml-xalan/java/src/" "/projects/apache/xml-xerces/java/build/src/" "/projects/sun/resolver/" "/home/ndw/java/")) t)
+ '(jde-run-read-app-args nil)
+ '(jde-gen-to-string-method-template (quote ("(end-of-line) '&" "\"public String toString() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n'>")))
+ '(jde-quote-classpath t)
+ '(jde-bug-window-message nil)
+ '(jde-build-use-make nil)
+ '(jde-javadoc-author-tag-template "\"* @author <a href=\\\"mailto:\" user-mail-address
+ \"\\\">\" user-full-name \"</a>\"")
+ '(jde-javadoc-describe-field-template "\"* Describe \" (jde-javadoc-field-type modifiers)
+ \" \" (jde-javadoc-code name) \" here.\"")
+ '(jde-javadoc-gen-link-URL nil)
+ '(jde-compile-option-classpath (quote ("/share/xsl/docbook/extensions/xalan2/.classes" "/projects/apache/xml-xalan/java/build/classes" "/projects/apache/xml-xalan/java/bin/bsf.jar" "/projects/apache/xml-xalan/java/bin/xerces.jar" "/projects/sun/resolver/.classes" "/projects/apache/xml-xerces/java/build/classes" "/home/ndw/java")) t)
+ '(jde-bug-jdk-directory "/usr/local/jdk1.2.2" t)
+ '(jde-gen-boilerplate-function (quote jde-gen-create-buffer-boilerplate))
+ '(jde-gen-entity-bean-template (quote ("(jde-import-insert-imports-into-buffer (list \"javax.ejb.*\"
+\"java.rmi.RemoteException\"))" "'> \"public void ejbActivate() throws RemoteException \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n '>'n" "'> \"public void ejbPassivate() throws RemoteException \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n '>'n" "'> \"public void ejbLoad() throws RemoteException \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n '>'n" "'> \"public void ejbStore() throws RemoteException \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n '>'n" "'> \"public void ejbRemove() throws RemoteException \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n '>'n" "'> \"public void setEntityContext(EntityContext ctx) throws RemoteException \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n '>'n" "'> \"public void unsetEntityContext() throws RemoteException \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n '>'n'>")))
+ '(jde-javadoc-describe-constructor-template "\"* Creates a new \" (jde-javadoc-code name) \" instance.\"")
+ '(jde-bug-server-shmem-name (quote (t . "JDEbug")))
+ '(jde-db-startup-commands nil)
+ '(jde-javadoc-gen-docletpath nil)
+ '(jde-javadoc-gen-split-index nil)
+ '(jde-compile-option-deprecation nil t)
+ '(jde-import-group-of-rules (quote (("^javax?\\."))))
+ '(jde-which-method-mode t)
+ '(jde-gen-k&r t)
+ '(jde-javadoc-gen-bottom "")
+ '(jde-javadoc-gen-footer "")
+ '(jde-db-option-classpath (quote ("/share/xsl/docbook/extensions/xalan2/.classes" "/projects/apache/xml-xalan/java/build/classes" "/projects/apache/xml-xalan/java/bin/bsf.jar" "/projects/apache/xml-xalan/java/bin/xerces.jar" "/projects/sun/resolver/.classes" "/projects/apache/xml-xerces/java/build/classes" "/home/ndw/java")) t)
+ '(jde-gen-cflow-for (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"for\")" "'(l '> \"for (\" (p \"for-clause: \" clause) \") \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'>'r'n" "\"} // end of for (\" (s clause) \")\"'>'n'>)" ")")))
+ '(jde-run-mode-hook nil)
+ '(jde-db-option-verify (quote (nil t)))
+ '(jde-compile-option-extdirs nil)
+ '(jde-imenu-sort nil)
+ '(jde-gen-get-set-var-template (quote ("(end-of-line) '&" "(P \"Variable type: \" type) \" \"" "(P \"Variable name: \" name) \";\" '>'n '>'n" "\"/**\" '>'n" "\"* Get the value of \" (s name) \".\" '>'n" "\"* @return value of \" (s name) \".\" '>'n" "\"*/\" '>'n" "'>'\"public \" (s type)" "(if (string= \"boolean\" (jde-gen-lookup-named 'type) ) " "\" is\" " "\" get\" ) " "(jde-gen-init-cap (jde-gen-lookup-named 'name))" "\"() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\" '>'n" "\"return \" (s name) \";\" '>'n \"}\"" "'>'n '>'n" "\"/**\" '>'n" "\"* Set the value of \" (s name) \".\" '>'n" "\"* @param v  Value to assign to \" (s name) \".\" '>'n" "\"*/\" '>'n" "'>'\"public void set\" (jde-gen-init-cap (jde-gen-lookup-named 'name))" "\"(\" (s type) \"  v) \" " "(if jde-gen-k&r " "()" "'>'n)" "\"{\" '>'n" "'>'\"this.\" (s name) \" = v;\" '>'n \"}\" '>'n'>")))
+ '(jde-bug-saved-breakpoints nil)
+ '(jde-compile-option-sourcepath (quote ("/share/xsl/docbook/extensions/xalan2" "/projects/apache/xml-xalan/java/build/src" "/projects/apache/xml-xerces/java/build/src" "/projects/sun/resolver")) t)
+ '(jde-gen-cflow-if (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"if\")" "'(l '> \"if (\" (p \"if-clause: \" clause) \") \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'>'r'n" "\"} // end of if (\" (s clause) \")\"'>'n'>)" ")")))
+ '(jde-db-option-java-profile (quote (nil . "./java.prof")))
+ '(jde-javadoc-gen-author t)
+ '(jde-compile-option-depend-switch (quote ("-Xdepend")))
+ '(jde-setnu-mode-enable nil)
+ '(jde-run-applet-doc "")
+ '(jde-compile-option-vm-args nil)
+ '(jde-javadoc-gen-overview "")
+ '(jde-javadoc-gen-notree nil)
+ '(jde-run-option-garbage-collection (quote (t t)))
+ '(jde-db-mode-hook nil)
+ '(jde-javadoc-command-path "javadoc")
+ '(jde-db-option-heap-profile (quote (nil "./java.hprof" 5 20 "Allocation objects")))
+ '(jde-import-group-function (quote jde-import-group-of))
+ '(jde-db-read-vm-args nil)
+ '(jde-bug-debug nil)
+ '(jde-javadoc-end-block-template nil)
+ '(jde-javadoc-gen-packages nil)
+ '(jde-gen-cflow-if-else (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"ife\")" "'(l '> \"if (\" (p \"if-clause: \" clause) \") \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'>'r'n" "\"} // end of if (\" (s clause) \")\"'> n" "'> \"else \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'>'r'n" "\"} // end of if (\" (s clause) \")else\"'>'n'>)" ")")))
+ '(jde-gen-cflow-while (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"while\")" "'(l '> \"while (\" (p \"while-clause: \" clause) \") \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'>'r'n" "\"} // end of while (\" (s clause) \")\"'>'n'>)" ")")))
+ '(jde-bug-server-socket (quote (t . "2112")))
+ '(jde-imenu-include-modifiers nil)
+ '(jde-appletviewer-option-encoding "")
+ '(jde-bug-breakpoint-cursor-colors (quote ("cyan" . "brown")))
+ '(jde-compile-option-target (quote ("1.1")))
+ '(jde-run-executable "")
+ '(jde-run-option-heap-size (quote ((1 . "megabytes") (16 . "megabytes"))))
+ '(jde-gen-cflow-switch (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"switch\")" "'(l '> \"switch (\" (p \"switch-condition: \" clause) \") \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n'" "\"case \" (p \"first value: \") \":\"'>'n'>'p'n" "\"break;\"'>'n'>'p'n" "\"default:\"'>'n'>'p'n" "\"break;\"'>'n" "\"} // end of switch (\" (s clause) \")\"'>'n'>)" ")")))
+ '(jde-which-method-abbrev-symbol "~")
+ '(jde-db-option-vm-args nil)
+ '(jde-run-application-class "org.apache.xalan.xslt.Process" t)
+ '(jde-javadoc-gen-doclet "")
+ '(jde-import-auto-sort nil)
+ '(jde-run-option-verbose (quote (nil nil nil)))
+ '(jde-project-file-name "prj.el")
+ '(jde-compile-option-debug (quote ("selected" (t nil nil))) t)
+ '(jde-bug-jre-home "")
+ '(jde-import-sorted-groups nil)
+ '(jde-run-applet-viewer "")
+ '(jde-javadoc-return-tag-template "\"* @return \" (jde-javadoc-a type)
+ \" \" (jde-javadoc-code type) \" value\"")
+ '(jde-javadoc-gen-version t)
+ '(jde-javadoc-gen-helpfile "")
+ '(jde-import-excluded-packages (quote ("bsh.*")))
+ '(jde-run-read-vm-args nil)
+ '(jde-help-docsets nil)
+ '(jde-gen-inner-class-template (quote ("(end-of-line) '& \"class \" (P \"Class name: \" class)" "(P \"Superclass: \" super t)" "(let ((parent (jde-gen-lookup-named 'super)))" "(if (not (string= parent \"\"))" "(concat \" extends \" parent ))) " "(if jde-gen-k&r " "()" "'>'n)" "\"{\" '>'n" "\"public \" (s class) \"() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n" "\"}\" '>'n'>")))
+ '(jde-auto-parse-buffer-interval 180)
+ '(jde-run-option-verify (quote (nil t)))
+ '(jde-import-reverse-sort-group nil)
+ '(jde-compile-option-optimize nil)
+ '(jde-gen-cflow-case (quote ("(if (jde-parse-comment-or-quoted-p)" "'(l \"case\")" "'(l 'n \"case \" (p \"value: \") \":\"'>'n'>'p'n" "\"break;\"'>'n'>'p)" ")")))
+ '(jde-compile-option-depend nil)
+ '(jde-javadoc-describe-class-template "\"* Describe class \" (jde-javadoc-code name) \" here.\"")
+ '(jde-javadoc-gen-serialwarn nil)
+ '(jde-gen-action-listener-template (quote ("'& (P \"Component name: \")" "\".addActionListener(new ActionListener() \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"public void actionPerformed(ActionEvent e) \"" "(if jde-gen-k&r " "()" "'>'n)" "\"{\"'>'n" "\"}\"'>'n \"});\"'>'n'>")))
+ '(jde-auto-parse-enable t)
+ '(jde-compile-option-command-line-args "")
+ '(jde-gen-buffer-templates (quote (("Class" . jde-gen-class) ("Console" . jde-gen-console) ("Swing App" . jde-gen-jfc-app))))
+ '(jde-project-context-switching-enabled-p t)
+ '(jde-javadoc-gen-args nil)
+ '(jde-run-option-stack-size (quote ((128 . "kilobytes") (400 . "kilobytes"))))
+ '(jde-run-option-properties nil t))
+
+
diff --git a/xsl/extensions/saxon551/.cvsignore b/xsl/extensions/saxon551/.cvsignore
new file mode 100644 (file)
index 0000000..4d3c216
--- /dev/null
@@ -0,0 +1 @@
+.classes
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/CVS.java b/xsl/extensions/saxon551/com/nwalsh/saxon/CVS.java
new file mode 100644 (file)
index 0000000..529546b
--- /dev/null
@@ -0,0 +1,90 @@
+package com.nwalsh.saxon;
+
+import java.io.*;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.text.DateFormat;
+import java.text.ParseException;
+
+/**
+ * <p>Saxon extension to convert CVS date strings into local time</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension to turn the CVS date strings, which are UTC:</p>
+ *
+ * <pre>&#36;Date: 2000/11/09 02:34:20 &#36;</pre>
+ *
+ * <p>into legibly formatted local time:</p>
+ *
+ * <pre>Wed Nov 08 18:34:20 PST 2000</pre>
+ *
+ * <p>(I happened to be in California when I wrote this documentation.)</p>
+
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class CVS {
+  /**
+   * <p>Constructor for CVS</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public CVS() {
+  }
+
+  /**
+   * <p>Convert a CVS date string into local time.</p>
+   *
+   * @param cvsDate The CVS date string.
+   *
+   * @return The date, converted to local time and reformatted.
+   */
+  public static String localTime (String cvsDate) {
+    // A cvsDate has the following form "$Date$"
+    if (!cvsDate.startsWith("$Date: ")) {
+      return cvsDate;
+    }
+
+    String yrS = cvsDate.substring(7,11);
+    String moS = cvsDate.substring(12,14);
+    String daS = cvsDate.substring(15,17);
+    String hrS = cvsDate.substring(18,20);
+    String miS = cvsDate.substring(21,23);
+    String seS = cvsDate.substring(24,26);
+
+    TimeZone tz = TimeZone.getTimeZone("GMT+0");
+    GregorianCalendar gmtCal = new GregorianCalendar(tz);
+
+    try {
+      gmtCal.set(Integer.parseInt(yrS),
+                Integer.parseInt(moS)-1,
+                Integer.parseInt(daS),
+                Integer.parseInt(hrS),
+                Integer.parseInt(miS),
+                Integer.parseInt(seS));
+    } catch (NumberFormatException e) {
+      // nop
+    }
+
+    Date d = gmtCal.getTime();
+
+    return d.toString();
+  }
+}
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/Callout.java b/xsl/extensions/saxon551/com/nwalsh/saxon/Callout.java
new file mode 100644 (file)
index 0000000..94547b1
--- /dev/null
@@ -0,0 +1,109 @@
+package com.nwalsh.saxon;
+
+import com.icl.saxon.om.ElementInfo;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class is just for book keeping in the Verbatim class.
+ * It stores information about the location of callouts.</p>
+ *
+ * <p>Only line/column based callouts are supported. This class
+ * implements the Comparable interface so that callouts can be sorted.
+ * Callouts are sorted so that they occur in left-to-right,
+ * top-to-bottom order based on line/column.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ * */
+public class Callout implements Comparable {
+  /** The callout number. */
+  private int callout = 0;
+  /** The area ElementInfo item that generated this callout. */
+  private ElementInfo area = null;
+  /** The line on which this callout occurs. */
+  private int line = 0;
+  /** The column in which this callout appears. */
+  private int col = 0;
+
+  /** The constructor; initialize the private data structures. */
+  public Callout(int callout, ElementInfo area, int line, int col) {
+    this.callout = callout;
+    this.area = area;
+    this.line = line;
+    this.col = col;
+  }
+
+  /**
+   * <p>The compareTo method compares this Callout with another.</p>
+   *
+   * <p>Given two Callouts, A and B, A < B if:</p>
+   *
+   * <ol>
+   * <li>A.line < B.line, or</li>
+   * <li>A.line = B.line && A.col < B.col, or</li>
+   * <li>A.line = B.line && A.col = B.col && A.callout < B.callout</li>
+   * <li>Otherwise, they're equal.</li>
+   * </ol>
+   */
+  public int compareTo (Object o) {
+    Callout c = (Callout) o;
+
+    if (line == c.getLine()) {
+      if (col > c.getColumn()) {
+       return 1;
+      } else if (col < c.getColumn()) {
+       return -1;
+      } else {
+       if (callout < c.getCallout()) {
+         return -1;
+       } else if (callout > c.getCallout()) {
+         return 1;
+       } else {
+         return 0;
+       }
+      }
+    } else {
+      if (line > c.getLine()) {
+       return 1;
+      } else {
+       return -1;
+      }
+    }
+  }
+
+  /** Access the Callout's area. */
+  public ElementInfo getArea() {
+    return area;
+  }
+
+  /** Access the Callout's line. */
+  public int getLine() {
+    return line;
+  }
+
+  /** Access the Callout's column. */
+  public int getColumn() {
+    return col;
+  }
+
+  /** Access the Callout's callout number. */
+  public int getCallout() {
+    return callout;
+  }
+}
+
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/FormatCallout.java b/xsl/extensions/saxon551/com/nwalsh/saxon/FormatCallout.java
new file mode 100644 (file)
index 0000000..af3ee56
--- /dev/null
@@ -0,0 +1,107 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.Name;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public abstract class FormatCallout {
+  protected static final String foURI = "http://www.w3.org/1999/XSL/Format";
+  protected static final String xhURI = "http://www.w3.org/1999/xhtml";
+  protected boolean foStylesheet = false;
+
+  public FormatCallout(boolean fo) {
+    foStylesheet = fo;
+  }
+
+  public String areaLabel(ElementInfo area) {
+    String label = null;
+
+    if (area.getAttributeList().getValue("label") != null) {
+      // If this area has a label, use it
+      label = area.getAttributeList().getValue("label");
+    } else {
+      // Otherwise, if its parent is an areaset and it has a label, use that
+      ElementInfo parent = (ElementInfo) area.getParentNode();
+      if (parent != null
+         && parent.getLocalName().equalsIgnoreCase("areaset")
+         && parent.getAttributeList().getValue("label") != null) {
+       label = parent.getAttributeList().getValue("label");
+      }
+    }
+
+    return label;
+  }
+
+  public void startSpan(Emitter rtf)
+    throws SAXException {
+    // no point in doing this for FO, right?
+    if (!foStylesheet) {
+      Name spanName = new Name("span");
+      AttributeCollection spanAttr = new AttributeCollection();
+      spanAttr.addAttribute(new Name("class"), "CDATA", "co");
+      rtf.startElement(spanName, spanAttr);
+    }
+  }
+
+  public void endSpan(Emitter rtf)
+    throws SAXException {
+    // no point in doing this for FO, right?
+    if (!foStylesheet) {
+      Name spanName = new Name("span");
+      rtf.endElement(spanName);
+    }
+  }
+
+  public void formatTextCallout(Emitter rtfEmitter,
+                               Callout callout) {
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String userLabel = areaLabel(area);
+    String label = "(" + num + ")";
+
+    if (userLabel != null) {
+      label = userLabel;
+    }
+
+    char chars[] = label.toCharArray();
+
+    try {
+      startSpan(rtfEmitter);
+      rtfEmitter.characters(chars, 0, label.length());
+      endSpan(rtfEmitter);
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in formatTextCallout");
+    }
+  }
+
+  public abstract void formatCallout(Emitter rtfEmitter,
+                                    Callout callout);
+}
+
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/FormatGraphicCallout.java b/xsl/extensions/saxon551/com/nwalsh/saxon/FormatGraphicCallout.java
new file mode 100644 (file)
index 0000000..4af78b9
--- /dev/null
@@ -0,0 +1,89 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.Name;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatGraphicCallout extends FormatCallout {
+  String graphicsPath = "";
+  String graphicsExt = "";
+  int graphicsMax = 0;
+
+  public FormatGraphicCallout(String path, String ext, int max, boolean fo) {
+    super(fo);
+    graphicsPath = path;
+    graphicsExt = ext;
+    graphicsMax = max;
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String userLabel = areaLabel(area);
+    String label = "(" + num + ")";
+
+    if (userLabel != null) {
+      label = userLabel;
+    }
+
+    try {
+      if (userLabel == null && num <= graphicsMax) {
+       Name imgName = null;
+       AttributeCollection imgAttr = null;
+
+       if (foStylesheet) {
+         imgName = new Name("fo",
+                            "http://www.w3.org/1999/XSL/Format",
+                            "external-graphic");
+         imgAttr = new AttributeCollection();
+         imgAttr.addAttribute(new Name("src"), "CDATA",
+                              graphicsPath + num + graphicsExt);
+         imgAttr.addAttribute(new Name("alt"), "CDATA", label);
+       } else {
+         imgName = new Name("img");
+         imgAttr = new AttributeCollection();
+         imgAttr.addAttribute(new Name("src"), "CDATA",
+                              graphicsPath + num + graphicsExt);
+         imgAttr.addAttribute(new Name("alt"), "CDATA", label);
+       }
+
+       startSpan(rtfEmitter);
+       rtfEmitter.startElement(imgName, imgAttr);
+       rtfEmitter.endElement(imgName);
+       endSpan(rtfEmitter);
+      } else {
+       formatTextCallout(rtfEmitter, callout);
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in graphic formatCallout");
+    }
+  }
+}
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/FormatTextCallout.java b/xsl/extensions/saxon551/com/nwalsh/saxon/FormatTextCallout.java
new file mode 100644 (file)
index 0000000..e6e19fe
--- /dev/null
@@ -0,0 +1,41 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.output.Emitter;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatTextCallout extends FormatCallout {
+  public FormatTextCallout(boolean fo) {
+    super(fo);
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+    formatTextCallout(rtfEmitter, callout);
+  }
+}
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/FormatUnicodeCallout.java b/xsl/extensions/saxon551/com/nwalsh/saxon/FormatUnicodeCallout.java
new file mode 100644 (file)
index 0000000..5ebb6ce
--- /dev/null
@@ -0,0 +1,65 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.Name;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatUnicodeCallout extends FormatCallout {
+  int unicodeMax = 0;
+  int unicodeStart = 0;
+
+  public FormatUnicodeCallout(int start, int max, boolean fo) {
+    super(fo);
+    unicodeMax = max;
+    unicodeStart = start;
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String label = areaLabel(area);
+
+    try {
+      if (label == null && num <= unicodeMax) {
+       char chars[] = new char[1];
+       chars[0] = (char) (unicodeStart + num - 1);
+
+       startSpan(rtfEmitter);
+       rtfEmitter.characters(chars, 0, 1);
+       endSpan(rtfEmitter);
+      } else {
+       formatTextCallout(rtfEmitter, callout);
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in graphic formatCallout");
+    }
+  }
+}
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/Text.java b/xsl/extensions/saxon551/com/nwalsh/saxon/Text.java
new file mode 100644 (file)
index 0000000..272ad51
--- /dev/null
@@ -0,0 +1,113 @@
+// Text - Saxon extension element for inserting text
+
+package com.nwalsh.saxon;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.net.MalformedURLException;
+import com.icl.saxon.*;
+import com.icl.saxon.style.*;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.output.*;
+import org.xml.sax.SAXException;
+import org.xml.sax.AttributeList;
+
+/**
+ * <p>Saxon extension element for inserting text
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension element for inserting text into a result tree.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Text extends StyleElement {
+  /**
+   * <p>Constructor for Text</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public Text() {
+  }
+
+  /**
+   * <p>Validate the arguments</p>
+   *
+   * <p>The element must have an href attribute.</p>
+   */
+  public void prepareAttributes() throws SAXException {
+    // Get mandatory database attribute
+    try {
+      String fnAtt = attributeList.getValue("href");
+      if (fnAtt == null) {
+       reportAbsence("href");
+      }
+    } catch (NoSuchFieldError e) {
+      // nop, must be Saxon6 parsing this extension element
+    }
+  }
+
+  /** Validate that the element occurs in a reasonable place. */
+  public void validate() throws SAXException {
+    checkWithinTemplate();
+  }
+
+  /**
+   * <p>Insert the text of the file into the result tree</p>
+   *
+   * <p>Processing this element inserts the contents of the URL named
+   * by the href attribute into the result tree as plain text.</p>
+   *
+   */
+  public void process( Context context ) throws SAXException {
+    Outputter out = context.getOutputter();
+
+    String hrefAtt = attributeList.getValue("href");
+    Expression hrefExpr = AttributeValueTemplate.make(hrefAtt, this);
+    String href = hrefExpr.evaluateAsString(context);
+    URL fileURL = null;
+
+    try {
+      try {
+       fileURL = new URL(href);
+      } catch (MalformedURLException e1) {
+       try {
+         fileURL = new URL("file:" + href);
+       } catch (MalformedURLException e2) {
+         System.out.println("Cannot open " + href);
+         return;
+       }
+      }
+
+      InputStreamReader isr = new InputStreamReader(fileURL.openStream());
+      BufferedReader is = new BufferedReader(isr);
+
+      char chars[] = new char[4096];
+      int len = 0;
+      while ((len = is.read(chars)) > 0) {
+       out.writeContent(chars, 0, len);
+      }
+      is.close();
+    } catch (Exception e) {
+      System.out.println("Cannot read " + href);
+    }
+  }
+}
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/TextFactory.java b/xsl/extensions/saxon551/com/nwalsh/saxon/TextFactory.java
new file mode 100644 (file)
index 0000000..34ef9d9
--- /dev/null
@@ -0,0 +1,64 @@
+// TextFactory - Saxon extension element factory
+
+package com.nwalsh.saxon;
+
+import com.icl.saxon.style.ExtensionElementFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>Saxon extension element factory
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension element factory for the Text extension element
+ * family.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ * @see Text
+ *
+ */
+public class TextFactory implements ExtensionElementFactory {
+  /**
+   * <p>Constructor for TextFactory</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public TextFactory() {
+  }
+
+  /**
+   * <p>Return the class that implements a particular extension element.</p>
+   *
+   * @param localname The local name of the extension element.
+   *
+   * @return The class that handles that extension element.
+   *
+   * @exception SAXException("Unknown Text extension element")
+   */
+  public Class getExtensionClass(String localname) throws SAXException {
+    if (localname.equals("insertfile")) {
+      try {
+       return Class.forName("com.nwalsh.saxon.Text");
+      } catch (ClassNotFoundException e) {
+       throw new SAXException("Failed to load class for Text extension element: "
+                              + localname);
+      }
+    }
+    throw new SAXException("Unknown Text extension element: "
+                          + localname);
+  }
+}
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/Verbatim.java b/xsl/extensions/saxon551/com/nwalsh/saxon/Verbatim.java
new file mode 100644 (file)
index 0000000..b1ded98
--- /dev/null
@@ -0,0 +1,979 @@
+// Verbatim.java - Saxon extensions supporting DocBook verbatim environments
+
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.Context;
+import com.icl.saxon.AttributeCollection;
+import com.icl.saxon.functions.Extensions;
+import com.icl.saxon.tree.*;
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Saxon extensions supporting DocBook verbatim environments</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * implementation of two features that would be impractical to
+ * implement directly in XSLT: line numbering and callouts.</p>
+ *
+ * <p><b>Line Numbering</b></p>
+ * <p>The <tt>numberLines</tt> family of functions takes a result tree
+ * fragment (assumed to contain the contents of a formatted verbatim
+ * element in DocBook: programlisting, screen, address, literallayout,
+ * or synopsis) and returns a result tree fragment decorated with
+ * line numbers.</p>
+ *
+ * <p><b>Callouts</b></p>
+ * <p>The <tt>insertCallouts</tt> family of functions takes an
+ * <tt>areaspec</tt> and a result tree fragment
+ * (assumed to contain the contents of a formatted verbatim
+ * element in DocBook: programlisting, screen, address, literallayout,
+ * or synopsis) and returns a result tree fragment decorated with
+ * callouts.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Verbatim {
+  /** A stack to hold the open elements while walking through a verbatim. */
+  private static Stack elementStack = null;
+  /** A stack to hold the temporarily closed elements. */
+  private static Stack tempStack = null;
+  /** The current line number. */
+  private static int lineNumber = 0;
+  /** The current column number. */
+  private static int colNumber = 0;
+  /** The modulus for line numbering (every 'modulus' line is numbered). */
+  private static int modulus = 0;
+  /** The width (in characters) of line numbers (for padding). */
+  private static int width = 0;
+  /** The separator between the line number and the verbatim text. */
+  private static String separator = "";
+  /** The (sorted) array of callouts obtained from the areaspec. */
+  private static Callout callout[] = null;
+  /** The number of callouts in the callout array. */
+  private static int calloutCount = 0;
+  /** A pointer used to keep track of our position in the callout array. */
+  private static int calloutPos = 0;
+  /** The default column for callouts. */
+  private static int defaultColumn = 60;
+  /** The callout formatter */
+  private static FormatCallout fCallout = null;
+
+  /**
+   * <p>Constructor for Verbatim</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public Verbatim() {
+  }
+
+  /**
+   * <p>Find the string value of a stylesheet variable or parameter</p>
+   *
+   * <p>Returns the string value of <code>varName</code> in the current
+   * <code>context</code>. Returns the empty string if the variable is
+   * not defined.</p>
+   *
+   * @param context The current stylesheet context
+   * @param varName The name of the variable (without the dollar sign)
+   *
+   * @return The string value of the variable
+   */
+  protected static String getVariable(Context context, String varName) {
+    Value variable = null;
+    String varString = null;
+
+    try {
+      variable = Extensions.evaluate(context, "$" + varName);
+      varString = variable.asString();
+      return varString;
+    } catch (SAXException se) {
+      System.out.println("Undefined variable: " + varName);
+      return "";
+    } catch (IllegalArgumentException e) {
+      System.out.println("Undefined variable: " + varName);
+      return "";
+    }
+  }
+
+  /**
+   * <p>Setup the parameters associated with line numbering</p>
+   *
+   * <p>This method queries the stylesheet for the variables
+   * associated with line numbering. It is called automatically before
+   * lines are numbered. The context is used to retrieve the values,
+   * this allows templates to redefine these variables.</p>
+   *
+   * <p>The following variables are queried. If the variables do not
+   * exist, builtin defaults will be used (but you may also get a bunch
+   * of messages from the Java interpreter).</p>
+   *
+   * <dl>
+   * <dt><code>linenumbering.everyNth</code></dt>
+   * <dd>Specifies the lines that will be numbered. The first line is
+   * always numbered. (builtin default: 5).</dd>
+   * <dt><code>linenumbering.width</code></dt>
+   * <dd>Specifies the width of the numbers. If the specified width is too
+   * narrow for the largest number needed, it will automatically be made
+   * wider. (builtin default: 3).</dd>
+   * <dt><code>linenumbering.separator</code></dt>
+   * <dd>Specifies the string that separates line numbers from lines
+   * in the program listing. (builtin default: " ").</dd>
+   * <dt><code>stylesheet.result.type</code></dt>
+   * <dd>Specifies the stylesheet result type. The value is either 'fo'
+   * (for XSL Formatting Objects) or it isn't. (builtin default: html).</dd>
+   * </dl>
+   *
+   * @param context The current stylesheet context
+   *
+   */
+  private static void setupLineNumbering(Context context) {
+    // Hardcoded defaults
+    modulus = 5;
+    width = 3;
+    separator = " ";
+
+    String varString = null;
+
+    // Get the modulus
+    varString = getVariable(context, "linenumbering.everyNth");
+    try {
+      modulus = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$linenumbering.everyNth is not a number: " + varString);
+    }
+
+    // Get the width
+    varString = getVariable(context, "linenumbering.width");
+    try {
+      width = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$linenumbering.width is not a number: " + varString);
+    }
+
+    // Get the separator
+    varString = getVariable(context, "linenumbering.separator");
+    separator = varString;
+  }
+
+  /**
+   * <p>Number lines in a verbatim environment.</p>
+   *
+   * <p>This method adds line numbers to a result tree fragment. Each
+   * newline that occurs in a text node is assumed to start a new line.
+   * The first line is always numbered, every subsequent saxonMod line
+   * is numbered (so if saxonMod=5, lines 1, 5, 10, 15, etc. will be
+   * numbered. If there are fewer than saxonMod lines in the environment,
+   * every line is numbered.</p>
+   *
+   * <p>Every line number will be right justified in a string saxonWidth
+   * characters long. If the line number of the last line in the
+   * environment is too long to fit in the specified width, the width
+   * is automatically increased to the smallest value that can hold the
+   * number of the last line. (In other words, if you specify the value 2
+   * and attempt to enumerate the lines of an environment that is 100 lines
+   * long, the value 3 will automatically be used for every line in the
+   * environment.)</p>
+   *
+   * <p>The saxonSep string is inserted between the line
+   * number and the original program listing. Lines that aren't numbered
+   * are preceded by a saxonWidth blank string and the separator.</p>
+   *
+   * <p>If inline markup extends across line breaks, markup changes are
+   * required. All the open elements are closed before the line break and
+   * "reopened" afterwards. The reopened elements will have the same
+   * attributes as the originals, except that 'name' and 'id' attributes
+   * are not duplicated.</p>
+   *
+   * @param saxonRTF The result tree fragment of the verbatim environment.
+   *
+   * @return The modified result tree fragment.
+   */
+  public static FragmentValue numberLines (Context context,
+                                          FragmentValue saxonRTF) {
+
+    setupLineNumbering(context);
+
+    try {
+      int numLines = countLineBreaks(saxonRTF.getFirst()) + 1;
+
+      elementStack = new Stack();
+      lineNumber = 0;
+
+      double log10numLines = Math.log(numLines) / Math.log(10);
+
+      if (width < log10numLines + 1) {
+       width = (int) Math.floor(log10numLines + 1);
+      }
+
+      FragmentValue rtf = new FragmentValue();
+      lineNumberFragment(rtf, saxonRTF.getFirst());
+      return rtf;
+    } catch (SAXException e) {
+      // This "can't" happen.
+      System.out.println("SAX Exception in numberLines");
+      return saxonRTF;
+    }
+  }
+
+  /**
+   * <p>Count the number of lines in a verbatim environment.</p>
+   *
+   * <p>This method walks over the nodes of a FragmentValue and
+   * returns the number of lines breaks that it contains.</p>
+   *
+   * @param node The root of the tree walk over.
+   */
+  private static int countLineBreaks(NodeInfo node) {
+    NodeInfo children[] = null;
+    int numLines = 0;
+
+    if (node.getNodeType() == NodeInfo.DOCUMENT) {
+      children = ((DocumentInfo) node).getAllChildNodes();
+    } else if (node.getNodeType() == NodeInfo.ELEMENT) {
+      children = ((ElementInfo) node).getAllChildNodes();
+    } else if (node.getNodeType() == NodeInfo.TEXT) {
+      String text = node.getValue();
+
+       // Walk through the text node looking for newlines
+      char chars[] = new char[text.length()];
+      int pos = 0;
+      for (int count = 0; count < text.length(); count++) {
+       if (text.charAt(count) == '\n') {
+         numLines++;
+       }
+      }
+    } else {
+      // nop
+    }
+
+    if (children != null) {
+      for (int count = 0; count < children.length; count++) {
+       numLines += countLineBreaks(children[count]);
+      }
+    }
+
+    return numLines;
+  }
+
+  /**
+   * <p>Build a FragmentValue with numbered lines.</p>
+   *
+   * <p>This is the method that actually does the work of numbering
+   * lines in a verbatim environment. It recursively walks through a
+   * tree of nodes, copying the structure into the rtf. Text nodes
+   * are examined for new lines and modified as requested by the
+   * global line numbering parameters.</p>
+   *
+   * <p>When called, rtf should be an empty FragmentValue and node
+   * should be the first child of the result tree fragment that contains
+   * the existing, formatted verbatim text.</p>
+   *
+   * @param rtf The resulting verbatim environment with numbered lines.
+   * @param node The root of the tree to copy.
+   */
+  private static void lineNumberFragment(FragmentValue rtf,
+                                        NodeInfo node) {
+    NodeInfo children[] = null;
+    boolean skipStack = false;
+
+    try {
+      if (node.getNodeType() == NodeInfo.DOCUMENT) {
+       rtf.startDocument();
+       children = ((DocumentInfo) node).getAllChildNodes();
+      } else if (node.getNodeType() == NodeInfo.ELEMENT) {
+       rtf.startElement(node.getExpandedName(),
+                        ((ElementInfo) node).getAttributeList());
+
+       if (elementStack.empty()) {
+         Name foBlock = new Name("fo",
+                                 "http://www.w3.org/1999/XSL/Format",
+                                 "block");
+         if (foBlock.equals(node.getExpandedName())
+             || node.getNodeName().equalsIgnoreCase("pre")
+             || node.getNodeName().equalsIgnoreCase("div")) {
+           // Don't push the outer-most wrapping div, pre, or fo:block
+           skipStack = true;
+         }
+       }
+
+       if (!skipStack) {
+         elementStack.push(node);
+       }
+
+       children = ((ElementInfo) node).getAllChildNodes();
+      } else if (node.getNodeType() == NodeInfo.TEXT) {
+       String text = node.getValue();
+
+       if (lineNumber == 0) {
+         // The first line is always numbered
+         formatLineNumber(rtf, ++lineNumber);
+       }
+
+       // Walk through the text node looking for newlines
+       char chars[] = new char[text.length()];
+       int pos = 0;
+       for (int count = 0; count < text.length(); count++) {
+         if (text.charAt(count) == '\n') {
+           // This is the tricky bit; if we find a newline, make sure
+           // it doesn't occur inside any markup.
+
+           if (pos > 0) {
+             rtf.characters(chars, 0, pos);
+             pos = 0;
+           }
+
+           // Close all the open elements...
+           closeOpenElements(rtf);
+
+           // Copy the newline to the output
+           chars[pos++] = text.charAt(count);
+           rtf.characters(chars, 0, pos);
+           pos = 0;
+
+           // Add the line number
+           formatLineNumber(rtf, ++lineNumber);
+
+           // Now "reopen" the elements that we closed...
+           openClosedElements(rtf);
+         } else {
+           chars[pos++] = text.charAt(count);
+         }
+       }
+
+       if (pos > 0) {
+         rtf.characters(chars, 0, pos);
+       }
+      } else if (node.getNodeType() == NodeInfo.COMMENT) {
+       String text = node.getValue();
+
+       char chars[] = new char[text.length()];
+       for (int count = 0; count < text.length(); count++) {
+         chars[count] = text.charAt(count);
+       }
+       rtf.comment(chars, 0, text.length());
+      } else if (node.getNodeType() == NodeInfo.PI) {
+       rtf.processingInstruction(node.getNodeName(), node.getValue());
+      } else {
+       System.out.println("Warning: unexpected node type in lineNumberFragment");
+      }
+
+      if (children != null) {
+       for (int count = 0; count < children.length; count++) {
+         lineNumberFragment(rtf, children[count]);
+       }
+      }
+
+      if (node.getNodeType() == NodeInfo.DOCUMENT) {
+       rtf.endDocument();
+      } else if (node.getNodeType() == NodeInfo.ELEMENT) {
+       rtf.endElement(node.getExpandedName());
+       if (!skipStack) {
+         elementStack.pop();
+       }
+      } else {
+       // nop
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in lineNumberFragment");
+    }
+  }
+
+  /**
+   * <p>Add a formatted line number to the result tree fragment.</p>
+   *
+   * <p>This method examines the global parameters that control line
+   * number presentation (modulus, width, and separator) and adds
+   * the appropriate text to the result tree fragment.</p>
+   *
+   * @param rtf The resulting verbatim environment with numbered lines.
+   * @param lineNumber The number of the current line.
+   */
+  private static void formatLineNumber(FragmentValue rtf,
+                                      int lineNumber) {
+    char ch = 160;
+    String lno = "";
+    if (lineNumber == 1
+       || (modulus >= 1 && (lineNumber % modulus == 0))) {
+      lno = "" + lineNumber;
+    }
+
+    while (lno.length() < width) {
+      lno = ch + lno;
+    }
+
+    lno += separator;
+
+    char chars[] = new char[lno.length()];
+    for (int count = 0; count < lno.length(); count++) {
+      chars[count] = lno.charAt(count);
+    }
+
+    try {
+      rtf.characters(chars, 0, lno.length());
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in formatLineNumber");
+    }
+  }
+
+  /**
+   * <p>Setup the parameters associated with callouts</p>
+   *
+   * <p>This method queries the stylesheet for the variables
+   * associated with line numbering. It is called automatically before
+   * callouts are processed. The context is used to retrieve the values,
+   * this allows templates to redefine these variables.</p>
+   *
+   * <p>The following variables are queried. If the variables do not
+   * exist, builtin defaults will be used (but you may also get a bunch
+   * of messages from the Java interpreter).</p>
+   *
+   * <dl>
+   * <dt><code>callout.graphics</code></dt>
+   * <dd>Are we using callout graphics? A value of 0 or "" is false,
+   * any other value is true. If callout graphics are not used, the
+   * parameters related to graphis are not queried.</dd>
+   * <dt><code>callout.graphics.path</code></dt>
+   * <dd>Specifies the path to callout graphics.</dd>
+   * <dt><code>callout.graphics.extension</code></dt>
+   * <dd>Specifies the extension ot use for callout graphics.</dd>
+   * <dt><code>callout.graphics.number.limit</code></dt>
+   * <dd>Identifies the largest number that can be represented as a
+   * graphic. Larger callout numbers will be represented using text.</dd>
+   * <dt><code>callout.defaultcolumn</code></dt>
+   * <dd>Specifies the default column for callout bullets that do not
+   * specify a column.</dd>
+   * <dt><code>stylesheet.result.type</code></dt>
+   * <dd>Specifies the stylesheet result type. The value is either 'fo'
+   * (for XSL Formatting Objects) or it isn't. (builtin default: html).</dd>
+   * </dl>
+   *
+   * @param context The current stylesheet context
+   *
+   */
+  private static void setupCallouts(Context context) {
+    boolean useGraphics = false;
+    boolean useUnicode = false;
+
+    int unicodeStart = 48;
+    int unicodeMax = 0;
+
+    // Hardcoded defaults
+    defaultColumn = 60;
+    String graphicsPath = null;
+    String graphicsExt = null;
+    int graphicsMax = 0;
+    boolean foStylesheet = false;
+
+    Value variable = null;
+    String varString = null;
+
+    // Get the stylesheet type
+    varString = getVariable(context, "stylesheet.result.type");
+    foStylesheet = (varString.equals("fo"));
+
+      // Get the default column
+    varString = getVariable(context, "callout.defaultcolumn");
+    try {
+      defaultColumn = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$callout.defaultcolumn is not a number: "
+                        + varString);
+    }
+
+    // Use graphics at all?
+    varString = getVariable(context, "callout.graphics");
+    useGraphics = !(varString.equals("0") || varString.equals(""));
+
+      // Use unicode at all?
+    varString = getVariable(context, "callout.unicode");
+    useUnicode = !(varString.equals("0") || varString.equals(""));
+
+    if (useGraphics) {
+      // Get the graphics path
+      varString = getVariable(context, "callout.graphics.path");
+      graphicsPath = varString;
+
+      // Get the graphics extension
+      varString = getVariable(context, "callout.graphics.extension");
+      graphicsExt = varString;
+
+      // Get the number limit
+      varString = getVariable(context, "callout.graphics.number.limit");
+      try {
+       graphicsMax = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.graphics.number.limit is not a number: "
+                          + varString);
+       graphicsMax = 0;
+      }
+
+      fCallout = new FormatGraphicCallout(graphicsPath,
+                                         graphicsExt,
+                                         graphicsMax,
+                                         foStylesheet);
+    } else if (useUnicode) {
+      // Get the starting character
+      varString = getVariable(context, "callout.unicode.start.character");
+      try {
+       unicodeStart = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.unicode.start.character is not a number: "
+                          + varString);
+       unicodeStart = 48;
+      }
+
+      // Get the number limit
+      varString = getVariable(context, "callout.unicode.number.limit");
+      try {
+       unicodeMax = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.unicode.number.limit is not a number: "
+                          + varString);
+       unicodeStart = 0;
+      }
+
+      fCallout = new FormatUnicodeCallout(unicodeStart,
+                                         unicodeMax,
+                                         foStylesheet);
+    } else {
+      fCallout = new FormatTextCallout(foStylesheet);
+    }
+  }
+
+  /**
+   * <p>Insert callouts into a verbatim environment.</p>
+   *
+   * <p>This method examines the <tt>areaset</tt> and <tt>area</tt> elements
+   * in the supplied <tt>areaspec</tt> and decorates the supplied
+   * result tree fragment with appropriate callout markers.</p>
+   *
+   * <p>If a <tt>label</tt> attribute is supplied on an <tt>area</tt>,
+   * its content will be used for the label, otherwise the callout
+   * number will be used. Callouts are
+   * numbered in document order. All of the <tt>area</tt>s in an
+   * <tt>areaset</tt> get the same number.</p>
+   *
+   * <p>If the callout number is not greater than <tt>gMax</tt>, the
+   * callout generated will be:</p>
+   *
+   * <pre>
+   * &lt;img src="$gPath/conumber$gExt" alt="conumber">
+   * </pre>
+   *
+   * <p>Otherwise, it will be the callout number surrounded by
+   * parenthesis.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the defaultColumn. Lines will be padded with blanks to reach the
+   * necessary column, but callouts that are located beyond the last
+   * line of the verbatim environment will be ignored.</p>
+   *
+   * <p>Callouts are inserted before the character at the line/column
+   * where they are to occur.</p>
+   *
+   * @param areaspecNodeSet The source node set that contains the areaspec.
+   * @param saxonRTF The result tree fragment of the verbatim environment.
+   * @param defaultColumn The column for callouts that specify only a line.
+   * @param gPath The path to use for callout graphics.
+   * @param gExt The extension to use for callout graphics.
+   * @param gMax The largest number that can be represented as a graphic.
+   * @param useFO Should fo:external-graphics be produced, as opposed to
+   * HTML imgs. This is bogus, the extension should figure it out, but I
+   * haven't figured out how to do that yet.
+   *
+   * @return The modified result tree fragment.
+   */
+  public static FragmentValue insertCallouts (Context context,
+                                             NodeSetIntent areaspecNodeSet,
+                                             FragmentValue saxonRTF) {
+
+    setupCallouts(context);
+
+    callout = new Callout[10];
+    calloutCount = 0;
+    calloutPos = 0;
+    lineNumber = 1;
+    colNumber = 1;
+
+    // First we walk through the areaspec to calculate the position
+    // of the callouts
+    //  <areaspec>
+    //  <areaset id="ex.plco.const" coords="">
+    //    <area id="ex.plco.c1" coords="4"/>
+    //    <area id="ex.plco.c2" coords="8"/>
+    //  </areaset>
+    //  <area id="ex.plco.ret" coords="12"/>
+    //  <area id="ex.plco.dest" coords="12"/>
+    //  </areaspec>
+    try {
+      int pos = 0;
+      int coNum = 0;
+      boolean inAreaSet = false;
+      NodeInfo areaspec = areaspecNodeSet.getFirst();
+      NodeInfo children[] = areaspec.getAllChildNodes();
+
+      for (int count = 0; count < children.length; count++) {
+       NodeInfo node = children[count];
+       if (node.getNodeType() == NodeInfo.ELEMENT) {
+         if (node.getNodeName().equalsIgnoreCase("areaset")) {
+           coNum++;
+           NodeInfo areas[] = node.getAllChildNodes();
+           for (int acount = 0; acount < areas.length; acount++) {
+             NodeInfo area = areas[acount];
+             if (area.getNodeType() == NodeInfo.ELEMENT) {
+               if (area.getNodeName().equalsIgnoreCase("area")) {
+                 addCallout(coNum, area, defaultColumn);
+               } else {
+                 System.out.println("Unexpected element in areaset: "
+                                    + area.getNodeName());
+               }
+             }
+           }
+         } else if (node.getNodeName().equalsIgnoreCase("area")) {
+           coNum++;
+           addCallout(coNum, node, defaultColumn);
+         } else {
+           System.out.println("Unexpected element in areaspec: "
+                              + node.getNodeName());
+         }
+       }
+      }
+
+      // Now sort them
+      java.util.Arrays.sort(callout, 0, calloutCount);
+
+      FragmentValue rtf = new FragmentValue();
+      calloutFragment(rtf, saxonRTF.getFirst());
+      return rtf;
+    } catch (SAXException e) {
+      return saxonRTF;
+    }
+  }
+
+  /**
+   * <p>Build a FragmentValue with callout decorations.</p>
+   *
+   * <p>This is the method that actually does the work of adding
+   * callouts to a verbatim environment. It recursively walks through a
+   * tree of nodes, copying the structure into the rtf. Text nodes
+   * are examined for the position of callouts as described by the
+   * global callout parameters.</p>
+   *
+   * <p>When called, rtf should be an empty FragmentValue and node
+   * should be the first child of the result tree fragment that contains
+   * the existing, formatted verbatim text.</p>
+   *
+   * @param rtf The resulting verbatim environment with numbered lines.
+   * @param node The root of the tree to copy.
+   */
+  private static void calloutFragment(FragmentValue rtf,
+                                     NodeInfo node) {
+    NodeInfo children[] = null;
+
+    try {
+      if (node.getNodeType() == NodeInfo.DOCUMENT) {
+       rtf.startDocument();
+       children = ((DocumentInfo) node).getAllChildNodes();
+      } else if (node.getNodeType() == NodeInfo.ELEMENT) {
+       rtf.startElement(node.getExpandedName(),
+                        ((ElementInfo) node).getAttributeList());
+       children = ((ElementInfo) node).getAllChildNodes();
+       elementStack.push(node);
+      } else if (node.getNodeType() == NodeInfo.TEXT) {
+       String text = node.getValue();
+
+       char chars[] = new char[text.length()];
+       int pos = 0;
+       for (int count = 0; count < text.length(); count++) {
+         if (calloutPos < calloutCount
+             && callout[calloutPos].getLine() == lineNumber
+             && callout[calloutPos].getColumn() == colNumber) {
+           if (pos > 0) {
+             rtf.characters(chars, 0, pos);
+             pos = 0;
+           }
+
+           closeOpenElements(rtf);
+
+           while (calloutPos < calloutCount
+                  && callout[calloutPos].getLine() == lineNumber
+                  && callout[calloutPos].getColumn() == colNumber) {
+             fCallout.formatCallout(rtf, callout[calloutPos]);
+             calloutPos++;
+           }
+
+           openClosedElements(rtf);
+         }
+
+         if (text.charAt(count) == '\n') {
+           // What if we need to pad this line?
+           if (calloutPos < calloutCount
+               && callout[calloutPos].getLine() == lineNumber
+               && callout[calloutPos].getColumn() > colNumber) {
+
+             if (pos > 0) {
+               rtf.characters(chars, 0, pos);
+               pos = 0;
+             }
+
+             closeOpenElements(rtf);
+
+             while (calloutPos < calloutCount
+                    && callout[calloutPos].getLine() == lineNumber
+                    && callout[calloutPos].getColumn() > colNumber) {
+               formatPad(rtf, callout[calloutPos].getColumn() - colNumber);
+               colNumber = callout[calloutPos].getColumn();
+               while (calloutPos < calloutCount
+                      && callout[calloutPos].getLine() == lineNumber
+                      && callout[calloutPos].getColumn() == colNumber) {
+                 fCallout.formatCallout(rtf, callout[calloutPos]);
+                 calloutPos++;
+               }
+             }
+
+             openClosedElements(rtf);
+           }
+
+           lineNumber++;
+           colNumber = 1;
+         } else {
+           colNumber++;
+         }
+         chars[pos++] = text.charAt(count);
+       }
+
+       if (pos > 0) {
+         rtf.characters(chars, 0, pos);
+       }
+      } else if (node.getNodeType() == NodeInfo.COMMENT) {
+       String text = node.getValue();
+       char chars[] = new char[text.length()];
+       for (int count = 0; count < text.length(); count++) {
+         chars[count] = text.charAt(count);
+       }
+       rtf.comment(chars, 0, text.length());
+      } else if (node.getNodeType() == NodeInfo.PI) {
+       rtf.processingInstruction(node.getNodeName(), node.getValue());
+      } else {
+       System.out.println("Warning: unexpected node type in calloutFragment");
+      }
+
+      if (children != null) {
+       for (int count = 0; count < children.length; count++) {
+         calloutFragment(rtf, children[count]);
+       }
+      }
+
+      if (node.getNodeType() == NodeInfo.DOCUMENT) {
+       rtf.endDocument();
+      } else if (node.getNodeType() == NodeInfo.ELEMENT) {
+       rtf.endElement(node.getExpandedName());
+       elementStack.pop();
+      } else {
+       // nop
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in calloutFragment");
+    }
+  }
+
+  /**
+   * <p>Add a callout to the global callout array</p>
+   *
+   * <p>This method examines a callout <tt>area</tt> and adds it to
+   * the global callout array if it can be interpreted.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the <tt>defaultColumn</tt>.</p>
+   *
+   * @param coNum The callout number.
+   * @param node The <tt>area</tt>.
+   * @param defaultColumn The default column for callouts.
+   */
+  private static void addCallout (int coNum,
+                                 NodeInfo node,
+                                 int defaultColumn) {
+    ElementInfo area = (ElementInfo) node;
+    AttributeCollection attr = area.getAttributeList();
+    String units  = attr.getValue("units");
+    String coords = attr.getValue("coords");
+
+    if (units != null
+       && !units.equalsIgnoreCase("linecolumn")
+       && !units.equalsIgnoreCase("linerange")) {
+      System.out.println("Only linecolumn and linerange units are supported");
+      return;
+    }
+
+    if (coords == null) {
+      System.out.println("Coords must be specified");
+      return;
+    }
+
+    // Now let's see if we can interpret the coordinates...
+    StringTokenizer st = new StringTokenizer(coords);
+    int tokenCount = 0;
+    int c1 = 0;
+    int c2 = 0;
+    while (st.hasMoreTokens()) {
+      tokenCount++;
+      if (tokenCount > 2) {
+       System.out.println("Unparseable coordinates");
+       return;
+      }
+      try {
+       String token = st.nextToken();
+       int coord = Integer.parseInt(token);
+       c2 = coord;
+       if (tokenCount == 1) {
+         c1 = coord;
+       }
+      } catch (NumberFormatException e) {
+       System.out.println("Unparseable coordinate");
+       return;
+      }
+    }
+
+    // Make sure we aren't going to blow past the end of our array
+    if (calloutCount == callout.length) {
+      Callout bigger[] = new Callout[calloutCount+10];
+      for (int count = 0; count < callout.length; count++) {
+       bigger[count] = callout[count];
+      }
+      callout = bigger;
+    }
+
+    // Ok, add the callout
+    if (tokenCount == 2) {
+      if (units != null && units.equalsIgnoreCase("linerange")) {
+       for (int count = c1; count <= c2; count++) {
+         callout[calloutCount++] = new Callout(coNum, area,
+                                               count, defaultColumn);
+       }
+      } else {
+       // assume linecolumn
+       callout[calloutCount++] = new Callout(coNum, area, c1, c2);
+      }
+    } else {
+      // if there's only one number, assume it's the line
+      callout[calloutCount++] = new Callout(coNum, area, c1, defaultColumn);
+    }
+  }
+
+  /**
+   * <p>Add blanks to the result tree fragment.</p>
+   *
+   * <p>This method adds <tt>numBlanks</tt> to the result tree fragment.
+   * It's used to pad lines when callouts occur after the last existing
+   * characater in a line.</p>
+   *
+   * @param rtf The resulting verbatim environment with numbered lines.
+   * @param numBlanks The number of blanks to add.
+   */
+  private static void formatPad(FragmentValue rtf,
+                               int numBlanks) {
+    char chars[] = new char[numBlanks];
+    for (int count = 0; count < numBlanks; count++) {
+      chars[count] = ' ';
+    }
+
+    try {
+      rtf.characters(chars, 0, numBlanks);
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in formatCallout");
+    }
+  }
+
+  private static void closeOpenElements(FragmentValue rtf)
+    throws SAXException {
+    String foURI = "http://www.w3.org/1999/XSL/Format";
+    String xhURI = "http://www.w3.org/1999/xhtml";
+
+    // Close all the open elements...
+    tempStack = new Stack();
+    while (!elementStack.empty()) {
+      ElementInfo elem = (ElementInfo) elementStack.pop();
+      Name exName = elem.getExpandedName();
+      String localName = elem.getLocalName();
+      String ns = exName.getURI();
+
+      if (ns != null && ns.equals("")) {
+       ns = null;
+      }
+
+      // If this is the bottom of the stack and it's an fo:block
+      // or an HTML pre or div, don't duplicate it...
+      if (elementStack.empty()
+         && (((ns != null)
+              && ns.equals(foURI)
+              && localName.equals("block"))
+             || ((ns == null)
+                 && localName.equalsIgnoreCase("pre"))
+             || ((ns != null)
+                 && ns.equals(xhURI)
+                 && localName.equals("pre"))
+             || ((ns == null)
+                 && localName.equalsIgnoreCase("div"))
+             || ((ns != null)
+                 && ns.equals(xhURI)
+                 && localName.equals("div")))) {
+       elementStack.push(elem);
+       break;
+      } else {
+       rtf.endElement(exName);
+       tempStack.push(elem);
+      }
+    }
+  }
+
+  private static void openClosedElements(FragmentValue rtf)
+    throws SAXException {
+    // Now "reopen" the elements that we closed...
+    while (!tempStack.empty()) {
+      ElementInfo elem = (ElementInfo) tempStack.pop();
+      AttributeCollection elemAttr = elem.getAttributeList();
+      AttributeCollection newAttr = new AttributeCollection();
+      for (int acount = 0; acount < elemAttr.getLength(); acount++) {
+       String name = elemAttr.getName(acount);
+
+       if (name.equalsIgnoreCase("name")
+           || name.equalsIgnoreCase("id")) {
+         // skip 'name' and 'id' attributes
+       } else {
+         newAttr.addAttribute(elemAttr.getExpandedName(acount),
+                              elemAttr.getType(acount),
+                              elemAttr.getValue(acount));
+       }
+      }
+
+      rtf.startElement(elem.getExpandedName(), newAttr);
+      elementStack.push(elem);
+    }
+  }
+}
diff --git a/xsl/extensions/saxon551/com/nwalsh/saxon/package.html b/xsl/extensions/saxon551/com/nwalsh/saxon/package.html
new file mode 100644 (file)
index 0000000..1253b73
--- /dev/null
@@ -0,0 +1,50 @@
+<html>
+<head>
+<title>Norman Walsh's Saxon Extensions Package</title>
+</head>
+<body>
+<p>Norman Walsh's Saxon Extensions Package for Saxon 5.*</p>
+
+<p>This package implements Saxon extensions for XSLT. Future development
+of this package will be limited to bug fixes only. The Saxon 6.0 Extension
+Package is a practically complete, and much cleaner, reimplementation.</p>
+
+<p><b>Copyright (C) 2000 Norman Walsh</b></p>
+<p>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:</p>
+
+<p>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.</p>
+
+<p>Except as contained in this notice, the names of individuals
+credited with contribution to this software shall not be used in
+advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the
+individuals in question.</p>
+
+<p>Anything derived from this Software that is publically
+distributed will be identified with a different name and the
+version strings in any derived Software will be changed so that no
+possibility of confusion between the derived package and this
+Software will exist.</p>
+</blockquote>
+
+<blockquote>
+<p><b>Warranty</b></p>
+<p>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 NORMAN WALSH OR ANY OTHER
+CONTRIBUTOR 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.</p>
+</blockquote>
+
+</body>
+</html>
diff --git a/xsl/extensions/saxon6/.cvsignore b/xsl/extensions/saxon6/.cvsignore
new file mode 100644 (file)
index 0000000..4d3c216
--- /dev/null
@@ -0,0 +1 @@
+.classes
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/CVS.java b/xsl/extensions/saxon6/com/nwalsh/saxon/CVS.java
new file mode 100644 (file)
index 0000000..529546b
--- /dev/null
@@ -0,0 +1,90 @@
+package com.nwalsh.saxon;
+
+import java.io.*;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.text.DateFormat;
+import java.text.ParseException;
+
+/**
+ * <p>Saxon extension to convert CVS date strings into local time</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension to turn the CVS date strings, which are UTC:</p>
+ *
+ * <pre>&#36;Date: 2000/11/09 02:34:20 &#36;</pre>
+ *
+ * <p>into legibly formatted local time:</p>
+ *
+ * <pre>Wed Nov 08 18:34:20 PST 2000</pre>
+ *
+ * <p>(I happened to be in California when I wrote this documentation.)</p>
+
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class CVS {
+  /**
+   * <p>Constructor for CVS</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public CVS() {
+  }
+
+  /**
+   * <p>Convert a CVS date string into local time.</p>
+   *
+   * @param cvsDate The CVS date string.
+   *
+   * @return The date, converted to local time and reformatted.
+   */
+  public static String localTime (String cvsDate) {
+    // A cvsDate has the following form "$Date$"
+    if (!cvsDate.startsWith("$Date: ")) {
+      return cvsDate;
+    }
+
+    String yrS = cvsDate.substring(7,11);
+    String moS = cvsDate.substring(12,14);
+    String daS = cvsDate.substring(15,17);
+    String hrS = cvsDate.substring(18,20);
+    String miS = cvsDate.substring(21,23);
+    String seS = cvsDate.substring(24,26);
+
+    TimeZone tz = TimeZone.getTimeZone("GMT+0");
+    GregorianCalendar gmtCal = new GregorianCalendar(tz);
+
+    try {
+      gmtCal.set(Integer.parseInt(yrS),
+                Integer.parseInt(moS)-1,
+                Integer.parseInt(daS),
+                Integer.parseInt(hrS),
+                Integer.parseInt(miS),
+                Integer.parseInt(seS));
+    } catch (NumberFormatException e) {
+      // nop
+    }
+
+    Date d = gmtCal.getTime();
+
+    return d.toString();
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/Callout.java b/xsl/extensions/saxon6/com/nwalsh/saxon/Callout.java
new file mode 100644 (file)
index 0000000..f0be0cd
--- /dev/null
@@ -0,0 +1,91 @@
+package com.nwalsh.saxon;
+
+import com.icl.saxon.om.*;
+import com.icl.saxon.tree.*;
+
+/**
+ * <p>A class for maintaining information about callouts.</p>
+ *
+ * <p>To make processing callouts easier, they are parsed out of the
+ * input structure and stored in a sorted array. (The array is sorted
+ * according to the order in which the callouts occur.)</p>
+ *
+ * <p>This class is just the little record
+ * that we store in the array for each callout.</p>
+ */
+public class Callout implements Comparable {
+  /** The callout number. */
+  private int callout = 0;
+  /** The area ElementInfo item that generated this callout. */
+  private ElementInfo area = null;
+  /** The line on which this callout occurs. */
+  private int line = 0;
+  /** The column in which this callout appears. */
+  private int col = 0;
+
+  /** The constructor; initialize the private data structures. */
+  public Callout(int callout, ElementInfo area, int line, int col) {
+    this.callout = callout;
+    this.area = area;
+    this.line = line;
+    this.col = col;
+  }
+
+  /**
+   * <p>The compareTo method compares this Callout with another.</p>
+   *
+   * <p>Given two Callouts, A and B, A < B if:</p>
+   *
+   * <ol>
+   * <li>A.line < B.line, or</li>
+   * <li>A.line = B.line && A.col < B.col, or</li>
+   * <li>A.line = B.line && A.col = B.col && A.callout < B.callout</li>
+   * <li>Otherwise, they're equal.</li>
+   * </ol>
+   */
+  public int compareTo (Object o) {
+    Callout c = (Callout) o;
+
+    if (line == c.getLine()) {
+       if (col > c.getColumn()) {
+         return 1;
+       } else if (col < c.getColumn()) {
+         return -1;
+       } else {
+         if (callout < c.getCallout()) {
+           return -1;
+         } else if (callout > c.getCallout()) {
+           return 1;
+         } else {
+           return 0;
+         }
+       }
+    } else {
+       if (line > c.getLine()) {
+         return 1;
+       } else {
+         return -1;
+       }
+    }
+  }
+
+  /** Access the Callout's area. */
+  public ElementInfo getArea() {
+    return area;
+  }
+
+  /** Access the Callout's line. */
+  public int getLine() {
+    return line;
+  }
+
+  /** Access the Callout's column. */
+  public int getColumn() {
+    return col;
+  }
+
+  /** Access the Callout's callout number. */
+  public int getCallout() {
+    return callout;
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/CalloutEmitter.java b/xsl/extensions/saxon6/com/nwalsh/saxon/CalloutEmitter.java
new file mode 100644 (file)
index 0000000..01cbfaa
--- /dev/null
@@ -0,0 +1,522 @@
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import com.icl.saxon.Builder;
+import com.icl.saxon.Context;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.functions.Extensions;
+import com.icl.saxon.om.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.tree.*;
+
+/**
+ * <p>Saxon extension to decorate a result tree fragment with callouts.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides the guts of a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation of callouts for verbatim environments. (It is used
+ * by the Verbatim class.)</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some verbatim environment. The Verbatim class initializes
+ * a CalloutEmitter with information about the callouts that should be applied
+ * to the verbatim environment in question. Then the result tree fragment
+ * is "replayed" through the CalloutEmitter; the CalloutEmitter builds a
+ * new result tree fragment from this event stream, decorated with callouts,
+ * and that is returned.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @see Verbatim
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class CalloutEmitter extends CopyEmitter {
+  /** A stack for the preserving information about open elements. */
+  protected Stack elementStack = null;
+
+  /** A stack for holding information about temporarily closed elements. */
+  protected Stack tempStack = null;
+
+  /** Is the next element absolutely the first element in the fragment? */
+  protected boolean firstElement = false;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /** The default column for callouts that specify only a line. */
+  protected int defaultColumn = 60;
+
+  /** Is the stylesheet currently running an FO stylesheet? */
+  protected boolean foStylesheet = false;
+
+  /** The current line number. */
+  private static int lineNumber = 0;
+
+  /** The current column number. */
+  private static int colNumber = 0;
+
+  /** The (sorted) array of callouts obtained from the areaspec. */
+  private static Callout callout[] = null;
+
+  /** The number of callouts in the callout array. */
+  private static int calloutCount = 0;
+
+  /** A pointer used to keep track of our position in the callout array. */
+  private static int calloutPos = 0;
+
+  /** The FormatCallout object to use for formatting callouts. */
+  private static FormatCallout fCallout = null;
+
+  /** <p>Constructor for the CalloutEmitter.</p>
+   *
+   * @param namePool The name pool to use for constructing elements and attributes.
+   * @param defaultColumn The default column for callouts.
+   * @param foStylesheet Is this an FO stylesheet?
+   * @param fCallout The callout formatting object
+   */
+  public CalloutEmitter(NamePool namePool,
+                       int defaultColumn,
+                       boolean foStylesheet,
+                       FormatCallout fCallout) {
+    super(namePool);
+    elementStack = new Stack();
+    firstElement = true;
+
+    this.defaultColumn = defaultColumn;
+    this.foStylesheet = foStylesheet;
+    this.fCallout = fCallout;
+  }
+
+  /**
+   * <p>Examine the areaspec and determine the number and position of 
+   * callouts.</p>
+   *
+   * <p>The <code><a href="http://docbook.org/tdg/html/areaspec.html">areaspecNodeSet</a></code>
+   * is examined and a sorted list of the callouts is constructed.</p>
+   *
+   * <p>This data structure is used to augment the result tree fragment
+   * with callout bullets.</p>
+   *
+   * @param areaspecNodeSet The source document &lt;areaspec&gt; element.
+   *
+   */
+  public void setupCallouts (NodeSetIntent areaspecNodeSet) {
+    callout = new Callout[10];
+    calloutCount = 0;
+    calloutPos = 0;
+    lineNumber = 1;
+    colNumber = 1;
+
+    // First we walk through the areaspec to calculate the position
+    // of the callouts
+    //  <areaspec>
+    //  <areaset id="ex.plco.const" coords="">
+    //    <area id="ex.plco.c1" coords="4"/>
+    //    <area id="ex.plco.c2" coords="8"/>
+    //  </areaset>
+    //  <area id="ex.plco.ret" coords="12"/>
+    //  <area id="ex.plco.dest" coords="12"/>
+    //  </areaspec>
+    try {
+      int pos = 0;
+      int coNum = 0;
+      boolean inAreaSet = false;
+      NodeInfo areaspec = areaspecNodeSet.getFirst();
+      NodeInfo children[] = areaspec.getAllChildNodes();
+
+      for (int count = 0; count < children.length; count++) {
+       NodeInfo node = children[count];
+       if (node.getNodeType() == NodeInfo.ELEMENT) {
+         if (node.getNodeName().equalsIgnoreCase("areaset")) {
+           coNum++;
+           NodeInfo areas[] = node.getAllChildNodes();
+           for (int acount = 0; acount < areas.length; acount++) {
+             NodeInfo area = areas[acount];
+             if (area.getNodeType() == NodeInfo.ELEMENT) {
+               if (area.getNodeName().equalsIgnoreCase("area")) {
+                 addCallout(coNum, area, defaultColumn);
+               } else {
+                 System.out.println("Unexpected element in areaset: "
+                                    + area.getNodeName());
+               }
+             }
+           }
+         } else if (node.getNodeName().equalsIgnoreCase("area")) {
+           coNum++;
+           addCallout(coNum, node, defaultColumn);
+         } else {
+           System.out.println("Unexpected element in areaspec: "
+                              + node.getNodeName());
+         }
+       }
+      }
+
+      // Now sort them
+      java.util.Arrays.sort(callout, 0, calloutCount);
+    } catch (SAXException e) {
+      //nop;
+    }
+  }
+
+  /** Process characters. */
+  public void characters(char[] chars, int start, int len)
+    throws org.xml.sax.SAXException {
+
+    // If we hit characters, then there's no first element...
+    firstElement = false;
+
+    if (lineNumber == 0) {
+      // if there are any text nodes, there's at least one line
+      lineNumber++;
+      colNumber = 1;
+    }
+
+    // Walk through the text node looking for callout positions
+    char[] newChars = new char[len];
+    int pos = 0;
+    for (int count = start; count < start+len; count++) {
+      if (calloutPos < calloutCount
+         && callout[calloutPos].getLine() == lineNumber
+         && callout[calloutPos].getColumn() == colNumber) {
+       if (pos > 0) {
+         rtf.characters(newChars, 0, pos);
+         pos = 0;
+       }
+
+       closeOpenElements(rtf);
+
+       while (calloutPos < calloutCount
+              && callout[calloutPos].getLine() == lineNumber
+              && callout[calloutPos].getColumn() == colNumber) {
+         fCallout.formatCallout(rtf, callout[calloutPos]);
+         calloutPos++;
+       }
+
+       openClosedElements(rtf);
+      }
+
+      if (chars[count] == '\n') {
+       // What if we need to pad this line?
+       if (calloutPos < calloutCount
+           && callout[calloutPos].getLine() == lineNumber
+           && callout[calloutPos].getColumn() > colNumber) {
+
+         if (pos > 0) {
+           rtf.characters(newChars, 0, pos);
+           pos = 0;
+         }
+
+         closeOpenElements(rtf);
+
+         while (calloutPos < calloutCount
+                && callout[calloutPos].getLine() == lineNumber
+                && callout[calloutPos].getColumn() > colNumber) {
+           formatPad(callout[calloutPos].getColumn() - colNumber);
+           colNumber = callout[calloutPos].getColumn();
+           while (calloutPos < calloutCount
+                  && callout[calloutPos].getLine() == lineNumber
+                  && callout[calloutPos].getColumn() == colNumber) {
+             fCallout.formatCallout(rtf, callout[calloutPos]);
+             calloutPos++;
+           }
+         }
+
+         openClosedElements(rtf);
+       }
+
+       lineNumber++;
+       colNumber = 1;
+      } else {
+       colNumber++;
+      }
+      newChars[pos++] = chars[count];
+    }
+
+    if (pos > 0) {
+      rtf.characters(newChars, 0, pos);
+    }
+  }
+
+  /**
+   * <p>Add blanks to the result tree fragment.</p>
+   *
+   * <p>This method adds <tt>numBlanks</tt> to the result tree fragment.
+   * It's used to pad lines when callouts occur after the last existing
+   * characater in a line.</p>
+   *
+   * @param numBlanks The number of blanks to add.
+   */
+  protected void formatPad(int numBlanks) {
+    char chars[] = new char[numBlanks];
+    for (int count = 0; count < numBlanks; count++) {
+      chars[count] = ' ';
+    }
+
+    try {
+      rtf.characters(chars, 0, numBlanks);
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in formatPad");
+    }
+  }
+
+  /**
+   * <p>Add a callout to the global callout array</p>
+   *
+   * <p>This method examines a callout <tt>area</tt> and adds it to
+   * the global callout array if it can be interpreted.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the <tt>defaultColumn</tt>.</p>
+   *
+   * @param coNum The callout number.
+   * @param node The <tt>area</tt>.
+   * @param defaultColumn The default column for callouts.
+   */
+  protected void addCallout (int coNum,
+                            NodeInfo node,
+                            int defaultColumn) {
+    ElementInfo area = (ElementInfo) node;
+    ExtendedAttributes attr = area.getAttributeList();
+    String units  = attr.getValue("units");
+    String coords = attr.getValue("coords");
+
+    if (units != null
+       && !units.equalsIgnoreCase("linecolumn")
+       && !units.equalsIgnoreCase("linerange")) {
+      System.out.println("Only linecolumn and linerange units are supported");
+      return;
+    }
+
+    if (coords == null) {
+      System.out.println("Coords must be specified");
+      return;
+    }
+
+    // Now let's see if we can interpret the coordinates...
+    StringTokenizer st = new StringTokenizer(coords);
+    int tokenCount = 0;
+    int c1 = 0;
+    int c2 = 0;
+    while (st.hasMoreTokens()) {
+      tokenCount++;
+      if (tokenCount > 2) {
+       System.out.println("Unparseable coordinates");
+       return;
+      }
+      try {
+       String token = st.nextToken();
+       int coord = Integer.parseInt(token);
+       c2 = coord;
+       if (tokenCount == 1) {
+         c1 = coord;
+       }
+      } catch (NumberFormatException e) {
+       System.out.println("Unparseable coordinate");
+       return;
+      }
+    }
+
+    // Make sure we aren't going to blow past the end of our array
+    if (calloutCount == callout.length) {
+      Callout bigger[] = new Callout[calloutCount+10];
+      for (int count = 0; count < callout.length; count++) {
+       bigger[count] = callout[count];
+      }
+      callout = bigger;
+    }
+
+    // Ok, add the callout
+    if (tokenCount == 2) {
+      if (units != null && units.equalsIgnoreCase("linerange")) {
+       for (int count = c1; count <= c2; count++) {
+         callout[calloutCount++] = new Callout(coNum, area,
+                                               count, defaultColumn);
+       }
+      } else {
+       // assume linecolumn
+       callout[calloutCount++] = new Callout(coNum, area, c1, c2);
+      }
+    } else {
+      // if there's only one number, assume it's the line
+      callout[calloutCount++] = new Callout(coNum, area, c1, defaultColumn);
+    }
+  }
+
+  /** Process end element events. */
+  public void endElement(int nameCode)
+    throws org.xml.sax.SAXException {
+    if (!elementStack.empty()) {
+      // if we didn't push the very first element (an fo:block or
+      // pre or div surrounding the whole block), then the stack will
+      // be empty when we get to the end of the first element...
+      elementStack.pop();
+    }
+    rtf.endElement(nameCode);
+  }
+
+  /** Process start element events. */
+  public void startElement(int nameCode,
+                          org.xml.sax.Attributes attributes,
+                          int[] namespaces,
+                          int nscount)
+    throws org.xml.sax.SAXException {
+
+    if (!skipThisElement(nameCode)) {
+      StartElementInfo sei = new StartElementInfo(nameCode, attributes,
+                                                 namespaces, nscount);
+      elementStack.push(sei);
+    }
+
+    firstElement = false;
+
+    rtf.startElement(nameCode, attributes, namespaces, nscount);
+  }
+
+  /**
+   * <p>Protect the outer-most block wrapper.</p>
+   *
+   * <p>Open elements in the result tree fragment are closed and reopened
+   * around callouts (so that callouts don't appear inside links or other
+   * environments). But if the result tree fragment is a single block
+   * (a div or pre in HTML, an fo:block in FO), that outer-most block is
+   * treated specially.</p>
+   *
+   * <p>This method returns true if the element in question is that
+   * outermost block.</p>
+   *
+   * @param nameCode The name code for the element
+   *
+   * @return True if the element is the outer-most block, false otherwise.
+   */
+  protected boolean skipThisElement(int nameCode) {
+    if (firstElement) {
+      int thisFingerprint = namePool.getFingerprint(nameCode);
+      int foBlockFingerprint = namePool.getFingerprint(foURI, "block");
+      int htmlPreFingerprint = namePool.getFingerprint("", "pre");
+      int htmlDivFingerprint = namePool.getFingerprint("", "div");
+
+      if ((foStylesheet && thisFingerprint == foBlockFingerprint)
+         || (!foStylesheet && (thisFingerprint == htmlPreFingerprint
+                               || thisFingerprint == htmlDivFingerprint))) {
+       // Don't push the outer-most wrapping div, pre, or fo:block
+       return true;
+      }
+    }
+
+    return false;
+  }
+
+  private void closeOpenElements(Emitter rtfEmitter)
+    throws SAXException {
+    // Close all the open elements...
+    tempStack = new Stack();
+    while (!elementStack.empty()) {
+      StartElementInfo elem = (StartElementInfo) elementStack.pop();
+      rtfEmitter.endElement(elem.getNameCode());
+      tempStack.push(elem);
+    }
+  }
+
+  private void openClosedElements(Emitter rtfEmitter)
+    throws SAXException {
+    // Now "reopen" the elements that we closed...
+    while (!tempStack.empty()) {
+      StartElementInfo elem = (StartElementInfo) tempStack.pop();
+      AttributeCollection attr = (AttributeCollection)elem.getAttributes();
+      AttributeCollection newAttr = new AttributeCollection(namePool);
+
+      for (int acount = 0; acount < attr.getLength(); acount++) {
+       String localName = attr.getLocalName(acount);
+       int nameCode = attr.getNameCode(acount);
+       String type = attr.getType(acount);
+       String value = attr.getValue(acount);
+       String uri = attr.getURI(acount);
+       String prefix = "";
+
+       if (localName.indexOf(':') > 0) {
+         prefix = localName.substring(0, localName.indexOf(':'));
+         localName = localName.substring(localName.indexOf(':')+1);
+       }
+
+       if (uri.equals("")
+           && ((foStylesheet
+                && localName.equals("id"))
+               || (!foStylesheet
+                   && (localName.equals("id")
+                       || localName.equals("name"))))) {
+         // skip this attribute
+       } else {
+         newAttr.addAttribute(prefix, uri, localName, type, value);
+       }
+      }
+
+      rtfEmitter.startElement(elem.getNameCode(),
+                             newAttr,
+                             elem.getNamespaces(),
+                             elem.getNSCount());
+
+      elementStack.push(elem);
+    }
+  }
+
+  /**
+   * <p>A private class for maintaining the information required to call
+   * the startElement method.</p>
+   *
+   * <p>In order to close and reopen elements, information about those
+   * elements has to be maintained. This class is just the little record
+   * that we push on the stack to keep track of that info.</p>
+   */
+  private class StartElementInfo {
+    private int _nameCode;
+    org.xml.sax.Attributes _attributes;
+    int[] _namespaces;
+    int _nscount;
+
+    public StartElementInfo(int nameCode,
+                           org.xml.sax.Attributes attributes,
+                           int[] namespaces,
+                           int nscount) {
+      _nameCode = nameCode;
+      _attributes = attributes;
+      _namespaces = namespaces;
+      _nscount = nscount;
+    }
+
+    public int getNameCode() {
+      return _nameCode;
+    }
+
+    public org.xml.sax.Attributes getAttributes() {
+      return _attributes;
+    }
+
+    public int[] getNamespaces() {
+      return _namespaces;
+    }
+
+    public int getNSCount() {
+      return _nscount;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/ColumnScanEmitter.java b/xsl/extensions/saxon6/com/nwalsh/saxon/ColumnScanEmitter.java
new file mode 100644 (file)
index 0000000..a206b1d
--- /dev/null
@@ -0,0 +1,179 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.expr.FragmentValue;
+import com.icl.saxon.Builder;
+
+/**
+ * <p>Saxon extension to scan the column widthsin a result tree fragment.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation to scan the column widths in a result tree
+ * fragment.</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some colgroup environment. That result tree fragment
+ * is "replayed" through the ColumnScanEmitter; the ColumnScanEmitter watches
+ * the cols go by and extracts the column widths that it sees. These
+ * widths are then made available.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class ColumnScanEmitter implements com.icl.saxon.output.Emitter {
+  /** The number of columns seen. */
+  protected int numColumns = 0;
+  protected String width[] = new String[5];
+  protected NamePool namePool = null;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /** Construct a new ColumnScanEmitter. */
+  public ColumnScanEmitter(NamePool namePool) {
+    numColumns = 0;
+    this.namePool = namePool;
+  }
+
+  /** Return the number of columns. */
+  public int columnCount() {
+    return numColumns;
+  }
+
+  /** Return the number of columns. */
+  public String[] columnWidths() {
+    return width;
+  }
+
+  /** Discarded. */
+  public void characters(char[] chars, int start, int len)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void comment(char[] chars, int start, int length)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void endDocument()
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void endElement(int nameCode)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void processingInstruction(java.lang.String name,
+                                   java.lang.String data)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setCharacterSet(CharacterSet charset)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setDocumentLocator(org.xml.sax.Locator locator) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setEscaping(boolean escaping)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setNamePool(NamePool namePool) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setOutputDetails(OutputDetails details)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setUnparsedEntity(java.lang.String name, java.lang.String uri)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setWriter(java.io.Writer writer)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void startDocument()
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Examine for column info. */
+  public void startElement(int nameCode,
+                   org.xml.sax.Attributes attributes,
+                   int[] namespaces, int nscount)
+    throws org.xml.sax.SAXException {
+
+    int thisFingerprint = namePool.getFingerprint(nameCode);
+    int colFingerprint = namePool.getFingerprint("", "col");
+    int foColFingerprint = namePool.getFingerprint(foURI, "table-column");
+
+    if (thisFingerprint == colFingerprint
+       || thisFingerprint == foColFingerprint) {
+      if (numColumns >= width.length) {
+       String newWidth[] = new String[width.length+10];
+       for (int count = 0; count < width.length; count++) {
+         newWidth[count] = width[count];
+       }
+       width = newWidth;
+      }
+
+      if (thisFingerprint == colFingerprint) {
+       if (attributes.getValue("width") == null) {
+         width[numColumns++] = "1*";
+       } else {
+         width[numColumns++] = attributes.getValue("width");
+       }
+      } else {
+       if (attributes.getValue("column-width") == null) {
+         width[numColumns++] = "1*";
+       } else {
+         width[numColumns++] = attributes.getValue("column-width");
+       }
+      }
+    }
+  }
+}
+
+
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/ColumnUpdateEmitter.java b/xsl/extensions/saxon6/com/nwalsh/saxon/ColumnUpdateEmitter.java
new file mode 100644 (file)
index 0000000..a1d4798
--- /dev/null
@@ -0,0 +1,95 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.expr.FragmentValue;
+import com.icl.saxon.Builder;
+import com.icl.saxon.tree.AttributeCollection;
+
+/**
+ * <p>Saxon extension to scan the column widthsin a result tree fragment.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation to scan the column widths in a result tree
+ * fragment.</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some colgroup environment. That result tree fragment
+ * is "replayed" through the ColumnUpdateEmitter; the ColumnUpdateEmitter watches
+ * the cols go by and extracts the column widths that it sees. These
+ * widths are then made available.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class ColumnUpdateEmitter extends CopyEmitter {
+  /** The number of columns seen. */
+  protected int numColumns = 0;
+  protected String width[] = null;
+  protected NamePool namePool = null;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /** Construct a new ColumnUpdateEmitter. */
+  public ColumnUpdateEmitter(NamePool namePool,
+                            String width[]) {
+    super(namePool);
+    numColumns = 0;
+    this.width = width;
+    this.namePool = namePool;
+  }
+
+  /** Examine for column info. */
+  public void startElement(int nameCode,
+                   org.xml.sax.Attributes attributes,
+                   int[] namespaces, int nscount)
+    throws org.xml.sax.SAXException {
+
+    int thisFingerprint = namePool.getFingerprint(nameCode);
+    int colFingerprint = namePool.getFingerprint("", "col");
+    int foColFingerprint = namePool.getFingerprint(foURI, "table-column");
+
+    if (thisFingerprint == colFingerprint) {
+      AttributeCollection attr = new AttributeCollection(namePool, attributes);
+      int widthFingerprint = namePool.getFingerprint("", "width");
+
+      if (attr.getValueByFingerprint(widthFingerprint) == null) {
+       attr.addAttribute(widthFingerprint, "CDATA", width[numColumns++]);
+      } else {
+       attr.setAttribute(widthFingerprint, "CDATA", width[numColumns++]);
+      }
+      attributes = attr;
+    } else if (thisFingerprint == foColFingerprint) {
+      AttributeCollection attr = new AttributeCollection(namePool, attributes);
+      int widthFingerprint = namePool.getFingerprint("", "column-width");
+
+      if (attr.getValueByFingerprint(widthFingerprint) == null) {
+       attr.addAttribute(widthFingerprint, "CDATA", width[numColumns++]);
+      } else {
+       attr.setAttribute(widthFingerprint, "CDATA", width[numColumns++]);
+      }
+      attributes = attr;
+    }
+
+    rtf.startElement(nameCode, attributes, namespaces, nscount);
+  }
+}
+
+
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/CopyEmitter.java b/xsl/extensions/saxon6/com/nwalsh/saxon/CopyEmitter.java
new file mode 100644 (file)
index 0000000..008fe99
--- /dev/null
@@ -0,0 +1,165 @@
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import com.icl.saxon.Builder;
+import com.icl.saxon.Context;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.functions.Extensions;
+import com.icl.saxon.om.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.tree.*;
+
+/**
+ * <p>A Saxon 6.0 Emitter that clones its input.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation of an emitter that manufactures a cloned result
+ * tree fragment.</p>
+ *
+ * <p>The purpose of this emitter is to provide something for
+ * CalloutEmitter and NumberLinesEmitter to extend.
+ * This emitter simply copies all input to a new result tree fragment.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @see CalloutEmitter
+ * @see NumberLinesEmitter
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class CopyEmitter implements com.icl.saxon.output.Emitter {
+  /** The result tree fragment containing the copied fragment. */
+  protected FragmentValue rtf = null;
+
+  /** <p>The namePool.</p>
+   *
+   * <p>Copied from the caller, it should be the runtime name pool.</p>
+   */
+  protected NamePool namePool = null;
+
+  /** <p>Constructor for the CopyEmitter.</p>
+   *
+   * @param namePool The name pool to use for constructing elements and attributes.
+   */
+  public CopyEmitter(NamePool namePool) {
+    try {
+      rtf = new FragmentValue();
+      rtf.allowConversion(true);
+      this.namePool = namePool;
+    } catch (SAXException e) {
+      rtf = null;
+    }
+  }
+
+  /**
+   * <p>Return the result tree fragment constructed by replaying events
+   * through this emitter.</p>
+   */
+  public FragmentValue getResultTreeFragment() {
+    return rtf;
+  }
+
+  /** Copy characters. */
+  public void characters(char[] chars, int start, int len)
+    throws org.xml.sax.SAXException {
+    rtf.characters(chars, start, len);
+  }
+
+  /** Copy comments. */
+  public void comment(char[] chars, int start, int length)
+    throws org.xml.sax.SAXException {
+    rtf.comment(chars, start, length);
+  }
+
+  /** Copy end document events. */
+  public void endDocument()
+    throws org.xml.sax.SAXException {
+    rtf.endDocument();
+  }
+
+  /** Copy end element events. */
+  public void endElement(int nameCode)
+    throws org.xml.sax.SAXException {
+    rtf.endElement(nameCode);
+  }
+
+  /** Copy processing instructions. */
+  public void processingInstruction(java.lang.String name,
+                                   java.lang.String data)
+    throws org.xml.sax.SAXException {
+    rtf.processingInstruction(name, data);
+  }
+
+  /** Copy set character set events. */
+  public void setCharacterSet(CharacterSet charset)
+    throws org.xml.sax.SAXException {
+    rtf.setCharacterSet(charset);
+  }
+
+  /** Copy set document locator events. */
+  public void setDocumentLocator(org.xml.sax.Locator locator) {
+    rtf.setDocumentLocator(locator);
+  }
+
+  /** Copy set escaping events. */
+  public void setEscaping(boolean escaping)
+    throws org.xml.sax.SAXException {
+    rtf.setEscaping(escaping);
+  }
+
+  /** Copy set name pool events. */
+  public void setNamePool(NamePool namePool) {
+    rtf.setNamePool(namePool);
+  }
+
+  /** Copy set output details events. */
+  public void setOutputDetails(OutputDetails details)
+    throws org.xml.sax.SAXException {
+    rtf.setOutputDetails(details);
+  }
+
+  /** Copy set unparsed entity events. */
+  public void setUnparsedEntity(java.lang.String name, java.lang.String uri)
+    throws org.xml.sax.SAXException {
+    rtf.setUnparsedEntity(name, uri);
+  }
+
+  /** Copy set writer events. */
+  public void setWriter(java.io.Writer writer)
+    throws org.xml.sax.SAXException {
+    rtf.setWriter(writer);
+  }
+
+  /** Copy start document events. */
+  public void startDocument()
+    throws org.xml.sax.SAXException {
+    rtf.startDocument();
+  }
+
+  /** Copy start element events. */
+  public void startElement(int nameCode,
+                          org.xml.sax.Attributes attributes,
+                          int[] namespaces,
+                          int nscount)
+    throws org.xml.sax.SAXException {
+    rtf.startElement(nameCode, attributes, namespaces, nscount);
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/FormatCallout.java b/xsl/extensions/saxon6/com/nwalsh/saxon/FormatCallout.java
new file mode 100644 (file)
index 0000000..8f76499
--- /dev/null
@@ -0,0 +1,110 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.NamePool;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.tree.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public abstract class FormatCallout {
+  protected static final String foURI = "http://www.w3.org/1999/XSL/Format";
+  protected static final String xhURI = "http://www.w3.org/1999/xhtml";
+  protected boolean foStylesheet = false;
+  protected NamePool namePool = null;
+
+  public FormatCallout(NamePool nPool, boolean fo) {
+    namePool = nPool;
+    foStylesheet = fo;
+  }
+
+  public String areaLabel(ElementInfo area) {
+    String label = null;
+
+    if (area.getAttributeList().getValue("label") != null) {
+      // If this area has a label, use it
+      label = area.getAttributeList().getValue("label");
+    } else {
+      // Otherwise, if its parent is an areaset and it has a label, use that
+      ElementInfo parent = (ElementInfo) area.getParentNode();
+      if (parent != null
+         && parent.getLocalName().equalsIgnoreCase("areaset")
+         && parent.getAttributeList().getValue("label") != null) {
+       label = parent.getAttributeList().getValue("label");
+      }
+    }
+
+    return label;
+  }
+
+  public void startSpan(Emitter rtf)
+    throws SAXException {
+    // no point in doing this for FO, right?
+    if (!foStylesheet && namePool != null) {
+      int spanName = namePool.allocate("", "", "span");
+      AttributeCollection spanAttr = new AttributeCollection(namePool);
+      int namespaces[] = new int[1];
+      spanAttr.addAttribute("", "", "class", "CDATA", "co");
+      rtf.startElement(spanName, spanAttr, namespaces, 0);
+    }
+  }
+
+  public void endSpan(Emitter rtf)
+    throws SAXException {
+    // no point in doing this for FO, right?
+    if (!foStylesheet && namePool != null) {
+      int spanName = namePool.allocate("", "", "span");
+      rtf.endElement(spanName);
+    }
+  }
+
+  public void formatTextCallout(Emitter rtfEmitter,
+                               Callout callout) {
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String userLabel = areaLabel(area);
+    String label = "(" + num + ")";
+
+    if (userLabel != null) {
+      label = userLabel;
+    }
+
+    char chars[] = label.toCharArray();
+
+    try {
+      startSpan(rtfEmitter);
+      rtfEmitter.characters(chars, 0, label.length());
+      endSpan(rtfEmitter);
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in formatTextCallout");
+    }
+  }
+
+  public abstract void formatCallout(Emitter rtfEmitter,
+                                    Callout callout);
+}
+
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/FormatGraphicCallout.java b/xsl/extensions/saxon6/com/nwalsh/saxon/FormatGraphicCallout.java
new file mode 100644 (file)
index 0000000..c9fabfe
--- /dev/null
@@ -0,0 +1,87 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.NamePool;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.tree.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatGraphicCallout extends FormatCallout {
+  String graphicsPath = "";
+  String graphicsExt = "";
+  int graphicsMax = 0;
+
+  public FormatGraphicCallout(NamePool nPool, String path, String ext, int max, boolean fo) {
+    super(nPool, fo);
+    graphicsPath = path;
+    graphicsExt = ext;
+    graphicsMax = max;
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String userLabel = areaLabel(area);
+    String label = "(" + num + ")";
+
+    if (userLabel != null) {
+      label = userLabel;
+    }
+
+    try {
+      if (userLabel == null && num <= graphicsMax) {
+       int imgName = 0;
+       AttributeCollection imgAttr = null;
+       int namespaces[] = new int[1];
+
+       if (foStylesheet) {
+         imgName = namePool.allocate("fo", foURI, "external-graphic");
+         imgAttr = new AttributeCollection(namePool);
+         imgAttr.addAttribute("", "", "src", "CDATA",
+                              graphicsPath + num + graphicsExt);
+       } else {
+         imgName = namePool.allocate("", "", "img");
+         imgAttr = new AttributeCollection(namePool);
+         imgAttr.addAttribute("", "", "src", "CDATA",
+                              graphicsPath + num + graphicsExt);
+         imgAttr.addAttribute("", "", "alt", "CDATA", label);
+       }
+
+       startSpan(rtfEmitter);
+       rtfEmitter.startElement(imgName, imgAttr, namespaces, 0);
+       rtfEmitter.endElement(imgName);
+       endSpan(rtfEmitter);
+      } else {
+       formatTextCallout(rtfEmitter, callout);
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in graphic formatCallout");
+    }
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/FormatTextCallout.java b/xsl/extensions/saxon6/com/nwalsh/saxon/FormatTextCallout.java
new file mode 100644 (file)
index 0000000..5c2d8c8
--- /dev/null
@@ -0,0 +1,42 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.NamePool;
+import com.icl.saxon.output.Emitter;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatTextCallout extends FormatCallout {
+  public FormatTextCallout(NamePool nPool, boolean fo) {
+    super(nPool, fo);
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+    formatTextCallout(rtfEmitter, callout);
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/FormatUnicodeCallout.java b/xsl/extensions/saxon6/com/nwalsh/saxon/FormatUnicodeCallout.java
new file mode 100644 (file)
index 0000000..137476d
--- /dev/null
@@ -0,0 +1,65 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.NamePool;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.tree.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatUnicodeCallout extends FormatCallout {
+  int unicodeMax = 0;
+  int unicodeStart = 0;
+
+  public FormatUnicodeCallout(NamePool nPool, int start, int max, boolean fo) {
+    super(nPool, fo);
+    unicodeMax = max;
+    unicodeStart = start;
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String label = areaLabel(area);
+
+    try {
+      if (label == null && num <= unicodeMax) {
+       char chars[] = new char[1];
+       chars[0] = (char) (unicodeStart + num - 1);
+
+       startSpan(rtfEmitter);
+       rtfEmitter.characters(chars, 0, 1);
+       endSpan(rtfEmitter);
+      } else {
+       formatTextCallout(rtfEmitter, callout);
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in graphic formatCallout");
+    }
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/LineCountEmitter.java b/xsl/extensions/saxon6/com/nwalsh/saxon/LineCountEmitter.java
new file mode 100644 (file)
index 0000000..257e3e6
--- /dev/null
@@ -0,0 +1,155 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.expr.FragmentValue;
+import com.icl.saxon.Builder;
+
+/**
+ * <p>Saxon extension to count the lines in a result tree fragment.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation to count the number of lines in a result tree
+ * fragment.</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some verbatim environment. That result tree fragment
+ * is "replayed" through the LineCountEmitter; the LineCountEmitter watches
+ * characters go by and counts the number of line feeds that it sees.
+ * That number is then returned.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @see Verbatim
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class LineCountEmitter implements com.icl.saxon.output.Emitter {
+  /** The number of lines seen. */
+  protected int numLines = 0;
+
+  /** Construct a new LineCountEmitter. */
+  public LineCountEmitter() {
+    numLines = 0;
+  }
+
+  /** Reset the number of lines. */
+  public void reset() {
+    numLines = 0;
+  }
+
+  /** Return the number of lines. */
+  public int lineCount() {
+    return numLines;
+  }
+
+  /** Process characters. */
+  public void characters(char[] chars, int start, int len)
+    throws org.xml.sax.SAXException {
+
+    if (numLines == 0) {
+      // If there are any characters at all, there's at least one line
+      numLines++;
+    }
+
+    for (int count = start; count < start+len; count++) {
+      if (chars[count] == '\n') {
+       numLines++;
+      }
+    }
+  }
+
+  /** Discarded. */
+  public void comment(char[] chars, int start, int length)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void endDocument()
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void endElement(int nameCode)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void processingInstruction(java.lang.String name,
+                                   java.lang.String data)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setCharacterSet(CharacterSet charset)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setDocumentLocator(org.xml.sax.Locator locator) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setEscaping(boolean escaping)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setNamePool(NamePool namePool) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setOutputDetails(OutputDetails details)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setUnparsedEntity(java.lang.String name, java.lang.String uri)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setWriter(java.io.Writer writer)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void startDocument()
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void startElement(int nameCode,
+                   org.xml.sax.Attributes attributes,
+                   int[] namespaces, int nscount)
+    throws org.xml.sax.SAXException {
+    // nop
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/NumberLinesEmitter.java b/xsl/extensions/saxon6/com/nwalsh/saxon/NumberLinesEmitter.java
new file mode 100644 (file)
index 0000000..3d318b8
--- /dev/null
@@ -0,0 +1,322 @@
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.tree.AttributeCollection;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.expr.FragmentValue;
+import com.icl.saxon.Builder;
+
+/**
+ * <p>Saxon extension to decorate a result tree fragment with line numbers.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides the guts of a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation of line numbering for verbatim environments. (It is used
+ * by the Verbatim class.)</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some verbatim environment. The Verbatim class initializes
+ * a NumberLinesEmitter with information about what lines should be
+ * numbered and how. Then the result tree fragment
+ * is "replayed" through the NumberLinesEmitter; the NumberLinesEmitter
+ * builds a
+ * new result tree fragment from this event stream, decorated with line
+ * numbers,
+ * and that is returned.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @see Verbatim
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class NumberLinesEmitter extends CopyEmitter {
+  /** A stack for the preserving information about open elements. */
+  protected Stack elementStack = null;
+
+  /** The current line number. */
+  protected int lineNumber = 0;
+
+  /** Is the next element absolutely the first element in the fragment? */
+  protected boolean firstElement = false;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /** Every <code>modulus</code> line will be numbered. */
+  protected int modulus = 5;
+
+  /** Line numbers are <code>width</code> characters wide. */
+  protected int width = 3;
+
+  /** Line numbers are separated from the listing by <code>separator</code>. */
+  protected String separator = " ";
+
+  /** Is the stylesheet currently running an FO stylesheet? */
+  protected boolean foStylesheet = false;
+
+  /** <p>Constructor for the NumberLinesEmitter.</p>
+   *
+   * @param namePool The name pool to use for constructing elements and attributes.
+   * @param modulus The modulus to use for this listing.
+   * @param width The width to use for line numbers in this listing.
+   * @param separator The separator to use for this listing.
+   * @param foStylesheet Is this an FO stylesheet?
+   */
+  public NumberLinesEmitter(NamePool namePool,
+                           int modulus,
+                           int width,
+                           String separator,
+                           boolean foStylesheet) {
+    super(namePool);
+    elementStack = new Stack();
+    firstElement = true;
+
+    this.modulus = modulus;
+    this.width = width;
+    this.separator = separator;
+    this.foStylesheet = foStylesheet;
+  }
+
+  /** Process characters. */
+  public void characters(char[] chars, int start, int len)
+    throws org.xml.sax.SAXException {
+
+    // If we hit characters, then there's no first element...
+    firstElement = false;
+
+    if (lineNumber == 0) {
+      // The first line is always numbered
+      formatLineNumber(++lineNumber);
+    }
+
+    // Walk through the text node looking for newlines
+    char[] newChars = new char[len];
+    int pos = 0;
+    for (int count = start; count < start+len; count++) {
+      if (chars[count] == '\n') {
+       // This is the tricky bit; if we find a newline, make sure
+       // it doesn't occur inside any markup.
+
+       if (pos > 0) {
+         // Output any characters that preceded this newline
+         rtf.characters(newChars, 0, pos);
+         pos = 0;
+       }
+
+       // Close all the open elements...
+       Stack tempStack = new Stack();
+       while (!elementStack.empty()) {
+         StartElementInfo elem = (StartElementInfo) elementStack.pop();
+         rtf.endElement(elem.getNameCode());
+         tempStack.push(elem);
+       }
+
+       // Copy the newline to the output
+       newChars[pos++] = chars[count];
+       rtf.characters(newChars, 0, pos);
+       pos = 0;
+
+       // Add the line number
+       formatLineNumber(++lineNumber);
+
+       // Now "reopen" the elements that we closed...
+       while (!tempStack.empty()) {
+         StartElementInfo elem = (StartElementInfo) tempStack.pop();
+         AttributeCollection attr = (AttributeCollection)elem.getAttributes();
+         AttributeCollection newAttr = new AttributeCollection(namePool);
+
+         for (int acount = 0; acount < attr.getLength(); acount++) {
+           String localName = attr.getLocalName(acount);
+           int nameCode = attr.getNameCode(acount);
+           String type = attr.getType(acount);
+           String value = attr.getValue(acount);
+           String uri = attr.getURI(acount);
+           String prefix = "";
+
+           if (localName.indexOf(':') > 0) {
+             prefix = localName.substring(0, localName.indexOf(':'));
+             localName = localName.substring(localName.indexOf(':')+1);
+           }
+
+           if (uri.equals("")
+               && ((foStylesheet
+                    && localName.equals("id"))
+                   || (!foStylesheet
+                       && (localName.equals("id")
+                           || localName.equals("name"))))) {
+             // skip this attribute
+           } else {
+             newAttr.addAttribute(prefix, uri, localName, type, value);
+           }
+         }
+
+         rtf.startElement(elem.getNameCode(),
+                          newAttr,
+                          elem.getNamespaces(),
+                          elem.getNSCount());
+
+         elementStack.push(elem);
+       }
+      } else {
+       newChars[pos++] = chars[count];
+      }
+    }
+
+    if (pos > 0) {
+      rtf.characters(newChars, 0, pos);
+      pos = 0;
+    }
+  }
+
+  /**
+   * <p>Add a formatted line number to the result tree fragment.</p>
+   *
+   * @param lineNumber The number of the current line.
+   */
+  protected void formatLineNumber(int lineNumber) 
+    throws SAXException {
+
+    char ch = 160; // &nbsp;
+
+    String lno = "";
+    if (lineNumber == 1
+       || (modulus >= 1 && (lineNumber % modulus == 0))) {
+      lno = "" + lineNumber;
+    }
+
+    while (lno.length() < width) {
+      lno = ch + lno;
+    }
+
+    lno += separator;
+
+    char chars[] = new char[lno.length()];
+    for (int count = 0; count < lno.length(); count++) {
+      chars[count] = lno.charAt(count);
+    }
+
+    characters(chars, 0, lno.length());
+  }
+
+  /** Process end element events. */
+  public void endElement(int nameCode)
+    throws org.xml.sax.SAXException {
+    if (!elementStack.empty()) {
+      // if we didn't push the very first element (an fo:block or
+      // pre or div surrounding the whole block), then the stack will
+      // be empty when we get to the end of the first element...
+      elementStack.pop();
+    }
+    rtf.endElement(nameCode);
+  }
+
+  /** Process start element events. */
+  public void startElement(int nameCode,
+                          org.xml.sax.Attributes attributes,
+                          int[] namespaces,
+                          int nscount)
+    throws org.xml.sax.SAXException {
+
+    if (!skipThisElement(nameCode)) {
+      StartElementInfo sei = new StartElementInfo(nameCode, attributes,
+                                                 namespaces, nscount);
+      elementStack.push(sei);
+    }
+
+    firstElement = false;
+
+    rtf.startElement(nameCode, attributes, namespaces, nscount);
+  }
+
+  /**
+   * <p>Protect the outer-most block wrapper.</p>
+   *
+   * <p>Open elements in the result tree fragment are closed and reopened
+   * around callouts (so that callouts don't appear inside links or other
+   * environments). But if the result tree fragment is a single block
+   * (a div or pre in HTML, an fo:block in FO), that outer-most block is
+   * treated specially.</p>
+   *
+   * <p>This method returns true if the element in question is that
+   * outermost block.</p>
+   *
+   * @param nameCode The name code for the element
+   *
+   * @return True if the element is the outer-most block, false otherwise.
+   */
+  protected boolean skipThisElement(int nameCode) {
+    if (firstElement) {
+      int foBlockFingerprint = namePool.getFingerprint(foURI, "block");
+      int htmlPreFingerprint = namePool.getFingerprint("", "pre");
+      int htmlDivFingerprint = namePool.getFingerprint("", "div");
+
+      if ((foStylesheet && nameCode == foBlockFingerprint)
+         || (!foStylesheet && (nameCode == htmlPreFingerprint
+                               || nameCode == htmlDivFingerprint))) {
+       // Don't push the outer-most wrapping div, pre, or fo:block
+       return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * <p>A private class for maintaining the information required to call
+   * the startElement method.</p>
+   *
+   * <p>In order to close and reopen elements, information about those
+   * elements has to be maintained. This class is just the little record
+   * that we push on the stack to keep track of that info.</p>
+   */
+  private class StartElementInfo {
+    private int _nameCode;
+    org.xml.sax.Attributes _attributes;
+    int[] _namespaces;
+    int _nscount;
+
+    public StartElementInfo(int nameCode,
+                           org.xml.sax.Attributes attributes,
+                           int[] namespaces,
+                           int nscount) {
+      _nameCode = nameCode;
+      _attributes = attributes;
+      _namespaces = namespaces;
+      _nscount = nscount;
+    }
+
+    public int getNameCode() {
+      return _nameCode;
+    }
+
+    public org.xml.sax.Attributes getAttributes() {
+      return _attributes;
+    }
+
+    public int[] getNamespaces() {
+      return _namespaces;
+    }
+
+    public int getNSCount() {
+      return _nscount;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/Table.java b/xsl/extensions/saxon6/com/nwalsh/saxon/Table.java
new file mode 100644 (file)
index 0000000..6428e81
--- /dev/null
@@ -0,0 +1,428 @@
+// Verbatim.java - Saxon extensions supporting DocBook verbatim environments
+
+package com.nwalsh.saxon;
+
+import java.util.Hashtable;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.Context;
+import com.icl.saxon.tree.*;
+import com.icl.saxon.functions.Extensions;
+import com.nwalsh.saxon.NumberLinesEmitter;
+import com.nwalsh.saxon.CalloutEmitter;
+
+/**
+ * <p>Saxon extensions supporting Tables</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * implementation of some code to adjust CALS Tables to HTML
+ * Tables.</p>
+ *
+ * <p><b>Column Widths</b></p>
+ * <p>The <tt>adjustColumnWidths</tt> method takes a result tree
+ * fragment (assumed to contain the colgroup of an HTML Table)
+ * and returns the result tree fragment with the column widths
+ * adjusted to HTML terms.</p>
+ *
+ * <p><b>Convert Lengths</b></p>
+ * <p>The <tt>convertLength</tt> method takes a length specification
+ * of the form 9999.99xx (where "xx" is a unit) and returns that length
+ * as an integral number of pixels. For convenience, percentage lengths
+ * are returned unchanged.</p>
+ * <p>The recognized units are: inches (in), centimeters (cm),
+ * millimeters (mm), picas (pc, 1pc=12pt), points (pt), and pixels (px).
+ * A number with no units is assumed to be pixels.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Table {
+  /** The number of pixels per inch */
+  private static int pixelsPerInch = 96;
+
+  /** The nominal table width (6in by default). */
+  private static int nominalWidth = 6 * pixelsPerInch;
+
+  /** The default table width (100% by default). */
+  private static String tableWidth = "100%";
+
+  /** Is this an FO stylesheet? */
+  private static boolean foStylesheet = false;
+
+  /** The hash used to associate units with a length in pixels. */
+  protected static Hashtable unitHash = null;
+
+  /**
+   * <p>Constructor for Verbatim</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public Table() {
+  }
+
+  /** Initialize the internal hash table with proper values. */
+  protected static void initializeHash() {
+    unitHash = new Hashtable();
+    unitHash.put("in", new Float(pixelsPerInch));
+    unitHash.put("cm", new Float(pixelsPerInch / 2.54));
+    unitHash.put("mm", new Float(pixelsPerInch / 25.4));
+    unitHash.put("pc", new Float((pixelsPerInch / 72) * 12));
+    unitHash.put("pt", new Float(pixelsPerInch / 72));
+    unitHash.put("px", new Float(1));
+  }
+
+  /** Set the pixels-per-inch value. Only positive values are legal. */
+  public static void setPixelsPerInch(int value) {
+    if (value > 0) {
+      pixelsPerInch = value;
+      initializeHash();
+    }
+  }
+
+  /** Return the current pixels-per-inch value. */
+  public int getPixelsPerInch() {
+    return pixelsPerInch;
+  }
+
+  /**
+   * <p>Convert a length specification to a number of pixels.</p>
+   *
+   * <p>The specified length should be of the form [+/-]999.99xx,
+   * where xx is a valid unit.</p>
+   */
+  public static int convertLength(String length) {
+    // The format of length should be 999.999xx
+    int sign = 1;
+    String digits = "";
+    String units = "";
+    char lench[] = length.toCharArray();
+    float flength = 0;
+    boolean done = false;
+    int pos = 0;
+    float factor = 1;
+    int pixels = 0;
+
+    if (unitHash == null) {
+      initializeHash();
+    }
+
+    if (lench[pos] == '+' || lench[pos] == '-') {
+      if (lench[pos] == '-') {
+       sign = -1;
+      }
+      pos++;
+    }
+
+    while (!done) {
+      if (pos >= lench.length) {
+       done = true;
+      } else {
+       if ((lench[pos] > '9' || lench[pos] < '0') && lench[pos] != '.') {
+         done = true;
+         units = length.substring(pos);
+       } else {
+         digits += lench[pos++];
+       }
+      }
+    }
+
+    try {
+      flength = Float.parseFloat(digits);
+    } catch (NumberFormatException e) {
+      System.out.println(digits + " is not a number; 1 used instead.");
+      flength = 1;
+    }
+
+    Float f = null;
+
+    if (!units.equals("")) {
+      f = (Float) unitHash.get(units);
+      if (f == null) {
+       System.out.println(units + " is not a known unit; 1 used instead.");
+       factor = 1;
+      } else {
+       factor = f.floatValue();
+      }
+    } else {
+      factor = 1;
+    }
+
+    f = new Float(flength * factor);
+
+    pixels = f.intValue() * sign;
+
+    return pixels;
+  }
+
+  /**
+   * <p>Find the string value of a stylesheet variable or parameter</p>
+   *
+   * <p>Returns the string value of <code>varName</code> in the current
+   * <code>context</code>. Returns the empty string if the variable is
+   * not defined.</p>
+   *
+   * @param context The current stylesheet context
+   * @param varName The name of the variable (without the dollar sign)
+   *
+   * @return The string value of the variable
+   */
+  protected static String getVariable(Context context, String varName) 
+    throws SAXException {
+    Value variable = null;
+    String varString = null;
+
+    try {
+      variable = Extensions.evaluate(context, "$" + varName);
+      varString = variable.asString();
+      return varString;
+    } catch (IllegalArgumentException e) {
+      System.out.println("Undefined variable: " + varName);
+      return "";
+    }
+  }
+
+  /**
+   * <p>Setup the parameters associated with column width calculations</p>
+   *
+   * <p>This method queries the stylesheet for the variables
+   * associated with table column widths. It is called automatically before
+   * column widths are adjusted. The context is used to retrieve the values,
+   * this allows templates to redefine these variables.</p>
+   *
+   * <p>The following variables are queried. If the variables do not
+   * exist, builtin defaults will be used (but you may also get a bunch
+   * of messages from the Java interpreter).</p>
+   *
+   * <dl>
+   * <dt><code>nominal.table.width</code></dt>
+   * <dd>The "normal" width for tables. This must be an absolute length.</dd>
+   * <dt><code>table.width</code></dt>
+   * <dd>The width for tables. This may be either an absolute
+   * length or a percentage.</dd>
+   * </dl>
+   *
+   * @param context The current stylesheet context
+   *
+   */
+  private static void setupColumnWidths(Context context) {
+    // Hardcoded defaults
+    nominalWidth = 6 * pixelsPerInch;
+    tableWidth = "100%";
+
+    String varString = null;
+
+    try {
+      // Get the stylesheet type
+      varString = getVariable(context, "stylesheet.result.type");
+      foStylesheet = varString.equals("fo");
+
+      // Get the nominal table width
+      varString = getVariable(context, "nominal.table.width");
+      nominalWidth = convertLength(varString);
+
+      // Get the table width
+      varString = getVariable(context, "table.width");
+      tableWidth = varString;
+    } catch (SAXException e) {
+      //nop, can't happen
+    }
+  }
+
+  /**
+   * <p>Adjust column widths in an HTML table.</p>
+   *
+   * <p>The specification of column widths in CALS (a relative width
+   * plus an optional absolute width) are incompatible with HTML column
+   * widths. This method adjusts CALS column width specifiers in an
+   * attempt to produce equivalent HTML specifiers.</p>
+   *
+   * <p>In order for this method to work, the CALS width specifications
+   * should be placed in the "width" attribute of the &lt;col>s within
+   * a &lt;colgroup>. Then the colgroup result tree fragment is passed
+   * to this method.</p>
+   *
+   * <p>This method makes use of two parameters from the XSL stylesheet
+   * that calls it: <code>nominal.table.width</code> and
+   * <code>table.width</code>. The value of <code>nominal.table.width</code>
+   * must be an absolute distance. The value of <code>table.width</code>
+   * can be either absolute or relative.</p>
+   *
+   * <p>Presented with a mixture of relative and
+   * absolute lengths, the table width is used to calculate
+   * appropriate values. If the <code>table.width</code> is relative,
+   * the nominal width is used for this calculation.</p>
+   *
+   * <p>There are three possible combinations of values:</p>
+   *
+   * <ol>
+   * <li>There are no relative widths; in this case the absolute widths
+   * are used in the HTML table.</li>
+   * <li>There are no absolute widths; in this case the relative widths
+   * are used in the HTML table.</li>
+   * <li>There are a mixture of absolute and relative widths:
+   *   <ol>
+   *     <li>If the table width is absolute, all widths become absolute.</li>
+   *     <li>If the table width is relative, make all the widths absolute
+   *         relative to the nominal table width then turn them all
+   *         back into relative widths.</li>
+   *   </ol>
+   * </li>
+   * </ol>
+   *
+   * @param context The stylesheet context; supplied automatically by Saxon
+   * @param rtf The result tree fragment containing the colgroup.
+   *
+   * @return The result tree fragment containing the adjusted colgroup.
+   *
+   */
+  public static FragmentValue adjustColumnWidths (Context context,
+                                                 FragmentValue rtf) {
+    setupColumnWidths(context);
+
+    try {
+      NamePool namePool = context.getController().getNamePool();
+      ColumnScanEmitter csEmitter = new ColumnScanEmitter(namePool);
+      rtf.replay(csEmitter);
+
+      int numColumns = csEmitter.columnCount();
+      String widths[] = csEmitter.columnWidths();
+
+      float relTotal = 0;
+      float relParts[] = new float[numColumns];
+
+      float absTotal = 0;
+      float absParts[] = new float[numColumns];
+
+      for (int count = 0; count < numColumns; count++) {
+       String width = widths[count];
+       int pos = width.indexOf("*");
+       if (pos >= 0) {
+         String relPart = width.substring(0, pos);
+         String absPart = width.substring(pos+1);
+
+         try {
+           float rel = Float.parseFloat(relPart);
+           relTotal += rel;
+           relParts[count] = rel;
+         } catch (NumberFormatException e) {
+           System.out.println(relPart + " is not a valid relative unit.");
+         }
+
+         int pixels = 0;
+         if (absPart != null && !absPart.equals("")) {
+           pixels = convertLength(absPart);
+         }
+
+         absTotal += pixels;
+         absParts[count] = pixels;
+       } else {
+         relParts[count] = 0;
+
+         int pixels = 0;
+         if (width != null && !width.equals("")) {
+           pixels = convertLength(width);
+         }
+
+         absTotal += pixels;
+         absParts[count] = pixels;
+       }
+      }
+
+      // Ok, now we have the relative widths and absolute widths in
+      // two parallel arrays.
+      //
+      // - If there are no relative widths, output the absolute widths
+      // - If there are no absolute widths, output the relative widths
+      // - If there are a mixture of relative and absolute widths,
+      //   - If the table width is absolute, turn these all into absolute
+      //     widths.
+      //   - If the table width is relative, turn these all into absolute
+      //     widths in the nominalWidth and then turn them back into
+      //     percentages.
+
+      if (relTotal == 0) {
+       for (int count = 0; count < numColumns; count++) {
+         Float f = new Float(absParts[count]);
+         if (foStylesheet) {
+           int pixels = f.intValue();
+           float inches = (float) pixels / pixelsPerInch;
+           widths[count] = inches + "in";
+         } else {
+           widths[count] = Integer.toString(f.intValue());
+         }
+       }
+      } else if (absTotal == 0) {
+       for (int count = 0; count < numColumns; count++) {
+         float rel = relParts[count] / relTotal * 100;
+         Float f = new Float(rel);
+         widths[count] = Integer.toString(f.intValue()) + "%";
+       }
+      } else {
+       int pixelWidth = nominalWidth;
+
+       if (tableWidth.indexOf("%") <= 0) {
+         pixelWidth = convertLength(tableWidth);
+       }
+
+       if (pixelWidth <= absTotal) {
+         System.out.println("Table is wider than table width.");
+       } else {
+         pixelWidth -= absTotal;
+       }
+
+       absTotal = 0;
+       for (int count = 0; count < numColumns; count++) {
+         float rel = relParts[count] / relTotal * pixelWidth;
+         relParts[count] = rel + absParts[count];
+         absTotal += rel + absParts[count];
+       }
+
+       if (tableWidth.indexOf("%") <= 0) {
+         for (int count = 0; count < numColumns; count++) {
+           Float f = new Float(relParts[count]);
+           if (foStylesheet) {
+             int pixels = f.intValue();
+             float inches = (float) pixels / pixelsPerInch;
+             widths[count] = inches + "in";
+           } else {
+             widths[count] = Integer.toString(f.intValue());
+           }
+         }
+       } else {
+         for (int count = 0; count < numColumns; count++) {
+           float rel = relParts[count] / absTotal * 100;
+           Float f = new Float(rel);
+           widths[count] = Integer.toString(f.intValue()) + "%";
+         }
+       }
+      }
+
+      ColumnUpdateEmitter cuEmitter = new ColumnUpdateEmitter(namePool,
+                                                             widths);
+
+      rtf.replay(cuEmitter);
+      return cuEmitter.getResultTreeFragment();
+    } catch (SAXException e) {
+      // This "can't" happen.
+      System.out.println("SAX Exception in numberLines");
+      return rtf;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/Text.java b/xsl/extensions/saxon6/com/nwalsh/saxon/Text.java
new file mode 100644 (file)
index 0000000..3964658
--- /dev/null
@@ -0,0 +1,131 @@
+// Text - Saxon extension element for inserting text
+
+package com.nwalsh.saxon;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.net.MalformedURLException;
+import com.icl.saxon.*;
+import com.icl.saxon.style.*;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.output.*;
+import org.xml.sax.SAXException;
+import org.xml.sax.AttributeList;
+
+/**
+ * <p>Saxon extension element for inserting text
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension element for inserting text into a result tree.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Text extends StyleElement {
+  /**
+   * <p>Constructor for Text</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public Text() {
+  }
+
+  /**
+   * <p>Is this element an instruction?</p>
+   *
+   * <p>Yes, it is.</p>
+   *
+   * @return true
+   */
+  public boolean isInstruction() {
+    return true;
+  }
+
+    /**
+    * <p>Can this element contain a template-body?</p>
+    *
+    * <p>Yes, it can, but only so that it can contain xsl:fallback.</p>
+    *
+    * @return true
+    */
+  public boolean mayContainTemplateBody() {
+    return true;
+  }
+
+  /**
+   * <p>Validate the arguments</p>
+   *
+   * <p>The element must have an href attribute.</p>
+   */
+  public void prepareAttributes() throws SAXException {
+    // Get mandatory href attribute
+    String fnAtt = getAttribute("href");
+    if (fnAtt == null) {
+      reportAbsence("href");
+    }
+  }
+
+  /** Validate that the element occurs in a reasonable place. */
+  public void validate() throws SAXException {
+    checkWithinTemplate();
+  }
+
+  /**
+   * <p>Insert the text of the file into the result tree</p>
+   *
+   * <p>Processing this element inserts the contents of the URL named
+   * by the href attribute into the result tree as plain text.</p>
+   *
+   */
+  public void process( Context context ) throws SAXException {
+    Outputter out = context.getOutputter();
+
+    String hrefAtt = getAttribute("href");
+    Expression hrefExpr = makeAttributeValueTemplate(hrefAtt);
+    String href = hrefExpr.evaluateAsString(context);
+    URL fileURL = null;
+
+    try {
+      try {
+       fileURL = new URL(href);
+      } catch (MalformedURLException e1) {
+       try {
+         fileURL = new URL("file:" + href);
+       } catch (MalformedURLException e2) {
+         System.out.println("Cannot open " + href);
+         return;
+       }
+      }
+
+      InputStreamReader isr = new InputStreamReader(fileURL.openStream());
+      BufferedReader is = new BufferedReader(isr);
+
+      char chars[] = new char[4096];
+      int len = 0;
+      while ((len = is.read(chars)) > 0) {
+       out.writeContent(chars, 0, len);
+      }
+      is.close();
+    } catch (Exception e) {
+      System.out.println("Cannot read " + href);
+    }
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/TextFactory.java b/xsl/extensions/saxon6/com/nwalsh/saxon/TextFactory.java
new file mode 100644 (file)
index 0000000..34ef9d9
--- /dev/null
@@ -0,0 +1,64 @@
+// TextFactory - Saxon extension element factory
+
+package com.nwalsh.saxon;
+
+import com.icl.saxon.style.ExtensionElementFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>Saxon extension element factory
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension element factory for the Text extension element
+ * family.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ * @see Text
+ *
+ */
+public class TextFactory implements ExtensionElementFactory {
+  /**
+   * <p>Constructor for TextFactory</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public TextFactory() {
+  }
+
+  /**
+   * <p>Return the class that implements a particular extension element.</p>
+   *
+   * @param localname The local name of the extension element.
+   *
+   * @return The class that handles that extension element.
+   *
+   * @exception SAXException("Unknown Text extension element")
+   */
+  public Class getExtensionClass(String localname) throws SAXException {
+    if (localname.equals("insertfile")) {
+      try {
+       return Class.forName("com.nwalsh.saxon.Text");
+      } catch (ClassNotFoundException e) {
+       throw new SAXException("Failed to load class for Text extension element: "
+                              + localname);
+      }
+    }
+    throw new SAXException("Unknown Text extension element: "
+                          + localname);
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/Verbatim.java b/xsl/extensions/saxon6/com/nwalsh/saxon/Verbatim.java
new file mode 100644 (file)
index 0000000..6e63dda
--- /dev/null
@@ -0,0 +1,447 @@
+// Verbatim.java - Saxon extensions supporting DocBook verbatim environments
+
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.Context;
+import com.icl.saxon.tree.*;
+import com.icl.saxon.functions.Extensions;
+import com.nwalsh.saxon.NumberLinesEmitter;
+import com.nwalsh.saxon.CalloutEmitter;
+
+/**
+ * <p>Saxon extensions supporting DocBook verbatim environments</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * implementation of two features that would be impractical to
+ * implement directly in XSLT: line numbering and callouts.</p>
+ *
+ * <p><b>Line Numbering</b></p>
+ * <p>The <tt>numberLines</tt> method takes a result tree
+ * fragment (assumed to contain the contents of a formatted verbatim
+ * element in DocBook: programlisting, screen, address, literallayout,
+ * or synopsis) and returns a result tree fragment decorated with
+ * line numbers.</p>
+ *
+ * <p><b>Callouts</b></p>
+ * <p>The <tt>insertCallouts</tt> method takes an
+ * <tt>areaspec</tt> and a result tree fragment
+ * (assumed to contain the contents of a formatted verbatim
+ * element in DocBook: programlisting, screen, address, literallayout,
+ * or synopsis) and returns a result tree fragment decorated with
+ * callouts.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Verbatim {
+  /** True if the stylesheet is producing formatting objects */
+  private static boolean foStylesheet = false;
+  /** The modulus for line numbering (every 'modulus' line is numbered). */
+  private static int modulus = 0;
+  /** The width (in characters) of line numbers (for padding). */
+  private static int width = 0;
+  /** The separator between the line number and the verbatim text. */
+  private static String separator = "";
+
+  /** The default column for callouts that have only a line or line range */
+  private static int defaultColumn = 60;
+
+  /** The FormatCallout object to use for formatting callouts. */
+  private static FormatCallout fCallout = null;
+
+  /**
+   * <p>Constructor for Verbatim</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public Verbatim() {
+  }
+
+  /**
+   * <p>Find the string value of a stylesheet variable or parameter</p>
+   *
+   * <p>Returns the string value of <code>varName</code> in the current
+   * <code>context</code>. Returns the empty string if the variable is
+   * not defined.</p>
+   *
+   * @param context The current stylesheet context
+   * @param varName The name of the variable (without the dollar sign)
+   *
+   * @return The string value of the variable
+   */
+  protected static String getVariable(Context context, String varName) {
+    Value variable = null;
+    String varString = null;
+
+    try {
+      variable = Extensions.evaluate(context, "$" + varName);
+      varString = variable.asString();
+      return varString;
+    } catch (SAXException e) {
+      System.out.println("Undefined variable: " + varName);
+      return "";
+    } catch (IllegalArgumentException e) {
+      System.out.println("Undefined variable: " + varName);
+      return "";
+    }
+  }
+
+  /**
+   * <p>Setup the parameters associated with line numbering</p>
+   *
+   * <p>This method queries the stylesheet for the variables
+   * associated with line numbering. It is called automatically before
+   * lines are numbered. The context is used to retrieve the values,
+   * this allows templates to redefine these variables.</p>
+   *
+   * <p>The following variables are queried. If the variables do not
+   * exist, builtin defaults will be used (but you may also get a bunch
+   * of messages from the Java interpreter).</p>
+   *
+   * <dl>
+   * <dt><code>linenumbering.everyNth</code></dt>
+   * <dd>Specifies the lines that will be numbered. The first line is
+   * always numbered. (builtin default: 5).</dd>
+   * <dt><code>linenumbering.width</code></dt>
+   * <dd>Specifies the width of the numbers. If the specified width is too
+   * narrow for the largest number needed, it will automatically be made
+   * wider. (builtin default: 3).</dd>
+   * <dt><code>linenumbering.separator</code></dt>
+   * <dd>Specifies the string that separates line numbers from lines
+   * in the program listing. (builtin default: " ").</dd>
+   * <dt><code>stylesheet.result.type</code></dt>
+   * <dd>Specifies the stylesheet result type. The value is either 'fo'
+   * (for XSL Formatting Objects) or it isn't. (builtin default: html).</dd>
+   * </dl>
+   *
+   * @param context The current stylesheet context
+   *
+   */
+  private static void setupLineNumbering(Context context) {
+    // Hardcoded defaults
+    modulus = 5;
+    width = 3;
+    separator = " ";
+    foStylesheet = false;
+
+    String varString = null;
+
+    // Get the modulus
+    varString = getVariable(context, "linenumbering.everyNth");
+    try {
+      modulus = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$linenumbering.everyNth is not a number: " + varString);
+    }
+
+    // Get the width
+    varString = getVariable(context, "linenumbering.width");
+    try {
+      width = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$linenumbering.width is not a number: " + varString);
+    }
+
+    // Get the separator
+    varString = getVariable(context, "linenumbering.separator");
+    separator = varString;
+
+      // Get the stylesheet type
+    varString = getVariable(context, "stylesheet.result.type");
+    foStylesheet = (varString.equals("fo"));
+  }
+
+  /**
+   * <p>Number lines in a verbatim environment</p>
+   *
+   * <p>The extension function expects the following variables to be
+   * available in the calling context: $linenumbering.everyNth,
+   * $linenumbering.width, $linenumbering.separator, and
+   * $stylesheet.result.type.</p>
+   *
+   * <p>This method adds line numbers to a result tree fragment. Each
+   * newline that occurs in a text node is assumed to start a new line.
+   * The first line is always numbered, every subsequent 'everyNth' line
+   * is numbered (so if everyNth=5, lines 1, 5, 10, 15, etc. will be
+   * numbered. If there are fewer than everyNth lines in the environment,
+   * every line is numbered.</p>
+   *
+   * <p>Every line number will be right justified in a string 'width'
+   * characters long. If the line number of the last line in the
+   * environment is too long to fit in the specified width, the width
+   * is automatically increased to the smallest value that can hold the
+   * number of the last line. (In other words, if you specify the value 2
+   * and attempt to enumerate the lines of an environment that is 100 lines
+   * long, the value 3 will automatically be used for every line in the
+   * environment.)</p>
+   *
+   * <p>The 'separator' string is inserted between the line
+   * number and the original program listing. Lines that aren't numbered
+   * are preceded by a 'width' blank string and the separator.</p>
+   *
+   * <p>If inline markup extends across line breaks, markup changes are
+   * required. All the open elements are closed before the line break and
+   * "reopened" afterwards. The reopened elements will have the same
+   * attributes as the originals, except that 'name' and 'id' attributes
+   * are not duplicated if the stylesheet.result.type is "html" and
+   * 'id' attributes will not be duplicated if the result type is "fo".</p>
+   *
+   * @param rtf The result tree fragment of the verbatim environment.
+   *
+   * @return The modified result tree fragment.
+   */
+  public static FragmentValue numberLines (Context context,
+                                          FragmentValue rtf) {
+    setupLineNumbering(context);
+
+    try {
+      LineCountEmitter lcEmitter = new LineCountEmitter();
+      rtf.replay(lcEmitter);
+      int numLines = lcEmitter.lineCount();
+
+      int listingModulus = numLines < modulus ? 1 : modulus;
+
+      double log10numLines = Math.log(numLines) / Math.log(10);
+
+      int listingWidth = width < log10numLines+1
+       ? (int) Math.floor(log10numLines + 1)
+       : width;
+
+      NamePool namePool = context.getController().getNamePool();
+      NumberLinesEmitter nlEmitter = new NumberLinesEmitter(namePool,
+                                                           listingModulus,
+                                                           listingWidth,
+                                                           separator,
+                                                           foStylesheet);
+      rtf.replay(nlEmitter);
+      return nlEmitter.getResultTreeFragment();
+    } catch (SAXException e) {
+      // This "can't" happen.
+      System.out.println("SAX Exception in numberLines");
+      return rtf;
+    }
+  }
+
+  /**
+   * <p>Setup the parameters associated with callouts</p>
+   *
+   * <p>This method queries the stylesheet for the variables
+   * associated with line numbering. It is called automatically before
+   * callouts are processed. The context is used to retrieve the values,
+   * this allows templates to redefine these variables.</p>
+   *
+   * <p>The following variables are queried. If the variables do not
+   * exist, builtin defaults will be used (but you may also get a bunch
+   * of messages from the Java interpreter).</p>
+   *
+   * <dl>
+   * <dt><code>callout.graphics</code></dt>
+   * <dd>Are we using callout graphics? A value of 0 or "" is false,
+   * any other value is true. If callout graphics are not used, the
+   * parameters related to graphis are not queried.</dd>
+   * <dt><code>callout.graphics.path</code></dt>
+   * <dd>Specifies the path to callout graphics.</dd>
+   * <dt><code>callout.graphics.extension</code></dt>
+   * <dd>Specifies the extension ot use for callout graphics.</dd>
+   * <dt><code>callout.graphics.number.limit</code></dt>
+   * <dd>Identifies the largest number that can be represented as a
+   * graphic. Larger callout numbers will be represented using text.</dd>
+   * <dt><code>callout.defaultcolumn</code></dt>
+   * <dd>Specifies the default column for callout bullets that do not
+   * specify a column.</dd>
+   * <dt><code>stylesheet.result.type</code></dt>
+   * <dd>Specifies the stylesheet result type. The value is either 'fo'
+   * (for XSL Formatting Objects) or it isn't. (builtin default: html).</dd>
+   * </dl>
+   *
+   * @param context The current stylesheet context
+   *
+   */
+  private static void setupCallouts(Context context) {
+    NamePool namePool = context.getController().getNamePool();
+
+    boolean useGraphics = false;
+    boolean useUnicode = false;
+
+    // Hardcoded defaults
+    defaultColumn = 60;
+    foStylesheet = false;
+
+    int unicodeStart = 48;
+    int unicodeMax = 0;
+
+    String graphicsPath = null;
+    String graphicsExt = null;
+    int graphicsMax = 0;
+
+    Value variable = null;
+    String varString = null;
+
+    // Get the stylesheet type
+    varString = getVariable(context, "stylesheet.result.type");
+    foStylesheet = (varString.equals("fo"));
+
+      // Get the default column
+    varString = getVariable(context, "callout.defaultcolumn");
+    try {
+      defaultColumn = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$callout.defaultcolumn is not a number: "
+                        + varString);
+    }
+
+    // Use graphics at all?
+    varString = getVariable(context, "callout.graphics");
+    useGraphics = !(varString.equals("0") || varString.equals(""));
+
+      // Use unicode at all?
+    varString = getVariable(context, "callout.unicode");
+    useUnicode = !(varString.equals("0") || varString.equals(""));
+
+    if (useGraphics) {
+      // Get the graphics path
+      varString = getVariable(context, "callout.graphics.path");
+      graphicsPath = varString;
+
+      // Get the graphics extension
+      varString = getVariable(context, "callout.graphics.extension");
+      graphicsExt = varString;
+
+      // Get the number limit
+      varString = getVariable(context, "callout.graphics.number.limit");
+      try {
+       graphicsMax = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.graphics.number.limit is not a number: "
+                          + varString);
+       graphicsMax = 0;
+      }
+
+      fCallout = new FormatGraphicCallout(namePool,
+                                         graphicsPath,
+                                         graphicsExt,
+                                         graphicsMax,
+                                         foStylesheet);
+    } else if (useUnicode) {
+      // Get the starting character
+      varString = getVariable(context, "callout.unicode.start.character");
+      try {
+       unicodeStart = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.unicode.start.character is not a number: "
+                          + varString);
+       unicodeStart = 48;
+      }
+
+      // Get the number limit
+      varString = getVariable(context, "callout.unicode.number.limit");
+      try {
+       unicodeMax = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.unicode.number.limit is not a number: "
+                          + varString);
+       unicodeStart = 0;
+      }
+
+      fCallout = new FormatUnicodeCallout(namePool,
+                                         unicodeStart,
+                                         unicodeMax,
+                                         foStylesheet);
+    } else {
+      fCallout = new FormatTextCallout(namePool, foStylesheet);
+    }
+  }
+
+  /**
+   * <p>Insert text callouts into a verbatim environment.</p>
+   *
+   * <p>This method examines the <tt>areaset</tt> and <tt>area</tt> elements
+   * in the supplied <tt>areaspec</tt> and decorates the supplied
+   * result tree fragment with appropriate callout markers.</p>
+   *
+   * <p>If a <tt>label</tt> attribute is supplied on an <tt>area</tt>,
+   * its content will be used for the label, otherwise the callout
+   * number will be used, surrounded by parenthesis. Callout numbers may
+   * also be represented as graphics. Callouts are
+   * numbered in document order. All of the <tt>area</tt>s in an
+   * <tt>areaset</tt> get the same number.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the defaultColumn. Lines will be padded with blanks to reach the
+   * necessary column, but callouts that are located beyond the last
+   * line of the verbatim environment will be ignored.</p>
+   *
+   * <p>Callouts are inserted before the character at the line/column
+   * where they are to occur.</p>
+   *
+   * <p>If graphical callouts are used, and the callout number is less
+   * than or equal to the $callout.graphics.number.limit, the following image
+   * will be generated for HTML:
+   *
+   * <pre>
+   * &lt;img src="$callout.graphics.path/999$callout.graphics.ext"
+   *         alt="conumber">
+   * </pre>
+   *
+   * If the $stylesheet.result.type is 'fo', the following image will
+   * be generated:
+   *
+   * <pre>
+   * &lt;fo:external-graphic src="$callout.graphics.path/999$callout.graphics.ext"/>
+   * </pre>
+   *
+   * <p>If the callout number exceeds $callout.graphics.number.limit,
+   * the callout will be the callout number surrounded by
+   * parenthesis.</p>
+   *
+   * @param context The stylesheet context.
+   * @param areaspecNodeSet The source node set that contains the areaspec.
+   * @param rtf The result tree fragment of the verbatim environment.
+   *
+   * @return The modified result tree fragment.
+   */
+
+  public static FragmentValue insertCallouts (Context context,
+                                             NodeSetIntent areaspecNodeSet,
+                                             FragmentValue rtf) {
+    setupCallouts(context);
+
+    try {
+      NamePool namePool = context.getController().getNamePool();
+      CalloutEmitter cEmitter = new CalloutEmitter(namePool,
+                                                  defaultColumn,
+                                                  foStylesheet,
+                                                  fCallout);
+      cEmitter.setupCallouts(areaspecNodeSet);
+      rtf.replay(cEmitter);
+      return cEmitter.getResultTreeFragment();
+    } catch (SAXException e) {
+      // This "can't" happen.
+      System.out.println("SAX Exception in insertCallouts");
+      return rtf;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon6/com/nwalsh/saxon/package.html b/xsl/extensions/saxon6/com/nwalsh/saxon/package.html
new file mode 100644 (file)
index 0000000..b05a467
--- /dev/null
@@ -0,0 +1,48 @@
+<html>
+<head>
+<title>Norman Walsh's Saxon Extensions Package</title>
+</head>
+<body>
+<p>Norman Walsh's Saxon Extensions Package for Saxon 6.*</p>
+
+<p>This package implements Saxon extensions for XSLT.</p>
+
+<p><b>Copyright (C) 2000 Norman Walsh</b></p>
+<p>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:</p>
+
+<p>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.</p>
+
+<p>Except as contained in this notice, the names of individuals
+credited with contribution to this software shall not be used in
+advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the
+individuals in question.</p>
+
+<p>Anything derived from this Software that is publically
+distributed will be identified with a different name and the
+version strings in any derived Software will be changed so that no
+possibility of confusion between the derived package and this
+Software will exist.</p>
+</blockquote>
+
+<blockquote>
+<p><b>Warranty</b></p>
+<p>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 NORMAN WALSH OR ANY OTHER
+CONTRIBUTOR 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.</p>
+</blockquote>
+
+</body>
+</html>
diff --git a/xsl/extensions/saxon61/.cvsignore b/xsl/extensions/saxon61/.cvsignore
new file mode 100644 (file)
index 0000000..4d3c216
--- /dev/null
@@ -0,0 +1 @@
+.classes
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/CVS.java b/xsl/extensions/saxon61/com/nwalsh/saxon/CVS.java
new file mode 100644 (file)
index 0000000..529546b
--- /dev/null
@@ -0,0 +1,90 @@
+package com.nwalsh.saxon;
+
+import java.io.*;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.text.DateFormat;
+import java.text.ParseException;
+
+/**
+ * <p>Saxon extension to convert CVS date strings into local time</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension to turn the CVS date strings, which are UTC:</p>
+ *
+ * <pre>&#36;Date: 2000/11/09 02:34:20 &#36;</pre>
+ *
+ * <p>into legibly formatted local time:</p>
+ *
+ * <pre>Wed Nov 08 18:34:20 PST 2000</pre>
+ *
+ * <p>(I happened to be in California when I wrote this documentation.)</p>
+
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class CVS {
+  /**
+   * <p>Constructor for CVS</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public CVS() {
+  }
+
+  /**
+   * <p>Convert a CVS date string into local time.</p>
+   *
+   * @param cvsDate The CVS date string.
+   *
+   * @return The date, converted to local time and reformatted.
+   */
+  public static String localTime (String cvsDate) {
+    // A cvsDate has the following form "$Date$"
+    if (!cvsDate.startsWith("$Date: ")) {
+      return cvsDate;
+    }
+
+    String yrS = cvsDate.substring(7,11);
+    String moS = cvsDate.substring(12,14);
+    String daS = cvsDate.substring(15,17);
+    String hrS = cvsDate.substring(18,20);
+    String miS = cvsDate.substring(21,23);
+    String seS = cvsDate.substring(24,26);
+
+    TimeZone tz = TimeZone.getTimeZone("GMT+0");
+    GregorianCalendar gmtCal = new GregorianCalendar(tz);
+
+    try {
+      gmtCal.set(Integer.parseInt(yrS),
+                Integer.parseInt(moS)-1,
+                Integer.parseInt(daS),
+                Integer.parseInt(hrS),
+                Integer.parseInt(miS),
+                Integer.parseInt(seS));
+    } catch (NumberFormatException e) {
+      // nop
+    }
+
+    Date d = gmtCal.getTime();
+
+    return d.toString();
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/Callout.java b/xsl/extensions/saxon61/com/nwalsh/saxon/Callout.java
new file mode 100644 (file)
index 0000000..f0be0cd
--- /dev/null
@@ -0,0 +1,91 @@
+package com.nwalsh.saxon;
+
+import com.icl.saxon.om.*;
+import com.icl.saxon.tree.*;
+
+/**
+ * <p>A class for maintaining information about callouts.</p>
+ *
+ * <p>To make processing callouts easier, they are parsed out of the
+ * input structure and stored in a sorted array. (The array is sorted
+ * according to the order in which the callouts occur.)</p>
+ *
+ * <p>This class is just the little record
+ * that we store in the array for each callout.</p>
+ */
+public class Callout implements Comparable {
+  /** The callout number. */
+  private int callout = 0;
+  /** The area ElementInfo item that generated this callout. */
+  private ElementInfo area = null;
+  /** The line on which this callout occurs. */
+  private int line = 0;
+  /** The column in which this callout appears. */
+  private int col = 0;
+
+  /** The constructor; initialize the private data structures. */
+  public Callout(int callout, ElementInfo area, int line, int col) {
+    this.callout = callout;
+    this.area = area;
+    this.line = line;
+    this.col = col;
+  }
+
+  /**
+   * <p>The compareTo method compares this Callout with another.</p>
+   *
+   * <p>Given two Callouts, A and B, A < B if:</p>
+   *
+   * <ol>
+   * <li>A.line < B.line, or</li>
+   * <li>A.line = B.line && A.col < B.col, or</li>
+   * <li>A.line = B.line && A.col = B.col && A.callout < B.callout</li>
+   * <li>Otherwise, they're equal.</li>
+   * </ol>
+   */
+  public int compareTo (Object o) {
+    Callout c = (Callout) o;
+
+    if (line == c.getLine()) {
+       if (col > c.getColumn()) {
+         return 1;
+       } else if (col < c.getColumn()) {
+         return -1;
+       } else {
+         if (callout < c.getCallout()) {
+           return -1;
+         } else if (callout > c.getCallout()) {
+           return 1;
+         } else {
+           return 0;
+         }
+       }
+    } else {
+       if (line > c.getLine()) {
+         return 1;
+       } else {
+         return -1;
+       }
+    }
+  }
+
+  /** Access the Callout's area. */
+  public ElementInfo getArea() {
+    return area;
+  }
+
+  /** Access the Callout's line. */
+  public int getLine() {
+    return line;
+  }
+
+  /** Access the Callout's column. */
+  public int getColumn() {
+    return col;
+  }
+
+  /** Access the Callout's callout number. */
+  public int getCallout() {
+    return callout;
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/CalloutEmitter.java b/xsl/extensions/saxon61/com/nwalsh/saxon/CalloutEmitter.java
new file mode 100644 (file)
index 0000000..693c6e8
--- /dev/null
@@ -0,0 +1,527 @@
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import javax.xml.transform.TransformerException;
+import com.icl.saxon.Builder;
+import com.icl.saxon.Context;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.functions.Extensions;
+import com.icl.saxon.om.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.tree.*;
+
+/**
+ * <p>Saxon extension to decorate a result tree fragment with callouts.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides the guts of a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation of callouts for verbatim environments. (It is used
+ * by the Verbatim class.)</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some verbatim environment. The Verbatim class initializes
+ * a CalloutEmitter with information about the callouts that should be applied
+ * to the verbatim environment in question. Then the result tree fragment
+ * is "replayed" through the CalloutEmitter; the CalloutEmitter builds a
+ * new result tree fragment from this event stream, decorated with callouts,
+ * and that is returned.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @see Verbatim
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class CalloutEmitter extends CopyEmitter {
+  /** A stack for the preserving information about open elements. */
+  protected Stack elementStack = null;
+
+  /** A stack for holding information about temporarily closed elements. */
+  protected Stack tempStack = null;
+
+  /** Is the next element absolutely the first element in the fragment? */
+  protected boolean firstElement = false;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /** The default column for callouts that specify only a line. */
+  protected int defaultColumn = 60;
+
+  /** Is the stylesheet currently running an FO stylesheet? */
+  protected boolean foStylesheet = false;
+
+  /** The current line number. */
+  private static int lineNumber = 0;
+
+  /** The current column number. */
+  private static int colNumber = 0;
+
+  /** The (sorted) array of callouts obtained from the areaspec. */
+  private static Callout callout[] = null;
+
+  /** The number of callouts in the callout array. */
+  private static int calloutCount = 0;
+
+  /** A pointer used to keep track of our position in the callout array. */
+  private static int calloutPos = 0;
+
+  /** The FormatCallout object to use for formatting callouts. */
+  private static FormatCallout fCallout = null;
+
+  /** <p>Constructor for the CalloutEmitter.</p>
+   *
+   * @param namePool The name pool to use for constructing elements and attributes.
+   * @param graphicsPath The path to callout number graphics.
+   * @param graphicsExt The extension for callout number graphics.
+   * @param graphicsMax The largest callout number that can be represented as a graphic.
+   * @param defaultColumn The default column for callouts.
+   * @param foStylesheet Is this an FO stylesheet?
+   */
+  public CalloutEmitter(NamePool namePool,
+                       int defaultColumn,
+                       boolean foStylesheet,
+                       FormatCallout fCallout) {
+    super(namePool);
+    elementStack = new Stack();
+    firstElement = true;
+
+    this.defaultColumn = defaultColumn;
+    this.foStylesheet = foStylesheet;
+    this.fCallout = fCallout;
+  }
+
+  /**
+   * <p>Examine the areaspec and determine the number and position of 
+   * callouts.</p>
+   *
+   * <p>The <code><a href="http://docbook.org/tdg/html/areaspec.html">areaspecNodeSet</a></code>
+   * is examined and a sorted list of the callouts is constructed.</p>
+   *
+   * <p>This data structure is used to augment the result tree fragment
+   * with callout bullets.</p>
+   *
+   * @param areaspecNodeSet The source document &lt;areaspec&gt; element.
+   *
+   */
+  public void setupCallouts (NodeSetIntent areaspecNodeSet) {
+    callout = new Callout[10];
+    calloutCount = 0;
+    calloutPos = 0;
+    lineNumber = 1;
+    colNumber = 1;
+
+    // First we walk through the areaspec to calculate the position
+    // of the callouts
+    //  <areaspec>
+    //  <areaset id="ex.plco.const" coords="">
+    //    <area id="ex.plco.c1" coords="4"/>
+    //    <area id="ex.plco.c2" coords="8"/>
+    //  </areaset>
+    //  <area id="ex.plco.ret" coords="12"/>
+    //  <area id="ex.plco.dest" coords="12"/>
+    //  </areaspec>
+    try {
+      int pos = 0;
+      int coNum = 0;
+      boolean inAreaSet = false;
+      NodeInfo areaspec = areaspecNodeSet.getFirst();
+      NodeInfo children[] = areaspec.getAllChildNodes();
+
+      for (int count = 0; count < children.length; count++) {
+       NodeInfo node = children[count];
+       if (node.getNodeType() == NodeInfo.ELEMENT) {
+         if (node.getNodeName().equalsIgnoreCase("areaset")) {
+           coNum++;
+           NodeInfo areas[] = node.getAllChildNodes();
+           for (int acount = 0; acount < areas.length; acount++) {
+             NodeInfo area = areas[acount];
+             if (area.getNodeType() == NodeInfo.ELEMENT) {
+               if (area.getNodeName().equalsIgnoreCase("area")) {
+                 addCallout(coNum, area, defaultColumn);
+               } else {
+                 System.out.println("Unexpected element in areaset: "
+                                    + area.getNodeName());
+               }
+             }
+           }
+         } else if (node.getNodeName().equalsIgnoreCase("area")) {
+           coNum++;
+           addCallout(coNum, node, defaultColumn);
+         } else {
+           System.out.println("Unexpected element in areaspec: "
+                              + node.getNodeName());
+         }
+       }
+      }
+
+      // Now sort them
+      java.util.Arrays.sort(callout, 0, calloutCount);
+    } catch (TransformerException e) {
+      //nop;
+    }
+  }
+
+  /** Process characters. */
+  public void characters(char[] chars, int start, int len)
+    throws TransformerException {
+
+    // If we hit characters, then there's no first element...
+    firstElement = false;
+
+    if (lineNumber == 0) {
+      // if there are any text nodes, there's at least one line
+      lineNumber++;
+      colNumber = 1;
+    }
+
+    // Walk through the text node looking for callout positions
+    char[] newChars = new char[len];
+    int pos = 0;
+    for (int count = start; count < start+len; count++) {
+      if (calloutPos < calloutCount
+         && callout[calloutPos].getLine() == lineNumber
+         && callout[calloutPos].getColumn() == colNumber) {
+       if (pos > 0) {
+         rtfEmitter.characters(newChars, 0, pos);
+         pos = 0;
+       }
+
+       closeOpenElements(rtfEmitter);
+
+       while (calloutPos < calloutCount
+              && callout[calloutPos].getLine() == lineNumber
+              && callout[calloutPos].getColumn() == colNumber) {
+         fCallout.formatCallout(rtfEmitter, callout[calloutPos]);
+         calloutPos++;
+       }
+
+       openClosedElements(rtfEmitter);
+      }
+
+      if (chars[count] == '\n') {
+       // What if we need to pad this line?
+       if (calloutPos < calloutCount
+           && callout[calloutPos].getLine() == lineNumber
+           && callout[calloutPos].getColumn() > colNumber) {
+
+         if (pos > 0) {
+           rtfEmitter.characters(newChars, 0, pos);
+           pos = 0;
+         }
+
+         closeOpenElements(rtfEmitter);
+
+         while (calloutPos < calloutCount
+                && callout[calloutPos].getLine() == lineNumber
+                && callout[calloutPos].getColumn() > colNumber) {
+           formatPad(callout[calloutPos].getColumn() - colNumber);
+           colNumber = callout[calloutPos].getColumn();
+           while (calloutPos < calloutCount
+                  && callout[calloutPos].getLine() == lineNumber
+                  && callout[calloutPos].getColumn() == colNumber) {
+             fCallout.formatCallout(rtfEmitter, callout[calloutPos]);
+             calloutPos++;
+           }
+         }
+
+         openClosedElements(rtfEmitter);
+       }
+
+       lineNumber++;
+       colNumber = 1;
+      } else {
+       colNumber++;
+      }
+      newChars[pos++] = chars[count];
+    }
+
+    if (pos > 0) {
+      rtfEmitter.characters(newChars, 0, pos);
+    }
+  }
+
+  /**
+   * <p>Add blanks to the result tree fragment.</p>
+   *
+   * <p>This method adds <tt>numBlanks</tt> to the result tree fragment.
+   * It's used to pad lines when callouts occur after the last existing
+   * characater in a line.</p>
+   *
+   * @param numBlanks The number of blanks to add.
+   */
+  protected void formatPad(int numBlanks) {
+    char chars[] = new char[numBlanks];
+    for (int count = 0; count < numBlanks; count++) {
+      chars[count] = ' ';
+    }
+
+    try {
+      rtfEmitter.characters(chars, 0, numBlanks);
+    } catch (TransformerException e) {
+      System.out.println("Transformer Exception in formatPad");
+    }
+  }
+
+  /**
+   * <p>Add a callout to the global callout array</p>
+   *
+   * <p>This method examines a callout <tt>area</tt> and adds it to
+   * the global callout array if it can be interpreted.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the <tt>defaultColumn</tt>.</p>
+   *
+   * @param coNum The callout number.
+   * @param node The <tt>area</tt>.
+   * @param defaultColumn The default column for callouts.
+   */
+  protected void addCallout (int coNum,
+                            NodeInfo node,
+                            int defaultColumn) {
+
+    ElementInfo area = (ElementInfo) node;
+    ExtendedAttributes attr = area.getAttributeList();
+    String units  = attr.getValue("units");
+    String coords = attr.getValue("coords");
+
+    if (units != null
+       && !units.equalsIgnoreCase("linecolumn")
+       && !units.equalsIgnoreCase("linerange")) {
+      System.out.println("Only linecolumn and linerange units are supported");
+      return;
+    }
+
+    if (coords == null) {
+      System.out.println("Coords must be specified");
+      return;
+    }
+
+    // Now let's see if we can interpret the coordinates...
+    StringTokenizer st = new StringTokenizer(coords);
+    int tokenCount = 0;
+    int c1 = 0;
+    int c2 = 0;
+    while (st.hasMoreTokens()) {
+      tokenCount++;
+      if (tokenCount > 2) {
+       System.out.println("Unparseable coordinates");
+       return;
+      }
+      try {
+       String token = st.nextToken();
+       int coord = Integer.parseInt(token);
+       c2 = coord;
+       if (tokenCount == 1) {
+         c1 = coord;
+       }
+      } catch (NumberFormatException e) {
+       System.out.println("Unparseable coordinate");
+       return;
+      }
+    }
+
+    // Make sure we aren't going to blow past the end of our array
+    if (calloutCount == callout.length) {
+      Callout bigger[] = new Callout[calloutCount+10];
+      for (int count = 0; count < callout.length; count++) {
+       bigger[count] = callout[count];
+      }
+      callout = bigger;
+    }
+
+    // Ok, add the callout
+    if (tokenCount == 2) {
+      if (units != null && units.equalsIgnoreCase("linerange")) {
+       for (int count = c1; count <= c2; count++) {
+         callout[calloutCount++] = new Callout(coNum, area,
+                                               count, defaultColumn);
+       }
+      } else {
+       // assume linecolumn
+       callout[calloutCount++] = new Callout(coNum, area, c1, c2);
+      }
+    } else {
+      // if there's only one number, assume it's the line
+      callout[calloutCount++] = new Callout(coNum, area, c1, defaultColumn);
+    }
+  }
+
+  /** Process end element events. */
+  public void endElement(int nameCode)
+    throws TransformerException {
+
+    if (!elementStack.empty()) {
+      // if we didn't push the very first element (an fo:block or
+      // pre or div surrounding the whole block), then the stack will
+      // be empty when we get to the end of the first element...
+      elementStack.pop();
+    }
+    rtfEmitter.endElement(nameCode);
+  }
+
+  /** Process start element events. */
+  public void startElement(int nameCode,
+                          org.xml.sax.Attributes attributes,
+                          int[] namespaces,
+                          int nscount)
+    throws TransformerException {
+
+    if (!skipThisElement(nameCode)) {
+      StartElementInfo sei = new StartElementInfo(nameCode, attributes,
+                                                 namespaces, nscount);
+      elementStack.push(sei);
+    }
+
+    firstElement = false;
+
+    rtfEmitter.startElement(nameCode, attributes, namespaces, nscount);
+  }
+
+  /**
+   * <p>Protect the outer-most block wrapper.</p>
+   *
+   * <p>Open elements in the result tree fragment are closed and reopened
+   * around callouts (so that callouts don't appear inside links or other
+   * environments). But if the result tree fragment is a single block
+   * (a div or pre in HTML, an fo:block in FO), that outer-most block is
+   * treated specially.</p>
+   *
+   * <p>This method returns true if the element in question is that
+   * outermost block.</p>
+   *
+   * @param nameCode The name code for the element
+   *
+   * @return True if the element is the outer-most block, false otherwise.
+   */
+  protected boolean skipThisElement(int nameCode) {
+    if (firstElement) {
+      int thisFingerprint    = namePool.getFingerprint(nameCode);
+      int foBlockFingerprint = namePool.getFingerprint(foURI, "block");
+      int htmlPreFingerprint = namePool.getFingerprint("", "pre");
+      int htmlDivFingerprint = namePool.getFingerprint("", "div");
+
+      if ((foStylesheet && thisFingerprint == foBlockFingerprint)
+         || (!foStylesheet && (thisFingerprint == htmlPreFingerprint
+                               || thisFingerprint == htmlDivFingerprint))) {
+       // Don't push the outer-most wrapping div, pre, or fo:block
+       return true;
+      }
+    }
+
+    return false;
+  }
+
+  private void closeOpenElements(Emitter rtfEmitter)
+    throws TransformerException {
+    // Close all the open elements...
+    tempStack = new Stack();
+    while (!elementStack.empty()) {
+      StartElementInfo elem = (StartElementInfo) elementStack.pop();
+      rtfEmitter.endElement(elem.getNameCode());
+      tempStack.push(elem);
+    }
+  }
+
+  private void openClosedElements(Emitter rtfEmitter)
+    throws TransformerException {
+    // Now "reopen" the elements that we closed...
+    while (!tempStack.empty()) {
+      StartElementInfo elem = (StartElementInfo) tempStack.pop();
+      AttributeCollection attr = (AttributeCollection)elem.getAttributes();
+      AttributeCollection newAttr = new AttributeCollection(namePool);
+
+      for (int acount = 0; acount < attr.getLength(); acount++) {
+       String localName = attr.getLocalName(acount);
+       int nameCode = attr.getNameCode(acount);
+       String type = attr.getType(acount);
+       String value = attr.getValue(acount);
+       String uri = attr.getURI(acount);
+       String prefix = "";
+
+       if (localName.indexOf(':') > 0) {
+         prefix = localName.substring(0, localName.indexOf(':'));
+         localName = localName.substring(localName.indexOf(':')+1);
+       }
+
+       if (uri.equals("")
+           && ((foStylesheet
+                && localName.equals("id"))
+               || (!foStylesheet
+                   && (localName.equals("id")
+                       || localName.equals("name"))))) {
+         // skip this attribute
+       } else {
+         newAttr.addAttribute(prefix, uri, localName, type, value);
+       }
+      }
+
+      rtfEmitter.startElement(elem.getNameCode(),
+                             newAttr,
+                             elem.getNamespaces(),
+                             elem.getNSCount());
+
+      elementStack.push(elem);
+    }
+  }
+
+  /**
+   * <p>A private class for maintaining the information required to call
+   * the startElement method.</p>
+   *
+   * <p>In order to close and reopen elements, information about those
+   * elements has to be maintained. This class is just the little record
+   * that we push on the stack to keep track of that info.</p>
+   */
+  private class StartElementInfo {
+    private int _nameCode;
+    org.xml.sax.Attributes _attributes;
+    int[] _namespaces;
+    int _nscount;
+
+    public StartElementInfo(int nameCode,
+                           org.xml.sax.Attributes attributes,
+                           int[] namespaces,
+                           int nscount) {
+      _nameCode = nameCode;
+      _attributes = attributes;
+      _namespaces = namespaces;
+      _nscount = nscount;
+    }
+
+    public int getNameCode() {
+      return _nameCode;
+    }
+
+    public org.xml.sax.Attributes getAttributes() {
+      return _attributes;
+    }
+
+    public int[] getNamespaces() {
+      return _namespaces;
+    }
+
+    public int getNSCount() {
+      return _nscount;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/ColumnScanEmitter.java b/xsl/extensions/saxon61/com/nwalsh/saxon/ColumnScanEmitter.java
new file mode 100644 (file)
index 0000000..0b7c3c9
--- /dev/null
@@ -0,0 +1,167 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.*;
+import javax.xml.transform.TransformerException;
+import com.icl.saxon.output.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.expr.FragmentValue;
+import com.icl.saxon.Builder;
+
+/**
+ * <p>Saxon extension to scan the column widthsin a result tree fragment.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation to scan the column widths in a result tree
+ * fragment.</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some colgroup environment. That result tree fragment
+ * is "replayed" through the ColumnScanEmitter; the ColumnScanEmitter watches
+ * the cols go by and extracts the column widths that it sees. These
+ * widths are then made available.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class ColumnScanEmitter extends com.icl.saxon.output.Emitter {
+  /** The number of columns seen. */
+  protected int numColumns = 0;
+  protected String width[] = new String[5];
+  protected NamePool namePool = null;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /** Construct a new ColumnScanEmitter. */
+  public ColumnScanEmitter(NamePool namePool) {
+    numColumns = 0;
+    this.namePool = namePool;
+  }
+
+  /** Return the number of columns. */
+  public int columnCount() {
+    return numColumns;
+  }
+
+  /** Return the number of columns. */
+  public String[] columnWidths() {
+    return width;
+  }
+
+  /** Discarded. */
+  public void characters(char[] chars, int start, int len)
+    throws TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void comment(char[] chars, int start, int length)
+    throws TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void endDocument()
+    throws TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void endElement(int nameCode)
+    throws TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void processingInstruction(java.lang.String name,
+                                   java.lang.String data)
+    throws TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setDocumentLocator(org.xml.sax.Locator locator) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setEscaping(boolean escaping)
+    throws TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setNamePool(NamePool namePool) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setUnparsedEntity(java.lang.String name, java.lang.String uri)
+    throws TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setWriter(java.io.Writer writer) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void startDocument()
+    throws TransformerException {
+    // nop
+  }
+
+  /** Examine for column info. */
+  public void startElement(int nameCode,
+                   org.xml.sax.Attributes attributes,
+                   int[] namespaces, int nscount)
+    throws TransformerException {
+
+    int thisFingerprint = namePool.getFingerprint(nameCode);
+    int colFingerprint = namePool.getFingerprint("", "col");
+    int foColFingerprint = namePool.getFingerprint(foURI, "table-column");
+
+    if (thisFingerprint == colFingerprint
+       || thisFingerprint == foColFingerprint) {
+      if (numColumns >= width.length) {
+       String newWidth[] = new String[width.length+10];
+       for (int count = 0; count < width.length; count++) {
+         newWidth[count] = width[count];
+       }
+       width = newWidth;
+      }
+
+      if (thisFingerprint == colFingerprint) {
+       if (attributes.getValue("width") == null) {
+         width[numColumns++] = "1*";
+       } else {
+         width[numColumns++] = attributes.getValue("width");
+       }
+      } else {
+       if (attributes.getValue("column-width") == null) {
+         width[numColumns++] = "1*";
+       } else {
+         width[numColumns++] = attributes.getValue("column-width");
+       }
+      }
+    }
+  }
+}
+
+
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/ColumnUpdateEmitter.java b/xsl/extensions/saxon61/com/nwalsh/saxon/ColumnUpdateEmitter.java
new file mode 100644 (file)
index 0000000..99b43c8
--- /dev/null
@@ -0,0 +1,96 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.om.*;
+import javax.xml.transform.TransformerException;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.expr.FragmentValue;
+import com.icl.saxon.Builder;
+import com.icl.saxon.tree.AttributeCollection;
+
+/**
+ * <p>Saxon extension to scan the column widthsin a result tree fragment.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation to scan the column widths in a result tree
+ * fragment.</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some colgroup environment. That result tree fragment
+ * is "replayed" through the ColumnUpdateEmitter; the ColumnUpdateEmitter watches
+ * the cols go by and extracts the column widths that it sees. These
+ * widths are then made available.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class ColumnUpdateEmitter extends CopyEmitter {
+  /** The number of columns seen. */
+  protected int numColumns = 0;
+  protected String width[] = null;
+  protected NamePool namePool = null;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /** Construct a new ColumnUpdateEmitter. */
+  public ColumnUpdateEmitter(NamePool namePool,
+                            String width[]) {
+    super(namePool);
+    numColumns = 0;
+    this.width = width;
+    this.namePool = namePool;
+  }
+
+  /** Examine for column info. */
+  public void startElement(int nameCode,
+                   org.xml.sax.Attributes attributes,
+                   int[] namespaces, int nscount)
+    throws TransformerException {
+
+    int thisFingerprint = namePool.getFingerprint(nameCode);
+    int colFingerprint = namePool.getFingerprint("", "col");
+    int foColFingerprint = namePool.getFingerprint(foURI, "table-column");
+
+    if (thisFingerprint == colFingerprint) {
+      AttributeCollection attr = new AttributeCollection(namePool, attributes);
+      int widthFingerprint = namePool.getFingerprint("", "width");
+
+      if (attr.getValueByFingerprint(widthFingerprint) == null) {
+       attr.addAttribute(widthFingerprint, "CDATA", width[numColumns++]);
+      } else {
+       attr.setAttribute(widthFingerprint, "CDATA", width[numColumns++]);
+      }
+      attributes = attr;
+    } else if (thisFingerprint == foColFingerprint) {
+      AttributeCollection attr = new AttributeCollection(namePool, attributes);
+      int widthFingerprint = namePool.getFingerprint("", "column-width");
+
+      if (attr.getValueByFingerprint(widthFingerprint) == null) {
+       attr.addAttribute(widthFingerprint, "CDATA", width[numColumns++]);
+      } else {
+       attr.setAttribute(widthFingerprint, "CDATA", width[numColumns++]);
+      }
+      attributes = attr;
+    }
+
+    rtfEmitter.startElement(nameCode, attributes, namespaces, nscount);
+  }
+}
+
+
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/CopyEmitter.java b/xsl/extensions/saxon61/com/nwalsh/saxon/CopyEmitter.java
new file mode 100644 (file)
index 0000000..ee15c9b
--- /dev/null
@@ -0,0 +1,150 @@
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import javax.xml.transform.TransformerException;
+import com.icl.saxon.Builder;
+import com.icl.saxon.Context;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.functions.Extensions;
+import com.icl.saxon.om.*;
+import com.icl.saxon.output.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.tree.*;
+
+/**
+ * <p>A Saxon 6.0 Emitter that clones its input.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation of an emitter that manufactures a cloned result
+ * tree fragment.</p>
+ *
+ * <p>The purpose of this emitter is to provide something for
+ * CalloutEmitter and NumberLinesEmitter to extend.
+ * This emitter simply copies all input to a new result tree fragment.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @see CalloutEmitter
+ * @see NumberLinesEmitter
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class CopyEmitter extends com.icl.saxon.output.Emitter {
+  /** The result tree fragment containing the copied fragment. */
+  protected FragmentValue rtf = null;
+  protected Emitter rtfEmitter = null;
+
+  /** <p>The namePool.</p>
+   *
+   * <p>Copied from the caller, it should be the runtime name pool.</p>
+   */
+  protected NamePool namePool = null;
+
+  /** <p>Constructor for the CopyEmitter.</p>
+   *
+   * @param namePool The name pool to use for constructing elements and attributes.
+   */
+  public CopyEmitter(NamePool namePool) {
+    rtf = new FragmentValue();
+    rtfEmitter = rtf.getEmitter();
+    this.namePool = namePool;
+  }
+
+  /**
+   * <p>Return the result tree fragment constructed by replaying events
+   * through this emitter.</p>
+   */
+  public FragmentValue getResultTreeFragment() {
+    return rtf;
+  }
+
+  /** Copy characters. */
+  public void characters(char[] chars, int start, int len)
+    throws TransformerException {
+    rtfEmitter.characters(chars, start, len);
+  }
+
+  /** Copy comments. */
+  public void comment(char[] chars, int start, int length)
+    throws TransformerException {
+    rtfEmitter.comment(chars, start, length);
+  }
+
+  /** Copy end document events. */
+  public void endDocument()
+    throws TransformerException {
+    rtfEmitter.endDocument();
+  }
+
+  /** Copy end element events. */
+  public void endElement(int nameCode)
+    throws TransformerException {
+    rtfEmitter.endElement(nameCode);
+  }
+
+  /** Copy processing instructions. */
+  public void processingInstruction(java.lang.String name,
+                                   java.lang.String data)
+    throws TransformerException {
+    rtfEmitter.processingInstruction(name, data);
+  }
+
+  /** Copy set document locator events. */
+  public void setDocumentLocator(org.xml.sax.Locator locator) {
+    rtfEmitter.setDocumentLocator(locator);
+  }
+
+  /** Copy set escaping events. */
+  public void setEscaping(boolean escaping)
+    throws TransformerException {
+    rtfEmitter.setEscaping(escaping);
+  }
+
+  /** Copy set name pool events. */
+  public void setNamePool(NamePool namePool) {
+    rtfEmitter.setNamePool(namePool);
+  }
+
+  /** Copy set unparsed entity events. */
+  public void setUnparsedEntity(java.lang.String name, java.lang.String uri)
+    throws TransformerException {
+    rtfEmitter.setUnparsedEntity(name, uri);
+  }
+
+  /** Copy set writer events. */
+  public void setWriter(java.io.Writer writer) {
+    rtfEmitter.setWriter(writer);
+  }
+
+  /** Copy start document events. */
+  public void startDocument()
+    throws TransformerException {
+    rtfEmitter.startDocument();
+  }
+
+  /** Copy start element events. */
+  public void startElement(int nameCode,
+                          org.xml.sax.Attributes attributes,
+                          int[] namespaces,
+                          int nscount)
+    throws TransformerException {
+    rtfEmitter.startElement(nameCode, attributes, namespaces, nscount);
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/FormatCallout.java b/xsl/extensions/saxon61/com/nwalsh/saxon/FormatCallout.java
new file mode 100644 (file)
index 0000000..c8be006
--- /dev/null
@@ -0,0 +1,112 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import javax.xml.transform.TransformerException;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.NamePool;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.tree.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public abstract class FormatCallout {
+  protected static final String foURI = "http://www.w3.org/1999/XSL/Format";
+  protected static final String xhURI = "http://www.w3.org/1999/xhtml";
+  protected boolean foStylesheet = false;
+  protected NamePool namePool = null;
+
+  public FormatCallout(NamePool nPool, boolean fo) {
+    namePool = nPool;
+    foStylesheet = fo;
+  }
+
+  public String areaLabel(ElementInfo area) {
+    String label = null;
+
+    if (area.getAttributeList().getValue("label") != null) {
+      // If this area has a label, use it
+      label = area.getAttributeList().getValue("label");
+    } else {
+      // Otherwise, if its parent is an areaset and it has a label, use that
+      ElementInfo parent = (ElementInfo) area.getParentNode();
+      if (parent != null
+         && parent.getLocalName().equalsIgnoreCase("areaset")
+         && parent.getAttributeList().getValue("label") != null) {
+       label = parent.getAttributeList().getValue("label");
+      }
+    }
+
+    return label;
+  }
+
+  public void startSpan(Emitter rtf)
+    throws TransformerException {
+    // no point in doing this for FO, right?
+    if (!foStylesheet && namePool != null) {
+      int spanName = namePool.allocate("", "", "span");
+      AttributeCollection spanAttr = new AttributeCollection(namePool);
+      int namespaces[] = new int[1];
+      spanAttr.addAttribute("", "", "class", "CDATA", "co");
+      rtf.startElement(spanName, spanAttr, namespaces, 0);
+    }
+  }
+
+  public void endSpan(Emitter rtf)
+    throws TransformerException {
+    // no point in doing this for FO, right?
+    if (!foStylesheet && namePool != null) {
+      int spanName = namePool.allocate("", "", "span");
+      rtf.endElement(spanName);
+    }
+  }
+
+  public void formatTextCallout(Emitter rtfEmitter,
+                               Callout callout) {
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String userLabel = areaLabel(area);
+    String label = "(" + num + ")";
+
+    if (userLabel != null) {
+      label = userLabel;
+    }
+
+    char chars[] = label.toCharArray();
+
+    try {
+      startSpan(rtfEmitter);
+      rtfEmitter.characters(chars, 0, label.length());
+      endSpan(rtfEmitter);
+    } catch (TransformerException e) {
+      System.out.println("Transformer Exception in formatTextCallout");
+    }
+  }
+
+  public abstract void formatCallout(Emitter rtfEmitter,
+                                    Callout callout);
+}
+
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/FormatGraphicCallout.java b/xsl/extensions/saxon61/com/nwalsh/saxon/FormatGraphicCallout.java
new file mode 100644 (file)
index 0000000..a615902
--- /dev/null
@@ -0,0 +1,89 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import javax.xml.transform.TransformerException;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.NamePool;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.tree.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatGraphicCallout extends FormatCallout {
+  String graphicsPath = "";
+  String graphicsExt = "";
+  int graphicsMax = 0;
+
+  public FormatGraphicCallout(NamePool nPool, String path, String ext, int max, boolean fo) {
+    super(nPool, fo);
+    graphicsPath = path;
+    graphicsExt = ext;
+    graphicsMax = max;
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String userLabel = areaLabel(area);
+    String label = "(" + num + ")";
+
+    if (userLabel != null) {
+      label = userLabel;
+    }
+
+    try {
+      if (userLabel == null && num <= graphicsMax) {
+       int imgName = 0;
+       AttributeCollection imgAttr = null;
+       int namespaces[] = new int[1];
+
+       if (foStylesheet) {
+         imgName = namePool.allocate("fo", foURI, "external-graphic");
+         imgAttr = new AttributeCollection(namePool);
+         imgAttr.addAttribute("", "", "src", "CDATA",
+                              graphicsPath + num + graphicsExt);
+       } else {
+         imgName = namePool.allocate("", "", "img");
+         imgAttr = new AttributeCollection(namePool);
+         imgAttr.addAttribute("", "", "src", "CDATA",
+                              graphicsPath + num + graphicsExt);
+         imgAttr.addAttribute("", "", "alt", "CDATA", label);
+       }
+
+       startSpan(rtfEmitter);
+       rtfEmitter.startElement(imgName, imgAttr, namespaces, 0);
+       rtfEmitter.endElement(imgName);
+       endSpan(rtfEmitter);
+      } else {
+       formatTextCallout(rtfEmitter, callout);
+      }
+    } catch (TransformerException e) {
+      System.out.println("Transformer Exception in graphic formatCallout");
+    }
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/FormatTextCallout.java b/xsl/extensions/saxon61/com/nwalsh/saxon/FormatTextCallout.java
new file mode 100644 (file)
index 0000000..0c0c0f7
--- /dev/null
@@ -0,0 +1,44 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import javax.xml.transform.TransformerException;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.NamePool;
+import com.icl.saxon.output.Emitter;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatTextCallout extends FormatCallout {
+  public FormatTextCallout(NamePool nPool, boolean fo) {
+    super(nPool, fo);
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+    formatTextCallout(rtfEmitter, callout);
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/FormatUnicodeCallout.java b/xsl/extensions/saxon61/com/nwalsh/saxon/FormatUnicodeCallout.java
new file mode 100644 (file)
index 0000000..e4fdc0e
--- /dev/null
@@ -0,0 +1,68 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+import javax.xml.transform.TransformerException;
+
+import com.icl.saxon.om.ElementInfo;
+import com.icl.saxon.om.NamePool;
+import com.icl.saxon.output.Emitter;
+import com.icl.saxon.tree.AttributeCollection;
+
+import com.nwalsh.saxon.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatUnicodeCallout extends FormatCallout {
+  int unicodeMax = 0;
+  int unicodeStart = 0;
+
+  public FormatUnicodeCallout(NamePool nPool, int start, int max, boolean fo) {
+    super(nPool, fo);
+    unicodeMax = max;
+    unicodeStart = start;
+  }
+
+  public void formatCallout(Emitter rtfEmitter,
+                           Callout callout) {
+
+    ElementInfo area = callout.getArea();
+    int num = callout.getCallout();
+    String label = areaLabel(area);
+
+    try {
+      if (label == null && num <= unicodeMax) {
+       char chars[] = new char[1];
+       chars[0] = (char) (unicodeStart + num - 1);
+
+       startSpan(rtfEmitter);
+       rtfEmitter.characters(chars, 0, 1);
+       endSpan(rtfEmitter);
+      } else {
+       formatTextCallout(rtfEmitter, callout);
+      }
+    } catch (TransformerException e) {
+      System.out.println("Transformer Exception in graphic formatCallout");
+    }
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/LineCountEmitter.java b/xsl/extensions/saxon61/com/nwalsh/saxon/LineCountEmitter.java
new file mode 100644 (file)
index 0000000..99d7b2d
--- /dev/null
@@ -0,0 +1,143 @@
+package com.nwalsh.saxon;
+
+import org.xml.sax.*;
+import javax.xml.transform.TransformerException;
+import com.icl.saxon.output.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.expr.FragmentValue;
+import com.icl.saxon.Builder;
+
+/**
+ * <p>Saxon extension to count the lines in a result tree fragment.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation to count the number of lines in a result tree
+ * fragment.</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some verbatim environment. That result tree fragment
+ * is "replayed" through the LineCountEmitter; the LineCountEmitter watches
+ * characters go by and counts the number of line feeds that it sees.
+ * That number is then returned.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @see Verbatim
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class LineCountEmitter extends com.icl.saxon.output.Emitter {
+  /** The number of lines seen. */
+  protected int numLines = 0;
+
+  /** Construct a new LineCountEmitter. */
+  public LineCountEmitter() {
+    numLines = 0;
+  }
+
+  /** Reset the number of lines. */
+  public void reset() {
+    numLines = 0;
+  }
+
+  /** Return the number of lines. */
+  public int lineCount() {
+    return numLines;
+  }
+
+  /** Process characters. */
+  public void characters(char[] chars, int start, int len)
+    throws javax.xml.transform.TransformerException {
+
+    if (numLines == 0) {
+      // If there are any characters at all, there's at least one line
+      numLines++;
+    }
+
+    for (int count = start; count < start+len; count++) {
+      if (chars[count] == '\n') {
+       numLines++;
+      }
+    }
+  }
+
+  /** Discarded. */
+  public void comment(char[] chars, int start, int length)
+    throws javax.xml.transform.TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void endDocument()
+    throws javax.xml.transform.TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void endElement(int nameCode)
+    throws javax.xml.transform.TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void processingInstruction(java.lang.String name,
+                                   java.lang.String data)
+    throws javax.xml.transform.TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setDocumentLocator(org.xml.sax.Locator locator) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setEscaping(boolean escaping)
+    throws javax.xml.transform.TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setNamePool(NamePool namePool) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setUnparsedEntity(java.lang.String name, java.lang.String uri)
+    throws javax.xml.transform.TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void setWriter(java.io.Writer writer) {
+    // nop
+  }
+
+  /** Discarded. */
+  public void startDocument()
+    throws javax.xml.transform.TransformerException {
+    // nop
+  }
+
+  /** Discarded. */
+  public void startElement(int nameCode,
+                   org.xml.sax.Attributes attributes,
+                   int[] namespaces, int nscount)
+    throws javax.xml.transform.TransformerException {
+    // nop
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/NumberLinesEmitter.java b/xsl/extensions/saxon61/com/nwalsh/saxon/NumberLinesEmitter.java
new file mode 100644 (file)
index 0000000..f8065e3
--- /dev/null
@@ -0,0 +1,323 @@
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import javax.xml.transform.TransformerException;
+import com.icl.saxon.output.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.tree.AttributeCollection;
+import com.icl.saxon.tinytree.TinyBuilder;
+import com.icl.saxon.expr.FragmentValue;
+import com.icl.saxon.Builder;
+
+/**
+ * <p>Saxon extension to decorate a result tree fragment with line numbers.</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides the guts of a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon 6.*</a>
+ * implementation of line numbering for verbatim environments. (It is used
+ * by the Verbatim class.)</p>
+ *
+ * <p>The general design is this: the stylesheets construct a result tree
+ * fragment for some verbatim environment. The Verbatim class initializes
+ * a NumberLinesEmitter with information about what lines should be
+ * numbered and how. Then the result tree fragment
+ * is "replayed" through the NumberLinesEmitter; the NumberLinesEmitter
+ * builds a
+ * new result tree fragment from this event stream, decorated with line
+ * numbers,
+ * and that is returned.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @see Verbatim
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class NumberLinesEmitter extends CopyEmitter {
+  /** A stack for the preserving information about open elements. */
+  protected Stack elementStack = null;
+
+  /** The current line number. */
+  protected int lineNumber = 0;
+
+  /** Is the next element absolutely the first element in the fragment? */
+  protected boolean firstElement = false;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /** Every <code>modulus</code> line will be numbered. */
+  protected int modulus = 5;
+
+  /** Line numbers are <code>width</code> characters wide. */
+  protected int width = 3;
+
+  /** Line numbers are separated from the listing by <code>separator</code>. */
+  protected String separator = " ";
+
+  /** Is the stylesheet currently running an FO stylesheet? */
+  protected boolean foStylesheet = false;
+
+  /** <p>Constructor for the NumberLinesEmitter.</p>
+   *
+   * @param namePool The name pool to use for constructing elements and attributes.
+   * @param modulus The modulus to use for this listing.
+   * @param width The width to use for line numbers in this listing.
+   * @param separator The separator to use for this listing.
+   * @param foStylesheet Is this an FO stylesheet?
+   */
+  public NumberLinesEmitter(NamePool namePool,
+                           int modulus,
+                           int width,
+                           String separator,
+                           boolean foStylesheet) {
+    super(namePool);
+    elementStack = new Stack();
+    firstElement = true;
+
+    this.modulus = modulus;
+    this.width = width;
+    this.separator = separator;
+    this.foStylesheet = foStylesheet;
+  }
+
+  /** Process characters. */
+  public void characters(char[] chars, int start, int len)
+    throws TransformerException {
+
+    // If we hit characters, then there's no first element...
+    firstElement = false;
+
+    if (lineNumber == 0) {
+      // The first line is always numbered
+      formatLineNumber(++lineNumber);
+    }
+
+    // Walk through the text node looking for newlines
+    char[] newChars = new char[len];
+    int pos = 0;
+    for (int count = start; count < start+len; count++) {
+      if (chars[count] == '\n') {
+       // This is the tricky bit; if we find a newline, make sure
+       // it doesn't occur inside any markup.
+
+       if (pos > 0) {
+         // Output any characters that preceded this newline
+         rtfEmitter.characters(newChars, 0, pos);
+         pos = 0;
+       }
+
+       // Close all the open elements...
+       Stack tempStack = new Stack();
+       while (!elementStack.empty()) {
+         StartElementInfo elem = (StartElementInfo) elementStack.pop();
+         rtfEmitter.endElement(elem.getNameCode());
+         tempStack.push(elem);
+       }
+
+       // Copy the newline to the output
+       newChars[pos++] = chars[count];
+       rtfEmitter.characters(newChars, 0, pos);
+       pos = 0;
+
+       // Add the line number
+       formatLineNumber(++lineNumber);
+
+       // Now "reopen" the elements that we closed...
+       while (!tempStack.empty()) {
+         StartElementInfo elem = (StartElementInfo) tempStack.pop();
+         AttributeCollection attr = (AttributeCollection)elem.getAttributes();
+         AttributeCollection newAttr = new AttributeCollection(namePool);
+
+         for (int acount = 0; acount < attr.getLength(); acount++) {
+           String localName = attr.getLocalName(acount);
+           int nameCode = attr.getNameCode(acount);
+           String type = attr.getType(acount);
+           String value = attr.getValue(acount);
+           String uri = attr.getURI(acount);
+           String prefix = "";
+
+           if (localName.indexOf(':') > 0) {
+             prefix = localName.substring(0, localName.indexOf(':'));
+             localName = localName.substring(localName.indexOf(':')+1);
+           }
+
+           if (uri.equals("")
+               && ((foStylesheet
+                    && localName.equals("id"))
+                   || (!foStylesheet
+                       && (localName.equals("id")
+                           || localName.equals("name"))))) {
+             // skip this attribute
+           } else {
+             newAttr.addAttribute(prefix, uri, localName, type, value);
+           }
+         }
+
+         rtfEmitter.startElement(elem.getNameCode(),
+                          newAttr,
+                          elem.getNamespaces(),
+                          elem.getNSCount());
+
+         elementStack.push(elem);
+       }
+      } else {
+       newChars[pos++] = chars[count];
+      }
+    }
+
+    if (pos > 0) {
+      rtfEmitter.characters(newChars, 0, pos);
+      pos = 0;
+    }
+  }
+
+  /**
+   * <p>Add a formatted line number to the result tree fragment.</p>
+   *
+   * @param lineNumber The number of the current line.
+   */
+  protected void formatLineNumber(int lineNumber) 
+    throws TransformerException {
+
+    char ch = 160; // &nbsp;
+
+    String lno = "";
+    if (lineNumber == 1
+       || (modulus >= 1 && (lineNumber % modulus == 0))) {
+      lno = "" + lineNumber;
+    }
+
+    while (lno.length() < width) {
+      lno = ch + lno;
+    }
+
+    lno += separator;
+
+    char chars[] = new char[lno.length()];
+    for (int count = 0; count < lno.length(); count++) {
+      chars[count] = lno.charAt(count);
+    }
+
+    characters(chars, 0, lno.length());
+  }
+
+  /** Process end element events. */
+  public void endElement(int nameCode)
+    throws TransformerException {
+    if (!elementStack.empty()) {
+      // if we didn't push the very first element (an fo:block or
+      // pre or div surrounding the whole block), then the stack will
+      // be empty when we get to the end of the first element...
+      elementStack.pop();
+    }
+    rtfEmitter.endElement(nameCode);
+  }
+
+  /** Process start element events. */
+  public void startElement(int nameCode,
+                          org.xml.sax.Attributes attributes,
+                          int[] namespaces,
+                          int nscount)
+    throws TransformerException {
+
+    if (!skipThisElement(nameCode)) {
+      StartElementInfo sei = new StartElementInfo(nameCode, attributes,
+                                                 namespaces, nscount);
+      elementStack.push(sei);
+    }
+
+    firstElement = false;
+
+    rtfEmitter.startElement(nameCode, attributes, namespaces, nscount);
+  }
+
+  /**
+   * <p>Protect the outer-most block wrapper.</p>
+   *
+   * <p>Open elements in the result tree fragment are closed and reopened
+   * around callouts (so that callouts don't appear inside links or other
+   * environments). But if the result tree fragment is a single block
+   * (a div or pre in HTML, an fo:block in FO), that outer-most block is
+   * treated specially.</p>
+   *
+   * <p>This method returns true if the element in question is that
+   * outermost block.</p>
+   *
+   * @param nameCode The name code for the element
+   *
+   * @return True if the element is the outer-most block, false otherwise.
+   */
+  protected boolean skipThisElement(int nameCode) {
+    if (firstElement) {
+      int foBlockFingerprint = namePool.getFingerprint(foURI, "block");
+      int htmlPreFingerprint = namePool.getFingerprint("", "pre");
+      int htmlDivFingerprint = namePool.getFingerprint("", "div");
+
+      if ((foStylesheet && nameCode == foBlockFingerprint)
+         || (!foStylesheet && (nameCode == htmlPreFingerprint
+                               || nameCode == htmlDivFingerprint))) {
+       // Don't push the outer-most wrapping div, pre, or fo:block
+       return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * <p>A private class for maintaining the information required to call
+   * the startElement method.</p>
+   *
+   * <p>In order to close and reopen elements, information about those
+   * elements has to be maintained. This class is just the little record
+   * that we push on the stack to keep track of that info.</p>
+   */
+  private class StartElementInfo {
+    private int _nameCode;
+    org.xml.sax.Attributes _attributes;
+    int[] _namespaces;
+    int _nscount;
+
+    public StartElementInfo(int nameCode,
+                           org.xml.sax.Attributes attributes,
+                           int[] namespaces,
+                           int nscount) {
+      _nameCode = nameCode;
+      _attributes = attributes;
+      _namespaces = namespaces;
+      _nscount = nscount;
+    }
+
+    public int getNameCode() {
+      return _nameCode;
+    }
+
+    public org.xml.sax.Attributes getAttributes() {
+      return _attributes;
+    }
+
+    public int[] getNamespaces() {
+      return _namespaces;
+    }
+
+    public int getNSCount() {
+      return _nscount;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/Table.java b/xsl/extensions/saxon61/com/nwalsh/saxon/Table.java
new file mode 100644 (file)
index 0000000..8afe55d
--- /dev/null
@@ -0,0 +1,428 @@
+// Verbatim.java - Saxon extensions supporting DocBook verbatim environments
+
+package com.nwalsh.saxon;
+
+import java.util.Hashtable;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import javax.xml.transform.TransformerException;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.Context;
+import com.icl.saxon.tree.*;
+import com.icl.saxon.functions.Extensions;
+
+/**
+ * <p>Saxon extensions supporting Tables</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * implementation of some code to adjust CALS Tables to HTML
+ * Tables.</p>
+ *
+ * <p><b>Column Widths</b></p>
+ * <p>The <tt>adjustColumnWidths</tt> method takes a result tree
+ * fragment (assumed to contain the colgroup of an HTML Table)
+ * and returns the result tree fragment with the column widths
+ * adjusted to HTML terms.</p>
+ *
+ * <p><b>Convert Lengths</b></p>
+ * <p>The <tt>convertLength</tt> method takes a length specification
+ * of the form 9999.99xx (where "xx" is a unit) and returns that length
+ * as an integral number of pixels. For convenience, percentage lengths
+ * are returned unchanged.</p>
+ * <p>The recognized units are: inches (in), centimeters (cm),
+ * millimeters (mm), picas (pc, 1pc=12pt), points (pt), and pixels (px).
+ * A number with no units is assumed to be pixels.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Table {
+  /** The number of pixels per inch */
+  private static int pixelsPerInch = 96;
+
+  /** The nominal table width (6in by default). */
+  private static int nominalWidth = 6 * pixelsPerInch;
+
+  /** The default table width (100% by default). */
+  private static String tableWidth = "100%";
+
+  /** Is this an FO stylesheet? */
+  private static boolean foStylesheet = false;
+
+  /** The hash used to associate units with a length in pixels. */
+  protected static Hashtable unitHash = null;
+
+  /**
+   * <p>Constructor for Verbatim</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public Table() {
+  }
+
+  /** Initialize the internal hash table with proper values. */
+  protected static void initializeHash() {
+    unitHash = new Hashtable();
+    unitHash.put("in", new Float(pixelsPerInch));
+    unitHash.put("cm", new Float(pixelsPerInch / 2.54));
+    unitHash.put("mm", new Float(pixelsPerInch / 25.4));
+    unitHash.put("pc", new Float((pixelsPerInch / 72) * 12));
+    unitHash.put("pt", new Float(pixelsPerInch / 72));
+    unitHash.put("px", new Float(1));
+  }
+
+  /** Set the pixels-per-inch value. Only positive values are legal. */
+  public static void setPixelsPerInch(int value) {
+    if (value > 0) {
+      pixelsPerInch = value;
+      initializeHash();
+    }
+  }
+
+  /** Return the current pixels-per-inch value. */
+  public int getPixelsPerInch() {
+    return pixelsPerInch;
+  }
+
+  /**
+   * <p>Convert a length specification to a number of pixels.</p>
+   *
+   * <p>The specified length should be of the form [+/-]999.99xx,
+   * where xx is a valid unit.</p>
+   */
+  public static int convertLength(String length) {
+    // The format of length should be 999.999xx
+    int sign = 1;
+    String digits = "";
+    String units = "";
+    char lench[] = length.toCharArray();
+    float flength = 0;
+    boolean done = false;
+    int pos = 0;
+    float factor = 1;
+    int pixels = 0;
+
+    if (unitHash == null) {
+      initializeHash();
+    }
+
+    if (lench[pos] == '+' || lench[pos] == '-') {
+      if (lench[pos] == '-') {
+       sign = -1;
+      }
+      pos++;
+    }
+
+    while (!done) {
+      if (pos >= lench.length) {
+       done = true;
+      } else {
+       if ((lench[pos] > '9' || lench[pos] < '0') && lench[pos] != '.') {
+         done = true;
+         units = length.substring(pos);
+       } else {
+         digits += lench[pos++];
+       }
+      }
+    }
+
+    try {
+      flength = Float.parseFloat(digits);
+    } catch (NumberFormatException e) {
+      System.out.println(digits + " is not a number; 1 used instead.");
+      flength = 1;
+    }
+
+    Float f = null;
+
+    if (!units.equals("")) {
+      f = (Float) unitHash.get(units);
+      if (f == null) {
+       System.out.println(units + " is not a known unit; 1 used instead.");
+       factor = 1;
+      } else {
+       factor = f.floatValue();
+      }
+    } else {
+      factor = 1;
+    }
+
+    f = new Float(flength * factor);
+
+    pixels = f.intValue() * sign;
+
+    return pixels;
+  }
+
+  /**
+   * <p>Find the string value of a stylesheet variable or parameter</p>
+   *
+   * <p>Returns the string value of <code>varName</code> in the current
+   * <code>context</code>. Returns the empty string if the variable is
+   * not defined.</p>
+   *
+   * @param context The current stylesheet context
+   * @param varName The name of the variable (without the dollar sign)
+   *
+   * @return The string value of the variable
+   */
+  protected static String getVariable(Context context, String varName) 
+    throws TransformerException {
+    Value variable = null;
+    String varString = null;
+
+    try {
+      variable = Extensions.evaluate(context, "$" + varName);
+      varString = variable.asString();
+      return varString;
+    } catch (IllegalArgumentException e) {
+      System.out.println("Undefined variable: " + varName);
+      return "";
+    }
+  }
+
+  /**
+   * <p>Setup the parameters associated with column width calculations</p>
+   *
+   * <p>This method queries the stylesheet for the variables
+   * associated with table column widths. It is called automatically before
+   * column widths are adjusted. The context is used to retrieve the values,
+   * this allows templates to redefine these variables.</p>
+   *
+   * <p>The following variables are queried. If the variables do not
+   * exist, builtin defaults will be used (but you may also get a bunch
+   * of messages from the Java interpreter).</p>
+   *
+   * <dl>
+   * <dt><code>nominal.table.width</code></dt>
+   * <dd>The "normal" width for tables. This must be an absolute length.</dd>
+   * <dt><code>table.width</code></dt>
+   * <dd>The width for tables. This may be either an absolute
+   * length or a percentage.</dd>
+   * </dl>
+   *
+   * @param context The current stylesheet context
+   *
+   */
+  private static void setupColumnWidths(Context context) {
+    // Hardcoded defaults
+    nominalWidth = 6 * pixelsPerInch;
+    tableWidth = "100%";
+
+    String varString = null;
+
+    try {
+      // Get the stylesheet type
+      varString = getVariable(context, "stylesheet.result.type");
+      foStylesheet = varString.equals("fo");
+
+      // Get the nominal table width
+      varString = getVariable(context, "nominal.table.width");
+      nominalWidth = convertLength(varString);
+
+      // Get the table width
+      varString = getVariable(context, "table.width");
+      tableWidth = varString;
+    } catch (TransformerException e) {
+      //nop, can't happen
+    }
+  }
+
+  /**
+   * <p>Adjust column widths in an HTML table.</p>
+   *
+   * <p>The specification of column widths in CALS (a relative width
+   * plus an optional absolute width) are incompatible with HTML column
+   * widths. This method adjusts CALS column width specifiers in an
+   * attempt to produce equivalent HTML specifiers.</p>
+   *
+   * <p>In order for this method to work, the CALS width specifications
+   * should be placed in the "width" attribute of the &lt;col>s within
+   * a &lt;colgroup>. Then the colgroup result tree fragment is passed
+   * to this method.</p>
+   *
+   * <p>This method makes use of two parameters from the XSL stylesheet
+   * that calls it: <code>nominal.table.width</code> and
+   * <code>table.width</code>. The value of <code>nominal.table.width</code>
+   * must be an absolute distance. The value of <code>table.width</code>
+   * can be either absolute or relative.</p>
+   *
+   * <p>Presented with a mixture of relative and
+   * absolute lengths, the table width is used to calculate
+   * appropriate values. If the <code>table.width</code> is relative,
+   * the nominal width is used for this calculation.</p>
+   *
+   * <p>There are three possible combinations of values:</p>
+   *
+   * <ol>
+   * <li>There are no relative widths; in this case the absolute widths
+   * are used in the HTML table.</li>
+   * <li>There are no absolute widths; in this case the relative widths
+   * are used in the HTML table.</li>
+   * <li>There are a mixture of absolute and relative widths:
+   *   <ol>
+   *     <li>If the table width is absolute, all widths become absolute.</li>
+   *     <li>If the table width is relative, make all the widths absolute
+   *         relative to the nominal table width then turn them all
+   *         back into relative widths.</li>
+   *   </ol>
+   * </li>
+   * </ol>
+   *
+   * @param context The stylesheet context; supplied automatically by Saxon
+   * @param rtf The result tree fragment containing the colgroup.
+   *
+   * @return The result tree fragment containing the adjusted colgroup.
+   *
+   */
+  public static FragmentValue adjustColumnWidths (Context context,
+                                                 FragmentValue rtf) {
+    setupColumnWidths(context);
+
+    try {
+      NamePool namePool = context.getController().getNamePool();
+
+      ColumnScanEmitter csEmitter = new ColumnScanEmitter(namePool);
+      rtf.replay(csEmitter);
+
+      int numColumns = csEmitter.columnCount();
+      String widths[] = csEmitter.columnWidths();
+
+      float relTotal = 0;
+      float relParts[] = new float[numColumns];
+
+      float absTotal = 0;
+      float absParts[] = new float[numColumns];
+
+      for (int count = 0; count < numColumns; count++) {
+       String width = widths[count];
+
+       int pos = width.indexOf("*");
+       if (pos >= 0) {
+         String relPart = width.substring(0, pos);
+         String absPart = width.substring(pos+1);
+
+         try {
+           float rel = Float.parseFloat(relPart);
+           relTotal += rel;
+           relParts[count] = rel;
+         } catch (NumberFormatException e) {
+           System.out.println(relPart + " is not a valid relative unit.");
+         }
+
+         int pixels = 0;
+         if (absPart != null && !absPart.equals("")) {
+           pixels = convertLength(absPart);
+         }
+
+         absTotal += pixels;
+         absParts[count] = pixels;
+       } else {
+         relParts[count] = 0;
+
+         int pixels = 0;
+         if (width != null && !width.equals("")) {
+           pixels = convertLength(width);
+         }
+
+         absTotal += pixels;
+         absParts[count] = pixels;
+       }
+      }
+
+      // Ok, now we have the relative widths and absolute widths in
+      // two parallel arrays.
+      //
+      // - If there are no relative widths, output the absolute widths
+      // - If there are no absolute widths, output the relative widths
+      // - If there are a mixture of relative and absolute widths,
+      //   - If the table width is absolute, turn these all into absolute
+      //     widths.
+      //   - If the table width is relative, turn these all into absolute
+      //     widths in the nominalWidth and then turn them back into
+      //     percentages.
+
+      if (relTotal == 0) {
+       for (int count = 0; count < numColumns; count++) {
+         Float f = new Float(absParts[count]);
+         if (foStylesheet) {
+           int pixels = f.intValue();
+           float inches = (float) pixels / pixelsPerInch;
+           widths[count] = inches + "in";
+         } else {
+           widths[count] = Integer.toString(f.intValue());
+         }
+       }
+      } else if (absTotal == 0) {
+       for (int count = 0; count < numColumns; count++) {
+         float rel = relParts[count] / relTotal * 100;
+         Float f = new Float(rel);
+         widths[count] = Integer.toString(f.intValue()) + "%";
+       }
+      } else {
+       int pixelWidth = nominalWidth;
+
+       if (tableWidth.indexOf("%") <= 0) {
+         pixelWidth = convertLength(tableWidth);
+       }
+
+       if (pixelWidth <= absTotal) {
+         System.out.println("Table is wider than table width.");
+       } else {
+         pixelWidth -= absTotal;
+       }
+
+       absTotal = 0;
+       for (int count = 0; count < numColumns; count++) {
+         float rel = relParts[count] / relTotal * pixelWidth;
+         relParts[count] = rel + absParts[count];
+         absTotal += rel + absParts[count];
+       }
+
+       if (tableWidth.indexOf("%") <= 0) {
+         for (int count = 0; count < numColumns; count++) {
+           Float f = new Float(relParts[count]);
+           if (foStylesheet) {
+             int pixels = f.intValue();
+             float inches = (float) pixels / pixelsPerInch;
+             widths[count] = inches + "in";
+           } else {
+             widths[count] = Integer.toString(f.intValue());
+           }
+         }
+       } else {
+         for (int count = 0; count < numColumns; count++) {
+           float rel = relParts[count] / absTotal * 100;
+           Float f = new Float(rel);
+           widths[count] = Integer.toString(f.intValue()) + "%";
+         }
+       }
+      }
+
+      ColumnUpdateEmitter cuEmitter = new ColumnUpdateEmitter(namePool,
+                                                             widths);
+      rtf.replay(cuEmitter);
+      return cuEmitter.getResultTreeFragment();
+    } catch (TransformerException e) {
+      // This "can't" happen.
+      System.out.println("Transformer Exception in adjustColumnWidths");
+      return rtf;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/Text.java b/xsl/extensions/saxon61/com/nwalsh/saxon/Text.java
new file mode 100644 (file)
index 0000000..f5a95d7
--- /dev/null
@@ -0,0 +1,132 @@
+// Text - Saxon extension element for inserting text
+
+package com.nwalsh.saxon;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.net.MalformedURLException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerConfigurationException;
+import com.icl.saxon.*;
+import com.icl.saxon.style.*;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.output.*;
+import org.xml.sax.AttributeList;
+
+/**
+ * <p>Saxon extension element for inserting text
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension element for inserting text into a result tree.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Text extends StyleElement {
+  /**
+   * <p>Constructor for Text</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public Text() {
+  }
+
+  /**
+   * <p>Is this element an instruction?</p>
+   *
+   * <p>Yes, it is.</p>
+   *
+   * @return true
+   */
+  public boolean isInstruction() {
+    return true;
+  }
+
+    /**
+    * <p>Can this element contain a template-body?</p>
+    *
+    * <p>Yes, it can, but only so that it can contain xsl:fallback.</p>
+    *
+    * @return true
+    */
+  public boolean mayContainTemplateBody() {
+    return true;
+  }
+
+  /**
+   * <p>Validate the arguments</p>
+   *
+   * <p>The element must have an href attribute.</p>
+   */
+  public void prepareAttributes() throws TransformerConfigurationException {
+    // Get mandatory href attribute
+    String fnAtt = getAttribute("href");
+    if (fnAtt == null) {
+      reportAbsence("href");
+    }
+  }
+
+  /** Validate that the element occurs in a reasonable place. */
+  public void validate() throws TransformerConfigurationException {
+    checkWithinTemplate();
+  }
+
+  /**
+   * <p>Insert the text of the file into the result tree</p>
+   *
+   * <p>Processing this element inserts the contents of the URL named
+   * by the href attribute into the result tree as plain text.</p>
+   *
+   */
+  public void process( Context context ) throws TransformerException {
+    Outputter out = context.getOutputter();
+
+    String hrefAtt = getAttribute("href");
+    Expression hrefExpr = makeAttributeValueTemplate(hrefAtt);
+    String href = hrefExpr.evaluateAsString(context);
+    URL fileURL = null;
+
+    try {
+      try {
+       fileURL = new URL(href);
+      } catch (MalformedURLException e1) {
+       try {
+         fileURL = new URL("file:" + href);
+       } catch (MalformedURLException e2) {
+         System.out.println("Cannot open " + href);
+         return;
+       }
+      }
+
+      InputStreamReader isr = new InputStreamReader(fileURL.openStream());
+      BufferedReader is = new BufferedReader(isr);
+
+      char chars[] = new char[4096];
+      int len = 0;
+      while ((len = is.read(chars)) > 0) {
+       out.writeContent(chars, 0, len);
+      }
+      is.close();
+    } catch (Exception e) {
+      System.out.println("Cannot read " + href);
+    }
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/TextFactory.java b/xsl/extensions/saxon61/com/nwalsh/saxon/TextFactory.java
new file mode 100644 (file)
index 0000000..ccf5001
--- /dev/null
@@ -0,0 +1,67 @@
+// TextFactory - Saxon extension element factory
+
+package com.nwalsh.saxon;
+
+import com.icl.saxon.style.ExtensionElementFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>Saxon extension element factory
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension element factory for the Text extension element
+ * family.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ * @see Text
+ *
+ */
+public class TextFactory implements ExtensionElementFactory {
+  /**
+   * <p>Constructor for TextFactory</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public TextFactory() {
+  }
+
+  /**
+   * <p>Return the class that implements a particular extension element.</p>
+   *
+   * @param localname The local name of the extension element.
+   *
+   * @return The class that handles that extension element.
+   *
+   * @exception SAXException("Unknown Text extension element")
+   */
+  public Class getExtensionClass(String localname) {
+    if (localname.equals("insertfile")) {
+      try {
+       return Class.forName("com.nwalsh.saxon.Text");
+      } catch (ClassNotFoundException e) {
+       return null;
+      }
+    }
+    return null;
+  }
+}
+
+
+
+
+
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/Verbatim.java b/xsl/extensions/saxon61/com/nwalsh/saxon/Verbatim.java
new file mode 100644 (file)
index 0000000..5823d88
--- /dev/null
@@ -0,0 +1,458 @@
+// Verbatim.java - Saxon extensions supporting DocBook verbatim environments
+
+package com.nwalsh.saxon;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import javax.xml.transform.TransformerException;
+import com.icl.saxon.expr.*;
+import com.icl.saxon.om.*;
+import com.icl.saxon.pattern.*;
+import com.icl.saxon.Context;
+import com.icl.saxon.tree.*;
+import com.icl.saxon.functions.Extensions;
+import com.nwalsh.saxon.NumberLinesEmitter;
+import com.nwalsh.saxon.CalloutEmitter;
+
+/**
+ * <p>Saxon extensions supporting DocBook verbatim environments</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * implementation of two features that would be impractical to
+ * implement directly in XSLT: line numbering and callouts.</p>
+ *
+ * <p><b>Line Numbering</b></p>
+ * <p>The <tt>numberLines</tt> method takes a result tree
+ * fragment (assumed to contain the contents of a formatted verbatim
+ * element in DocBook: programlisting, screen, address, literallayout,
+ * or synopsis) and returns a result tree fragment decorated with
+ * line numbers.</p>
+ *
+ * <p><b>Callouts</b></p>
+ * <p>The <tt>insertCallouts</tt> method takes an
+ * <tt>areaspec</tt> and a result tree fragment
+ * (assumed to contain the contents of a formatted verbatim
+ * element in DocBook: programlisting, screen, address, literallayout,
+ * or synopsis) and returns a result tree fragment decorated with
+ * callouts.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Verbatim {
+  /** True if the stylesheet is producing formatting objects */
+  private static boolean foStylesheet = false;
+  /** The modulus for line numbering (every 'modulus' line is numbered). */
+  private static int modulus = 0;
+  /** The width (in characters) of line numbers (for padding). */
+  private static int width = 0;
+  /** The separator between the line number and the verbatim text. */
+  private static String separator = "";
+
+  /** True if callouts have been setup */
+  private static boolean calloutsSetup = false;
+  /** The default column for callouts that have only a line or line range */
+  private static int defaultColumn = 60;
+  /** The path to use for graphical callout decorations. */
+  private static String graphicsPath = null;
+  /** The extension to use for graphical callout decorations. */
+  private static String graphicsExt = null;
+  /** The largest callout number that can be represented graphically. */
+  private static int graphicsMax = 10;
+
+  /** The FormatCallout object to use for formatting callouts. */
+  private static FormatCallout fCallout = null;
+
+  /**
+   * <p>Constructor for Verbatim</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public Verbatim() {
+  }
+
+  /**
+   * <p>Find the string value of a stylesheet variable or parameter</p>
+   *
+   * <p>Returns the string value of <code>varName</code> in the current
+   * <code>context</code>. Returns the empty string if the variable is
+   * not defined.</p>
+   *
+   * @param context The current stylesheet context
+   * @param varName The name of the variable (without the dollar sign)
+   *
+   * @return The string value of the variable
+   */
+  protected static String getVariable(Context context, String varName) {
+    Value variable = null;
+    String varString = null;
+
+    try {
+      variable = Extensions.evaluate(context, "$" + varName);
+      varString = variable.asString();
+      return varString;
+    } catch (TransformerException te) {
+      System.out.println("Undefined variable: " + varName);
+      return "";
+    } catch (IllegalArgumentException iae) {
+      System.out.println("Undefined variable: " + varName);
+      return "";
+    }
+  }
+
+  /**
+   * <p>Setup the parameters associated with line numbering</p>
+   *
+   * <p>This method queries the stylesheet for the variables
+   * associated with line numbering. It is called automatically before
+   * lines are numbered. The context is used to retrieve the values,
+   * this allows templates to redefine these variables.</p>
+   *
+   * <p>The following variables are queried. If the variables do not
+   * exist, builtin defaults will be used (but you may also get a bunch
+   * of messages from the Java interpreter).</p>
+   *
+   * <dl>
+   * <dt><code>linenumbering.everyNth</code></dt>
+   * <dd>Specifies the lines that will be numbered. The first line is
+   * always numbered. (builtin default: 5).</dd>
+   * <dt><code>linenumbering.width</code></dt>
+   * <dd>Specifies the width of the numbers. If the specified width is too
+   * narrow for the largest number needed, it will automatically be made
+   * wider. (builtin default: 3).</dd>
+   * <dt><code>linenumbering.separator</code></dt>
+   * <dd>Specifies the string that separates line numbers from lines
+   * in the program listing. (builtin default: " ").</dd>
+   * <dt><code>stylesheet.result.type</code></dt>
+   * <dd>Specifies the stylesheet result type. The value is either 'fo'
+   * (for XSL Formatting Objects) or it isn't. (builtin default: html).</dd>
+   * </dl>
+   *
+   * @param context The current stylesheet context
+   *
+   */
+  private static void setupLineNumbering(Context context) {
+    // Hardcoded defaults
+    modulus = 5;
+    width = 3;
+    separator = " ";
+    foStylesheet = false;
+
+    String varString = null;
+
+    // Get the modulus
+    varString = getVariable(context, "linenumbering.everyNth");
+    try {
+      modulus = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$linenumbering.everyNth is not a number: " + varString);
+    }
+
+    // Get the width
+    varString = getVariable(context, "linenumbering.width");
+    try {
+      width = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$linenumbering.width is not a number: " + varString);
+    }
+
+    // Get the separator
+    varString = getVariable(context, "linenumbering.separator");
+    separator = varString;
+
+    // Get the stylesheet type
+    varString = getVariable(context, "stylesheet.result.type");
+    foStylesheet = (varString.equals("fo"));
+  }
+
+  /**
+   * <p>Number lines in a verbatim environment</p>
+   *
+   * <p>The extension function expects the following variables to be
+   * available in the calling context: $linenumbering.everyNth,
+   * $linenumbering.width, $linenumbering.separator, and
+   * $stylesheet.result.type.</p>
+   *
+   * <p>This method adds line numbers to a result tree fragment. Each
+   * newline that occurs in a text node is assumed to start a new line.
+   * The first line is always numbered, every subsequent 'everyNth' line
+   * is numbered (so if everyNth=5, lines 1, 5, 10, 15, etc. will be
+   * numbered. If there are fewer than everyNth lines in the environment,
+   * every line is numbered.</p>
+   *
+   * <p>Every line number will be right justified in a string 'width'
+   * characters long. If the line number of the last line in the
+   * environment is too long to fit in the specified width, the width
+   * is automatically increased to the smallest value that can hold the
+   * number of the last line. (In other words, if you specify the value 2
+   * and attempt to enumerate the lines of an environment that is 100 lines
+   * long, the value 3 will automatically be used for every line in the
+   * environment.)</p>
+   *
+   * <p>The 'separator' string is inserted between the line
+   * number and the original program listing. Lines that aren't numbered
+   * are preceded by a 'width' blank string and the separator.</p>
+   *
+   * <p>If inline markup extends across line breaks, markup changes are
+   * required. All the open elements are closed before the line break and
+   * "reopened" afterwards. The reopened elements will have the same
+   * attributes as the originals, except that 'name' and 'id' attributes
+   * are not duplicated if the stylesheet.result.type is "html" and
+   * 'id' attributes will not be duplicated if the result type is "fo".</p>
+   *
+   * @param rtf The result tree fragment of the verbatim environment.
+   *
+   * @return The modified result tree fragment.
+   */
+  public static FragmentValue numberLines (Context context,
+                                          FragmentValue rtf) {
+
+    setupLineNumbering(context);
+
+    try {
+      LineCountEmitter lcEmitter = new LineCountEmitter();
+      rtf.replay(lcEmitter);
+      int numLines = lcEmitter.lineCount();
+
+      int listingModulus = numLines < modulus ? 1 : modulus;
+
+      double log10numLines = Math.log(numLines) / Math.log(10);
+
+      int listingWidth = width < log10numLines+1
+       ? (int) Math.floor(log10numLines + 1)
+       : width;
+
+      NamePool namePool = context.getController().getNamePool();
+      NumberLinesEmitter nlEmitter = new NumberLinesEmitter(namePool,
+                                                           listingModulus,
+                                                           listingWidth,
+                                                           separator,
+                                                           foStylesheet);
+      rtf.replay(nlEmitter);
+      return nlEmitter.getResultTreeFragment();
+    } catch (TransformerException e) {
+      // This "can't" happen.
+      System.out.println("Transformer Exception in numberLines");
+      return rtf;
+    }
+  }
+
+  /**
+   * <p>Setup the parameters associated with callouts</p>
+   *
+   * <p>This method queries the stylesheet for the variables
+   * associated with line numbering. It is called automatically before
+   * callouts are processed. The context is used to retrieve the values,
+   * this allows templates to redefine these variables.</p>
+   *
+   * <p>The following variables are queried. If the variables do not
+   * exist, builtin defaults will be used (but you may also get a bunch
+   * of messages from the Java interpreter).</p>
+   *
+   * <dl>
+   * <dt><code>callout.graphics</code></dt>
+   * <dd>Are we using callout graphics? A value of 0 or "" is false,
+   * any other value is true. If callout graphics are not used, the
+   * parameters related to graphis are not queried.</dd>
+   * <dt><code>callout.graphics.path</code></dt>
+   * <dd>Specifies the path to callout graphics.</dd>
+   * <dt><code>callout.graphics.extension</code></dt>
+   * <dd>Specifies the extension ot use for callout graphics.</dd>
+   * <dt><code>callout.graphics.number.limit</code></dt>
+   * <dd>Identifies the largest number that can be represented as a
+   * graphic. Larger callout numbers will be represented using text.</dd>
+   * <dt><code>callout.defaultcolumn</code></dt>
+   * <dd>Specifies the default column for callout bullets that do not
+   * specify a column.</dd>
+   * <dt><code>stylesheet.result.type</code></dt>
+   * <dd>Specifies the stylesheet result type. The value is either 'fo'
+   * (for XSL Formatting Objects) or it isn't. (builtin default: html).</dd>
+   * </dl>
+   *
+   * @param context The current stylesheet context
+   *
+   */
+  private static void setupCallouts(Context context) {
+    NamePool namePool = context.getController().getNamePool();
+
+    boolean useGraphics = false;
+    boolean useUnicode = false;
+
+    int unicodeStart = 49;
+    int unicodeMax = 0;
+
+    // Hardcoded defaults
+    defaultColumn = 60;
+    graphicsPath = null;
+    graphicsExt = null;
+    graphicsMax = 0;
+    foStylesheet = false;
+    calloutsSetup = true;
+
+    Value variable = null;
+    String varString = null;
+
+    // Get the stylesheet type
+    varString = getVariable(context, "stylesheet.result.type");
+    foStylesheet = (varString.equals("fo"));
+
+    // Get the default column
+    varString = getVariable(context, "callout.defaultcolumn");
+    try {
+      defaultColumn = Integer.parseInt(varString);
+    } catch (NumberFormatException nfe) {
+      System.out.println("$callout.defaultcolumn is not a number: "
+                        + varString);
+    }
+
+    // Use graphics at all?
+    varString = getVariable(context, "callout.graphics");
+    useGraphics = !(varString.equals("0") || varString.equals(""));
+
+    // Use unicode at all?
+    varString = getVariable(context, "callout.unicode");
+    useUnicode = !(varString.equals("0") || varString.equals(""));
+
+    if (useGraphics) {
+      // Get the graphics path
+      varString = getVariable(context, "callout.graphics.path");
+      graphicsPath = varString;
+
+      // Get the graphics extension
+      varString = getVariable(context, "callout.graphics.extension");
+      graphicsExt = varString;
+
+      // Get the number limit
+      varString = getVariable(context, "callout.graphics.number.limit");
+      try {
+       graphicsMax = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.graphics.number.limit is not a number: "
+                          + varString);
+       graphicsMax = 0;
+      }
+
+      fCallout = new FormatGraphicCallout(namePool,
+                                         graphicsPath,
+                                         graphicsExt,
+                                         graphicsMax,
+                                         foStylesheet);
+    } else if (useUnicode) {
+      // Get the starting character
+      varString = getVariable(context, "callout.unicode.start.character");
+      try {
+       unicodeStart = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.unicode.start.character is not a number: "
+                          + varString);
+       unicodeStart = 48;
+      }
+
+      // Get the number limit
+      varString = getVariable(context, "callout.unicode.number.limit");
+      try {
+       unicodeMax = Integer.parseInt(varString);
+      } catch (NumberFormatException nfe) {
+       System.out.println("$callout.unicode.number.limit is not a number: "
+                          + varString);
+       unicodeStart = 0;
+      }
+
+      fCallout = new FormatUnicodeCallout(namePool,
+                                         unicodeStart,
+                                         unicodeMax,
+                                         foStylesheet);
+    } else {
+      fCallout = new FormatTextCallout(namePool, foStylesheet);
+    }
+  }
+
+  /**
+   * <p>Insert text callouts into a verbatim environment.</p>
+   *
+   * <p>This method examines the <tt>areaset</tt> and <tt>area</tt> elements
+   * in the supplied <tt>areaspec</tt> and decorates the supplied
+   * result tree fragment with appropriate callout markers.</p>
+   *
+   * <p>If a <tt>label</tt> attribute is supplied on an <tt>area</tt>,
+   * its content will be used for the label, otherwise the callout
+   * number will be used, surrounded by parenthesis. Callout numbers may
+   * also be represented as graphics. Callouts are
+   * numbered in document order. All of the <tt>area</tt>s in an
+   * <tt>areaset</tt> get the same number.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the defaultColumn. Lines will be padded with blanks to reach the
+   * necessary column, but callouts that are located beyond the last
+   * line of the verbatim environment will be ignored.</p>
+   *
+   * <p>Callouts are inserted before the character at the line/column
+   * where they are to occur.</p>
+   *
+   * <p>If graphical callouts are used, and the callout number is less
+   * than or equal to the $callout.graphics.number.limit, the following image
+   * will be generated for HTML:
+   *
+   * <pre>
+   * &lt;img src="$callout.graphics.path/999$callout.graphics.ext"
+   *         alt="conumber">
+   * </pre>
+   *
+   * If the $stylesheet.result.type is 'fo', the following image will
+   * be generated:
+   *
+   * <pre>
+   * &lt;fo:external-graphic src="$callout.graphics.path/999$callout.graphics.ext"/>
+   * </pre>
+   *
+   * <p>If the callout number exceeds $callout.graphics.number.limit,
+   * the callout will be the callout number surrounded by
+   * parenthesis.</p>
+   *
+   * @param context The stylesheet context.
+   * @param areaspecNodeSet The source node set that contains the areaspec.
+   * @param rtf The result tree fragment of the verbatim environment.
+   *
+   * @return The modified result tree fragment.
+   */
+
+  public static FragmentValue insertCallouts (Context context,
+                                             NodeSetIntent areaspecNodeSet,
+                                             FragmentValue rtf) {
+
+    setupCallouts(context);
+
+    try {
+      NamePool namePool = context.getController().getNamePool();
+      CalloutEmitter cEmitter = new CalloutEmitter(namePool,
+                                                  defaultColumn,
+                                                  foStylesheet,
+                                                  fCallout);
+      cEmitter.setupCallouts(areaspecNodeSet);
+      rtf.replay(cEmitter);
+      return cEmitter.getResultTreeFragment();
+    } catch (TransformerException e) {
+      // This "can't" happen.
+      System.out.println("Transformer Exception in insertCallouts");
+      return rtf;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon61/com/nwalsh/saxon/package.html b/xsl/extensions/saxon61/com/nwalsh/saxon/package.html
new file mode 100644 (file)
index 0000000..b05a467
--- /dev/null
@@ -0,0 +1,48 @@
+<html>
+<head>
+<title>Norman Walsh's Saxon Extensions Package</title>
+</head>
+<body>
+<p>Norman Walsh's Saxon Extensions Package for Saxon 6.*</p>
+
+<p>This package implements Saxon extensions for XSLT.</p>
+
+<p><b>Copyright (C) 2000 Norman Walsh</b></p>
+<p>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:</p>
+
+<p>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.</p>
+
+<p>Except as contained in this notice, the names of individuals
+credited with contribution to this software shall not be used in
+advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the
+individuals in question.</p>
+
+<p>Anything derived from this Software that is publically
+distributed will be identified with a different name and the
+version strings in any derived Software will be changed so that no
+possibility of confusion between the derived package and this
+Software will exist.</p>
+</blockquote>
+
+<blockquote>
+<p><b>Warranty</b></p>
+<p>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 NORMAN WALSH OR ANY OTHER
+CONTRIBUTOR 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.</p>
+</blockquote>
+
+</body>
+</html>
diff --git a/xsl/extensions/xalan2/.cvsignore b/xsl/extensions/xalan2/.cvsignore
new file mode 100644 (file)
index 0000000..4d3c216
--- /dev/null
@@ -0,0 +1 @@
+.classes
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/CVS.java b/xsl/extensions/xalan2/com/nwalsh/xalan/CVS.java
new file mode 100644 (file)
index 0000000..acf1d05
--- /dev/null
@@ -0,0 +1,90 @@
+package com.nwalsh.xalan;
+
+import java.io.*;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.text.DateFormat;
+import java.text.ParseException;
+
+/**
+ * <p>Saxon extension to convert CVS date strings into local time</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension to turn the CVS date strings, which are UTC:</p>
+ *
+ * <pre>&#36;Date: 2000/11/09 02:34:20 &#36;</pre>
+ *
+ * <p>into legibly formatted local time:</p>
+ *
+ * <pre>Wed Nov 08 18:34:20 PST 2000</pre>
+ *
+ * <p>(I happened to be in California when I wrote this documentation.)</p>
+
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class CVS {
+  /**
+   * <p>Constructor for CVS</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public CVS() {
+  }
+
+  /**
+   * <p>Convert a CVS date string into local time.</p>
+   *
+   * @param cvsDate The CVS date string.
+   *
+   * @return The date, converted to local time and reformatted.
+   */
+  public String localTime (String cvsDate) {
+    // A cvsDate has the following form "$Date$"
+    if (!cvsDate.startsWith("$Date: ")) {
+      return cvsDate;
+    }
+
+    String yrS = cvsDate.substring(7,11);
+    String moS = cvsDate.substring(12,14);
+    String daS = cvsDate.substring(15,17);
+    String hrS = cvsDate.substring(18,20);
+    String miS = cvsDate.substring(21,23);
+    String seS = cvsDate.substring(24,26);
+
+    TimeZone tz = TimeZone.getTimeZone("GMT+0");
+    GregorianCalendar gmtCal = new GregorianCalendar(tz);
+
+    try {
+      gmtCal.set(Integer.parseInt(yrS),
+                Integer.parseInt(moS)-1,
+                Integer.parseInt(daS),
+                Integer.parseInt(hrS),
+                Integer.parseInt(miS),
+                Integer.parseInt(seS));
+    } catch (NumberFormatException e) {
+      // nop
+    }
+
+    Date d = gmtCal.getTime();
+
+    return d.toString();
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/Callout.java b/xsl/extensions/xalan2/com/nwalsh/xalan/Callout.java
new file mode 100644 (file)
index 0000000..920cfc3
--- /dev/null
@@ -0,0 +1,143 @@
+package com.nwalsh.xalan;
+
+import org.w3c.dom.*;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class is just for book keeping in the Verbatim class.
+ * It stores information about the location of callouts.</p>
+ *
+ * <p>Only line/column based callouts are supported. This class
+ * implements the Comparable interface so that callouts can be sorted.
+ * Callouts are sorted so that they occur in left-to-right,
+ * top-to-bottom order based on line/column.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ * */
+public class Callout implements Comparable {
+  /** The callout number. */
+  private int callout = 0;
+  /** The area Element item that generated this callout. */
+  private Element area = null;
+  /** The line on which this callout occurs. */
+  private int line = 0;
+  /** The column in which this callout appears. */
+  private int col = 0;
+  /** The type of callout. */
+  private int type = 0;
+  /** The other type of callout. */
+  private String otherType = null;
+
+  public static final int CALS_PAIR = 1;
+  public static final int LINE_COLUMN = 2;
+  public static final int LINE_COLUMN_PAIR = 3;
+  public static final int LINE_RANGE = 4;
+  public static final int OTHER = 5;
+
+  /** The constructor; initialize the private data structures. */
+  public Callout(int callout, Element area, int line, int col, int type) {
+    this.callout = callout;
+    this.area = area;
+    this.line = line;
+    this.col = col;
+    this.type = type;
+    this.otherType = null;
+  }
+
+  /** The constructor; initialize the private data structures. */
+  public Callout(int callout, Element area, int line, int col, String otherType) {
+    this.callout = callout;
+    this.area = area;
+    this.line = line;
+    this.col = col;
+    this.type = Callout.OTHER;
+    this.otherType = otherType;
+  }
+
+  /**
+   * <p>The compareTo method compares this Callout with another.</p>
+   *
+   * <p>Given two Callouts, A and B, A < B if:</p>
+   *
+   * <ol>
+   * <li>A.line < B.line, or</li>
+   * <li>A.line = B.line && A.col < B.col, or</li>
+   * <li>A.line = B.line && A.col = B.col && A.callout < B.callout</li>
+   * <li>Otherwise, they're equal.</li>
+   * </ol>
+   */
+  public int compareTo (Object o) {
+    Callout c = (Callout) o;
+
+    if (line == c.getLine()) {
+      if (col > c.getColumn()) {
+       return 1;
+      } else if (col < c.getColumn()) {
+       return -1;
+      } else {
+       if (callout < c.getCallout()) {
+         return -1;
+       } else if (callout > c.getCallout()) {
+         return 1;
+       } else {
+         return 0;
+       }
+      }
+    } else {
+      if (line > c.getLine()) {
+       return 1;
+      } else {
+       return -1;
+      }
+    }
+  }
+
+  /** Access the Callout's area. */
+  public Element getArea() {
+    return area;
+  }
+
+  /** Access the Callout's line. */
+  public int getLine() {
+    return line;
+  }
+
+  /** Access the Callout's column. */
+  public int getColumn() {
+    return col;
+  }
+
+  /** Access the Callout's callout number. */
+  public int getCallout() {
+    return callout;
+  }
+
+  /** Access the Callout's type. */
+  public int getType() {
+    return type;
+  }
+
+  /** Access the Callout's otherType. */
+  public String getOtherType() {
+    return otherType;
+  }
+
+
+}
+
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/FormatCallout.java b/xsl/extensions/xalan2/com/nwalsh/xalan/FormatCallout.java
new file mode 100644 (file)
index 0000000..99363b5
--- /dev/null
@@ -0,0 +1,106 @@
+package com.nwalsh.xalan;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+import org.w3c.dom.*;
+import org.apache.xml.utils.DOMBuilder;
+import org.apache.xml.utils.AttList;
+import com.nwalsh.xalan.Callout;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public abstract class FormatCallout {
+  protected static final String foURI = "http://www.w3.org/1999/XSL/Format";
+  protected static final String xhURI = "http://www.w3.org/1999/xhtml";
+  protected boolean stylesheetFO = false;
+
+  public FormatCallout() {
+    //nop;
+  }
+
+  public String areaLabel(Element area) {
+    NamedNodeMap domAttr = area.getAttributes();
+    AttList attr = new AttList(domAttr);
+    String label = null;
+
+    if (attr.getValue("label") != null) {
+      // If this area has a label, use it
+      label = attr.getValue("label");
+    } else {
+      // Otherwise, if its parent is an areaset and it has a label, use that
+      Element parent = (Element) area.getParentNode();
+      NamedNodeMap pdomAttr = parent.getAttributes();
+      AttList pAttr = new AttList(pdomAttr);
+      if (parent != null
+         && parent.getNodeName().equals("areaset")
+         && pAttr.getValue("label") != null) {
+       label = pAttr.getValue("label");
+      }
+    }
+
+    return label;
+  }
+
+  public void startSpan(DOMBuilder rtf)
+    throws SAXException {
+    // no point in doing this for FO, right?
+    if (!stylesheetFO) {
+      AttributesImpl spanAttr = new AttributesImpl();
+      spanAttr.addAttribute("", "class", "class", "CDATA", "co");
+      rtf.startElement("", "span", "span", spanAttr);
+    }
+  }
+
+  public void endSpan(DOMBuilder rtf) 
+    throws SAXException {
+    // no point in doing this for FO, right?
+    if (!stylesheetFO) {
+      rtf.endElement("", "span", "span");
+    }
+  }
+
+  public void formatTextCallout(DOMBuilder rtf,
+                               Callout callout) {
+    Element area = callout.getArea();
+    int num = callout.getCallout();
+    String userLabel = areaLabel(area);
+    String label = "(" + num + ")";
+
+    if (userLabel != null) {
+      label = userLabel;
+    }
+
+    char chars[] = label.toCharArray();
+
+    try {
+      startSpan(rtf);
+      rtf.characters(chars, 0, label.length());
+      endSpan(rtf);
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in text formatCallout");
+    }
+  }
+
+  public abstract void formatCallout(DOMBuilder rtf,
+                                    Callout callout);
+}
+
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/FormatGraphicCallout.java b/xsl/extensions/xalan2/com/nwalsh/xalan/FormatGraphicCallout.java
new file mode 100644 (file)
index 0000000..a4f83bd
--- /dev/null
@@ -0,0 +1,83 @@
+package com.nwalsh.xalan;
+
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+import org.apache.xml.utils.DOMBuilder;
+import com.nwalsh.xalan.Callout;
+import org.apache.xml.utils.AttList;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatGraphicCallout extends FormatCallout {
+  String graphicsPath = "";
+  String graphicsExt = "";
+  int graphicsMax = 0;
+
+  public FormatGraphicCallout(String path, String ext, int max, boolean fo) {
+    graphicsPath = path;
+    graphicsExt = ext;
+    graphicsMax = max;
+    stylesheetFO = fo;
+  }
+
+  public void formatCallout(DOMBuilder rtf,
+                           Callout callout) {
+    Element area = callout.getArea();
+    int num = callout.getCallout();
+    String label = areaLabel(area);
+
+    try {
+      if (label == null && num <= graphicsMax) {
+       AttributesImpl imgAttr = new AttributesImpl();
+       String ns = "";
+       String prefix = "";
+       String imgName = "";
+
+       if (stylesheetFO) {
+         ns = foURI;
+         prefix = "fo:"; // FIXME: this could be a problem...
+         imgName = "external-graphic";
+         imgAttr.addAttribute("", "src", "src", "CDATA",
+                              graphicsPath + num + graphicsExt);
+         imgAttr.addAttribute("", "alt", "alt", "CDATA", label);
+       } else {
+         ns = "";
+         prefix = "";
+         imgName = "img";
+         imgAttr.addAttribute("", "src", "src", "CDATA",
+                              graphicsPath + num + graphicsExt);
+         imgAttr.addAttribute("", "alt", "alt", "CDATA", label);
+       }
+
+       startSpan(rtf);
+       rtf.startElement(ns, imgName, prefix+imgName, imgAttr);
+       rtf.endElement(ns, imgName, prefix+imgName);
+       endSpan(rtf);
+      } else {
+       formatTextCallout(rtf, callout);
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in graphics formatCallout");
+    }
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/FormatTextCallout.java b/xsl/extensions/xalan2/com/nwalsh/xalan/FormatTextCallout.java
new file mode 100644 (file)
index 0000000..8cdbef5
--- /dev/null
@@ -0,0 +1,38 @@
+package com.nwalsh.xalan;
+
+import org.w3c.dom.*;
+import org.apache.xml.utils.DOMBuilder;
+import com.nwalsh.xalan.Callout;
+import org.apache.xml.utils.AttList;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatTextCallout extends FormatCallout {
+  public FormatTextCallout(boolean fo) {
+    stylesheetFO = fo;
+  }
+
+  public void formatCallout(DOMBuilder rtf,
+                           Callout callout) {
+    formatTextCallout(rtf, callout);
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/FormatUnicodeCallout.java b/xsl/extensions/xalan2/com/nwalsh/xalan/FormatUnicodeCallout.java
new file mode 100644 (file)
index 0000000..ef8f352
--- /dev/null
@@ -0,0 +1,61 @@
+package com.nwalsh.xalan;
+
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+import org.apache.xml.utils.DOMBuilder;
+import com.nwalsh.xalan.Callout;
+import org.apache.xml.utils.AttList;
+
+/**
+ * <p>Utility class for the Verbatim extension (ignore this).</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000, 2001 Norman Walsh.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @see Verbatim
+ *
+ * @version $Id$
+ **/
+
+public class FormatUnicodeCallout extends FormatCallout {
+  int unicodeMax = 0;
+  int unicodeStart = 0;
+
+  public FormatUnicodeCallout(int start, int max, boolean fo) {
+    unicodeMax = max;
+    unicodeStart = start;
+    stylesheetFO = fo;
+  }
+
+  public void formatCallout(DOMBuilder rtf,
+                           Callout callout) {
+    Element area = callout.getArea();
+    int num = callout.getCallout();
+    String label = areaLabel(area);
+
+    try {
+      if (label == null && num <= unicodeMax) {
+       char chars[] = new char[1];
+       chars[0] = (char) (unicodeStart + num - 1);
+
+       startSpan(rtf);
+       rtf.characters(chars, 0, 1);
+       endSpan(rtf);
+      } else {
+       formatTextCallout(rtf, callout);
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in unicode formatCallout");
+    }
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/Func.java b/xsl/extensions/xalan2/com/nwalsh/xalan/Func.java
new file mode 100644 (file)
index 0000000..e03ae6b
--- /dev/null
@@ -0,0 +1,59 @@
+// Func - Xalann extension function test
+
+package com.nwalsh.xalan;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.AttributeList;
+import org.xml.sax.ContentHandler;
+
+import org.w3c.dom.*;
+import org.w3c.dom.traversal.NodeIterator;
+import org.apache.xerces.dom.*;
+
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XRTreeFrag;
+import org.apache.xpath.XPath;
+import org.apache.xpath.NodeSet;
+import org.apache.xalan.extensions.XSLProcessorContext;
+import org.apache.xalan.extensions.ExpressionContext;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xalan.templates.ElemExtensionCall;
+import org.apache.xalan.templates.OutputProperties;
+import org.apache.xalan.res.XSLTErrorResources;
+
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.TransformerException;
+
+public class Func {
+  public Func() {
+  }
+
+  public DocumentFragment doSomething(NodeIterator rtf) {
+    System.out.println("Got here 2: " + rtf);
+
+    DocumentFragment df = (DocumentFragment) rtf.nextNode();
+    Element node = (Element) df.getFirstChild();
+
+    System.out.println("node=" + node);
+    System.out.println("namesp uri: " + node.getNamespaceURI());
+    System.out.println("local name: " + node.getLocalName());
+
+    return df;
+  }
+
+  public DocumentFragment doSomething(DocumentFragment rtf) {
+    System.out.println("Got here: " + rtf);
+
+    return rtf;
+    /*
+    Element node = (Element) rtf.getFirstChild();
+
+    System.out.println("node=" + node);
+    System.out.println("namesp uri: " + node.getNamespaceURI());
+    System.out.println("local name: " + node.getLocalName());
+
+    return rtf;
+    */
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/Params.java b/xsl/extensions/xalan2/com/nwalsh/xalan/Params.java
new file mode 100644 (file)
index 0000000..6e52427
--- /dev/null
@@ -0,0 +1,58 @@
+// Params.java - Read stylesheet parameters in Xalan
+
+package com.nwalsh.xalan;
+
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.XPathContext;
+import org.apache.xalan.extensions.ExpressionContext;
+import org.apache.xml.utils.QName;
+
+import javax.xml.transform.TransformerException;
+
+public class Params {
+
+  public static String getString(ExpressionContext context,
+                                String varName) {
+    try {
+      XPathContext xpc = (XPathContext) context;
+      XObject var = xpc.getVariable(new QName(varName));
+      if (var != null) {
+       return var.toString();
+      } else {
+       System.out.println("$" + varName + " is not a defined parameter.");
+       return "";
+      }
+    } catch (TransformerException te) {
+      System.out.println("Transformer exception getting value of $" + varName);
+      return "";
+    }
+  }
+
+  public static int getInt(ExpressionContext context,
+                          String varName) {
+    String stringValue = getString(context, varName);
+    if (stringValue != null) {
+      try {
+       int value = Integer.parseInt(stringValue);
+       return value;
+      } catch (NumberFormatException e) {
+       System.out.println("$" + varName + " is not an integer.");
+      }
+    }
+    return 0;
+  }
+
+  public static boolean getBoolean(ExpressionContext context,
+                                  String varName) {
+    String stringValue = getString(context, varName);
+    if (stringValue != null) {
+      if (stringValue.equals("0") || stringValue.equals("")) {
+       return false;
+      } else {
+       return true;
+      }
+    } else {
+      return false;
+    }
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/Table.java b/xsl/extensions/xalan2/com/nwalsh/xalan/Table.java
new file mode 100644 (file)
index 0000000..02b3231
--- /dev/null
@@ -0,0 +1,532 @@
+// Verbatim.java - Xalan extensions supporting DocBook verbatim environments
+
+package com.nwalsh.xalan;
+
+import java.util.Hashtable;
+import org.xml.sax.*;
+import org.xml.sax.helpers.AttributesImpl;
+import org.w3c.dom.*;
+import org.w3c.dom.traversal.NodeIterator;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.XPathContext;
+import org.apache.xalan.extensions.ExpressionContext;
+import org.apache.xml.utils.DOMBuilder;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.AttList;
+
+/**
+ * <p>Xalan extensions supporting Tables</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://xml.apache.org/xalan/">Xalan</a>
+ * implementation of some code to adjust CALS Tables to HTML
+ * Tables.</p>
+ *
+ * <p><b>Column Widths</b></p>
+ * <p>The <tt>adjustColumnWidths</tt> method takes a result tree
+ * fragment (assumed to contain the colgroup of an HTML Table)
+ * and returns the result tree fragment with the column widths
+ * adjusted to HTML terms.</p>
+ *
+ * <p><b>Convert Lengths</b></p>
+ * <p>The <tt>convertLength</tt> method takes a length specification
+ * of the form 9999.99xx (where "xx" is a unit) and returns that length
+ * as an integral number of pixels. For convenience, percentage lengths
+ * are returned unchanged.</p>
+ * <p>The recognized units are: inches (in), centimeters (cm),
+ * millimeters (mm), picas (pc, 1pc=12pt), points (pt), and pixels (px).
+ * A number with no units is assumed to be pixels.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Table {
+  /** The number of pixels per inch */
+  private static int pixelsPerInch = 96;
+
+  /** The hash used to associate units with a length in pixels. */
+  protected static Hashtable unitHash = null;
+
+  /** The FO namespace name. */
+  protected static String foURI = "http://www.w3.org/1999/XSL/Format";
+
+  /**
+   * <p>Constructor for Verbatim</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public Table() {
+  }
+
+  /** Initialize the internal hash table with proper values. */
+  protected static void initializeHash() {
+    unitHash = new Hashtable();
+    unitHash.put("in", new Float(pixelsPerInch));
+    unitHash.put("cm", new Float(pixelsPerInch / 2.54));
+    unitHash.put("mm", new Float(pixelsPerInch / 25.4));
+    unitHash.put("pc", new Float((pixelsPerInch / 72) * 12));
+    unitHash.put("pt", new Float(pixelsPerInch / 72));
+    unitHash.put("px", new Float(1));
+  }
+
+  /** Set the pixels-per-inch value. Only positive values are legal. */
+  public static void setPixelsPerInch(int value) {
+    if (value > 0) {
+      pixelsPerInch = value;
+      initializeHash();
+    }
+  }
+
+  /** Return the current pixels-per-inch value. */
+  public int getPixelsPerInch() {
+    return pixelsPerInch;
+  }
+
+  /**
+   * <p>Convert a length specification to a number of pixels.</p>
+   *
+   * <p>The specified length should be of the form [+/-]999.99xx,
+   * where xx is a valid unit.</p>
+   */
+  public static int convertLength(String length) {
+    // The format of length should be 999.999xx
+    int sign = 1;
+    String digits = "";
+    String units = "";
+    char lench[] = length.toCharArray();
+    float flength = 0;
+    boolean done = false;
+    int pos = 0;
+    float factor = 1;
+    int pixels = 0;
+
+    if (unitHash == null) {
+      initializeHash();
+    }
+
+    if (lench[pos] == '+' || lench[pos] == '-') {
+      if (lench[pos] == '-') {
+       sign = -1;
+      }
+      pos++;
+    }
+
+    while (!done) {
+      if (pos >= lench.length) {
+       done = true;
+      } else {
+       if ((lench[pos] > '9' || lench[pos] < '0') && lench[pos] != '.') {
+         done = true;
+         units = length.substring(pos);
+       } else {
+         digits += lench[pos++];
+       }
+      }
+    }
+
+    try {
+      flength = Float.parseFloat(digits);
+    } catch (NumberFormatException e) {
+      System.out.println(digits + " is not a number; 1 used instead.");
+      flength = 1;
+    }
+
+    Float f = null;
+
+    if (!units.equals("")) {
+      f = (Float) unitHash.get(units);
+      if (f == null) {
+       System.out.println(units + " is not a known unit; 1 used instead.");
+       factor = 1;
+      } else {
+       factor = f.floatValue();
+      }
+    } else {
+      factor = 1;
+    }
+
+    f = new Float(flength * factor);
+
+    pixels = f.intValue() * sign;
+
+    return pixels;
+  }
+
+  /**
+   * <p>Find the string value of a stylesheet variable or parameter</p>
+   *
+   * <p>Returns the string value of <code>varName</code> in the current
+   * <code>context</code>. Returns the empty string if the variable is
+   * not defined.</p>
+   *
+   * @param context The current stylesheet context
+   * @param varName The name of the variable (without the dollar sign)
+   *
+   * @return The string value of the variable
+   */
+  private String getStringVariable(ExpressionContext context,
+                                  String varName) {
+    try {
+      XPathContext xpc = (XPathContext) context;
+      XObject var = xpc.getVariable(new QName(varName));
+      if (var != null) {
+       return var.toString();
+      } else {
+       System.out.println("$" + varName + " is not a defined parameter.");
+       return "";
+      }
+    } catch (TransformerException te) {
+      System.out.println("Transformer exception getting value of $" + varName);
+      return "";
+    }
+  }
+
+  private int getIntVariable(ExpressionContext context,
+                            String varName) {
+    String stringValue = getStringVariable(context, varName);
+    if (stringValue != null) {
+      try {
+       int value = Integer.parseInt(stringValue);
+       return value;
+      } catch (NumberFormatException e) {
+       System.out.println("$" + varName + " is not an integer.");
+      }
+    }
+    return 0;
+  }
+
+  private boolean getBooleanVariable(ExpressionContext context,
+                                    String varName) {
+    String stringValue = getStringVariable(context, varName);
+    if (stringValue != null) {
+      if (stringValue.equals("0") || stringValue.equals("")) {
+       return false;
+      } else {
+       return true;
+      }
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * <p>Adjust column widths in an HTML table.</p>
+   *
+   * <p>The specification of column widths in CALS (a relative width
+   * plus an optional absolute width) are incompatible with HTML column
+   * widths. This method adjusts CALS column width specifiers in an
+   * attempt to produce equivalent HTML specifiers.</p>
+   *
+   * <p>In order for this method to work, the CALS width specifications
+   * should be placed in the "width" attribute of the &lt;col>s within
+   * a &lt;colgroup>. Then the colgroup result tree fragment is passed
+   * to this method.</p>
+   *
+   * <p>This method makes use of two parameters from the XSL stylesheet
+   * that calls it: <code>nominal.table.width</code> and
+   * <code>table.width</code>. The value of <code>nominal.table.width</code>
+   * must be an absolute distance. The value of <code>table.width</code>
+   * can be either absolute or relative.</p>
+   *
+   * <p>Presented with a mixture of relative and
+   * absolute lengths, the table width is used to calculate
+   * appropriate values. If the <code>table.width</code> is relative,
+   * the nominal width is used for this calculation.</p>
+   *
+   * <p>There are three possible combinations of values:</p>
+   *
+   * <ol>
+   * <li>There are no relative widths; in this case the absolute widths
+   * are used in the HTML table.</li>
+   * <li>There are no absolute widths; in this case the relative widths
+   * are used in the HTML table.</li>
+   * <li>There are a mixture of absolute and relative widths:
+   *   <ol>
+   *     <li>If the table width is absolute, all widths become absolute.</li>
+   *     <li>If the table width is relative, make all the widths absolute
+   *         relative to the nominal table width then turn them all
+   *         back into relative widths.</li>
+   *   </ol>
+   * </li>
+   * </ol>
+   *
+   * @param context The stylesheet context; supplied automatically by Xalan
+   * @param rtf The result tree fragment containing the colgroup.
+   *
+   * @return The result tree fragment containing the adjusted colgroup.
+   *
+   */
+
+  public DocumentFragment adjustColumnWidths (ExpressionContext context,
+                                             NodeIterator xalanNI) {
+
+    int nominalWidth = convertLength(Params.getString(context,
+                                                     "nominal.table.width"));
+    String tableWidth = Params.getString(context, "table.width");
+    String styleType = Params.getString(context, "stylesheet.result.type");
+    boolean foStylesheet = styleType.equals("fo");
+
+    DocumentFragment xalanRTF = (DocumentFragment) xalanNI.nextNode();
+    Element colgroup = (Element) xalanRTF.getFirstChild();
+
+    // N.B. ...stree.ElementImpl doesn't implement getElementsByTagName()
+
+    Node firstCol = null;
+    // If this is an FO tree, there might be no colgroup...
+    if (colgroup.getLocalName().equals("colgroup")) {
+      firstCol = colgroup.getFirstChild();
+    } else {
+      firstCol = colgroup;
+    }
+
+    // Count the number of columns...
+    Node child = firstCol;
+    int numColumns = 0;
+    while (child != null) {
+      if (child.getNodeType() == Node.ELEMENT_NODE
+         && (child.getNodeName().equals("col")
+             || (child.getNamespaceURI().equals(foURI)
+                 && child.getLocalName().equals("table-column")))) {
+       numColumns++;
+      }
+
+      child = child.getNextSibling();
+    }
+
+    String widths[] = new String[numColumns];
+    Element columns[] = new Element[numColumns];
+    int colnum = 0;
+
+    child = firstCol;
+    while (child != null) {
+      if (child.getNodeType() == Node.ELEMENT_NODE
+         && (child.getNodeName().equals("col")
+             || (child.getNamespaceURI().equals(foURI)
+                 && child.getLocalName().equals("table-column")))) {
+       Element col = (Element) child;
+       NamedNodeMap domAttr = col.getAttributes();
+       AttList attr = new AttList(domAttr);
+
+       columns[colnum] = col;
+
+       if (foStylesheet) {
+         if (attr.getValue("column-width") == null) {
+           widths[colnum] = "1*";
+         } else {
+           widths[colnum] = attr.getValue("column-width");
+         }
+       } else {
+         if (attr.getValue("width") == null) {
+           widths[colnum] = "1*";
+         } else {
+           widths[colnum] = attr.getValue("width");
+         }
+       }
+
+       colnum++;
+      }
+      child = child.getNextSibling();
+    }
+
+    float relTotal = 0;
+    float relParts[] = new float[numColumns];
+
+    float absTotal = 0;
+    float absParts[] = new float[numColumns];
+
+    for (int count = 0; count < numColumns; count++) {
+      String width = widths[count];
+      int pos = width.indexOf("*");
+      if (pos >= 0) {
+       String relPart = width.substring(0, pos);
+       String absPart = width.substring(pos+1);
+
+       try {
+         float rel = Float.parseFloat(relPart);
+         relTotal += rel;
+         relParts[count] = rel;
+       } catch (NumberFormatException e) {
+         System.out.println(relPart + " is not a valid relative unit.");
+       }
+
+       int pixels = 0;
+       if (absPart != null && !absPart.equals("")) {
+         pixels = convertLength(absPart);
+       }
+
+       absTotal += pixels;
+       absParts[count] = pixels;
+      } else {
+       relParts[count] = 0;
+
+       int pixels = 0;
+       if (width != null && !width.equals("")) {
+         pixels = convertLength(width);
+       }
+
+       absTotal += pixels;
+       absParts[count] = pixels;
+      }
+    }
+
+    // Ok, now we have the relative widths and absolute widths in
+    // two parallel arrays.
+    //
+    // - If there are no relative widths, output the absolute widths
+    // - If there are no absolute widths, output the relative widths
+    // - If there are a mixture of relative and absolute widths,
+    //   - If the table width is absolute, turn these all into absolute
+    //     widths.
+    //   - If the table width is relative, turn these all into absolute
+    //     widths in the nominalWidth and then turn them back into
+    //     percentages.
+
+    if (relTotal == 0) {
+      for (int count = 0; count < numColumns; count++) {
+       Float f = new Float(absParts[count]);
+       if (foStylesheet) {
+         int pixels = f.intValue();
+         float inches = (float) pixels / pixelsPerInch;
+         widths[count] = inches + "in";
+       } else {
+         widths[count] = Integer.toString(f.intValue());
+       }
+      }
+    } else if (absTotal == 0) {
+      for (int count = 0; count < numColumns; count++) {
+       float rel = relParts[count] / relTotal * 100;
+       Float f = new Float(rel);
+       widths[count] = Integer.toString(f.intValue()) + "%";
+      }
+    } else {
+      int pixelWidth = nominalWidth;
+
+      if (tableWidth.indexOf("%") <= 0) {
+       pixelWidth = convertLength(tableWidth);
+      }
+
+      if (pixelWidth <= absTotal) {
+       System.out.println("Table is wider than table width.");
+      } else {
+       pixelWidth -= absTotal;
+      }
+
+      absTotal = 0;
+      for (int count = 0; count < numColumns; count++) {
+       float rel = relParts[count] / relTotal * pixelWidth;
+       relParts[count] = rel + absParts[count];
+       absTotal += rel + absParts[count];
+      }
+
+      if (tableWidth.indexOf("%") <= 0) {
+       for (int count = 0; count < numColumns; count++) {
+         Float f = new Float(relParts[count]);
+         if (foStylesheet) {
+           int pixels = f.intValue();
+           float inches = (float) pixels / pixelsPerInch;
+           widths[count] = inches + "in";
+         } else {
+           widths[count] = Integer.toString(f.intValue());
+         }
+       }
+      } else {
+       for (int count = 0; count < numColumns; count++) {
+         float rel = relParts[count] / absTotal * 100;
+         Float f = new Float(rel);
+         widths[count] = Integer.toString(f.intValue()) + "%";
+       }
+      }
+    }
+
+    // Now rebuild the colgroup with the right widths
+
+    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+    DocumentBuilder docBuilder = null;
+
+    try {
+      docBuilder = docFactory.newDocumentBuilder();
+    } catch (ParserConfigurationException e) {
+      System.out.println("PCE!");
+      return xalanRTF;
+    }
+    Document doc = docBuilder.newDocument();
+    DocumentFragment df = doc.createDocumentFragment();
+    DOMBuilder rtf = new DOMBuilder(doc, df);
+
+    try {
+      String ns = colgroup.getNamespaceURI();
+      String localName = colgroup.getLocalName();
+      String name = colgroup.getTagName();
+      NamedNodeMap colgroupDomAttr = colgroup.getAttributes();
+      AttList colgroupAttr = new AttList(colgroupDomAttr);
+
+      if (colgroup.getLocalName().equals("colgroup")) {
+       rtf.startElement(ns, localName, name, colgroupAttr);
+      }
+
+      for (colnum = 0; colnum < numColumns; colnum++) {
+       Element col = columns[colnum];
+
+       NamedNodeMap domAttr = col.getAttributes();
+
+       AttributesImpl attr = new AttributesImpl();
+       for (int acount = 0; acount < domAttr.getLength(); acount++) {
+         Node a = domAttr.item(acount);
+         String a_ns = a.getNamespaceURI();
+         String a_localName = a.getLocalName();
+
+         if ((foStylesheet && !a_localName.equals("column-width"))
+             || !a_localName.equalsIgnoreCase("width")) {
+           attr.addAttribute(a.getNamespaceURI(),
+                             a.getLocalName(),
+                             a.getNodeName(),
+                             "CDATA",
+                             a.getNodeValue());
+         }
+       }
+
+       if (foStylesheet) {
+         attr.addAttribute("", "column-width", "column-width", "CDATA", widths[colnum]);
+       } else {
+         attr.addAttribute("", "width", "width", "CDATA", widths[colnum]);
+       }
+
+       rtf.startElement(col.getNamespaceURI(),
+                        col.getLocalName(),
+                        col.getTagName(),
+                        attr);
+       rtf.endElement(col.getNamespaceURI(),
+                      col.getLocalName(),
+                      col.getTagName());
+      }
+
+      if (colgroup.getLocalName().equals("colgroup")) {
+       rtf.endElement(ns, localName, name);
+      }
+    } catch (SAXException se) {
+      System.out.println("SE!");
+      return xalanRTF;
+    }
+
+    return df;
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/Text.java b/xsl/extensions/xalan2/com/nwalsh/xalan/Text.java
new file mode 100644 (file)
index 0000000..4ca3234
--- /dev/null
@@ -0,0 +1,128 @@
+// Text - Xalan extension element for inserting text
+
+package com.nwalsh.xalan;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.AttributeList;
+import org.xml.sax.ContentHandler;
+
+import org.w3c.dom.*;
+import org.apache.xerces.dom.*;
+
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.XPath;
+import org.apache.xpath.NodeSet;
+import org.apache.xalan.extensions.XSLProcessorContext;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xalan.templates.ElemExtensionCall;
+import org.apache.xalan.templates.OutputProperties;
+import org.apache.xalan.res.XSLTErrorResources;
+
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.TransformerException;
+
+/**
+ * <p>Xalan extension element for inserting text
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2001 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://xml.apache.org/xalan/">Xalan</a>
+ * extension element for inserting text into a result tree.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Text {
+  /**
+   * <p>Constructor for Text</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public Text() {
+  }
+
+  public NodeList insertfile(XSLProcessorContext context,
+                            ElemExtensionCall elem)
+    throws MalformedURLException,
+           FileNotFoundException,
+           IOException,
+          TransformerException {
+    String href = getFilename(context, elem);
+
+    NodeSet textNodes = new NodeSet();
+    Document textDoc = DOMImplementationImpl.getDOMImplementation().createDocument(null, "tmpDoc", null);
+
+    URL fileURL = null;
+
+    try {
+      try {
+       fileURL = new URL(href);
+      } catch (MalformedURLException e1) {
+       try {
+         fileURL = new URL("file:" + href);
+       } catch (MalformedURLException e2) {
+         System.out.println("Cannot open " + href);
+         return null;
+       }
+      }
+
+      InputStreamReader isr = new InputStreamReader(fileURL.openStream());
+      BufferedReader is = new BufferedReader(isr);
+
+      char chars[] = new char[4096];
+      int len = 0;
+      while ((len = is.read(chars)) > 0) {
+       String s = new String(chars, 0, len);
+       // Does it matter that this produces multiple, adjacent text
+       // nodes? I don't think so...
+       textNodes.addNode(textDoc.createTextNode(s));
+      }
+      is.close();
+    } catch (Exception e) {
+      System.out.println("Cannot read " + href);
+    }
+
+    return textNodes;
+  }
+
+  private String getFilename(XSLProcessorContext context, ElemExtensionCall elem)
+    throws java.net.MalformedURLException,
+          java.io.FileNotFoundException,
+          java.io.IOException,
+          javax.xml.transform.TransformerException {
+
+    String fileName;
+
+    fileName = ((ElemExtensionCall)elem).getAttribute ("href",
+                                                      context.getContextNode(),
+                                                      context.getTransformer());
+
+    if(fileName == null) {
+      context.getTransformer().getMsgMgr().error(elem,
+                                                "No 'href' on text, or not a filename");
+    }
+
+    return fileName;
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/Verbatim.java b/xsl/extensions/xalan2/com/nwalsh/xalan/Verbatim.java
new file mode 100644 (file)
index 0000000..6797add
--- /dev/null
@@ -0,0 +1,900 @@
+// Verbatim.java - Xalan extensions supporting DocBook verbatim environments
+
+package com.nwalsh.xalan;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import org.xml.sax.*;
+import org.xml.sax.helpers.AttributesImpl;
+import org.w3c.dom.*;
+import org.w3c.dom.traversal.NodeIterator;
+import org.apache.xerces.dom.*;
+
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.NodeSet;
+import org.apache.xalan.extensions.XSLProcessorContext;
+import org.apache.xalan.extensions.ExpressionContext;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xalan.templates.ElemExtensionCall;
+import org.apache.xalan.templates.OutputProperties;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xml.utils.DOMBuilder;
+import org.apache.xml.utils.AttList;
+import org.apache.xml.utils.QName;
+
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.TransformerException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.nwalsh.xalan.Callout;
+import com.nwalsh.xalan.Params;
+
+/**
+ * <p>Xalan extensions supporting DocBook verbatim environments</p>
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2001 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://xml.apache.org/xalan">Xalan</a>
+ * implementation of two features that would be impractical to
+ * implement directly in XSLT: line numbering and callouts.</p>
+ *
+ * <p><b>Line Numbering</b></p>
+ * <p>The <tt>numberLines</tt> family of functions takes a result tree
+ * fragment (assumed to contain the contents of a formatted verbatim
+ * element in DocBook: programlisting, screen, address, literallayout,
+ * or synopsis) and returns a result tree fragment decorated with
+ * line numbers.</p>
+ *
+ * <p><b>Callouts</b></p>
+ * <p>The <tt>insertCallouts</tt> family of functions takes an
+ * <tt>areaspec</tt> and a result tree fragment
+ * (assumed to contain the contents of a formatted verbatim
+ * element in DocBook: programlisting, screen, address, literallayout,
+ * or synopsis) and returns a result tree fragment decorated with
+ * callouts.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Verbatim {
+  /** A stack to hold the open elements while walking through a RTF. */
+  private Stack elementStack = null;
+  /** A stack to hold the temporarily closed elements. */
+  private Stack tempStack = null;
+  /** The current line number. */
+  private int lineNumber = 0;
+  /** The current column number. */
+  private int colNumber = 0;
+  /** The modulus for line numbering (every 'modulus' line is numbered). */
+  private int modulus = 0;
+  /** The width (in characters) of line numbers (for padding). */
+  private int width = 0;
+  /** The separator between the line number and the verbatim text. */
+  private String separator = "";
+  /** The (sorted) array of callouts obtained from the areaspec. */
+  private Callout callout[] = null;
+  /** The number of callouts in the callout array. */
+  private int calloutCount = 0;
+  /** A pointer used to keep track of our position in the callout array. */
+  private int calloutPos = 0;
+  /** The path to use for graphical callout decorations. */
+  private String graphicsPath = null;
+  /** The extension to use for graphical callout decorations. */
+  private String graphicsExt = null;
+  /** The largest callout number that can be represented graphically. */
+  private int graphicsMax = 10;
+  /** Should graphic callouts use fo:external-graphics or imgs. */
+  private boolean graphicsFO = false;
+
+  private static final String foURI = "http://www.w3.org/1999/XSL/Format";
+  private static final String xhURI = "http://www.w3.org/1999/xhtml";
+
+  /**
+   * <p>Constructor for Verbatim</p>
+   *
+   * <p>All of the methods are static, so the constructor does nothing.</p>
+   */
+  public Verbatim() {
+  }
+
+  /**
+   * <p>Number lines in a verbatim environment.</p>
+   *
+   * <p>This method adds line numbers to a result tree fragment. Each
+   * newline that occurs in a text node is assumed to start a new line.
+   * The first line is always numbered, every subsequent xalanMod line
+   * is numbered (so if xalanMod=5, lines 1, 5, 10, 15, etc. will be
+   * numbered. If there are fewer than xalanMod lines in the environment,
+   * every line is numbered.</p>
+   *
+   * <p>xalanMod is taken from the $linenumbering.everyNth parameter.</p>
+   *
+   * <p>Every line number will be right justified in a string xalanWidth
+   * characters long. If the line number of the last line in the
+   * environment is too long to fit in the specified width, the width
+   * is automatically increased to the smallest value that can hold the
+   * number of the last line. (In other words, if you specify the value 2
+   * and attempt to enumerate the lines of an environment that is 100 lines
+   * long, the value 3 will automatically be used for every line in the
+   * environment.)</p>
+   *
+   * <p>xalanWidth is taken from the $linenumbering.width parameter.</p>
+   *
+   * <p>The xalanSep string is inserted between the line
+   * number and the original program listing. Lines that aren't numbered
+   * are preceded by a xalanWidth blank string and the separator.</p>
+   *
+   * <p>xalanSep is taken from the $linenumbering.separator parameter.</p>
+   *
+   * <p>If inline markup extends across line breaks, markup changes are
+   * required. All the open elements are closed before the line break and
+   * "reopened" afterwards. The reopened elements will have the same
+   * attributes as the originals, except that 'name' and 'id' attributes
+   * are not duplicated.</p>
+   *
+   * @param xalanRTF The result tree fragment of the verbatim environment.
+   *
+   * @return The modified result tree fragment.
+   */
+  public DocumentFragment numberLines (ExpressionContext context,
+                                      NodeIterator xalanNI) {
+
+    int xalanMod = Params.getInt(context, "linenumbering.everyNth");
+    int xalanWidth = Params.getInt(context, "linenumbering.width");
+    String xalanSep = Params.getString(context, "linenumbering.separator");
+
+    DocumentFragment xalanRTF = (DocumentFragment) xalanNI.nextNode();
+    int numLines = countLineBreaks(xalanRTF) + 1;
+
+    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+    DocumentBuilder docBuilder = null;
+
+    try {
+      docBuilder = docFactory.newDocumentBuilder();
+    } catch (ParserConfigurationException e) {
+      System.out.println("PCE!");
+      return xalanRTF;
+    }
+    Document doc = docBuilder.newDocument();
+    DocumentFragment df = doc.createDocumentFragment();
+    DOMBuilder db = new DOMBuilder(doc, df);
+
+    elementStack = new Stack();
+    lineNumber = 0;
+    modulus = numLines < xalanMod ? 1 : xalanMod;
+    width = xalanWidth;
+    separator = xalanSep;
+
+    double log10numLines = Math.log(numLines) / Math.log(10);
+
+    if (width < log10numLines + 1) {
+      width = (int) Math.floor(log10numLines + 1);
+    }
+
+    lineNumberFragment(db, xalanRTF);
+    return df;
+  }
+
+  /**
+   * <p>Count the number of lines in a verbatim environment.</p>
+   *
+   * <p>This method walks over the nodes of a DocumentFragment and
+   * returns the number of lines breaks that it contains.</p>
+   *
+   * @param node The root of the tree walk over.
+   */
+  private int countLineBreaks(Node node) {
+    int numLines = 0;
+
+    if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE
+       || node.getNodeType() == Node.ELEMENT_NODE) {
+      Node child = node.getFirstChild();
+      while (child != null) {
+       numLines += countLineBreaks(child);
+       child = child.getNextSibling();
+      }
+    } else if (node.getNodeType() == Node.TEXT_NODE) {
+      String text = node.getNodeValue();
+
+      // Walk through the text node looking for newlines
+      int pos = 0;
+      for (int count = 0; count < text.length(); count++) {
+       if (text.charAt(count) == '\n') {
+         numLines++;
+       }
+      }
+    } else {
+      // nop
+    }
+
+    return numLines;
+  }
+
+  /**
+   * <p>Build a DocumentFragment with numbered lines.</p>
+   *
+   * <p>This is the method that actually does the work of numbering
+   * lines in a verbatim environment. It recursively walks through a
+   * tree of nodes, copying the structure into the rtf. Text nodes
+   * are examined for new lines and modified as requested by the
+   * global line numbering parameters.</p>
+   *
+   * <p>When called, rtf should be an empty DocumentFragment and node
+   * should be the first child of the result tree fragment that contains
+   * the existing, formatted verbatim text.</p>
+   *
+   * @param rtf The resulting verbatim environment with numbered lines.
+   * @param node The root of the tree to copy.
+   */
+  private void lineNumberFragment(DOMBuilder rtf,
+                                 Node node) {
+    try {
+      if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
+       Node child = node.getFirstChild();
+       while (child != null) {
+         lineNumberFragment(rtf, child);
+         child = child.getNextSibling();
+       }
+      } else if (node.getNodeType() == Node.ELEMENT_NODE) {
+       String ns = node.getNamespaceURI();
+       String localName = node.getLocalName();
+       String name = ((Element) node).getTagName();
+       NamedNodeMap domAttr = node.getAttributes();
+       AttList attr = new AttList(domAttr);
+
+       rtf.startElement(ns, localName, name, attr);
+       elementStack.push(node);
+
+       Node child = node.getFirstChild();
+       while (child != null) {
+         lineNumberFragment(rtf, child);
+         child = child.getNextSibling();
+       }
+      } else if (node.getNodeType() == Node.TEXT_NODE) {
+       String text = node.getNodeValue();
+
+       if (lineNumber == 0) {
+         // The first line is always numbered
+         formatLineNumber(rtf, ++lineNumber);
+       }
+
+       // Walk through the text node looking for newlines
+       char chars[] = text.toCharArray();
+       int pos = 0;
+       for (int count = 0; count < text.length(); count++) {
+         if (text.charAt(count) == '\n') {
+           // This is the tricky bit; if we find a newline, make sure
+           // it doesn't occur inside any markup.
+
+           if (pos > 0) {
+             rtf.characters(chars, 0, pos);
+             pos = 0;
+           }
+
+           closeOpenElements(rtf);
+
+           // Copy the newline to the output
+           chars[pos++] = text.charAt(count);
+           rtf.characters(chars, 0, pos);
+           pos = 0;
+
+           // Add the line number
+           formatLineNumber(rtf, ++lineNumber);
+
+           openClosedElements(rtf);
+         } else {
+           chars[pos++] = text.charAt(count);
+         }
+       }
+
+       if (pos > 0) {
+         rtf.characters(chars, 0, pos);
+       }
+      } else if (node.getNodeType() == Node.COMMENT_NODE) {
+       String text = node.getNodeValue();
+       char chars[] = text.toCharArray();
+       rtf.comment(chars, 0, text.length());
+      } else if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
+       rtf.processingInstruction(node.getNodeName(), node.getNodeValue());
+      } else {
+       System.out.println("Warning: unexpected node type in lineNumberFragment");
+      }
+
+      if (node.getNodeType() == Node.ELEMENT_NODE) {
+       String ns = node.getNamespaceURI();
+       String localName = node.getLocalName();
+       String name = ((Element) node).getTagName();
+       rtf.endElement(ns, localName, name);
+       elementStack.pop();
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in lineNumberFragment");
+    }
+  }
+
+  /**
+   * <p>Add a formatted line number to the result tree fragment.</p>
+   *
+   * <p>This method examines the global parameters that control line
+   * number presentation (modulus, width, and separator) and adds
+   * the appropriate text to the result tree fragment.</p>
+   *
+   * @param rtf The resulting verbatim environment with numbered lines.
+   * @param lineNumber The number of the current line.
+   */
+  private void formatLineNumber(DOMBuilder rtf,
+                               int lineNumber) {
+    char ch = 160;
+    String lno = "";
+    if (lineNumber == 1
+       || (modulus >= 1 && (lineNumber % modulus == 0))) {
+      lno = "" + lineNumber;
+    }
+
+    while (lno.length() < width) {
+      lno = ch + lno;
+    }
+
+    lno += separator;
+
+    char chars[] = lno.toCharArray();
+    try {
+      rtf.characters(chars, 0, lno.length());
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in formatLineNumber");
+    }
+  }
+
+  /**
+   * <p>Insert text callouts into a verbatim environment.</p>
+   *
+   * <p>This method examines the <tt>areaset</tt> and <tt>area</tt> elements
+   * in the supplied <tt>areaspec</tt> and decorates the supplied
+   * result tree fragment with appropriate callout markers.</p>
+   *
+   * <p>If a <tt>label</tt> attribute is supplied on an <tt>area</tt>,
+   * its content will be used for the label, otherwise the callout
+   * number will be used, surrounded by parenthesis. Callouts are
+   * numbered in document order. All of the <tt>area</tt>s in an
+   * <tt>areaset</tt> get the same number.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the defaultColumn. Lines will be padded with blanks to reach the
+   * necessary column, but callouts that are located beyond the last
+   * line of the verbatim environment will be ignored.</p>
+   *
+   * <p>Callouts are inserted before the character at the line/column
+   * where they are to occur.</p>
+   *
+   * @param areaspecNodeSet The source node set that contains the areaspec.
+   * @param xalanRTF The result tree fragment of the verbatim environment.
+   * @param defaultColumn The column for callouts that specify only a line.
+   *
+   * @return The modified result tree fragment.  */
+
+  /**
+   * <p>Insert graphical callouts into a verbatim environment.</p>
+   *
+   * <p>This method examines the <tt>areaset</tt> and <tt>area</tt> elements
+   * in the supplied <tt>areaspec</tt> and decorates the supplied
+   * result tree fragment with appropriate callout markers.</p>
+   *
+   * <p>If a <tt>label</tt> attribute is supplied on an <tt>area</tt>,
+   * its content will be used for the label, otherwise the callout
+   * number will be used. Callouts are
+   * numbered in document order. All of the <tt>area</tt>s in an
+   * <tt>areaset</tt> get the same number.</p>
+   *
+   * <p>If the callout number is not greater than <tt>gMax</tt>, the
+   * callout generated will be:</p>
+   *
+   * <pre>
+   * &lt;img src="$gPath/conumber$gExt" alt="conumber">
+   * </pre>
+   *
+   * <p>Otherwise, it will be the callout number surrounded by
+   * parenthesis.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the defaultColumn. Lines will be padded with blanks to reach the
+   * necessary column, but callouts that are located beyond the last
+   * line of the verbatim environment will be ignored.</p>
+   *
+   * <p>Callouts are inserted before the character at the line/column
+   * where they are to occur.</p>
+   *
+   * @param areaspecNodeSet The source node set that contains the areaspec.
+   * @param xalanRTF The result tree fragment of the verbatim environment.
+   * @param defaultColumn The column for callouts that specify only a line.
+   * @param gPath The path to use for callout graphics.
+   * @param gExt The extension to use for callout graphics.
+   * @param gMax The largest number that can be represented as a graphic.
+   * @param useFO Should fo:external-graphics be produced, as opposed to
+   * HTML imgs. This is bogus, the extension should figure it out, but I
+   * haven't figured out how to do that yet.
+   *
+   * @return The modified result tree fragment.
+   */
+
+  public DocumentFragment insertCallouts (ExpressionContext context,
+                                         NodeIterator areaspecNodeSet,
+                                         NodeIterator xalanNI) {
+
+    String type = Params.getString(context, "stylesheet.result.type");
+    boolean useFO = type.equals("fo");
+    int defaultColumn = Params.getInt(context, "callout.defaultcolumn");
+
+    if (Params.getBoolean(context, "callout.graphics")) {
+      String gPath = Params.getString(context, "callout.graphics.path");
+      String gExt = Params.getString(context, "callout.graphics.extension");
+      int gMax = Params.getInt(context, "callout.graphics.number.limit");
+      return insertGraphicCallouts(areaspecNodeSet, xalanNI, defaultColumn,
+                                  gPath, gExt, gMax, useFO);
+    } else if (Params.getBoolean(context, "callout.unicode")) {
+      int uStart = Params.getInt(context, "callout.unicode.start.character");
+      int uMax = Params.getInt(context, "callout.unicode.number.limit");
+      return insertUnicodeCallouts(areaspecNodeSet, xalanNI, defaultColumn,
+                                  uStart, uMax, useFO);
+    } else {
+      return insertTextCallouts(areaspecNodeSet, xalanNI, defaultColumn, useFO);
+    }
+  }
+
+  public DocumentFragment insertGraphicCallouts (NodeIterator areaspecNodeSet,
+                                                NodeIterator xalanNI,
+                                                int defaultColumn,
+                                                String gPath,
+                                                String gExt,
+                                                int gMax,
+                                                boolean useFO) {
+    FormatGraphicCallout fgc = new FormatGraphicCallout(gPath,gExt,gMax,useFO);
+    return insertCallouts(areaspecNodeSet, xalanNI, defaultColumn, fgc);
+  }
+
+  public DocumentFragment insertUnicodeCallouts (NodeIterator areaspecNodeSet,
+                                                NodeIterator xalanNI,
+                                                int defaultColumn,
+                                                int uStart,
+                                                int uMax,
+                                                boolean useFO) {
+    FormatUnicodeCallout fuc = new FormatUnicodeCallout(uStart, uMax, useFO);
+    return insertCallouts(areaspecNodeSet, xalanNI, defaultColumn, fuc);
+  }
+
+  public DocumentFragment insertTextCallouts (NodeIterator areaspecNodeSet,
+                                             NodeIterator xalanNI,
+                                             int defaultColumn,
+                                             boolean useFO) {
+    FormatTextCallout ftc = new FormatTextCallout(useFO);
+    return insertCallouts(areaspecNodeSet, xalanNI, defaultColumn, ftc);
+  }
+
+  public DocumentFragment insertCallouts (NodeIterator areaspecNodeSet,
+                                         NodeIterator xalanNI,
+                                         int defaultColumn,
+                                         FormatCallout fCallout) {
+
+    DocumentFragment xalanRTF = (DocumentFragment) xalanNI.nextNode();
+
+    callout = new Callout[10];
+    calloutCount = 0;
+    calloutPos = 0;
+    lineNumber = 1;
+    colNumber = 1;
+
+    // First we walk through the areaspec to calculate the position
+    // of the callouts
+    //  <areaspec>
+    //  <areaset id="ex.plco.const" coords="">
+    //    <area id="ex.plco.c1" coords="4"/>
+    //    <area id="ex.plco.c2" coords="8"/>
+    //  </areaset>
+    //  <area id="ex.plco.ret" coords="12"/>
+    //  <area id="ex.plco.dest" coords="12"/>
+    //  </areaspec>
+    int pos = 0;
+    int coNum = 0;
+    boolean inAreaSet = false;
+    Node node = areaspecNodeSet.nextNode();
+    node = node.getFirstChild();
+    while (node != null) {
+      if (node.getNodeType() == Node.ELEMENT_NODE) {
+       if (node.getNodeName().equals("areaset")) {
+         coNum++;
+         Node area = node.getFirstChild();
+         while (area != null) {
+           if (area.getNodeType() == Node.ELEMENT_NODE) {
+             if (area.getNodeName().equals("area")) {
+               addCallout(coNum, area, defaultColumn);
+             } else {
+               System.out.println("Unexpected element in areaset: "
+                                  + area.getNodeName());
+             }
+           }
+           area = area.getNextSibling();
+         }
+       } else if (node.getNodeName().equalsIgnoreCase("area")) {
+         coNum++;
+         addCallout(coNum, node, defaultColumn);
+       } else {
+         System.out.println("Unexpected element in areaspec: "
+                            + node.getNodeName());
+       }
+      }
+
+      node = node.getNextSibling();
+    }
+
+    // Now sort them
+    java.util.Arrays.sort(callout, 0, calloutCount);
+
+    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+    DocumentBuilder docBuilder = null;
+
+    try {
+      docBuilder = docFactory.newDocumentBuilder();
+    } catch (ParserConfigurationException e) {
+      System.out.println("PCE 2!");
+      return xalanRTF;
+    }
+    Document doc = docBuilder.newDocument();
+    DocumentFragment df = doc.createDocumentFragment();
+    DOMBuilder db = new DOMBuilder(doc, df);
+
+    elementStack = new Stack();
+    calloutFragment(db, xalanRTF, fCallout);
+    return df;
+  }
+
+  /**
+   * <p>Build a FragmentValue with callout decorations.</p>
+   *
+   * <p>This is the method that actually does the work of adding
+   * callouts to a verbatim environment. It recursively walks through a
+   * tree of nodes, copying the structure into the rtf. Text nodes
+   * are examined for the position of callouts as described by the
+   * global callout parameters.</p>
+   *
+   * <p>When called, rtf should be an empty FragmentValue and node
+   * should be the first child of the result tree fragment that contains
+   * the existing, formatted verbatim text.</p>
+   *
+   * @param rtf The resulting verbatim environment with numbered lines.
+   * @param node The root of the tree to copy.
+   */
+  private void calloutFragment(DOMBuilder rtf,
+                              Node node,
+                              FormatCallout fCallout) {
+    try {
+      if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
+       Node child = node.getFirstChild();
+       while (child != null) {
+         calloutFragment(rtf, child, fCallout);
+         child = child.getNextSibling();
+       }
+      } else if (node.getNodeType() == Node.ELEMENT_NODE) {
+       String ns = node.getNamespaceURI();
+       String localName = node.getLocalName();
+       String name = ((Element) node).getTagName();
+       NamedNodeMap domAttr = node.getAttributes();
+       AttList attr = new AttList(domAttr);
+
+       rtf.startElement(ns, localName, name, attr);
+       elementStack.push(node);
+
+       Node child = node.getFirstChild();
+       while (child != null) {
+         calloutFragment(rtf, child, fCallout);
+         child = child.getNextSibling();
+       }
+      } else if (node.getNodeType() == Node.TEXT_NODE) {
+       String text = node.getNodeValue();
+
+       char chars[] = text.toCharArray();
+       int pos = 0;
+       for (int count = 0; count < text.length(); count++) {
+         if (calloutPos < calloutCount
+             && callout[calloutPos].getLine() == lineNumber
+             && callout[calloutPos].getColumn() == colNumber) {
+           if (pos > 0) {
+             rtf.characters(chars, 0, pos);
+             pos = 0;
+           }
+
+           closeOpenElements(rtf);
+
+           while (calloutPos < calloutCount
+                  && callout[calloutPos].getLine() == lineNumber
+                  && callout[calloutPos].getColumn() == colNumber) {
+             fCallout.formatCallout(rtf, callout[calloutPos]);
+             calloutPos++;
+           }
+
+           openClosedElements(rtf);
+         }
+
+         if (text.charAt(count) == '\n') {
+           // What if we need to pad this line?
+           if (calloutPos < calloutCount
+               && callout[calloutPos].getLine() == lineNumber
+               && callout[calloutPos].getColumn() > colNumber) {
+
+             if (pos > 0) {
+               rtf.characters(chars, 0, pos);
+               pos = 0;
+             }
+
+             closeOpenElements(rtf);
+
+             while (calloutPos < calloutCount
+                    && callout[calloutPos].getLine() == lineNumber
+                    && callout[calloutPos].getColumn() > colNumber) {
+               formatPad(rtf, callout[calloutPos].getColumn() - colNumber);
+               colNumber = callout[calloutPos].getColumn();
+               while (calloutPos < calloutCount
+                      && callout[calloutPos].getLine() == lineNumber
+                      && callout[calloutPos].getColumn() == colNumber) {
+                 fCallout.formatCallout(rtf, callout[calloutPos]);
+                 calloutPos++;
+               }
+             }
+
+             openClosedElements(rtf);
+           }
+
+           lineNumber++;
+           colNumber = 1;
+         } else {
+           colNumber++;
+         }
+         chars[pos++] = text.charAt(count);
+       }
+
+       if (pos > 0) {
+         rtf.characters(chars, 0, pos);
+       }
+      } else if (node.getNodeType() == Node.COMMENT_NODE) {
+       String text = node.getNodeValue();
+       char chars[] = text.toCharArray();
+       rtf.comment(chars, 0, text.length());
+      } else if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
+       rtf.processingInstruction(node.getNodeName(), node.getNodeValue());
+      } else {
+       System.out.println("Warning: unexpected node type in calloutFragment: " + node.getNodeType() + ": " + node.getNodeName());
+      }
+
+      if (node.getNodeType() == Node.ELEMENT_NODE) {
+       String ns = node.getNamespaceURI();
+       String localName = node.getLocalName();
+       String name = ((Element) node).getTagName();
+       rtf.endElement(ns, localName, name);
+       elementStack.pop();
+      } else {
+       // nop
+      }
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in calloutFragment");
+    }
+  }
+
+  /**
+   * <p>Add a callout to the global callout array</p>
+   *
+   * <p>This method examines a callout <tt>area</tt> and adds it to
+   * the global callout array if it can be interpreted.</p>
+   *
+   * <p>Only the <tt>linecolumn</tt> and <tt>linerange</tt> units are
+   * supported. If no unit is specifed, <tt>linecolumn</tt> is assumed.
+   * If only a line is specified, the callout decoration appears in
+   * the <tt>defaultColumn</tt>.</p>
+   *
+   * @param coNum The callout number.
+   * @param node The <tt>area</tt>.
+   * @param defaultColumn The default column for callouts.
+   */
+  private void addCallout (int coNum,
+                          Node node,
+                          int defaultColumn) {
+    Element area = (Element) node;
+
+    NamedNodeMap domAttr = node.getAttributes();
+    AttList attr = new AttList(domAttr);
+
+    String units = attr.getValue("units");
+    String otherUnits = attr.getValue("otherunits");
+    String coords = attr.getValue("coords");
+    int type = 0;
+    String otherType = null;
+
+    if (units == null || units.equals("linecolumn")) {
+      type = Callout.LINE_COLUMN; // the default
+    } else if (units.equals("linerange")) {
+      type = Callout.LINE_RANGE;
+    } else if (units.equals("linecolumnpair")) {
+      type = Callout.LINE_COLUMN_PAIR;
+    } else if (units.equals("calspair")) {
+      type = Callout.CALS_PAIR;
+    } else {
+      type = Callout.OTHER;
+      otherType = otherUnits;
+    }
+
+    if (type != Callout.LINE_COLUMN
+       && type != Callout.LINE_RANGE) {
+      System.out.println("Only linecolumn and linerange units are supported");
+      return;
+    }
+
+    if (coords == null) {
+      System.out.println("Coords must be specified");
+      return;
+    }
+
+    // Now let's see if we can interpret the coordinates...
+    StringTokenizer st = new StringTokenizer(coords);
+    int tokenCount = 0;
+    int c1 = 0;
+    int c2 = 0;
+    while (st.hasMoreTokens()) {
+      tokenCount++;
+      if (tokenCount > 2) {
+       System.out.println("Unparseable coordinates");
+       return;
+      }
+      try {
+       String token = st.nextToken();
+       int coord = Integer.parseInt(token);
+       c2 = coord;
+       if (tokenCount == 1) {
+         c1 = coord;
+       }
+      } catch (NumberFormatException e) {
+       System.out.println("Unparseable coordinate");
+       return;
+      }
+    }
+
+    // Make sure we aren't going to blow past the end of our array
+    if (calloutCount == callout.length) {
+      Callout bigger[] = new Callout[calloutCount+10];
+      for (int count = 0; count < callout.length; count++) {
+       bigger[count] = callout[count];
+      }
+      callout = bigger;
+    }
+
+    // Ok, add the callout
+    if (tokenCount == 2) {
+      if (type == Callout.LINE_RANGE) {
+       for (int count = c1; count <= c2; count++) {
+         callout[calloutCount++] = new Callout(coNum, area,
+                                               count, defaultColumn,
+                                               type);
+       }
+      } else {
+       // assume linecolumn
+       callout[calloutCount++] = new Callout(coNum, area, c1, c2, type);
+      }
+    } else {
+      // if there's only one number, assume it's the line
+      callout[calloutCount++] = new Callout(coNum, area, c1, defaultColumn, type);
+    }
+  }
+
+  /**
+   * <p>Add blanks to the result tree fragment.</p>
+   *
+   * <p>This method adds <tt>numBlanks</tt> to the result tree fragment.
+   * It's used to pad lines when callouts occur after the last existing
+   * characater in a line.</p>
+   *
+   * @param rtf The resulting verbatim environment with numbered lines.
+   * @param numBlanks The number of blanks to add.
+   */
+  private void formatPad(DOMBuilder rtf,
+                        int numBlanks) {
+    char chars[] = new char[numBlanks];
+    for (int count = 0; count < numBlanks; count++) {
+      chars[count] = ' ';
+    }
+
+    try {
+      rtf.characters(chars, 0, numBlanks);
+    } catch (SAXException e) {
+      System.out.println("SAX Exception in formatCallout");
+    }
+  }
+
+  private void closeOpenElements(DOMBuilder rtf)
+    throws SAXException {
+    // Close all the open elements...
+    tempStack = new Stack();
+    while (!elementStack.empty()) {
+      Node elem = (Node) elementStack.pop();
+
+      String ns = elem.getNamespaceURI();
+      String localName = elem.getLocalName();
+      String name = ((Element) elem).getTagName();
+
+      // If this is the bottom of the stack and it's an fo:block
+      // or an HTML pre or div, don't duplicate it...
+      if (elementStack.empty()
+         && (((ns != null)
+              && ns.equals(foURI)
+              && localName.equals("block"))
+             || (((ns == null)
+                  && localName.equalsIgnoreCase("pre"))
+                 || ((ns != null)
+                     && ns.equals(xhURI)
+                     && localName.equals("pre")))
+             || (((ns == null)
+                  && localName.equalsIgnoreCase("div"))
+                 || ((ns != null)
+                     && ns.equals(xhURI)
+                     && localName.equals("div"))))) {
+       elementStack.push(elem);
+       break;
+      } else {
+       rtf.endElement(ns, localName, name);
+       tempStack.push(elem);
+      }
+    }
+  }
+
+  private void openClosedElements(DOMBuilder rtf)
+    throws SAXException {
+    // Now "reopen" the elements that we closed...
+    while (!tempStack.empty()) {
+      Node elem = (Node) tempStack.pop();
+
+      String ns = elem.getNamespaceURI();
+      String localName = elem.getLocalName();
+      String name = ((Element) elem).getTagName();
+      NamedNodeMap domAttr = elem.getAttributes();
+
+      AttributesImpl attr = new AttributesImpl();
+      for (int acount = 0; acount < domAttr.getLength(); acount++) {
+       Node a = domAttr.item(acount);
+
+       if (((ns == null || ns == "http://www.w3.org/1999/xhtml")
+            && localName.equalsIgnoreCase("a"))
+           || (a.getLocalName().equalsIgnoreCase("id"))) {
+         // skip this attribute
+       } else {
+         attr.addAttribute(a.getNamespaceURI(),
+                           a.getLocalName(),
+                           a.getNodeName(),
+                           "CDATA",
+                           a.getNodeValue());
+       }
+      }
+
+      rtf.startElement(ns, localName, name, attr);
+      elementStack.push(elem);
+    }
+
+    tempStack = null;
+  }
+}
diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/package.html b/xsl/extensions/xalan2/com/nwalsh/xalan/package.html
new file mode 100644 (file)
index 0000000..92224fa
--- /dev/null
@@ -0,0 +1,48 @@
+<html>
+<head>
+<title>Norman Walsh's Xalan Extensions Package</title>
+</head>
+<body>
+<p>Norman Walsh's Xalan Extensions Package for Xalan2</p>
+
+<p>This package implements Xalan extensions for XSLT.</p>
+
+<p><b>Copyright (C) 2000 Norman Walsh</b></p>
+<p>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:</p>
+
+<p>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.</p>
+
+<p>Except as contained in this notice, the names of individuals
+credited with contribution to this software shall not be used in
+advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the
+individuals in question.</p>
+
+<p>Anything derived from this Software that is publically
+distributed will be identified with a different name and the
+version strings in any derived Software will be changed so that no
+possibility of confusion between the derived package and this
+Software will exist.</p>
+</blockquote>
+
+<blockquote>
+<p><b>Warranty</b></p>
+<p>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 NORMAN WALSH OR ANY OTHER
+CONTRIBUTOR 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.</p>
+</blockquote>
+
+</body>
+</html>
diff --git a/xsl/fo/.cvsignore b/xsl/fo/.cvsignore
new file mode 100644 (file)
index 0000000..c7dc21b
--- /dev/null
@@ -0,0 +1 @@
+titlepage.templates.xsl
diff --git a/xsl/fo/Makefile b/xsl/fo/Makefile
new file mode 100644 (file)
index 0000000..0afd45c
--- /dev/null
@@ -0,0 +1,4 @@
+all: titlepage.templates.xsl
+
+titlepage.templates.xsl: titlepage.templates.xml ../template/titlepage.xsl
+       saxon $< ../template/titlepage.xsl $@
diff --git a/xsl/fo/admon.xsl b/xsl/fo/admon.xsl
new file mode 100644 (file)
index 0000000..6280ff8
--- /dev/null
@@ -0,0 +1,116 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="note|important|warning|caution|tip">
+  <xsl:choose>
+    <xsl:when test="$admon.graphics != 0">
+      <xsl:call-template name="graphical.admonition"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="nongraphical.admonition"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="admon.graphic.width">
+  <xsl:param name="node" select="."/>
+  <xsl:text>36pt</xsl:text>
+</xsl:template>
+
+<xsl:template name="admon.graphic">
+  <xsl:param name="node" select="."/>
+  <xsl:value-of select="$admon.graphics.path"/>
+  <xsl:choose>
+    <xsl:when test="name($node)='note'">note</xsl:when>
+    <xsl:when test="name($node)='warning'">warning</xsl:when>
+    <xsl:when test="name($node)='caution'">caution</xsl:when>
+    <xsl:when test="name($node)='tip'">tip</xsl:when>
+    <xsl:when test="name($node)='important'">important</xsl:when>
+    <xsl:otherwise>note</xsl:otherwise>
+  </xsl:choose>
+  <xsl:value-of select="$admon.graphics.extension"/>
+</xsl:template>
+
+<xsl:template name="graphical.admonition">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <fo:table>
+      <fo:table-body>
+        <fo:table-row>
+          <fo:table-cell number-rows-spanned="2">
+            <fo:block>
+              <fo:external-graphic width="auto" height="auto">
+                <xsl:attribute name="src">
+                  <xsl:call-template name="admon.graphic"/>
+                </xsl:attribute>
+                <xsl:attribute name="content-width">
+                  <xsl:call-template name="admon.graphic.width"/>
+                </xsl:attribute>
+              </fo:external-graphic>
+            </fo:block>
+          </fo:table-cell>
+          <fo:table-cell>
+            <fo:block>
+              <xsl:apply-templates select="." mode="object.title.markup"/>
+            </fo:block>
+          </fo:table-cell>
+        </fo:table-row>
+        <fo:table-row>
+          <fo:table-cell number-columns-spanned="2">
+            <fo:block>
+              <xsl:apply-templates/>
+            </fo:block>
+          </fo:table-cell>
+        </fo:table-row>
+      </fo:table-body>
+    </fo:table>
+  </fo:block>
+</xsl:template>
+
+<xsl:template name="nongraphical.admonition">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block space-before.minimum="0.8em"
+            space-before.optimum="1em"
+            space-before.maximum="1.2em"
+            start-indent="0.25in"
+            end-indent="0.25in"
+            id="{$id}">
+    <fo:block font-size="14pt" font-weight="bold" keep-with-next='always'>
+      <xsl:apply-templates select="." mode="object.title.markup"/>
+    </fo:block>
+
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="note/title"></xsl:template>
+<xsl:template match="important/title"></xsl:template>
+<xsl:template match="warning/title"></xsl:template>
+<xsl:template match="caution/title"></xsl:template>
+<xsl:template match="tip/title"></xsl:template>
+
+<xsl:template match="title" mode="admonition.title.mode">
+  <fo:block font-size="14pt" font-weight="bold" keep-with-next='always'>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/autoidx.xsl b/xsl/fo/autoidx.xsl
new file mode 100644 (file)
index 0000000..2973193
--- /dev/null
@@ -0,0 +1,332 @@
+<?xml version="1.0"?>
+<!DOCTYPE xsl:stylesheet [
+
+<!ENTITY primary   'concat(primary/@sortas, primary[not(@sortas)])'>
+<!ENTITY secondary 'concat(secondary/@sortas, secondary[not(@sortas)])'>
+<!ENTITY tertiary  'concat(tertiary/@sortas, tertiary[not(@sortas)])'>
+
+<!ENTITY section   '(ancestor-or-self::set
+                     |ancestor-or-self::book
+                     |ancestor-or-self::part
+                     |ancestor-or-self::reference
+                     |ancestor-or-self::partintro
+                     |ancestor-or-self::chapter
+                     |ancestor-or-self::appendix
+                     |ancestor-or-self::preface
+                     |ancestor-or-self::section
+                     |ancestor-or-self::sect1
+                     |ancestor-or-self::sect2
+                     |ancestor-or-self::sect3
+                     |ancestor-or-self::sect4
+                     |ancestor-or-self::sect5
+                     |ancestor-or-self::refsect1
+                     |ancestor-or-self::refsect2
+                     |ancestor-or-self::refsect3
+                     |ancestor-or-self::simplesect
+                     |ancestor-or-self::bibliography
+                     |ancestor-or-self::glossary
+                     |ancestor-or-self::index)[last()]'>
+
+<!ENTITY section.id 'generate-id(&section;)'>
+<!ENTITY sep '" "'>
+]>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version="1.0">
+
+<xsl:import href="docbook.xsl"/>
+
+<!-- ==================================================================== -->
+<!-- Derived from Jeni Tennison's work in the HTML case -->
+
+<xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/>
+<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
+
+<xsl:key name="letter"
+         match="indexterm"
+         use="translate(substring(&primary;, 1, 1),$lowercase,$uppercase)"/>
+
+<xsl:key name="primary"
+         match="indexterm"
+         use="&primary;"/>
+
+<xsl:key name="secondary"
+         match="indexterm"
+         use="concat(&primary;, &sep;, &secondary;)"/>
+
+<xsl:key name="tertiary"
+         match="indexterm"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
+
+<xsl:key name="primary-section"
+         match="indexterm[not(secondary) and not(see)]"
+         use="concat(&primary;, &sep;, &section.id;)"/>
+
+<xsl:key name="secondary-section"
+         match="indexterm[not(tertiary) and not(see)]"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &section.id;)"/>
+
+<xsl:key name="tertiary-section"
+         match="indexterm[not(see)]"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, &section.id;)"/>
+
+<xsl:key name="see-also"
+         match="indexterm[seealso]"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, seealso)"/>
+
+<xsl:key name="see"
+         match="indexterm[see]"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see)"/>
+
+<xsl:key name="sections" match="*[@id]" use="@id"/>
+
+<xsl:template name="generate-index">
+  <xsl:variable name="terms" select="//indexterm[count(.|key('letter',
+                                     translate(substring(&primary;, 1, 1),$lowercase,$uppercase))[1]) = 1]"/>
+  <xsl:variable name="alphabetical"
+                select="$terms[contains(concat($lowercase, $uppercase),
+                                        substring(&primary;, 1, 1))]"/>
+  <xsl:variable name="others" select="$terms[not(contains(concat($lowercase,
+                                                 $uppercase),
+                                             substring(&primary;, 1, 1)))]"/>
+  <fo:block>
+    <xsl:if test="$others">
+      <fo:block font-size="16pt"
+                font-weight="bold"
+                keep-with-next.within-column="always"
+                space-before="1em">
+        <xsl:call-template name="gentext">
+          <xsl:with-param name="key" select="'index symbols'"/>
+        </xsl:call-template>
+      </fo:block>
+      <fo:block>
+        <xsl:apply-templates select="$others[count(.|key('primary',
+                                     &primary;)[1]) = 1]"
+                             mode="index-primary">
+          <xsl:sort select="&primary;"/>
+        </xsl:apply-templates>
+      </fo:block>
+    </xsl:if>
+    <xsl:apply-templates select="$alphabetical[count(.|key('letter',
+                                 translate(substring(&primary;, 1, 1),$lowercase,$uppercase))[1]) = 1]"
+                         mode="index-div">
+      <xsl:sort select="&primary;"/>
+    </xsl:apply-templates>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-div">
+  <xsl:variable name="key" select="translate(substring(&primary;, 1, 1),$lowercase,$uppercase)"/>
+  <fo:block>
+    <!-- this isn't quite exactly right. ideally all the symbols would -->
+    <!-- be grouped together. as it stands, they all get separate divs -->
+    <!-- but at least this test makes sure that they don't all get     -->
+    <!-- separate titles as well. -->
+    <xsl:if test="contains(concat($lowercase, $uppercase), $key)">
+      <fo:block font-size="16pt"
+                font-weight="bold"
+                keep-with-next.within-column="always"
+                space-before="1em">
+        <xsl:value-of select="translate($key, $lowercase, $uppercase)"/>
+      </fo:block>
+    </xsl:if>
+    <fo:block>
+      <xsl:apply-templates select="key('letter', $key)[count(.|key('primary', &primary;)[1]) = 1]"
+                           mode="index-primary">
+        <xsl:sort select="&primary;"/>
+      </xsl:apply-templates>
+    </fo:block>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-primary">
+  <xsl:variable name="key" select="&primary;"/>
+  <xsl:variable name="refs" select="key('primary', $key)"/>
+  <fo:block>
+    <xsl:value-of select="primary"/>
+
+    <xsl:variable name="page-number-citations">
+      <xsl:for-each select="$refs[generate-id() = generate-id(key('primary-section', concat($key, &sep;, &section.id;))[1])]">
+        <xsl:apply-templates select="." mode="reference"/>
+      </xsl:for-each>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$passivetex.extensions != '0'">
+        <fotex:sort xmlns:fotex="http://www.tug.org/fotex">
+          <xsl:copy-of select="$page-number-citations"/>
+        </fotex:sort>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:copy-of select="$page-number-citations"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </fo:block>
+  <xsl:if test="$refs/secondary or $refs[not(secondary)]/*[self::see or self::seealso]">
+    <fo:block start-indent="1pc">
+      <fo:block>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &sep;, &sep;, see))[1])]"
+                             mode="index-see">
+          <xsl:sort select="see"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &sep;, &sep;, seealso))[1])]"
+                             mode="index-seealso">
+          <xsl:sort select="seealso"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[secondary and count(.|key('secondary', concat($key, &sep;, &secondary;))[1]) = 1]" 
+                             mode="index-secondary">
+          <xsl:sort select="&secondary;"/>
+        </xsl:apply-templates>
+      </fo:block>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-secondary">
+  <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;)"/>
+  <xsl:variable name="refs" select="key('secondary', $key)"/>
+  <fo:block>
+    <xsl:value-of select="secondary"/>
+
+    <xsl:variable name="page-number-citations">
+      <xsl:for-each select="$refs[generate-id() = generate-id(key('secondary-section', concat($key, &sep;, &section.id;))[1])]">
+        <xsl:apply-templates select="." mode="reference"/>
+      </xsl:for-each>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$passivetex.extensions != '0'">
+        <fotex:sort xmlns:fotex="http://www.tug.org/fotex">
+          <xsl:copy-of select="$page-number-citations"/>
+        </fotex:sort>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:copy-of select="$page-number-citations"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </fo:block>
+  <xsl:if test="$refs/tertiary or $refs[not(tertiary)]/*[self::see or self::seealso]">
+    <fo:block start-indent="2pc">
+      <fo:block>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, see))[1])]"
+                             mode="index-see">
+          <xsl:sort select="see"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, seealso))[1])]"
+                             mode="index-seealso">
+          <xsl:sort select="seealso"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[tertiary and count(.|key('tertiary', concat($key, &sep;, &tertiary;))[1]) = 1]" 
+                             mode="index-tertiary">
+          <xsl:sort select="&tertiary;"/>
+        </xsl:apply-templates>
+      </fo:block>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-tertiary">
+  <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
+  <xsl:variable name="refs" select="key('tertiary', $key)"/>
+  <fo:block>
+    <xsl:value-of select="tertiary"/>
+
+    <xsl:variable name="page-number-citations">
+      <xsl:for-each select="$refs[generate-id() = generate-id(key('tertiary-section', concat($key, &sep;, &section.id;))[1])]">
+        <xsl:apply-templates select="." mode="reference"/>
+      </xsl:for-each>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$passivetex.extensions != '0'">
+        <fotex:sort xmlns:fotex="http://www.tug.org/fotex">
+          <xsl:copy-of select="$page-number-citations"/>
+        </fotex:sort>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:copy-of select="$page-number-citations"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </fo:block>
+  <xsl:variable name="see" select="$refs/see | $refs/seealso"/>
+  <xsl:if test="$see">
+    <fo:block>
+      <fo:block>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see))[1])]"
+                             mode="index-see">
+          <xsl:sort select="see"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, seealso))[1])]"
+                             mode="index-seealso">
+          <xsl:sort select="seealso"/>
+        </xsl:apply-templates>
+      </fo:block>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="reference">
+  <xsl:if test="$passivetex.extensions = '0'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <xsl:choose>
+    <xsl:when test="@zone and string(@zone)">
+      <xsl:call-template name="reference">
+        <xsl:with-param name="zones" select="normalize-space(@zone)"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="id">
+        <xsl:call-template name="object.id"/>
+      </xsl:variable>
+      <fo:page-number-citation ref-id="{$id}"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="reference">
+  <xsl:param name="zones"/>
+  <xsl:choose>
+    <xsl:when test="contains($zones, ' ')">
+      <xsl:variable name="zone" select="substring-before($zones, ' ')"/>
+      <xsl:variable name="target" select="key('sections', $zone)"/>
+
+      <xsl:variable name="id">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="$target[1]"/>
+        </xsl:call-template>
+      </xsl:variable>
+
+      <fo:page-number-citation ref-id="{$id}"/>
+
+      <xsl:if test="$passivetex.extensions = '0'">
+        <xsl:text>, </xsl:text>
+      </xsl:if>
+      <xsl:call-template name="reference">
+        <xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="zone" select="$zones"/>
+      <xsl:variable name="target" select="key('sections', $zone)"/>
+
+      <xsl:variable name="id">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="$target[1]"/>
+        </xsl:call-template>
+      </xsl:variable>
+
+      <fo:page-number-citation ref-id="{$id}"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-see">
+   <fo:block><xsl:value-of select="see"/></fo:block>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-seealso">
+   <fo:block><xsl:value-of select="seealso"/></fo:block>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/autotoc.xsl b/xsl/fo/autotoc.xsl
new file mode 100644 (file)
index 0000000..ac5c526
--- /dev/null
@@ -0,0 +1,182 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template name="division.toc">
+  <xsl:variable name="nodes"
+                select="part|reference|preface
+                        |chapter|appendix
+                        |article
+                        |bibliography|glossary|index"/>
+  <xsl:if test="$nodes">
+    <fo:block xsl:use-attribute-sets="toc.margin.properties">
+      <xsl:call-template name="table.of.contents.titlepage"/>
+      <xsl:apply-templates select="$nodes" mode="toc"/>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="component.toc">
+  <xsl:variable name="nodes" select="section|sect1|refentry
+                                     |article|bibliography|glossary
+                                     |appendix"/>
+  <xsl:if test="$nodes">
+    <fo:block xsl:use-attribute-sets="toc.margin.properties">
+      <fo:block>
+         <fo:inline font-weight="bold">
+           <xsl:call-template name="gentext">
+             <xsl:with-param name="key">TableofContents</xsl:with-param>
+           </xsl:call-template>
+         </fo:inline>
+       </fo:block>
+      <xsl:apply-templates select="$nodes" mode="toc"/>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="toc.line">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block text-align-last="justify"
+            end-indent="2pc"
+            last-line-end-indent="-2pc">
+    <fo:inline keep-with-next.within-line="always">
+      <xsl:apply-templates select="." mode="label.markup"/>
+      <xsl:text> </xsl:text>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </fo:inline>
+    <fo:inline keep-together.within-line="always">
+      <xsl:text> </xsl:text>
+      <fo:leader leader-pattern="dots"
+                 keep-with-next.within-line="always"/>
+      <xsl:text> </xsl:text>
+      <fo:basic-link internal-destination="{$id}">
+<!--                     xsl:use-attribute-sets="xref.properties">-->
+        <fo:page-number-citation ref-id="{$id}"/>
+      </fo:basic-link>
+    </fo:inline>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="part" mode="toc">
+  <xsl:call-template name="toc.line"/>
+
+  <xsl:if test="chapter|appendix|preface|reference">
+    <fo:block start-indent="{count(ancestor::*)*2}pc">
+      <xsl:apply-templates select="chapter|appendix|preface|reference"
+                           mode="toc"/>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="reference" mode="toc">
+  <xsl:call-template name="toc.line"/>
+
+  <xsl:if test="refentry">
+    <fo:block start-indent="{count(ancestor::*)*2}pc">
+      <xsl:apply-templates select="refentry" mode="toc"/>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="refentry" mode="toc">
+  <xsl:call-template name="toc.line"/>
+</xsl:template>
+
+<xsl:template match="preface|chapter|appendix|article"
+              mode="toc">
+  <xsl:call-template name="toc.line"/>
+
+  <xsl:if test="section|sect1">
+    <fo:block start-indent="{count(ancestor::*)*2}pc">
+      <xsl:apply-templates select="section|sect1"
+                           mode="toc"/>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="section|sect1|sect2|sect3|sect4|sect5"
+              mode="toc">
+  <xsl:call-template name="toc.line"/>
+
+  <xsl:if test="section|sect2|sect3|sect4|sect5">
+    <fo:block start-indent="{count(ancestor::*)*2}pc">
+      <xsl:apply-templates select="section|sect2|sect3|sect4|sect5"
+                           mode="toc"/>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="bibliography|glossary"
+              mode="toc">
+  <xsl:call-template name="toc.line"/>
+</xsl:template>
+
+<xsl:template match="index"
+              mode="toc">
+  <xsl:if test="* or $generate.index">
+    <xsl:call-template name="toc.line"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="title" mode="toc">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="list.of.titles">
+  <xsl:param name="titles" select="'table'"/>
+  <xsl:param name="nodes" select=".//table"/>
+
+  <xsl:if test="$nodes">
+    <fo:block>
+      <xsl:choose>
+        <xsl:when test="$titles='table'">
+          <xsl:call-template name="list.of.tables.titlepage"/>
+        </xsl:when>
+        <xsl:when test="$titles='figure'">
+          <xsl:call-template name="list.of.figures.titlepage"/>
+        </xsl:when>
+        <xsl:when test="$titles='equation'">
+          <xsl:call-template name="list.of.equations.titlepage"/>
+        </xsl:when>
+        <xsl:when test="$titles='example'">
+          <xsl:call-template name="list.of.examples.titlepage"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="list.of.unknowns.titlepage"/>
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:apply-templates select="$nodes" mode="toc"/>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="figure|table|example|equation" mode="toc">
+  <xsl:call-template name="toc.line"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/biblio.xsl b/xsl/fo/biblio.xsl
new file mode 100644 (file)
index 0000000..df29b56
--- /dev/null
@@ -0,0 +1,961 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="bibliography">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="component.separator"/>
+    <xsl:call-template name="bibliography.titlepage"/>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="book/bibliography">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="bibliography.titlepage"/>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="bibliography/bibliographyinfo"></xsl:template>
+<xsl:template match="bibliography/title"></xsl:template>
+<xsl:template match="bibliography/subtitle"></xsl:template>
+<xsl:template match="bibliography/titleabbrev"></xsl:template>
+
+<xsl:template match="bibliography/title" mode="component.title.mode">
+  <fo:block xsl:use-attribute-sets="component.title.properties">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="bibliography/subtitle" mode="component.title.mode">
+  <fo:block font-size="18pt" font-weight="bold" font-style="italic">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="bibliodiv">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="bibliodiv/title">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <fo:block font-size="16pt" font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="biblioentry">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <fo:block id="{$id}" xsl:use-attribute-sets="normal.para.spacing">
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="bibliomixed">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <fo:block id="{$id}" xsl:use-attribute-sets="normal.para.spacing">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="bibliography.mode">
+  <xsl:apply-templates select="."/><!-- try the default mode -->
+</xsl:template>
+
+<xsl:template match="abbrev" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:text>[</xsl:text>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:text>] </xsl:text>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="abstract" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="address" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="affiliation" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="shortaffil" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="jobtitle" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="artheader|articleinfo" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="artpagenums" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="author" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:call-template name="person.name"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="authorblurb" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="authorgroup" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:call-template name="person.name.list"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="authorinitials" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="bibliomisc" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="bibliomset" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="biblioset" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="biblioset/title|biblioset/citetitle" 
+              mode="bibliography.mode">
+  <xsl:variable name="relation" select="../@relation"/>
+  <xsl:choose>
+    <xsl:when test="$relation='article'">
+      <xsl:call-template name="dingbat">
+        <xsl:with-param name="dingbat">ldquo</xsl:with-param>
+      </xsl:call-template>
+      <xsl:apply-templates/>
+      <xsl:call-template name="dingbat">
+        <xsl:with-param name="dingbat">rdquo</xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <fo:inline font-style="italic">
+        <xsl:apply-templates/>
+      </fo:inline>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:value-of select="$biblioentry.item.separator"/>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="bookbiblio" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="citetitle" mode="bibliography.mode">
+  <fo:inline>
+    <fo:inline font-style="italic">
+      <xsl:apply-templates mode="bibliography.mode"/>
+    </fo:inline>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="collab" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="confgroup" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="contractnum" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="contractsponsor" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="contrib" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="copyright" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'Copyright'"/>
+    </xsl:call-template>
+    <xsl:call-template name="gentext.space"/>
+    <xsl:call-template name="dingbat">
+      <xsl:with-param name="dingbat">copyright</xsl:with-param>
+    </xsl:call-template>
+    <xsl:call-template name="gentext.space"/>
+    <xsl:apply-templates select="year" mode="bibliography.mode"/>
+    <xsl:if test="holder">
+      <xsl:call-template name="gentext.space"/>
+      <xsl:apply-templates select="holder" mode="bibliography.mode"/>
+    </xsl:if>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="year" mode="bibliography.mode">
+  <xsl:apply-templates/><xsl:text>, </xsl:text>
+</xsl:template>
+
+<xsl:template match="year[position()=last()]" mode="bibliography.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="holder" mode="bibliography.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="corpauthor" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="corpname" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="date" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="edition" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="editor" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:call-template name="person.name"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="firstname" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="honorific" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="invpartnumber" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="isbn" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="issn" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="issuenum" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="lineage" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="orgname" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="othercredit" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="othername" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="pagenums" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="printhistory" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="productname" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="productnumber" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="pubdate" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="publisher" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="publishername" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="pubsnumber" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="releaseinfo" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="revhistory" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="seriesinfo" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="seriesvolnums" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="surname" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="title" mode="bibliography.mode">
+  <fo:inline>
+    <fo:inline font-style="italic">
+      <xsl:apply-templates mode="bibliography.mode"/>
+    </fo:inline>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="titleabbrev" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="volumenum" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="orgdiv" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="collabname" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="confdates" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="conftitle" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="confnum" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="confsponsor" mode="bibliography.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </fo:inline>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="bibliomixed.mode">
+  <xsl:apply-templates select="."/><!-- try the default mode -->
+</xsl:template>
+
+<xsl:template match="abbrev" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="abstract" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="address" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="affiliation" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="shortaffil" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="jobtitle" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="artpagenums" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="author" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="authorblurb" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="authorgroup" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="authorinitials" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="bibliomisc" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="bibliomset" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="bibliomset/title|bibliomset/citetitle" 
+              mode="bibliomixed.mode">
+  <xsl:variable name="relation" select="../@relation"/>
+  <xsl:choose>
+    <xsl:when test="$relation='article'">
+      <xsl:call-template name="dingbat">
+        <xsl:with-param name="dingbat">ldquo</xsl:with-param>
+      </xsl:call-template>
+      <xsl:apply-templates/>
+      <xsl:call-template name="dingbat">
+        <xsl:with-param name="dingbat">rdquo</xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <fo:inline font-style="italic">
+        <xsl:apply-templates/>
+      </fo:inline>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="biblioset" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="citetitle" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="collab" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="confgroup" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="contractnum" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="contractsponsor" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="contrib" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="copyright" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="corpauthor" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="corpname" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="date" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="edition" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="editor" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="firstname" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="honorific" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="invpartnumber" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="isbn" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="issn" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="issuenum" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="lineage" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="orgname" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="othercredit" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="othername" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="pagenums" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="printhistory" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="productname" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="productnumber" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="pubdate" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="publisher" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="publishername" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="pubsnumber" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="releaseinfo" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="revhistory" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="seriesvolnums" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="surname" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="title" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="titleabbrev" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="volumenum" mode="bibliomixed.mode">
+  <fo:inline>
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </fo:inline>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/block.xsl b/xsl/fo/block.xsl
new file mode 100644 (file)
index 0000000..5af1132
--- /dev/null
@@ -0,0 +1,213 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template name="block.object">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="para">
+  <fo:block xsl:use-attribute-sets="normal.para.spacing">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="simpara">
+  <fo:block xsl:use-attribute-sets="normal.para.spacing">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="formalpara">
+  <fo:block xsl:use-attribute-sets="normal.para.spacing">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="formalpara/title">
+  <fo:inline font-weight="bold"
+             keep-with-next.within-line="always"
+             padding-end="1em">
+    <xsl:apply-templates/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="formalpara/para">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="blockquote">
+  <fo:block start-indent="1in" end-indent="1in">
+    <xsl:call-template name="semiformal.object"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="epigraph">
+  <fo:block>
+    <xsl:apply-templates select="para"/>
+    <fo:inline>
+      <xsl:text>--</xsl:text>
+      <xsl:apply-templates select="attribution"/>
+    </fo:inline>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="attribution">
+  <fo:inline><xsl:apply-templates/></fo:inline>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="sidebar">
+  <fo:block>
+    <xsl:if test="./title">
+      <fo:block font-weight="bold"
+                keep-with-next.within-column="always"
+                hyphenate="false">
+        <xsl:apply-templates select="./title" mode="sidebar.title.mode"/>
+      </fo:block>
+    </xsl:if>
+
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="sidebar/title">
+</xsl:template>
+
+<xsl:template match="sidebar/title" mode="sidebar.title.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="abstract">
+  <fo:block>
+    <xsl:if test="@id">
+      <xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
+    </xsl:if>
+    <xsl:call-template name="formal.object.heading">
+      <xsl:with-param name="title">
+        <xsl:apply-templates select="." mode="title.markup"/>
+      </xsl:with-param>
+    </xsl:call-template>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="abstract/title">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="msgset">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msgentry">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="msg">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="msgmain">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msgsub">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msgrel">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msgtext">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msginfo">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="msglevel">
+  <fo:block>
+    <fo:inline font-weight="bold"
+               keep-with-next.within-line="always">
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'msgset'"/>
+        <xsl:with-param name="name" select="'MsgLevel'"/>
+      </xsl:call-template>
+    </fo:inline>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="msgorig">
+  <fo:block>
+    <fo:inline font-weight="bold"
+               keep-with-next.within-line="always">
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'msgset'"/>
+        <xsl:with-param name="name" select="'MsgOrig'"/>
+      </xsl:call-template>
+    </fo:inline>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="msgaud">
+  <fo:block>
+    <fo:inline font-weight="bold"
+               keep-with-next.within-line="always">
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'msgset'"/>
+        <xsl:with-param name="name" select="'MsgAud'"/>
+      </xsl:call-template>
+    </fo:inline>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="msgexplan">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="msgexplan/title">
+  <fo:block font-weight="bold"
+            keep-with-next.within-column="always"
+            hyphenate="false">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="highlights">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/callout.xsl b/xsl/fo/callout.xsl
new file mode 100644 (file)
index 0000000..6862916
--- /dev/null
@@ -0,0 +1,159 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                xmlns:sverb="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Verbatim"
+                xmlns:xverb="com.nwalsh.xalan.Verbatim"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="sverb xverb lxslt"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<lxslt:component prefix="xverb"
+                 functions="insertCallouts"/>
+
+<xsl:template match="programlistingco|screenco">
+  <xsl:variable name="verbatim" select="programlisting|screen"/>
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:choose>
+    <xsl:when test="$use.extensions != '0'
+                    and $callouts.extension != '0'">
+      <xsl:variable name="rtf">
+        <xsl:apply-templates select="$verbatim">
+          <xsl:with-param name="suppress-numbers" select="'1'"/>
+        </xsl:apply-templates>
+      </xsl:variable>
+
+      <xsl:variable name="rtf-with-callouts">
+        <xsl:choose>
+          <xsl:when test="contains($vendor, 'SAXON ')">
+            <xsl:copy-of select="sverb:insertCallouts(areaspec,$rtf)"/>
+          </xsl:when>
+          <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+            <xsl:copy-of select="xverb:insertCallouts(areaspec,$rtf)"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:message terminate="yes">
+              <xsl:text>Don't know how to do callouts with </xsl:text>
+              <xsl:value-of select="$vendor"/>
+            </xsl:message>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:choose>
+        <xsl:when test="$verbatim/@linenumbering = 'numbered'
+                        and $linenumbering.extension != '0'">
+          <xsl:call-template name="number.rtf.lines">
+            <xsl:with-param name="rtf" select="$rtf-with-callouts"/>
+            <xsl:with-param name="linenumbering.everyNth"
+                            select="$linenumbering.everyNth"/>
+            <xsl:with-param name="linenumbering.width"
+                            select="$linenumbering.width"/>
+            <xsl:with-param name="linenumbering.separator"
+                            select="$linenumbering.separator"/>
+          </xsl:call-template>
+          <xsl:apply-templates select="calloutlist"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:copy-of select="$rtf-with-callouts"/>
+          <xsl:apply-templates select="calloutlist"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="areaspec|areaset|area">
+</xsl:template>
+
+<xsl:template match="areaset" mode="conumber">
+  <xsl:number count="area|areaset" format="1"/>
+</xsl:template>
+
+<xsl:template match="area" mode="conumber">
+  <xsl:number count="area|areaset" format="1"/>
+</xsl:template>
+
+<xsl:template match="co">
+  <fo:inline id="{@id}">
+    <xsl:apply-templates select="." mode="callout-bug"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="co" mode="callout-bug">
+  <xsl:call-template name="callout-bug">
+    <xsl:with-param name="conum">
+      <xsl:number count="co" format="1"/>
+    </xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="callout-bug">
+  <xsl:param name="conum" select='1'/>
+
+  <xsl:choose>
+    <!-- Draw callouts as images -->
+    <xsl:when test="$callout.graphics != '0'
+                  and $conum &lt;= $callout.graphics.number.limit">
+      <fo:external-graphic
+          src="{$callout.graphics.path}{$conum}{$callout.graphics.extension}"/>
+    </xsl:when>
+
+    <!-- Pick callouts from Zapf Dingbats - max 10 -->
+    <xsl:when test="$callout.dingbats != '0' and $conum &lt;= 10">
+      <fo:inline font-family="ZapfDingbats">
+        <xsl:choose>
+          <xsl:when test="$conum=1">&#x2776;</xsl:when>
+          <xsl:when test="$conum=2">&#x2777;</xsl:when>
+          <xsl:when test="$conum=3">&#x2778;</xsl:when>
+          <xsl:when test="$conum=4">&#x2779;</xsl:when>
+          <xsl:when test="$conum=5">&#x277A;</xsl:when>
+          <xsl:when test="$conum=6">&#x277B;</xsl:when>
+          <xsl:when test="$conum=7">&#x277C;</xsl:when>
+          <xsl:when test="$conum=8">&#x277D;</xsl:when>
+          <xsl:when test="$conum=9">&#x277E;</xsl:when>
+          <xsl:when test="$conum=10">&#x277F;</xsl:when>
+          <xsl:otherwise><!-- overflow -->
+            <xsl:attribute name="color">red</xsl:attribute>
+            <xsl:text>&#x25CF;</xsl:text>
+            <xsl:message>
+              <xsl:text>A callout list contains more than 10 callouts;</xsl:text>
+              <xsl:text> callout numbering truncated.</xsl:text>
+            </xsl:message>
+          </xsl:otherwise>
+        </xsl:choose>
+      </fo:inline>
+    </xsl:when>
+
+    <!-- FIXME: how do I do callout.unicode here? -->
+
+    <!-- Most safe: draw a dark gray square with a white number inside -->
+    <xsl:otherwise>
+      <fo:inline background-color="#404040"
+                 color="white"
+                 padding-top="0.1em"
+                 padding-bottom="0.1em"
+                 padding-start="0.2em"
+                 padding-end="0.2em"
+                 baseline-shift="0.1em"
+                 font-family="Times"
+                 font-weight="bold"
+                 font-size="75%"><xsl:value-of select="$conum"/></fo:inline>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/component.xsl b/xsl/fo/component.xsl
new file mode 100644 (file)
index 0000000..a490fb0
--- /dev/null
@@ -0,0 +1,361 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template name="component.title">
+  <xsl:param name="node" select="."/>
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="$node"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="title">
+    <xsl:apply-templates select="$node" mode="title.markup"/>
+  </xsl:variable>
+
+  <xsl:if test="$passivetex.extensions != 0">
+    <fotex:bookmark xmlns:fotex="http://www.tug.org/fotex"
+                    fotex-bookmark-level="2"
+                    fotex-bookmark-label="{$id}">
+      <xsl:value-of select="$title"/>
+    </fotex:bookmark>
+  </xsl:if>
+
+  <fo:block keep-with-next.within-column="always"
+            hyphenate="false">
+    <xsl:copy-of select="$title"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template name="component.subtitle">
+  <xsl:param name="node" select="."/>
+  <xsl:variable name="subtitle">
+    <xsl:apply-templates select="$node" mode="subtitle.markup"/>
+  </xsl:variable>
+
+  <xsl:if test="$subtitle != ''">
+    <fo:block font-size="16pt"
+              font-weight="bold"
+              font-style="italic"
+              keep-with-next.within-column="always"
+              hyphenate="false">
+      <xsl:copy-of select="$subtitle"/>
+    </fo:block>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="component.separator">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="dedication" mode="dedication">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    format="i"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="dedication.titlepage"/>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="dedication"></xsl:template> <!-- see mode="dedication" -->
+<xsl:template match="dedication/docinfo"></xsl:template>
+<xsl:template match="dedication/title"></xsl:template>
+<xsl:template match="dedication/subtitle"></xsl:template>
+<xsl:template match="dedication/titleabbrev"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="preface">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    format="i"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="component.separator"/>
+      <xsl:call-template name="preface.titlepage"/>
+      <xsl:if test="$generate.component.toc">
+        <xsl:call-template name="component.toc"/>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="preface/docinfo"></xsl:template>
+<xsl:template match="preface/title"></xsl:template>
+<xsl:template match="preface/titleabbrev"></xsl:template>
+<xsl:template match="preface/subtitle"></xsl:template>
+
+<xsl:template match="chapter">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="not(preceding::chapter)">
+      <xsl:attribute name="initial-page-number">1</xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="component.separator"/>
+      <xsl:call-template name="chapter.titlepage"/>
+      <xsl:if test="$generate.component.toc">
+        <xsl:call-template name="component.toc"/>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="chapter/docinfo"></xsl:template>
+<xsl:template match="chapter/title"></xsl:template>
+<xsl:template match="chapter/titleabbrev"></xsl:template>
+<xsl:template match="chapter/subtitle"></xsl:template>
+
+<xsl:template match="appendix">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="component.separator"/>
+      <xsl:call-template name="appendix.titlepage"/>
+      <xsl:if test="$generate.component.toc">
+        <xsl:call-template name="component.toc"/>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="appendix/docinfo"></xsl:template>
+<xsl:template match="appendix/title"></xsl:template>
+<xsl:template match="appendix/titleabbrev"></xsl:template>
+<xsl:template match="appendix/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="dedication" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="preface" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="chapter" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+      <xsl:text>.</xsl:text>
+      <xsl:if test="$add.space">
+        <xsl:call-template name="gentext.space"/>
+      </xsl:if>
+    </xsl:when>
+    <xsl:when test="$chapter.autolabel">
+      <xsl:number from="book" count="chapter" format="1."/>
+      <xsl:if test="$add.space">
+        <xsl:call-template name="gentext.space"/>
+      </xsl:if>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="appendix" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+      <xsl:text>.</xsl:text>
+      <xsl:if test="$add.space">
+        <xsl:call-template name="gentext.space"/>
+      </xsl:if>
+    </xsl:when>
+    <xsl:when test="$chapter.autolabel">
+      <xsl:number from="book" count="appendix" format="A."/>
+      <xsl:if test="$add.space">
+        <xsl:call-template name="gentext.space"/>
+      </xsl:if>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="article" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="bibliography" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="glossary" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="index" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="article">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="article.titlepage"/>
+      <xsl:if test="$generate.component.toc">
+        <xsl:call-template name="component.toc"/>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="article/artheader"></xsl:template>
+<xsl:template match="article/articleinfo"></xsl:template>
+<xsl:template match="article/title"></xsl:template>
+<xsl:template match="article/subtitle"></xsl:template>
+
+<xsl:template match="article/appendix">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id='{$id}'>
+    <xsl:call-template name="section.heading">
+      <xsl:with-param name="level" select="2"/>
+      <xsl:with-param name="title">
+        <xsl:apply-templates select="." mode="title.markup"/>
+      </xsl:with-param>
+    </xsl:call-template>
+
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/division.xsl b/xsl/fo/division.xsl
new file mode 100644 (file)
index 0000000..610e8b9
--- /dev/null
@@ -0,0 +1,359 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template name="division.title">
+  <xsl:param name="node" select="."/>
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="$node"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="title">
+    <xsl:apply-templates select="$node" mode="title.markup"/>
+  </xsl:variable>
+
+  <xsl:if test="$passivetex.extensions != 0">
+    <fotex:bookmark xmlns:fotex="http://www.tug.org/fotex"
+                    fotex-bookmark-level="1"
+                    fotex-bookmark-label="{$id}">
+      <xsl:value-of select="$title"/>
+    </fotex:bookmark>
+  </xsl:if>
+
+  <fo:block keep-with-next.within-column="always"
+            hyphenate="false">
+    <xsl:copy-of select="$title"/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="set">
+  <xsl:variable name="preamble"
+                select="*[not(self::book or self::setindex)]"/>
+  <xsl:variable name="content" select="book|setindex"/>
+
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <xsl:if test="$preamble">
+    <fo:page-sequence id="{$id}"
+                      hyphenate="{$hyphenate}"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="set.titlepage"/>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+
+  <xsl:apply-templates select="$content"/>
+</xsl:template>
+
+<xsl:template match="set/setinfo"></xsl:template>
+<xsl:template match="set/title"></xsl:template>
+<xsl:template match="set/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="book">
+  <xsl:variable name="preamble"
+                select="title|subtitle|titleabbrev|bookinfo"/>
+  <xsl:variable name="content"
+                select="*[not(self::title or self::subtitle
+                            or self::titleabbrev
+                            or self::bookinfo)]"/>
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <xsl:if test="$preamble">
+    <fo:page-sequence id="{$id}"
+                      hyphenate="{$hyphenate}"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="book.titlepage"/>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+
+  <xsl:if test="$generate.division.toc != '0'">
+    <fo:page-sequence hyphenate="{$hyphenate}"
+                      format="i"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="division.toc"/>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+
+  <xsl:if test="$generate.division.figure.lot != '0' and .//figure">
+    <fo:page-sequence hyphenate="{$hyphenate}"
+                      format="i"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="list.of.titles">
+          <xsl:with-param name="titles" select="'figure'"/>
+          <xsl:with-param name="nodes" select=".//figure"/>
+        </xsl:call-template>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+
+  <xsl:if test="$generate.division.table.lot != '0' and .//table">
+    <fo:page-sequence hyphenate="{$hyphenate}"
+                      format="i"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="list.of.titles">
+          <xsl:with-param name="titles" select="'table'"/>
+          <xsl:with-param name="nodes" select=".//table"/>
+        </xsl:call-template>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+
+  <xsl:if test="$generate.division.example.lot != '0' and .//example">
+    <fo:page-sequence hyphenate="{$hyphenate}"
+                      format="i"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="list.of.titles">
+          <xsl:with-param name="titles" select="'example'"/>
+          <xsl:with-param name="nodes" select=".//example"/>
+        </xsl:call-template>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+
+  <xsl:if test="$generate.division.equation.lot != '0' and .//equation">
+    <fo:page-sequence hyphenate="{$hyphenate}"
+                      format="i"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="list.of.titles">
+          <xsl:with-param name="titles" select="'equation'"/>
+          <xsl:with-param name="nodes" select=".//equation"/>
+        </xsl:call-template>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+
+  <xsl:apply-templates select="dedication" mode="dedication"/>
+
+  <xsl:apply-templates select="$content"/>
+</xsl:template>
+
+<xsl:template match="book/bookinfo"></xsl:template>
+<xsl:template match="book/title"></xsl:template>
+<xsl:template match="book/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="part">
+  <xsl:if test="not(partintro)">
+    <xsl:variable name="id">
+      <xsl:call-template name="object.id"/>
+    </xsl:variable>
+    <xsl:variable name="master-name">
+      <xsl:call-template name="select.pagemaster"/>
+    </xsl:variable>
+
+    <fo:page-sequence id="{$id}"
+                      hyphenate="{$hyphenate}"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="part.titlepage"/>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="part" mode="part.titlepage.mode">
+  <!-- done this way to force the context node to be the part -->
+  <xsl:call-template name="part.titlepage"/>
+</xsl:template>
+
+<xsl:template match="part/docinfo"></xsl:template>
+<xsl:template match="part/title"></xsl:template>
+<xsl:template match="part/subtitle"></xsl:template>
+
+<xsl:template match="part/partintro">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="ancestor::part"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:apply-templates select=".." mode="part.titlepage.mode"/>
+      <xsl:if test="title">
+        <xsl:call-template name="partintro.titlepage"/>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="partintro/title"></xsl:template>
+<xsl:template match="partintro/subtitle"></xsl:template>
+<xsl:template match="partintro/titleabbrev"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="book" mode="division.number">
+  <xsl:number from="set" count="book" format="1."/>
+</xsl:template>
+
+<xsl:template match="part" mode="division.number">
+  <xsl:number from="book" count="part" format="I."/>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/docbook.xsl b/xsl/fo/docbook.xsl
new file mode 100644 (file)
index 0000000..27eaa17
--- /dev/null
@@ -0,0 +1,146 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<xsl:output method="xml"
+            indent="yes"/>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:include href="../VERSION"/>
+<xsl:include href="../lib/lib.xsl"/>
+<xsl:include href="../common/l10n.xsl"/>
+<xsl:include href="../common/common.xsl"/>
+<xsl:include href="../common/labels.xsl"/>
+<xsl:include href="../common/titles.xsl"/>
+<xsl:include href="../common/subtitles.xsl"/>
+<xsl:include href="../common/gentext.xsl"/>
+<xsl:include href="param.xsl"/>
+<xsl:include href="autotoc.xsl"/>
+<xsl:include href="lists.xsl"/>
+<xsl:include href="callout.xsl"/>
+<xsl:include href="verbatim.xsl"/>
+<xsl:include href="graphics.xsl"/>
+<xsl:include href="xref.xsl"/>
+<xsl:include href="formal.xsl"/>
+<xsl:include href="table.xsl"/>
+<xsl:include href="sections.xsl"/>
+<xsl:include href="inline.xsl"/>
+<xsl:include href="footnote.xsl"/>
+<xsl:include href="fo.xsl"/>
+<xsl:include href="info.xsl"/>
+<xsl:include href="keywords.xsl"/>
+<xsl:include href="division.xsl"/>
+<xsl:include href="index.xsl"/>
+<xsl:include href="toc.xsl"/>
+<xsl:include href="refentry.xsl"/>
+<xsl:include href="math.xsl"/>
+<xsl:include href="admon.xsl"/>
+<xsl:include href="component.xsl"/>
+<xsl:include href="biblio.xsl"/>
+<xsl:include href="glossary.xsl"/>
+<xsl:include href="block.xsl"/>
+<xsl:include href="qandaset.xsl"/>
+<xsl:include href="synop.xsl"/>
+<xsl:include href="titlepage.xsl"/>
+<xsl:include href="titlepage.templates.xsl"/>
+<xsl:include href="pagesetup.xsl"/>
+<xsl:include href="pi.xsl"/>
+
+<xsl:include href="fop.xsl"/>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*">
+  <fo:block color="red">
+    <xsl:text>&lt;</xsl:text>
+    <xsl:value-of select="name(.)"/>
+    <xsl:text>&gt;</xsl:text>
+    <xsl:apply-templates/> 
+    <xsl:text>&lt;/</xsl:text>
+    <xsl:value-of select="name(.)"/>
+    <xsl:text>&gt;</xsl:text>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="text()">
+  <xsl:value-of select="."/> 
+</xsl:template>
+
+<xsl:template match="/">
+  <xsl:message>
+    <xsl:text>Making </xsl:text>
+    <xsl:value-of select="$page.orientation"/>
+    <xsl:text> pages on </xsl:text>
+    <xsl:value-of select="$paper.type"/>
+    <xsl:text> paper (</xsl:text>
+    <xsl:value-of select="$page.width"/>
+    <xsl:text>x</xsl:text>
+    <xsl:value-of select="$page.height"/>
+    <xsl:text>)</xsl:text>
+  </xsl:message>
+
+  <xsl:variable name="document.element" select="*[1]"/>
+  <xsl:variable name="title">
+    <xsl:choose>
+      <xsl:when test="$document.element/title[1]">
+        <xsl:value-of select="$document.element/title[1]"/>
+      </xsl:when>
+      <xsl:otherwise>[could not find document title]</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="docinfo" 
+                select="*[1]/artheader
+                        |*[1]/articleinfo
+                        |*[1]/sectioninfo
+                        |*[1]/sect1info"/>
+
+  <fo:root font-family="Times Roman"
+           font-size="12pt"
+           text-align="justify">
+    <xsl:call-template name="setup.pagemasters"/>
+    <xsl:choose>
+      <xsl:when test="$rootid != ''">
+        <xsl:choose>
+          <xsl:when test="count(id($rootid)) = 0">
+            <xsl:message terminate="yes">
+              <xsl:text>ID '</xsl:text>
+              <xsl:value-of select="$rootid"/>
+              <xsl:text>' not found in document.</xsl:text>
+            </xsl:message>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:if test="$fop.extensions != 0">
+              <xsl:apply-templates select="id($rootid)" mode="outline"/>
+            </xsl:if>
+            <xsl:apply-templates select="id($rootid)"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:if test="$fop.extensions != 0">
+          <xsl:apply-templates mode="outline"/>
+        </xsl:if>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+
+  </fo:root>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/fo.xsl b/xsl/fo/fo.xsl
new file mode 100644 (file)
index 0000000..9caa429
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template name="dingbat">
+  <xsl:param name="dingbat">bullet</xsl:param>
+  <xsl:choose>
+    <xsl:when test="$dingbat='bullet'">o</xsl:when>
+    <xsl:when test="$dingbat='copyright'">&#x00A9;</xsl:when>
+    <xsl:when test="$dingbat='trademark'">&#x2122;</xsl:when>
+    <xsl:when test="$dingbat='trade'">&#x2122;</xsl:when>
+    <xsl:when test="$dingbat='registered'">&#x00AE;</xsl:when>
+    <xsl:when test="$dingbat='service'">(SM)</xsl:when>
+    <xsl:when test="$dingbat='ldquo'">"</xsl:when>
+    <xsl:when test="$dingbat='rdquo'">"</xsl:when>
+    <xsl:when test="$dingbat='lsquo'">'</xsl:when>
+    <xsl:when test="$dingbat='rsquo'">'</xsl:when>
+    <xsl:when test="$dingbat='em-dash'">--</xsl:when>
+    <xsl:when test="$dingbat='en-dash'">-</xsl:when>
+    <xsl:otherwise>o</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/footnote.xsl b/xsl/fo/footnote.xsl
new file mode 100644 (file)
index 0000000..014f34e
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="footnote">
+  <fo:footnote>
+    <fo:inline>
+      <xsl:text>[</xsl:text>
+      <xsl:apply-templates select="." mode="footnote.number"/>
+      <xsl:text>]</xsl:text>
+    </fo:inline>
+    <fo:footnote-body font-size="{$footnote.font.size}">
+      <xsl:apply-templates/>
+    </fo:footnote-body>
+  </fo:footnote>
+</xsl:template>
+
+<xsl:template match="footnoteref">
+  <xsl:variable name="footnote" select="id(@linkend)"/>
+  <fo:inline>
+    <xsl:text>[</xsl:text>
+    <xsl:apply-templates select="$footnote" mode="footnote.number"/>
+    <xsl:text>]</xsl:text>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="footnote" mode="footnote.number">
+  <xsl:number level="any" format="1"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="footnote/para[1]
+                     |footnote/simpara[1]
+                     |footnote/formalpara[1]"
+              priority="2">
+  <!-- this only works if the first thing in a footnote is a para, -->
+  <!-- which is ok, because it usually is. -->
+  <fo:block>
+    <xsl:text>[</xsl:text>
+    <xsl:apply-templates select="ancestor::footnote" mode="footnote.number"/>
+    <xsl:text>] </xsl:text>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/fop.xsl b/xsl/fo/fop.xsl
new file mode 100644 (file)
index 0000000..9fb64c5
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                xmlns:fox="http://xml.apache.org/fop/extensions"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+     (c) Stephane Bline Peregrine Systems 2001
+     Driver file to allow pdf bookmarking (based on fop implementation).
+     ******************************************************************** -->
+
+<xsl:template match="set" mode="outline">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fox:outline internal-destination="{$id}">
+    <fox:label>
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:apply-templates select="." mode="title.markup"/>
+    </fox:label>
+
+  <xsl:if test="book">
+      <xsl:apply-templates select="book"
+                           mode="outline"/>
+  </xsl:if>
+  </fox:outline>
+</xsl:template>
+
+<xsl:template match="book" mode="outline">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fox:outline internal-destination="{$id}">
+    <fox:label>
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:apply-templates select="." mode="title.markup"/>
+    </fox:label>
+
+  <xsl:if test="part|preface|chapter|appendix">
+      <xsl:apply-templates select="part|preface|chapter|appendix"
+                           mode="outline"/>
+  </xsl:if>
+  </fox:outline>
+</xsl:template>
+
+
+<xsl:template match="part" mode="outline">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fox:outline internal-destination="{$id}">
+    <fox:label>
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:apply-templates select="." mode="title.markup"/>
+    </fox:label>
+
+  <xsl:if test="chapter|appendix|preface|reference">
+      <xsl:apply-templates select="chapter|appendix|preface|reference"
+                           mode="outline"/>
+  </xsl:if>
+  </fox:outline>
+</xsl:template>
+
+<xsl:template match="preface|chapter|appendix"
+              mode="outline">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fox:outline internal-destination="{$id}">
+    <fox:label>
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:apply-templates select="." mode="title.markup"/>
+    </fox:label>
+
+  <xsl:if test="section|sect1">
+      <xsl:apply-templates select="section|sect1"
+                           mode="outline"/>
+  </xsl:if>
+  </fox:outline>
+</xsl:template>
+
+<xsl:template match="section|sect1|sect2|sect3|sect4|sect5"
+              mode="outline">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fox:outline internal-destination="{$id}">
+    <fox:label>
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:apply-templates select="." mode="title.markup"/>
+    </fox:label>
+
+  <xsl:if test="section|sect2|sect3|sect4|sect5">
+      <xsl:apply-templates select="section|sect2|sect3|sect4|sect5"
+                           mode="outline"/>
+  </xsl:if>
+  </fox:outline>
+</xsl:template>
+
+<xsl:template match="bibliography|glossary|index"
+              mode="outline">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fox:outline internal-destination="{$id}">
+    <fox:label>
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:apply-templates select="." mode="title.markup"/>
+    </fox:label>
+  </fox:outline>
+</xsl:template>
+
+<xsl:template match="title" mode="outline">
+  <xsl:apply-templates/>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/formal.xsl b/xsl/fo/formal.xsl
new file mode 100644 (file)
index 0000000..129ce9e
--- /dev/null
@@ -0,0 +1,133 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template name="formal.object">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}"
+            space-before.minimum="1em"
+            space-before.optimum="1.5em"
+            space-before.maximum="2em"
+            space-after.minimum="1em"
+            space-after.optimum="1.5em"
+            space-after.maximum="2em">
+            keep-with-previous.within-column="always">
+    <xsl:call-template name="formal.object.heading">
+       <xsl:with-param name="title">
+         <xsl:apply-templates select="." mode="title.markup"/>
+       </xsl:with-param>
+    </xsl:call-template>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template name="formal.object.heading">
+  <xsl:param name="title"></xsl:param>
+  <fo:block xsl:use-attribute-sets="formal.title.properties">
+    <xsl:copy-of select="$title"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template name="informal.object">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template name="semiformal.object">
+  <xsl:choose>
+    <xsl:when test="./title">
+      <xsl:call-template name="formal.object"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="informal.object"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="figure|example">
+  <xsl:call-template name="formal.object"/>
+</xsl:template>
+
+<xsl:template match="table">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="prop-columns"
+    select=".//colspec[contains(@colwidth, '*')]"/>
+
+  <fo:table-and-caption id="{$id}"
+      keep-together.within-column="always"
+      space-before.minimum="0.8em"
+      space-before.optimum="1em"
+      space-before.maximum="1.2em"
+      space-after.minimum="0.8em"
+      space-after.optimum="1em"
+      space-after.maximum="1.2em">
+    <fo:table-caption>
+      <fo:block font-weight='bold'
+          space-after.minimum="0.2em"
+          space-after.optimum="0.5em"
+          space-after.maximum="0.8em"
+          keep-with-next.within-column="always"
+          hyphenate="false">
+         <xsl:apply-templates select="." mode="title.markup"/>
+      </fo:block>
+    </fo:table-caption>
+    <fo:table>
+      <xsl:if test="count($prop-columns) != 0">
+       <xsl:attribute name="table-layout">fixed</xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </fo:table>
+  </fo:table-and-caption>
+</xsl:template>
+
+<xsl:template match="equation">
+  <xsl:call-template name="semiformal.object"/>
+</xsl:template>
+
+<xsl:template match="figure/title"></xsl:template>
+<xsl:template match="table/title"></xsl:template>
+<xsl:template match="example/title"></xsl:template>
+<xsl:template match="equation/title"></xsl:template>
+
+<xsl:template match="informalfigure">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+<xsl:template match="informalexample">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+<xsl:template match="informaltable">
+  <xsl:variable name="prop-columns"
+    select=".//colspec[contains(@colwidth, '*')]"/>
+
+  <fo:table>
+    <xsl:if test="count($prop-columns) != 0">
+      <xsl:attribute name="table-layout">fixed</xsl:attribute>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </fo:table>
+</xsl:template>
+
+<xsl:template match="informalequation">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/glossary.xsl b/xsl/fo/glossary.xsl
new file mode 100644 (file)
index 0000000..bcf35f7
--- /dev/null
@@ -0,0 +1,292 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:variable name="glossterm-width">2in</xsl:variable>
+<xsl:variable name="glossterm-sep">0.25in</xsl:variable>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="glossary">
+  <xsl:variable name="divs" select="glossdiv"/>
+  <xsl:variable name="entries" select="glossentry"/>
+  <xsl:variable name="preamble"
+                select="*[not(self::title
+                            or self::subtitle
+                            or self::glossdiv
+                            or self::glossentry)]"/>
+
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="component.separator"/>
+
+    <xsl:call-template name="glossary.titlepage"/>
+
+    <xsl:if test="$preamble">
+      <xsl:apply-templates select="$preamble"/>
+    </xsl:if>
+
+    <xsl:if test="$divs">
+      <xsl:apply-templates select="$divs"/>
+    </xsl:if>
+
+    <xsl:if test="$entries">
+      <fo:list-block provisional-distance-between-starts="{$glossterm-width}"
+                     provisional-label-separation="{$glossterm-sep}"
+                     xsl:use-attribute-sets="normal.para.spacing">
+        <xsl:apply-templates select="$entries"/>
+      </fo:list-block>
+    </xsl:if>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="book/glossary">
+  <xsl:variable name="divs" select="glossdiv"/>
+  <xsl:variable name="entries" select="glossentry"/>
+  <xsl:variable name="preamble"
+                select="*[not(self::title
+                            or self::subtitle
+                            or self::glossdiv
+                            or self::glossentry)]"/>
+
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="glossary.titlepage"/>
+
+      <xsl:if test="$preamble">
+        <xsl:apply-templates select="$preamble"/>
+      </xsl:if>
+
+      <xsl:if test="$divs">
+        <xsl:apply-templates select="$divs"/>
+      </xsl:if>
+
+      <xsl:if test="$entries">
+        <fo:list-block provisional-distance-between-starts="{$glossterm-width}"
+                       provisional-label-separation="{$glossterm-sep}"
+                       xsl:use-attribute-sets="normal.para.spacing">
+          <xsl:apply-templates select="$entries"/>
+        </fo:list-block>
+      </xsl:if>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="glossary/glossaryinfo"></xsl:template>
+<xsl:template match="glossary/title"></xsl:template>
+<xsl:template match="glossary/subtitle"></xsl:template>
+<xsl:template match="glossary/titleabbrev"></xsl:template>
+
+<xsl:template match="glossary/title" mode="component.title.mode">
+  <fo:block font-size="18pt"
+            font-weight="bold"
+            keep-with-next.within-column="always"
+            hyphenate="false">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="glossary/subtitle" mode="component.title.mode">
+  <fo:block font-size="16pt"
+            font-weight="bold"
+            font-style="italic"
+            keep-with-next.within-column="always"
+            hyphenate="false">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="glosslist">
+  <fo:list-block provisional-distance-between-starts="{$glossterm-width}"
+                 provisional-label-separation="{$glossterm-sep}"
+                 xsl:use-attribute-sets="normal.para.spacing">
+      <xsl:apply-templates/>
+    </fo:list-block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="glossdiv">
+  <xsl:variable name="entries" select="glossentry"/>
+  <xsl:variable name="preamble"
+                select="*[not(self::title
+                            or self::subtitle
+                            or self::glossentry)]"/>
+
+  <xsl:apply-templates select="title|subtitle"/>
+  <xsl:apply-templates select="$preamble"/>
+  <fo:list-block provisional-distance-between-starts="{$glossterm-width}"
+                 provisional-label-separation="{$glossterm-sep}"
+                 xsl:use-attribute-sets="normal.para.spacing">
+    <xsl:apply-templates select="$entries"/>
+  </fo:list-block>
+</xsl:template>
+
+<xsl:template match="glossdiv/title">
+  <fo:block font-size="16pt" font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<!--
+GlossEntry ::=
+  GlossTerm, Acronym?, Abbrev?,
+  (IndexTerm)*,
+  RevHistory?,
+  (GlossSee | GlossDef+)
+-->
+
+<xsl:template match="glossentry">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:list-item id="{$id}"
+                xsl:use-attribute-sets="normal.para.spacing">
+    <xsl:apply-templates/>
+  </fo:list-item>
+</xsl:template>
+
+<xsl:template match="glossentry/glossterm">
+  <fo:list-item-label end-indent="label-end()">
+    <fo:block>
+      <xsl:apply-templates/>
+    </fo:block>
+  </fo:list-item-label>
+</xsl:template>
+
+<xsl:template match="glossentry/acronym">
+</xsl:template>
+
+<xsl:template match="glossentry/abbrev">
+</xsl:template>
+
+<xsl:template match="glossentry/revhistory">
+</xsl:template>
+
+<xsl:template match="glossentry/glosssee">
+  <xsl:variable name="otherterm" select="@otherterm"/>
+  <xsl:variable name="targets" select="//node()[@id=$otherterm]"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+  <fo:list-item-body start-indent="body-start()">
+    <fo:block>
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'glossary'"/>
+        <xsl:with-param name="name" select="'see'"/>
+      </xsl:call-template>
+      <xsl:choose>
+        <xsl:when test="@otherterm">
+          <xsl:apply-templates select="$target" mode="xref"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates/>
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:text>.</xsl:text>
+    </fo:block>
+  </fo:list-item-body>
+</xsl:template>
+
+<xsl:template match="glossentry/glossdef">
+  <fo:list-item-body start-indent="body-start()">
+    <xsl:apply-templates/>
+  </fo:list-item-body>
+</xsl:template>
+
+<xsl:template match="glossentry/glossdef/para[1]">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="glossseealso">
+  <xsl:variable name="otherterm" select="@otherterm"/>
+  <xsl:variable name="targets" select="//node()[@id=$otherterm]"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+  <fo:block>
+    <xsl:call-template name="gentext.template">
+      <xsl:with-param name="context" select="'glossary'"/>
+      <xsl:with-param name="name" select="'seealso'"/>
+    </xsl:call-template>
+    <xsl:choose>
+      <xsl:when test="@otherterm">
+        <xsl:apply-templates select="$target" mode="xref"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+    <xsl:text>.</xsl:text>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="glossentry" mode="xref">
+  <xsl:apply-templates select="./glossterm[1]" mode="xref"/>
+</xsl:template>
+
+<xsl:template match="glossterm" mode="xref">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="parent::glossentry"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <fo:basic-link internal-destination="{$id}"
+                 xsl:use-attribute-sets="xref.properties">
+    <xsl:apply-templates/>
+    <xsl:call-template name="insert.page.citation">
+      <xsl:with-param name="id" select="$id"/>
+    </xsl:call-template>
+  </fo:basic-link>
+</xsl:template>
+
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/graphics.xsl b/xsl/fo/graphics.xsl
new file mode 100644 (file)
index 0000000..a19ef6d
--- /dev/null
@@ -0,0 +1,273 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                xmlns:xlink="http://www.w3.org/1999/xlink"
+                xmlns:stext="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.TextFactory"
+                xmlns:xtext="com.nwalsh.xalan.Text"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="xlink stext xtext lxslt"
+                extension-element-prefixes="stext xtext"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     Contributors:
+     Colin Paul Adams, <colin@colina.demon.co.uk>
+
+     ******************************************************************** -->
+
+<xsl:template match="screenshot">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="screeninfo">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process.image">
+  <!-- When this template is called, the current node should be  -->
+  <!-- a graphic, inlinegraphic, imagedata, or videodata. All    -->
+  <!-- those elements have the same set of attributes, so we can -->
+  <!-- handle them all in one place.                             -->
+  <xsl:variable name="input-filename">
+    <xsl:choose>
+      <xsl:when test="@entityref">
+        <xsl:value-of select="unparsed-entity-uri(@entityref)"/>
+      </xsl:when>
+      <xsl:when test="@fileref">
+        <xsl:text>file:</xsl:text>
+        <xsl:value-of select="@fileref"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:message>
+          <xsl:text>Expected @entityref or @fileref on </xsl:text>
+          <xsl:value-of select="name(.)"/>
+        </xsl:message>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="fileext">
+    <xsl:call-template name="filename-extension">
+      <xsl:with-param name="filename" select="$input-filename"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:variable name="filename">
+    <xsl:choose>
+      <xsl:when test="$fileext != ''">
+        <xsl:value-of select="$input-filename"/>
+      </xsl:when>
+      <xsl:when test="$graphic.default.extension != ''">
+        <xsl:value-of select="$input-filename"/>
+        <xsl:text>.</xsl:text>
+        <xsl:value-of select="$graphic.default.extension"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$input-filename"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="scale">
+    <xsl:choose>
+      <xsl:when test="@scale"><xsl:value-of select="@scale"/>%</xsl:when>
+      <xsl:otherwise>auto</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="width">
+    <xsl:choose>
+      <xsl:when test="@width">
+        <xsl:call-template name="length-spec">
+          <xsl:with-param name="length" select="@width"/>
+          <xsl:with-param name="default.units" select="$default.units"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>auto</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="height">
+    <xsl:choose>
+      <xsl:when test="@depth">
+        <xsl:call-template name="length-spec">
+          <xsl:with-param name="length" select="@depth"/>
+          <xsl:with-param name="default.units" select="$default.units"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>auto</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!-- Scaling seems to require calculating an absolute width and height
+       from a scale factor and the intrinsic width and height (possibly
+       with contributions from the specified width and height). I'm not
+       sure how to specify that... -->
+
+  <fo:external-graphic src="url({$filename})"
+    content-width="{$width}" content-height="{$height}"
+    width="auto" height="auto"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="graphic">
+  <fo:block>
+    <xsl:call-template name="process.image"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="inlinegraphic">
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+  <xsl:variable name="filename">
+    <xsl:choose>
+      <xsl:when test="@entityref">
+        <xsl:value-of select="unparsed-entity-uri(@entityref)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="@fileref"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="@format='linespecific'">
+      <xsl:choose>
+        <xsl:when test="$use.extensions != '0'
+                        and $textinsert.extension != '0'">
+          <xsl:choose>
+            <xsl:when test="contains($vendor, 'SAXON')">
+              <stext:insertfile href="{$filename}"/>
+            </xsl:when>
+            <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+              <xtext:insertfile href="{$filename}"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:message terminate="yes">
+                <xsl:text>Don't know how to insert files with </xsl:text>
+                <xsl:value-of select="$vendor"/>
+              </xsl:message>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise>
+          <a xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"
+             href="{$filename}"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="process.image"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="mediaobject">
+  <fo:block>
+    <xsl:call-template name="select.mediaobject"/>
+    <xsl:apply-templates select="caption"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="inlinemediaobject">
+  <xsl:call-template name="select.mediaobject"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="imageobjectco">
+  <xsl:apply-templates select="imageobject"/>
+  <xsl:apply-templates select="calloutlist"/>
+</xsl:template>
+
+<xsl:template match="imageobject">
+  <xsl:apply-templates select="imagedata"/>
+</xsl:template>
+
+<xsl:template match="imagedata">
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+  <xsl:variable name="filename">
+    <xsl:call-template name="mediaobject.filename">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="@format='linespecific'">
+      <xsl:choose>
+        <xsl:when test="$use.extensions != '0'
+                        and $textinsert.extension != '0'">
+          <xsl:choose>
+            <xsl:when test="contains($vendor, 'SAXON')">
+              <stext:insertfile href="{$filename}"/>
+            </xsl:when>
+            <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+              <xtext:insertfile href="{$filename}"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:message terminate="yes">
+                <xsl:text>Don't know how to insert files with </xsl:text>
+                <xsl:value-of select="$vendor"/>
+              </xsl:message>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise>
+          <a xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"
+             href="{$filename}"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="process.image"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="videoobject">
+  <xsl:apply-templates select="videodata"/>
+</xsl:template>
+
+<xsl:template match="videodata">
+  <xsl:call-template name="process.image"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="audioobject">
+  <xsl:apply-templates select="audiodata"/>
+</xsl:template>
+
+<xsl:template match="audiodata">
+  <xsl:call-template name="process.image"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="textobject">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="caption">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/index.xsl b/xsl/fo/index.xsl
new file mode 100644 (file)
index 0000000..f609571
--- /dev/null
@@ -0,0 +1,119 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="index">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="component.separator"/>
+    <xsl:call-template name="index.titlepage"/>
+    <xsl:apply-templates/>
+    <xsl:if test="count(indexentry) = 0 and count(indexdiv) = 0">
+      <xsl:call-template name="generate-index"/>
+    </xsl:if>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="book/index">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="index.titlepage"/>
+      <xsl:apply-templates/>
+      <xsl:if test="count(indexentry) = 0 and count(indexdiv) = 0">
+        <xsl:call-template name="generate-index"/>
+      </xsl:if>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="index/title"></xsl:template>
+<xsl:template match="index/subtitle"></xsl:template>
+<xsl:template match="index/titleabbrev"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="indexdiv">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="indexdiv/title">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <fo:block font-size="16pt" font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="indexterm">
+  <fo:wrapper>
+    <xsl:attribute name="id">
+      <xsl:call-template name="object.id"/>
+    </xsl:attribute>
+    <xsl:comment>
+      <xsl:value-of select="primary"/>
+      <xsl:if test="secondary">
+        <xsl:text>, </xsl:text>
+        <xsl:value-of select="secondary"/>
+      </xsl:if>
+      <xsl:if test="tertiary">
+        <xsl:text>, </xsl:text>
+        <xsl:value-of select="tertiary"/>
+      </xsl:if>
+    </xsl:comment>
+  </fo:wrapper>
+</xsl:template>
+
+<xsl:template match="indexentry">
+</xsl:template>
+
+<xsl:template name="generate-index">
+  <!-- nop: use autoidx.xsl to get automatic indexing -->
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/info.xsl b/xsl/fo/info.xsl
new file mode 100644 (file)
index 0000000..bca6ce0
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- These templates define the "default behavior" for info
+     elements.  Even if you don't process the *info wrappers,
+     some of these elements are needed because the elements are
+     processed from named templates that are called with modes.
+     Since modes aren't sticky, these rules apply. 
+     (TODO: clarify this comment) -->
+
+<!-- ==================================================================== -->
+<!-- called from named templates in a given mode -->
+
+<xsl:template match="corpauthor">
+  <fo:inline>
+    <xsl:apply-templates/>
+  </fo:inline>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/inline.xsl b/xsl/fo/inline.xsl
new file mode 100644 (file)
index 0000000..939ab8d
--- /dev/null
@@ -0,0 +1,576 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template name="inline.charseq">
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+  <xsl:copy-of select="$content"/>
+</xsl:template>
+
+<xsl:template name="inline.monoseq">
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+  <fo:inline font-family="monospace">
+    <xsl:copy-of select="$content"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template name="inline.boldseq">
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+  <fo:inline font-weight="bold">
+    <xsl:copy-of select="$content"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template name="inline.italicseq">
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+  <fo:inline font-style="italic">
+    <xsl:copy-of select="$content"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template name="inline.boldmonoseq">
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+  <fo:inline font-weight="bold" font-family="monospace">
+    <xsl:copy-of select="$content"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template name="inline.italicmonoseq">
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+  <fo:inline font-style="italic" font-family="monospace">
+    <xsl:copy-of select="$content"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template name="inline.superscriptseq">
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+  <fo:inline vertical-align="super">
+    <xsl:copy-of select="$content"/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template name="inline.subscriptseq">
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+  <fo:inline vertical-align="sub">
+    <xsl:copy-of select="$content"/>
+  </fo:inline>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="accel">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="action">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="application">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="classname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="exceptionname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="interfacename">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="methodname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="command">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+<xsl:template match="computeroutput">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="database">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="errorcode">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="errorname">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="errortype">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="envar">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="filename">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="function">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="guibutton">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guiicon">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guilabel">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guimenu">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guimenuitem">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guisubmenu">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="hardware">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="interface">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="interfacedefinition">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="keycap">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+<xsl:template match="keycode">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="keysym">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="literal">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="medialabel">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="shortcut">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+<xsl:template match="mousebutton">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="option">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="parameter">
+  <xsl:call-template name="inline.italicmonoseq"/>
+</xsl:template>
+
+<xsl:template match="property">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="prompt">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="replaceable">
+  <xsl:call-template name="inline.italicmonoseq"/>
+</xsl:template>
+
+<xsl:template match="returnvalue">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="structfield">
+  <xsl:call-template name="inline.italicmonoseq"/>
+</xsl:template>
+
+<xsl:template match="structname">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="symbol">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="systemitem">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="token">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="type">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="userinput">
+  <xsl:call-template name="inline.boldmonoseq"/>
+</xsl:template>
+
+<xsl:template match="abbrev">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="acronym">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="citerefentry">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="citetitle">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="emphasis">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="foreignphrase">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="markup">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="phrase">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="quote">
+  <xsl:variable name="depth">
+    <xsl:call-template name="dot.count">
+      <xsl:with-param name="string"><xsl:number level="multiple"/></xsl:with-param>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:choose>
+    <xsl:when test="$depth mod 2 = 0">
+      <xsl:call-template name="gentext.startquote"/>
+      <xsl:call-template name="inline.charseq"/>
+      <xsl:call-template name="gentext.endquote"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext.nestedstartquote"/>
+      <xsl:call-template name="inline.charseq"/>
+      <xsl:call-template name="gentext.nestedendquote"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="varname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="wordasword">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="lineannotation">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="superscript">
+  <xsl:call-template name="inline.superscriptseq"/>
+</xsl:template>
+
+<xsl:template match="subscript">
+  <xsl:call-template name="inline.subscriptseq"/>
+</xsl:template>
+
+<xsl:template match="trademark">
+  <xsl:call-template name="inline.charseq"/>
+  <xsl:if test="@class">
+    <xsl:call-template name="dingbat">
+      <xsl:with-param name="dingbat" select="@class"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="firstterm">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="glossterm">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="sgmltag">
+  <xsl:variable name="class">
+    <xsl:choose>
+      <xsl:when test="@class">
+        <xsl:value-of select="@class"/>
+      </xsl:when>
+      <xsl:otherwise>element</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$class='attribute'">
+      <xsl:call-template name="inline.charseq"/>
+    </xsl:when>
+    <xsl:when test="$class='attvalue'">
+      <xsl:call-template name="inline.monoseq"/>
+    </xsl:when>
+    <xsl:when test="$class='element'">
+      <xsl:call-template name="inline.monoseq"/>
+    </xsl:when>
+    <xsl:when test="$class='endtag'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;/</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='genentity'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&amp;</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='numcharref'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&amp;#</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='paramentity'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>%</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='pi'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;?</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='starttag'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='sgmlcomment'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;!--</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>--&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="inline.charseq"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="email">
+  <xsl:call-template name="inline.monoseq">
+    <xsl:with-param name="content">
+      <xsl:text>&lt;</xsl:text>
+      <xsl:apply-templates/>
+      <xsl:text>&gt;</xsl:text>
+    </xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="keycombo">
+  <xsl:variable name="action" select="@action"/>
+  <xsl:variable name="joinchar">
+    <xsl:choose>
+      <xsl:when test="$action='seq'"><xsl:text> </xsl:text></xsl:when>
+      <xsl:when test="$action='simul'">+</xsl:when>
+      <xsl:when test="$action='press'">-</xsl:when>
+      <xsl:when test="$action='click'">-</xsl:when>
+      <xsl:when test="$action='double-click'">-</xsl:when>
+      <xsl:when test="$action='other'"></xsl:when>
+      <xsl:otherwise>-</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:for-each select="./*">
+    <xsl:if test="position()>1"><xsl:value-of select="$joinchar"/></xsl:if>
+    <xsl:apply-templates/>
+  </xsl:for-each>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="menuchoice">
+  <xsl:variable name="shortcut" select="./shortcut"/>
+  <xsl:call-template name="process.menuchoice"/>
+  <xsl:if test="$shortcut">
+    <xsl:text> (</xsl:text>
+    <xsl:apply-templates select="$shortcut"/>
+    <xsl:text>)</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="process.menuchoice">
+  <xsl:param name="nodelist" select="guibutton|guiicon|guilabel|guimenu|guimenuitem|guisubmenu|interface"/><!-- not(shortcut) -->
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($nodelist)"></xsl:when>
+    <xsl:when test="$count=1">
+      <xsl:apply-templates select="$nodelist[$count=position()]"/>
+      <xsl:call-template name="process.menuchoice">
+        <xsl:with-param name="nodelist" select="$nodelist"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="node" select="$nodelist[$count=position()]"/>
+      <xsl:choose>
+        <xsl:when test="name($node)='guimenuitem'
+                        or name($node)='guisubmenu'">
+          <xsl:text>-&gt;</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>+</xsl:otherwise>
+      </xsl:choose>
+      <xsl:apply-templates select="$node"/>
+      <xsl:call-template name="process.menuchoice">
+        <xsl:with-param name="nodelist" select="$nodelist"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="optional">
+  <xsl:value-of select="$arg.choice.opt.open.str"/>
+  <xsl:call-template name="inline.charseq"/>
+  <xsl:value-of select="$arg.choice.opt.close.str"/>
+</xsl:template>
+
+<xsl:template match="citation">
+  <!-- todo: biblio-citation-check -->
+  <xsl:text>[</xsl:text>
+  <xsl:call-template name="inline.charseq"/>
+  <xsl:text>]</xsl:text>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="comment|remark">
+  <xsl:if test="$show.comments != 0">
+    <fo:inline font-style="italic">
+      <xsl:call-template name="inline.charseq"/>
+    </fo:inline>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="productname">
+  <xsl:call-template name="inline.charseq"/>
+  <xsl:if test="@class">
+    <xsl:call-template name="dingbat">
+      <xsl:with-param name="dingbat" select="@class"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="productnumber">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="pob|street|city|state|postcode|country|otheraddr">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="phone|fax">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<!-- in Addresses, for example -->
+<xsl:template match="honorific|firstname|surname|lineage|othername">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/keywords.xsl b/xsl/fo/keywords.xsl
new file mode 100644 (file)
index 0000000..2303b35
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="keywordset"></xsl:template>
+<xsl:template match="subjectset"></xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/lists.xsl b/xsl/fo/lists.xsl
new file mode 100644 (file)
index 0000000..4889c72
--- /dev/null
@@ -0,0 +1,536 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="itemizedlist">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <xsl:if test="title">
+    <xsl:apply-templates select="title" mode="list.title.mode"/>
+  </xsl:if>
+
+  <fo:list-block id="{$id}" xsl:use-attribute-sets="list.block.spacing"
+                 provisional-distance-between-starts="1.5em"
+                 provisional-label-separation="0.2em">
+    <xsl:apply-templates/>
+  </fo:list-block>
+</xsl:template>
+
+<xsl:template match="itemizedlist/title|orderedlist/title|variablelist/title">
+  <!--nop-->
+</xsl:template>
+
+<xsl:template match="itemizedlist/listitem">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
+    <fo:list-item-label end-indent="label-end()">
+      <fo:block>
+        <xsl:text>&#x2022;</xsl:text>
+      </fo:block>
+    </fo:list-item-label>
+    <fo:list-item-body start-indent="body-start()">
+      <xsl:apply-templates/>
+    </fo:list-item-body>
+  </fo:list-item>
+</xsl:template>
+
+<xsl:template match="orderedlist">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <xsl:if test="title">
+    <xsl:apply-templates select="title" mode="list.title.mode"/>
+  </xsl:if>
+
+  <fo:list-block id="{$id}" xsl:use-attribute-sets="list.block.spacing"
+                 provisional-distance-between-starts="2em"
+                 provisional-label-separation="0.2em">
+    <xsl:apply-templates/>
+  </fo:list-block>
+</xsl:template>
+
+<xsl:template match="orderedlist/listitem">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
+    <fo:list-item-label end-indent="label-end()">
+      <fo:block>
+        <xsl:number count="listitem" format="1."/>
+      </fo:block>
+    </fo:list-item-label>
+    <fo:list-item-body start-indent="body-start()">
+      <xsl:apply-templates/>
+    </fo:list-item-body>
+  </fo:list-item>
+</xsl:template>
+
+<xsl:template match="listitem/para[1]
+                     |listitem/simpara[1]
+                     |listitem/formalpara[1]
+                     |callout/para[1]
+                     |callout/simpara[1]
+                     |callout/formalpara[1]"
+              priority="2">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="variablelist">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <xsl:variable name="termlength">
+    <xsl:choose>
+      <!-- FIXME: handle @termlength="1in" -->
+      <xsl:when test="@termlength">
+        <xsl:value-of select="@termlength"/>
+        <xsl:text>em</xsl:text>
+      </xsl:when>
+      <!-- FIXME: calculate some reasonable width -->
+      <xsl:otherwise>
+        <xsl:text>1in</xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:if test="title">
+    <xsl:apply-templates select="title" mode="list.title.mode"/>
+  </xsl:if>
+
+  <fo:list-block id="{$id}"
+                 provisional-distance-between-starts="{$termlength}"
+                 provisional-label-separation="0.25in"
+                 xsl:use-attribute-sets="list.block.spacing">
+    <xsl:apply-templates/>
+  </fo:list-block>
+</xsl:template>
+
+<xsl:template match="varlistentry">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
+    <fo:list-item-label end-indent="label-end()">
+      <fo:block>
+        <xsl:apply-templates select="term"/>
+      </fo:block>
+    </fo:list-item-label>
+    <fo:list-item-body start-indent="body-start()">
+      <xsl:apply-templates select="listitem"/>
+    </fo:list-item-body>
+  </fo:list-item>
+</xsl:template>
+
+<xsl:template match="varlistentry/term">
+  <fo:inline><xsl:apply-templates/>, </fo:inline>
+</xsl:template>
+
+<xsl:template match="varlistentry/term[position()=last()]" priority="2">
+  <fo:inline><xsl:apply-templates/></fo:inline>
+</xsl:template>
+
+<xsl:template match="varlistentry/listitem">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="title" mode="list.title.mode">
+  <fo:block font-size="12pt" font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="simplelist">
+  <!-- with no type specified, the default is 'vert' -->
+  <fo:table>
+    <fo:table-body>
+      <xsl:call-template name="simplelist.vert">
+       <xsl:with-param name="cols">
+         <xsl:choose>
+           <xsl:when test="@columns">
+             <xsl:value-of select="@columns"/>
+           </xsl:when>
+           <xsl:otherwise>1</xsl:otherwise>
+         </xsl:choose>
+       </xsl:with-param>
+      </xsl:call-template>
+    </fo:table-body>
+  </fo:table>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='inline']">
+  <fo:inline><xsl:apply-templates/></fo:inline>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='horiz']">
+  <fo:table>
+    <fo:table-body>
+      <xsl:call-template name="simplelist.horiz">
+       <xsl:with-param name="cols">
+         <xsl:choose>
+           <xsl:when test="@columns">
+             <xsl:value-of select="@columns"/>
+           </xsl:when>
+           <xsl:otherwise>1</xsl:otherwise>
+         </xsl:choose>
+       </xsl:with-param>
+      </xsl:call-template>
+    </fo:table-body>
+  </fo:table>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='vert']">
+  <fo:table>
+    <fo:table-body>
+      <xsl:call-template name="simplelist.vert">
+       <xsl:with-param name="cols">
+         <xsl:choose>
+           <xsl:when test="@columns">
+             <xsl:value-of select="@columns"/>
+           </xsl:when>
+           <xsl:otherwise>1</xsl:otherwise>
+         </xsl:choose>
+       </xsl:with-param>
+      </xsl:call-template>
+    </fo:table-body>
+  </fo:table>
+</xsl:template>
+
+<xsl:template name="simplelist.horiz">
+  <xsl:param name="cols">1</xsl:param>
+  <xsl:param name="cell">1</xsl:param>
+  <xsl:param name="members" select="./member"/>
+
+  <xsl:if test="$cell &lt;= count($members)">
+    <fo:table-row>
+      <xsl:call-template name="simplelist.horiz.row">
+        <xsl:with-param name="cols" select="$cols"/>
+        <xsl:with-param name="cell" select="$cell"/>
+        <xsl:with-param name="members" select="$members"/>
+      </xsl:call-template>
+   </fo:table-row>
+    <xsl:call-template name="simplelist.horiz">
+      <xsl:with-param name="cols" select="$cols"/>
+      <xsl:with-param name="cell" select="$cell + $cols"/>
+      <xsl:with-param name="members" select="$members"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="simplelist.horiz.row">
+  <xsl:param name="cols">1</xsl:param>
+  <xsl:param name="cell">1</xsl:param>
+  <xsl:param name="members" select="./member"/>
+  <xsl:param name="curcol">1</xsl:param>
+
+  <xsl:if test="$curcol &lt;= $cols">
+    <fo:table-cell>
+      <fo:block>
+        <xsl:if test="$members[position()=$cell]">
+          <xsl:apply-templates select="$members[position()=$cell]"/>
+        </xsl:if>
+      </fo:block>
+    </fo:table-cell>
+    <xsl:call-template name="simplelist.horiz.row">
+      <xsl:with-param name="cols" select="$cols"/>
+      <xsl:with-param name="cell" select="$cell+1"/>
+      <xsl:with-param name="members" select="$members"/>
+      <xsl:with-param name="curcol" select="$curcol+1"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="simplelist.vert">
+  <xsl:param name="cols">1</xsl:param>
+  <xsl:param name="cell">1</xsl:param>
+  <xsl:param name="members" select="./member"/>
+  <xsl:param name="rows"
+             select="floor((count($members)+$cols - 1) div $cols)"/>
+
+  <xsl:if test="$cell &lt;= $rows">
+    <fo:table-row>
+      <xsl:call-template name="simplelist.vert.row">
+        <xsl:with-param name="cols" select="$cols"/>
+        <xsl:with-param name="rows" select="$rows"/>
+        <xsl:with-param name="cell" select="$cell"/>
+        <xsl:with-param name="members" select="$members"/>
+      </xsl:call-template>
+   </fo:table-row>
+    <xsl:call-template name="simplelist.vert">
+      <xsl:with-param name="cols" select="$cols"/>
+      <xsl:with-param name="cell" select="$cell+1"/>
+      <xsl:with-param name="members" select="$members"/>
+      <xsl:with-param name="rows" select="$rows"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="simplelist.vert.row">
+  <xsl:param name="cols">1</xsl:param>
+  <xsl:param name="rows">1</xsl:param>
+  <xsl:param name="cell">1</xsl:param>
+  <xsl:param name="members" select="./member"/>
+  <xsl:param name="curcol">1</xsl:param>
+
+  <xsl:if test="$curcol &lt;= $cols">
+    <fo:table-cell>
+      <fo:block>
+        <xsl:if test="$members[position()=$cell]">
+          <xsl:apply-templates select="$members[position()=$cell]"/>
+        </xsl:if>
+      </fo:block>
+    </fo:table-cell>
+    <xsl:call-template name="simplelist.vert.row">
+      <xsl:with-param name="cols" select="$cols"/>
+      <xsl:with-param name="rows" select="$rows"/>
+      <xsl:with-param name="cell" select="$cell+$rows"/>
+      <xsl:with-param name="members" select="$members"/>
+      <xsl:with-param name="curcol" select="$curcol+1"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="member">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='inline']/member">
+  <xsl:apply-templates/>
+  <xsl:text>, </xsl:text>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='inline']/member[position()=last()]"
+              priority="2">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="procedure">
+  <xsl:variable name="title" select="title"/>
+  <xsl:variable name="preamble"
+                select="*[not(self::step or self::title)]"/>
+  <xsl:variable name="steps" select="step"/>
+
+  <fo:block space-before.optimum="1em"
+            space-before.minimum="0.8em"
+            space-before.maximum="1.2em">
+    <xsl:if test="./title">
+      <fo:block font-weight="bold">
+        <xsl:apply-templates select="./title" mode="procedure.title.mode"/>
+      </fo:block>
+    </xsl:if>
+
+    <xsl:apply-templates select="$preamble"/>
+
+    <fo:list-block xsl:use-attribute-sets="list.block.spacing"
+                   provisional-distance-between-starts="2em"
+                   provisional-label-separation="0.2em">
+      <xsl:apply-templates select="$steps"/>
+    </fo:list-block>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="procedure/title">
+</xsl:template>
+
+<xsl:template match="procedure/title" mode="procedure.title.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="substeps">
+  <fo:list-block xsl:use-attribute-sets="list.block.spacing"
+                 provisional-distance-between-starts="2em"
+                 provisional-label-separation="0.2em">
+    <xsl:apply-templates/>
+  </fo:list-block>
+</xsl:template>
+
+<xsl:template match="step">
+  <fo:list-item>
+    <fo:list-item-label end-indent="label-end()">
+      <fo:block>
+        <xsl:number count="step" format="1."/>
+      </fo:block>
+    </fo:list-item-label>
+    <fo:list-item-body start-indent="body-start()">
+      <xsl:apply-templates/>
+    </fo:list-item-body>
+  </fo:list-item>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="segmentedlist">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="segmentedlist/title">
+  <fo:block font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="segtitle">
+</xsl:template>
+
+<xsl:template match="segtitle" mode="segtitle-in-seg">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="seglistitem">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="seg">
+  <xsl:variable name="segnum" select="position()"/>
+  <xsl:variable name="seglist" select="ancestor::segmentedlist"/>
+  <xsl:variable name="segtitles" select="$seglist/segtitle"/>
+
+  <!--
+     Note: segtitle is only going to be the right thing in a well formed
+     SegmentedList.  If there are too many Segs or too few SegTitles,
+     you'll get something odd...maybe an error
+  -->
+
+  <fo:block>
+    <fo:inline font-weight="bold">
+      <xsl:apply-templates select="$segtitles[$segnum=position()]"
+                           mode="segtitle-in-seg"/>
+      <xsl:text>: </xsl:text>
+    </fo:inline>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="calloutlist">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:if test="./title">
+      <fo:block font-weight="bold">
+        <xsl:apply-templates select="./title" mode="calloutlist.title.mode"/>
+      </fo:block>
+    </xsl:if>
+
+    <fo:list-block space-before.optimum="1em"
+                   space-before.minimum="0.8em"
+                   space-before.maximum="1.2em"
+                   provisional-distance-between-starts="2.2em"
+                   provisional-label-separation="0.2em">
+      <xsl:apply-templates/>
+    </fo:list-block>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="calloutlist/title">
+</xsl:template>
+
+<xsl:template match="calloutlist/title" mode="calloutlist.title.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="callout">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <fo:list-item id="{$id}">
+    <fo:list-item-label end-indent="label-end()">
+      <fo:block>
+        <xsl:call-template name="callout.arearefs">
+          <xsl:with-param name="arearefs" select="@arearefs"/>
+        </xsl:call-template>
+      </fo:block>
+    </fo:list-item-label>
+    <fo:list-item-body start-indent="body-start()">
+      <xsl:apply-templates/>
+    </fo:list-item-body>
+  </fo:list-item>
+</xsl:template>
+
+<xsl:template name="callout.arearefs">
+  <xsl:param name="arearefs"></xsl:param>
+  <xsl:if test="$arearefs!=''">
+    <xsl:choose>
+      <xsl:when test="substring-before($arearefs,' ')=''">
+        <xsl:call-template name="callout.arearef">
+          <xsl:with-param name="arearef" select="$arearefs"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="callout.arearef">
+          <xsl:with-param name="arearef"
+                          select="substring-before($arearefs,' ')"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+    <xsl:call-template name="callout.arearefs">
+      <xsl:with-param name="arearefs"
+                      select="substring-after($arearefs,' ')"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="callout.arearef">
+  <xsl:param name="arearef"></xsl:param>
+  <xsl:variable name="targets" select="id($arearef)"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+
+  <xsl:choose>
+    <xsl:when test="count($target)=0">
+      <xsl:value-of select="$arearef"/>
+      <xsl:text>: ???</xsl:text>
+    </xsl:when>
+    <xsl:when test="local-name($target)='co'">
+      <xsl:apply-templates select="$target" mode="callout-bug"/>
+    </xsl:when>
+    <xsl:when test="local-name($target)='areaset'">
+      <xsl:call-template name="callout-bug">
+        <xsl:with-param name="conum">
+          <xsl:apply-templates select="$target" mode="conumber"/>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="local-name($target)='area'">
+      <xsl:choose>
+        <xsl:when test="$target/parent::areaset">
+          <xsl:call-template name="callout-bug">
+            <xsl:with-param name="conum">
+              <xsl:apply-templates select="$target/parent::areaset"
+                                   mode="conumber"/>
+            </xsl:with-param>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="callout-bug">
+            <xsl:with-param name="conum">
+              <xsl:apply-templates select="$target" mode="conumber"/>
+            </xsl:with-param>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>???</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/math.xsl b/xsl/fo/math.xsl
new file mode 100644 (file)
index 0000000..23c0585
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                xmlns:mml="http://www.w3.org/1998/Math/MathML"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="inlineequation">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="alt">
+</xsl:template>
+
+<!-- just send the MathML all the way through... -->
+<xsl:template match="mml:*">
+  <xsl:element name="{name(.)}">
+    <xsl:copy-of select="@*"/>
+    <xsl:apply-templates select="node()"/>
+  </xsl:element>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/pagesetup.xsl b/xsl/fo/pagesetup.xsl
new file mode 100644 (file)
index 0000000..54dad59
--- /dev/null
@@ -0,0 +1,433 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version="1.0">
+
+<!-- ==================================================================== -->
+
+<xsl:template name="setup.pagemasters">
+  <fo:layout-master-set>
+    <!-- one sided, single column -->
+    <fo:simple-page-master master-name="blank"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.outer}"
+                           margin-right="{$page.margin.inner}">
+      <fo:region-body
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before region-name="xsl-region-before-blank"
+                        extent="{$region.before.extent}"/>
+      <fo:region-after region-name="xsl-region-after-blank"
+                       extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- one sided, single column -->
+    <fo:simple-page-master master-name="simple1"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.outer}"
+                           margin-right="{$page.margin.inner}">
+      <fo:region-body
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before extent="{$region.before.extent}"/>
+      <fo:region-after extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- for left-hand/even pages in twosided mode, single column -->
+    <fo:simple-page-master master-name="left1"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.outer}"
+                           margin-right="{$page.margin.inner}">
+      <fo:region-body
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before region-name="xsl-region-before-left"
+                        extent="{$region.before.extent}"/>
+      <fo:region-after region-name="xsl-region-after-left"
+                       extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- for right-hand/odd pages in twosided mode, single column -->
+    <fo:simple-page-master master-name="right1"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.inner}"
+                           margin-right="{$page.margin.outer}">
+      <fo:region-body
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before region-name="xsl-region-before-right"
+                        extent="{$region.before.extent}"/>
+      <fo:region-after region-name="xsl-region-after-right"
+                       extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- special case of first page in either mode, single column -->
+    <fo:simple-page-master master-name="first1"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.inner}"
+                           margin-right="{$page.margin.inner}">
+      <fo:region-body
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before region-name="xsl-region-before-first"
+                        extent="{$region.before.extent}"/>
+      <fo:region-after region-name="xsl-region-after-first"
+                       extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- for pages in one-side mode, 2 column -->
+    <fo:simple-page-master master-name="simple2"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.outer}"
+                           margin-right="{$page.margin.inner}">
+      <fo:region-body
+                      column-count="{$column.count}"
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before extent="{$region.before.extent}"/>
+      <fo:region-after extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- for left-hand/even pages in twosided mode, 2 column -->
+    <fo:simple-page-master master-name="left2"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.outer}"
+                           margin-right="{$page.margin.inner}">
+      <fo:region-body
+                      column-count="{$column.count}"
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before region-name="xsl-region-before-left"
+                        extent="{$region.before.extent}"/>
+      <fo:region-after region-name="xsl-region-after-left"
+                       extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- for right-hand/odd pages in twosided mode, 2 column -->
+    <fo:simple-page-master master-name="right2"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.inner}"
+                           margin-right="{$page.margin.outer}">
+      <fo:region-body
+                      column-count="{$column.count}"
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before region-name="xsl-region-before-right"
+                        extent="{$region.before.extent}"/>
+      <fo:region-after region-name="xsl-region-after-right"
+                       extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- special case of first page in either mode -->
+    <fo:simple-page-master master-name="first2"
+                           page-width="{$page.width}"
+                           page-height="{$page.height}"
+                           margin-top="{$page.margin.top}"
+                           margin-bottom="{$page.margin.bottom}"
+                           margin-left="{$page.margin.inner}"
+                           margin-right="{$page.margin.inner}">
+      <fo:region-body
+                      column-count="1"
+                      margin-bottom="{$body.margin.bottom}"
+                      margin-top="{$body.margin.top}"/>
+      <fo:region-before region-name="xsl-region-before-first"
+                        extent="{$region.before.extent}"/>
+      <fo:region-after region-name="xsl-region-after-first"
+                       extent="{$region.after.extent}"/>
+    </fo:simple-page-master>
+
+    <!-- setup for title-page, 1 column -->
+    <fo:page-sequence-master master-name="titlepage1">
+      <fo:repeatable-page-master-alternatives>
+        <fo:conditional-page-master-reference master-name="first1"/>
+      </fo:repeatable-page-master-alternatives>
+    </fo:page-sequence-master>
+
+    <!-- setup for single-sided, 1 column -->
+    <fo:page-sequence-master master-name="oneside1">
+      <fo:repeatable-page-master-alternatives>
+        <fo:conditional-page-master-reference master-name="simple1"/>
+      </fo:repeatable-page-master-alternatives>
+    </fo:page-sequence-master>
+
+    <!-- setup for double-sided, 1 column -->
+    <fo:page-sequence-master master-name="twoside1">
+      <fo:repeatable-page-master-alternatives>
+        <fo:conditional-page-master-reference master-name="blank"
+                                              blank-or-not-blank="blank"/>
+        <fo:conditional-page-master-reference master-name="right1"
+                                              odd-or-even="odd"/>
+        <fo:conditional-page-master-reference master-name="left1"
+                                              odd-or-even="even"/>
+      </fo:repeatable-page-master-alternatives>
+    </fo:page-sequence-master>
+
+    <!-- setup for title-page, 2 column -->
+    <fo:page-sequence-master master-name="titlepage2">
+      <fo:repeatable-page-master-alternatives>
+        <fo:conditional-page-master-reference master-name="first2"/>
+      </fo:repeatable-page-master-alternatives>
+    </fo:page-sequence-master>
+
+    <!-- setup for single-sided, 2 column -->
+    <fo:page-sequence-master master-name="oneside2">
+      <fo:repeatable-page-master-alternatives>
+        <fo:conditional-page-master-reference master-name="simple2"/>
+      </fo:repeatable-page-master-alternatives>
+    </fo:page-sequence-master>
+
+    <!-- setup for double-sided, 2 column -->
+    <fo:page-sequence-master master-name="twoside2">
+      <fo:repeatable-page-master-alternatives>
+        <fo:conditional-page-master-reference master-name="blank"
+                                              blank-or-not-blank="blank"/>
+        <fo:conditional-page-master-reference master-name="right2"
+                                              odd-or-even="odd"/>
+        <fo:conditional-page-master-reference master-name="left2"
+                                              odd-or-even="even"/>
+      </fo:repeatable-page-master-alternatives>
+    </fo:page-sequence-master>
+
+    <xsl:call-template name="user.pagemasters"/>
+
+    </fo:layout-master-set>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="user.pagemasters"/> <!-- intentionally empty -->
+
+<!-- ==================================================================== -->
+
+<!-- $double.sided, $column.count, and context -->
+
+<xsl:template name="select.pagemaster">
+  <xsl:param name="element" select="local-name(.)"/>
+  <xsl:choose>
+    <xsl:when test="$double.sided != 0">
+      <xsl:choose>
+        <xsl:when test="$column.count &gt; 1">
+          <xsl:call-template name="select.doublesided.multicolumn.pagemaster">
+            <xsl:with-param name="element" select="$element"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="select.doublesided.pagemaster">
+            <xsl:with-param name="element" select="$element"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:choose>
+        <xsl:when test="$column.count &gt; 1">
+          <xsl:call-template name="select.singlesided.multicolumn.pagemaster">
+            <xsl:with-param name="element" select="$element"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="select.singlesided.pagemaster">
+            <xsl:with-param name="element" select="$element"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="select.doublesided.multicolumn.pagemaster">
+  <xsl:param name="element" select="local-name(.)"/>
+  <xsl:choose>
+    <xsl:when test="$element='set' or $element='book' or $element='part'">
+      <xsl:text>titlepage2</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>twoside2</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="select.doublesided.pagemaster">
+  <xsl:param name="element" select="local-name(.)"/>
+  <xsl:choose>
+    <xsl:when test="$element='set' or $element='book' or $element='part'">
+      <xsl:text>titlepage1</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>twoside1</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="select.singlesided.multicolumn.pagemaster">
+  <xsl:param name="element" select="local-name(.)"/>
+  <xsl:choose>
+    <xsl:when test="$element='set' or $element='book' or $element='part'">
+      <xsl:text>titlepage2</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>oneside2</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="select.singlesided.pagemaster">
+  <xsl:param name="element" select="local-name(.)"/>
+  <xsl:choose>
+    <xsl:when test="$element='set' or $element='book' or $element='part'">
+      <xsl:text>titlepage1</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>oneside1</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="running.head.mode">
+  <xsl:param name="master-name" select="'unknown'"/>
+  <!-- by default, nothing -->
+  <xsl:choose>
+    <xsl:when test="$master-name='titlepage1'">
+    </xsl:when>
+    <xsl:when test="$master-name='oneside1'">
+    </xsl:when>
+    <xsl:when test="$master-name='twoside1'">
+    </xsl:when>
+    <xsl:when test="$master-name='titlepage2'">
+    </xsl:when>
+    <xsl:when test="$master-name='oneside2'">
+    </xsl:when>
+    <xsl:when test="$master-name='twoside2'">
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="chapter|appendix" mode="running.head.mode">
+  <xsl:param name="master-name" select="'unknown'"/>
+  <xsl:variable name="head">
+    <fo:block font-size="{$body.font.size}">
+      <xsl:apply-templates select="." mode="label.markup"/>
+      <xsl:text> </xsl:text>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </fo:block>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$master-name='titlepage1'"></xsl:when>
+    <xsl:when test="$master-name='oneside1'">
+      <fo:static-content flow-name="xsl-region-before">
+        <fo:block text-align="center">
+          <xsl:copy-of select="$head"/>
+        </fo:block>
+      </fo:static-content>
+    </xsl:when>
+    <xsl:when test="$master-name='twoside1'">
+      <fo:static-content flow-name="xsl-region-before-left">
+        <fo:block text-align="right">
+          <xsl:copy-of select="$head"/>
+        </fo:block>
+      </fo:static-content>
+      <fo:static-content flow-name="xsl-region-before-right">
+        <fo:block text-align="left">
+          <xsl:copy-of select="$head"/>
+        </fo:block>
+      </fo:static-content>
+    </xsl:when>
+    <xsl:when test="$master-name='titlepage2'"></xsl:when>
+    <xsl:when test="$master-name='oneside2'">
+      <fo:static-content flow-name="xsl-region-before">
+        <fo:block text-align="center">
+          <xsl:copy-of select="$head"/>
+        </fo:block>
+      </fo:static-content>
+    </xsl:when>
+    <xsl:when test="$master-name='twoside2'">
+      <fo:static-content flow-name="xsl-region-before-left">
+        <fo:block text-align="right">
+          <xsl:copy-of select="$head"/>
+        </fo:block>
+      </fo:static-content>
+      <fo:static-content flow-name="xsl-region-before-right">
+        <fo:block text-align="left">
+          <xsl:copy-of select="$head"/>
+        </fo:block>
+      </fo:static-content>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*" mode="running.foot.mode">
+  <xsl:param name="master-name" select="'unknown'"/>
+  <xsl:variable name="foot">
+    <fo:page-number/>
+  </xsl:variable>
+  <!-- by default, the page number -->
+  <xsl:choose>
+    <xsl:when test="$master-name='titlepage1'"></xsl:when>
+    <xsl:when test="$master-name='oneside1'">
+      <fo:static-content flow-name="xsl-region-after">
+        <fo:block text-align="center" font-size="{$body.font.size}">
+          <xsl:copy-of select="$foot"/>
+        </fo:block>
+      </fo:static-content>
+    </xsl:when>
+    <xsl:when test="$master-name='twoside1'">
+      <fo:static-content flow-name="xsl-region-after-left">
+        <fo:block text-align="left" font-size="{$body.font.size}">
+          <xsl:copy-of select="$foot"/>
+        </fo:block>
+      </fo:static-content>
+      <fo:static-content flow-name="xsl-region-after-right">
+        <fo:block text-align="right" font-size="{$body.font.size}">
+          <xsl:copy-of select="$foot"/>
+        </fo:block>
+      </fo:static-content>
+    </xsl:when>
+    <xsl:when test="$master-name='titlepage2'"></xsl:when>
+    <xsl:when test="$master-name='oneside2'">
+      <fo:static-content flow-name="xsl-after-before">
+        <fo:block text-align="center" font-size="{$body.font.size}">
+          <xsl:copy-of select="$foot"/>
+        </fo:block>
+      </fo:static-content>
+    </xsl:when>
+    <xsl:when test="$master-name='twoside2'">
+      <fo:static-content flow-name="xsl-region-after-left">
+        <fo:block text-align="left" font-size="{$body.font.size}">
+          <xsl:copy-of select="$foot"/>
+        </fo:block>
+      </fo:static-content>
+      <fo:static-content flow-name="xsl-region-after-right">
+        <fo:block text-align="right" font-size="{$body.font.size}">
+          <xsl:copy-of select="$foot"/>
+        </fo:block>
+      </fo:static-content>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="set|book|part|reference" mode="running.foot.mode">
+  <!-- nothing -->
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/param.xsl b/xsl/fo/param.xsl
new file mode 100644 (file)
index 0000000..9db4d1d
--- /dev/null
@@ -0,0 +1,1111 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<doc:reference xmlns="">
+<referenceinfo>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<copyright><year>1999</year><year>2000</year>
+<holder>Norman Walsh</holder>
+</copyright>
+</referenceinfo>
+<title>Formatting Object Parameter Reference</title>
+
+<partintro>
+<section><title>Introduction</title>
+
+<para>This is technical reference documentation for the DocBook XSL
+Stylesheets; it documents (some of) the parameters, templates, and
+other elements of the stylesheets.</para>
+
+<para>This reference describes each of the Formatting Object
+Stylesheet parameters.  These are the <quote>easily
+customizable</quote> parts of the stylesheet.  If you want to specify
+an alternate value for one or more of these parameters, you can do so
+in a <quote>driver</quote> stylesheet.</para>
+
+<para>For example, if you want to turn on automatic section numbering,
+you might create a driver stylesheet like this:</para>
+
+<programlisting><![CDATA[<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+  <xsl:import href="/path/to/fo/docbook.xsl"/>
+
+  <xsl:param name="section.autolabel" select="1"/>
+
+</xsl:stylesheet>]]></programlisting>
+
+<para>Naturally, you have to change the
+<sgmltag class='attribute'>href</sgmltag> attribute on
+<literal>&lt;xsl:import&gt;</literal>
+to point to <filename>docbook.xsl</filename>
+on your system.</para>
+
+<para>This is not intended to be <quote>user</quote> documentation.
+It is provided for developers writing customization layers for the
+stylesheets, and for anyone who's interested in <quote>how it
+works</quote>.</para>
+
+<para>Although I am trying to be thorough, this documentation is known
+to be incomplete. Don't forget to read the source, too :-)</para>
+</section>
+</partintro>
+</doc:reference>
+
+<xsl:param name="author.othername.in.middle" select="1"/>
+<xsl:param name="html.stylesheet">docbook.css</xsl:param>
+<xsl:param name="html.stylesheet.type">text/css</xsl:param>
+<xsl:param name="refentry.xref.manvolnum" select="1"/>
+<xsl:param name="show.comments" select="1"/>
+<xsl:param name="funcsynopsis.style">kr</xsl:param>
+<xsl:param name="funcsynopsis.decoration" select="1"/>
+<xsl:param name="refentry.generate.name" select="1"/>
+
+<xsl:param name="admon.graphics" select="0"/>
+<xsl:param name="admon.graphics.path">../images/</xsl:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="admon.graphics.extension" select="'.png'" doc:type='string'/>
+
+<doc:param name="admon.graphics.extension" xmlns="">
+<refpurpose>Extension for admonition graphics</refpurpose>
+<refdescription>
+<para>Sets the extension to use on admonition graphics.</para>
+</refdescription>
+</doc:param>
+
+<xsl:param name="section.autolabel" select="0"/>
+<xsl:param name="section.label.includes.component.label" select="0"/>
+<xsl:param name="chapter.autolabel" select="1"/>
+<xsl:param name="appendix.autolabel" select="1"/>
+<xsl:param name="part.autolabel" select="1"/>
+<xsl:param name="preface.autolabel" select="0"/>
+
+<xsl:param name="biblioentry.item.separator">. </xsl:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="qandadiv.autolabel" select="1"/>
+
+<doc:variable name="qandadiv.autolabel" xmlns="">
+<refpurpose>Are divisions in QAndASets enumerated?</refpurpose>
+<refdescription>
+<para>If true (non-zero), unlabeled qandadivs will be enumerated.
+</para>
+</refdescription>
+</doc:variable>
+
+<!-- ==================================================================== -->
+<xsl:param name="qanda.inherit.numeration" select="0"/>
+
+<doc:variable name="qanda.inherit.numeration" xmlns="">
+<refpurpose>Does enumeration of QandASet components inherit the numeration of parent elements?</refpurpose>
+<refdescription>
+<para>If true (non-zero), numbered QandADiv elements and Questions and Answers inherit
+the numeration of the ancestors of the QandASet.
+</para>
+</refdescription>
+</doc:variable>
+
+<!-- ==================================================================== -->
+
+<xsl:param name="graphic.default.extension"></xsl:param>
+
+<doc:variable name="graphic.default.extension" xmlns="">
+<refpurpose>Default extension for graphic filenames</refpurpose>
+<refdescription>
+<para>If a <sgmltag>graphic</sgmltag> or <sgmltag>mediaobject</sgmltag>
+includes a reference to a filename that does not include an extension,
+and the <sgmltag class="attribute">format</sgmltag> attribute is
+<emphasis>unspecified</emphasis>, the default extension will be used.
+</para>
+</refdescription>
+</doc:variable>
+
+<!-- ==================================================================== -->
+<xsl:attribute-set name="formal.title.properties"
+                   use-attribute-sets="normal.para.spacing">
+  <xsl:attribute name="font-weight">bold</xsl:attribute>
+  <xsl:attribute name="font-size">12pt</xsl:attribute>
+  <xsl:attribute name="hyphenate">false</xsl:attribute>
+  <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+</xsl:attribute-set>
+
+<doc:attribute-set name="formal.title.properties" xmlns="">
+<refpurpose>Properties of formal object titles</refpurpose>
+<refdescription>
+<para>This attribute set is used to specify the properties of formal
+object titles.
+</para>
+</refdescription>
+</doc:attribute-set>
+
+<!-- ==================================================================== -->
+<xsl:attribute-set name="component.title.properties">
+  <xsl:attribute name="space-before.optimum">2em</xsl:attribute>
+  <xsl:attribute name="space-before.minimum">1.8em</xsl:attribute>
+  <xsl:attribute name="space-before.maximum">2.2em</xsl:attribute>
+  <xsl:attribute name="font-weight">bold</xsl:attribute>
+  <xsl:attribute name="font-size">18pt</xsl:attribute>
+  <xsl:attribute name="space-after.optimum">1.5em</xsl:attribute>
+  <xsl:attribute name="space-after.minimum">1.3em</xsl:attribute>
+  <xsl:attribute name="space-after.maximum">1.8em</xsl:attribute>
+  <xsl:attribute name="hyphenate">false</xsl:attribute>
+  <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+</xsl:attribute-set>
+
+<doc:attribute-set name="component.title.properties" xmlns="">
+<refpurpose>Properties of component titles</refpurpose>
+<refdescription>
+<para>This attribute set is used to specify the properties of component
+titles.
+</para>
+</refdescription>
+</doc:attribute-set>
+
+<!-- ==================================================================== -->
+<xsl:attribute-set name="admonition.title.properties">
+  <xsl:attribute name="font-size">14pt</xsl:attribute>
+  <xsl:attribute name="font-weight">bold</xsl:attribute>
+  <xsl:attribute name="hyphenate">false</xsl:attribute>
+  <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+</xsl:attribute-set>
+
+<doc:attribute-set name="admonition.title.properties" xmlns="">
+<refpurpose>Properties of admonition titles</refpurpose>
+<refdescription>
+<para>This attribute set is used to specify the properties of admonition
+titles.
+</para>
+</refdescription>
+</doc:attribute-set>
+
+<!-- ==================================================================== -->
+<xsl:attribute-set name="toc.margin.properties">
+  <xsl:attribute name="space-before.minimum">0.5em</xsl:attribute>
+  <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+  <xsl:attribute name="space-before.maximum">2em</xsl:attribute>
+  <xsl:attribute name="space-after.minimum">0.5em</xsl:attribute>
+  <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
+  <xsl:attribute name="space-after.maximum">2em</xsl:attribute>
+</xsl:attribute-set>
+
+<!-- ==================================================================== -->
+<xsl:attribute-set name="xref.properties">
+<!--
+  <xsl:attribute name="background-color">#F0F0F0</xsl:attribute>
+  <xsl:attribute name="padding-start">1pt</xsl:attribute>
+  <xsl:attribute name="padding-end">1pt</xsl:attribute>
+-->
+</xsl:attribute-set>
+
+<doc:attribute-set name="xref.properties" xmlns="">
+<refpurpose>Visual properties of hotlinks</refpurpose>
+<refdescription>
+<para>This attribute set is used to specify properties of xrefs
+</para>
+</refdescription>
+</doc:attribute-set>
+
+<!-- ==================================================================== -->
+<xsl:param name="insert.xref.page.number" select="0" doc:type='boolean'/>
+<doc:param name="insert.xref.page.number" xmlns="">
+<refpurpose>Turns page numbers in xrefs on and off</refpurpose>
+<refdescription>
+<para>When equal to 1, this parameter triggers generation of page
+number citations after xrefs.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:attribute-set name="normal.para.spacing">
+  <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+  <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+  <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+</xsl:attribute-set>
+
+<doc:attribute-set name="normal.para.spacing" xmlns="">
+<refpurpose>Spacing properties of normal paragraphs</refpurpose>
+<refdescription>
+<para>This attribute set is used to specify the spacing properties
+of normal paragraphs.
+</para>
+</refdescription>
+</doc:attribute-set>
+
+<!-- ==================================================================== -->
+
+<xsl:attribute-set name="list.block.spacing">
+  <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+  <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+  <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+</xsl:attribute-set>
+
+<doc:attribute-set name="list.block.spacing" xmlns="">
+<refpurpose>Spacing properties of list blocks</refpurpose>
+<refdescription>
+<para>This attribute set is used to specify the spacing properties
+of list blocks.
+</para>
+</refdescription>
+</doc:attribute-set>
+
+<!-- ==================================================================== -->
+
+<xsl:attribute-set name="list.item.spacing">
+  <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+  <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+  <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+</xsl:attribute-set>
+
+<doc:attribute-set name="list.item.spacing" xmlns="">
+<refpurpose>Spacing properties of list items</refpurpose>
+<refdescription>
+<para>This attribute set is used to specify the spacing properties
+of list items.
+</para>
+</refdescription>
+</doc:attribute-set>
+
+<!-- ==================================================================== -->
+<xsl:param name="rootid" select="''"/>
+
+<doc:param name="rootid" xmlns="">
+<refpurpose>Specify the root element to format</refpurpose>
+<refdescription>
+<para>If <parameter>rootid</parameter> is specified, it must be the
+value of an ID that occurs in the document being formatted. The entire
+document will be loaded and parsed, but formatting will begin at the
+element identified, rather than at the root. For example, this allows
+you to process only chapter 4 of a book.</para>
+<para>Because the entire document is available to the processor, automatic
+numbering, cross references, and other dependencies are correctly
+resolved.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.graphics" select="'0'"/>
+
+<doc:param name="callout.graphics" xmlns="">
+<refpurpose>Use graphics for callouts?</refpurpose>
+<refdescription>
+<para>If non-zero, callouts are presented with graphics (e.g., reverse-video
+circled numbers instead of "(1)", "(2)", etc.).
+Default graphics are provided in the distribution.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.unicode" select="1"/>
+
+<doc:param name="callout.unicode" xmlns="">
+<refpurpose>First character to use for Unicode callouts</refpurpose>
+<refdescription>
+<para>If non-zero, callouts are presented with Unicode characters
+starting with the character specified. Zero indicates that Unicode
+callouts should not be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.dingbats" select="'0'"/>
+
+<doc:param name="callout.dingbats" xmlns="">
+<refpurpose>Use Zapf Dingbats for callouts?</refpurpose>
+<refdescription>
+<para>If non-zero, callouts are presented with Zapf Dingbats.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.unicode.start.character" select="10102"
+           doc:type='integer'/>
+
+<doc:param name="callout.graphics.number.limit" xmlns="">
+<refpurpose>Number of the largest callout graphic</refpurpose>
+<refdescription>
+<para>If <parameter>callout.graphics</parameter>
+is non-zero, graphics are used to represent
+callout numbers. The value of
+<parameter>callout.graphics.number.limit</parameter>
+is
+the largest number for which a graphic exists. If the callout number
+exceeds this limit, the default presentation "(nnn)" will always
+be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.unicode.number.limit" select="'10'"
+           doc:type='integer'/>
+
+<doc:param name="callout.graphics.number.limit" xmlns="">
+<refpurpose>Number of the largest callout graphic</refpurpose>
+<refdescription>
+<para>If <parameter>callout.graphics</parameter>
+is non-zero, graphics are used to represent
+callout numbers. The value of
+<parameter>callout.graphics.number.limit</parameter>
+is
+the largest number for which a graphic exists. If the callout number
+exceeds this limit, the default presentation "(nnn)" will always
+be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.graphics.extension" select="'.png'"/>
+
+<doc:param name="callout.graphics.extension" xmlns="">
+<refpurpose>Extension for callout graphics</refpurpose>
+<refdescription>
+<para>Sets the extension to use on callout graphics.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.graphics.path" select="'../images/callouts/'"/>
+
+<doc:param name="callout.graphics.path" xmlns="">
+<refpurpose>Path to callout graphics</refpurpose>
+<refdescription>
+<para>Sets the path, probably relative to the directory where the HTML
+files are created, to the callout graphics.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.graphics.number.limit" select="'10'"/>
+
+<doc:param name="callout.graphics.number.limit" xmlns="">
+<refpurpose>Number of the largest callout graphic</refpurpose>
+<refdescription>
+<para>If <parameter>callout.graphics</parameter>
+is non-zero, graphics are used to represent
+callout numbers. The value of
+<parameter>callout.graphics.number.limit</parameter>
+is
+the largest number for which a graphic exists. If the callout number
+exceeds this limit, the default presentation "(nnn)" will always
+be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="use.extensions" select="'0'"/>
+
+<doc:param name="use.extensions" xmlns="">
+<refpurpose>Enable extensions</refpurpose>
+<refdescription>
+<para>If non-zero, extensions may be used. Each extension is
+further controlled by its own parameter. But if
+<parameter>use.extensions</parameter> is zero, no extensions will
+be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="textinsert.extension" select="'1'"/>
+
+<doc:param name="textinsert.extension" xmlns="">
+<refpurpose>Enable the textinsert extension element</refpurpose>
+<refdescription>
+<para>The textinsert extension element inserts the contents of a
+a file into the result tree (as text).
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="linenumbering.extension" select="'1'"/>
+
+<doc:param name="linenumbering.extension" xmlns="">
+<refpurpose>Enable the line numbering extension</refpurpose>
+<refdescription>
+<para>If true, verbatim environments (elements that have the
+format='linespecific' notation attribute: address, literallayout,
+programlisting, screen, synopsis) that specify line numbering will
+have, surprise, line numbers.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="linenumbering.everyNth" select="'5'"/>
+
+<doc:param name="linenumbering.everyNth" xmlns="">
+<refpurpose>Indicate which lines should be numbered</refpurpose>
+<refdescription>
+<para>If line numbering is enabled, everyNth line will be numbered.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="linenumbering.width" select="'3'"/>
+
+<doc:param name="linenumbering.width" xmlns="">
+<refpurpose>Indicates the width of line numbers</refpurpose>
+<refdescription>
+<para>If line numbering is enabled, line numbers will appear right
+justified in a field "width" characters wide.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="linenumbering.separator" select="' '"/>
+
+<doc:param name="linenumbering.separator" xmlns="">
+<refpurpose>Specify a separator between line numbers and lines</refpurpose>
+<refdescription>
+<para>The separator is inserted between line numbers and lines in
+the verbatim environment.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callouts.extension" select="'1'"/>
+
+<doc:param name="callouts.extension" xmlns="">
+<refpurpose>Enable the callout extension</refpurpose>
+<refdescription>
+<para>The callouts extension processes <sgmltag>areaset</sgmltag>
+elements in <sgmltag>ProgramListingCO</sgmltag> and other text-based
+callout elements.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.defaultcolumn" select="'60'"/>
+
+<doc:param name="callout.defaultcolumn" xmlns="">
+<refpurpose>Indicates what column callouts appear in by default</refpurpose>
+<refdescription>
+<para>If a callout does not identify a column (for example, if it uses
+the <literal>linerange</literal> <sgmltag class="attribute">unit</sgmltag>),
+it will appear in the default column.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="tablecolumns.extension" select="'1'" doc:type='boolean'/>
+
+<doc:param name="tablecolumns.extension" xmlns="">
+<refpurpose>Enable the table columns extension function</refpurpose>
+<refdescription>
+<para>The table columns extension function adjusts the widths of table
+columns in the HTML result to more accurately reflect the specifications
+in the CALS table.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="nominal.table.width" select="'6in'" doc:type='length'/>
+
+<doc:param name="nominal.table.width" xmlns="">
+<refpurpose>The (absolute) nominal width of tables</refpurpose>
+<refdescription>
+<para>In order to convert CALS column widths into FO column widths, it
+is sometimes necessary to have an absolute table width to use for conversion
+of mixed absolute and relative widths. This value must be an absolute
+length (not a percentage).</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="default.table.width" select="''" doc:type='length'/>
+
+<doc:param name="default.table.width" xmlns="">
+<refpurpose>The default width of tables</refpurpose>
+<refdescription>
+<para>If specified, this value will be used for the WIDTH attribute on
+tables that do not specify an alternate width (with the dbhtml processing
+instruction).</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="paper.type" select="'USletter'"/>
+<doc:param name="paper.type" xmlns="">
+<refpurpose>Select the paper type</refpurpose>
+<refdescription>
+<para>The paper type is a convenient way to specify the paper size.
+The list of known paper sizes includes USletter and most of the A,
+B, and C sizes. See <literal>page.width.portrait</literal>, for example.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.orientation" select="'portrait'"/>
+<doc:param name="page.orientation" xmlns="">
+<refpurpose>Select the page orientation</refpurpose>
+<refdescription>
+<para>In portrait orientation, the short edge is horizontal; in
+landscape orientation, it is vertical.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.width.portrait">
+  <xsl:choose>
+    <xsl:when test="$paper.type = 'USletter'">8.5in</xsl:when>
+    <xsl:when test="$paper.type = '4A0'">1682mm</xsl:when>
+    <xsl:when test="$paper.type = '2A0'">1189mm</xsl:when>
+    <xsl:when test="$paper.type = 'A0'">841mm</xsl:when>
+    <xsl:when test="$paper.type = 'A1'">594mm</xsl:when>
+    <xsl:when test="$paper.type = 'A2'">420mm</xsl:when>
+    <xsl:when test="$paper.type = 'A3'">297mm</xsl:when>
+    <xsl:when test="$paper.type = 'A4'">210mm</xsl:when>
+    <xsl:when test="$paper.type = 'A5'">148mm</xsl:when>
+    <xsl:when test="$paper.type = 'A6'">105mm</xsl:when>
+    <xsl:when test="$paper.type = 'A7'">74mm</xsl:when>
+    <xsl:when test="$paper.type = 'A8'">52mm</xsl:when>
+    <xsl:when test="$paper.type = 'A9'">37mm</xsl:when>
+    <xsl:when test="$paper.type = 'A10'">26mm</xsl:when>
+    <xsl:when test="$paper.type = 'B0'">1000mm</xsl:when>
+    <xsl:when test="$paper.type = 'B1'">707mm</xsl:when>
+    <xsl:when test="$paper.type = 'B2'">500mm</xsl:when>
+    <xsl:when test="$paper.type = 'B3'">353mm</xsl:when>
+    <xsl:when test="$paper.type = 'B4'">250mm</xsl:when>
+    <xsl:when test="$paper.type = 'B5'">176mm</xsl:when>
+    <xsl:when test="$paper.type = 'B6'">125mm</xsl:when>
+    <xsl:when test="$paper.type = 'B7'">88mm</xsl:when>
+    <xsl:when test="$paper.type = 'B8'">62mm</xsl:when>
+    <xsl:when test="$paper.type = 'B9'">44mm</xsl:when>
+    <xsl:when test="$paper.type = 'B10'">31mm</xsl:when>
+    <xsl:when test="$paper.type = 'C0'">917mm</xsl:when>
+    <xsl:when test="$paper.type = 'C1'">648mm</xsl:when>
+    <xsl:when test="$paper.type = 'C2'">458mm</xsl:when>
+    <xsl:when test="$paper.type = 'C3'">324mm</xsl:when>
+    <xsl:when test="$paper.type = 'C4'">229mm</xsl:when>
+    <xsl:when test="$paper.type = 'C5'">162mm</xsl:when>
+    <xsl:when test="$paper.type = 'C6'">114mm</xsl:when>
+    <xsl:when test="$paper.type = 'C7'">81mm</xsl:when>
+    <xsl:when test="$paper.type = 'C8'">57mm</xsl:when>
+    <xsl:when test="$paper.type = 'C9'">40mm</xsl:when>
+    <xsl:when test="$paper.type = 'C10'">28mm</xsl:when>
+    <xsl:otherwise>8.5in</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<doc:param name="page.width.portrait" xmlns="">
+<refpurpose>Specify the physical size of the short edge of the page</refpurpose>
+<refdescription>
+<para>The portrait page width is the length of the short
+edge of the physical page.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.height.portrait">
+  <xsl:choose>
+    <xsl:when test="$paper.type = 'A4landscape'">210mm</xsl:when>
+    <xsl:when test="$paper.type = 'USletter'">11in</xsl:when>
+    <xsl:when test="$paper.type = 'USlandscape'">8.5in</xsl:when>
+    <xsl:when test="$paper.type = '4A0'">2378mm</xsl:when>
+    <xsl:when test="$paper.type = '2A0'">1682mm</xsl:when>
+    <xsl:when test="$paper.type = 'A0'">1189mm</xsl:when>
+    <xsl:when test="$paper.type = 'A1'">841mm</xsl:when>
+    <xsl:when test="$paper.type = 'A2'">594mm</xsl:when>
+    <xsl:when test="$paper.type = 'A3'">420mm</xsl:when>
+    <xsl:when test="$paper.type = 'A4'">297mm</xsl:when>
+    <xsl:when test="$paper.type = 'A5'">210mm</xsl:when>
+    <xsl:when test="$paper.type = 'A6'">148mm</xsl:when>
+    <xsl:when test="$paper.type = 'A7'">105mm</xsl:when>
+    <xsl:when test="$paper.type = 'A8'">74mm</xsl:when>
+    <xsl:when test="$paper.type = 'A9'">52mm</xsl:when>
+    <xsl:when test="$paper.type = 'A10'">37mm</xsl:when>
+    <xsl:when test="$paper.type = 'B0'">1414mm</xsl:when>
+    <xsl:when test="$paper.type = 'B1'">1000mm</xsl:when>
+    <xsl:when test="$paper.type = 'B2'">707mm</xsl:when>
+    <xsl:when test="$paper.type = 'B3'">500mm</xsl:when>
+    <xsl:when test="$paper.type = 'B4'">353mm</xsl:when>
+    <xsl:when test="$paper.type = 'B5'">250mm</xsl:when>
+    <xsl:when test="$paper.type = 'B6'">176mm</xsl:when>
+    <xsl:when test="$paper.type = 'B7'">125mm</xsl:when>
+    <xsl:when test="$paper.type = 'B8'">88mm</xsl:when>
+    <xsl:when test="$paper.type = 'B9'">62mm</xsl:when>
+    <xsl:when test="$paper.type = 'B10'">44mm</xsl:when>
+    <xsl:when test="$paper.type = 'C0'">1297mm</xsl:when>
+    <xsl:when test="$paper.type = 'C1'">917mm</xsl:when>
+    <xsl:when test="$paper.type = 'C2'">648mm</xsl:when>
+    <xsl:when test="$paper.type = 'C3'">458mm</xsl:when>
+    <xsl:when test="$paper.type = 'C4'">324mm</xsl:when>
+    <xsl:when test="$paper.type = 'C5'">229mm</xsl:when>
+    <xsl:when test="$paper.type = 'C6'">162mm</xsl:when>
+    <xsl:when test="$paper.type = 'C7'">114mm</xsl:when>
+    <xsl:when test="$paper.type = 'C8'">81mm</xsl:when>
+    <xsl:when test="$paper.type = 'C9'">57mm</xsl:when>
+    <xsl:when test="$paper.type = 'C10'">40mm</xsl:when>
+    <xsl:otherwise>11in</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<doc:param name="page.height.portrait" xmlns="">
+<refpurpose>Specify the physical size of the long edge of the page</refpurpose>
+<refdescription>
+<para>The portrait page height is the length of the long
+edge of the physical page.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.width">
+  <xsl:choose>
+    <xsl:when test="$page.orientation = 'portrait'">
+      <xsl:value-of select="$page.width.portrait"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$page.height.portrait"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<doc:param name="page.width" xmlns="">
+<refpurpose>The width of the physical page</refpurpose>
+<refdescription>
+<para>The page width is generally calculated from the
+<literal>paper.type</literal> and
+<literal>page.orientation</literal>.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.height">
+  <xsl:choose>
+    <xsl:when test="$page.orientation = 'portrait'">
+      <xsl:value-of select="$page.height.portrait"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$page.width.portrait"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<doc:param name="page.height" xmlns="">
+<refpurpose>The height of the physical page</refpurpose>
+<refdescription>
+<para>The page height is generally calculated from the
+<literal>paper.type</literal> and
+<literal>page.orientation</literal>.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="double.sided" select="'0'"/>
+
+<doc:param name="double.sided" xmlns="">
+<refpurpose>Is the document to be printed double sided?</refpurpose>
+<refdescription>
+<para>Double-sided documents are printed with a slightly wider margin
+on the binding edge of the page.
+</para>
+<para>FIXME: The current set of parameters does not take writing direction
+into account.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="column.count" select="'1'"/>
+
+<doc:param name="column.count" xmlns="">
+<refpurpose>Specifies the number of columns of text on the page</refpurpose>
+<refdescription>
+<para>The specified number of columns of text will appear on each page.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="region.after.extent" select="'12pt'"/>
+
+<doc:param name="region.after.extent" xmlns="">
+<refpurpose>Specifies the height of the footer.</refpurpose>
+<refdescription>
+<para>The region after extent is the height of the area where footers
+are printed.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="region.before.extent" select="'12pt'"/>
+
+<doc:param name="region.before.extent" xmlns="">
+<refpurpose>Specifies the height of the header</refpurpose>
+<refdescription>
+<para>The region before extent is the height of the area where headers
+are printed.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.margin.top">1in</xsl:param>
+
+<doc:param name="page.margin.top" xmlns="">
+<refpurpose>The top margin of the page</refpurpose>
+<refdescription>
+<para>The top page margin is the distance from the physical top of the
+page to the first line of text (body or header).
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.margin.bottom">1in</xsl:param>
+
+<doc:param name="page.margin.bottom" xmlns="">
+<refpurpose>The bottom margin of the page</refpurpose>
+<refdescription>
+<para>The bottom page margin is the distance from the physical bottom of
+the page to the last line of text (body or footer).
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.margin.inner">
+  <xsl:choose>
+    <xsl:when test="$double.sided != 0">1.25in</xsl:when>
+    <xsl:otherwise>1in</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<doc:param name="page.margin.inner" xmlns="">
+<refpurpose>The inner page margin</refpurpose>
+<refdescription>
+<para>The inner page margin is the distance from binding edge of the
+page to the first column of text. In the left-to-right, top-to-bottom writing
+direction, this is the left margin of recto pages.</para>
+<para>The inner and outer margins are usually the same unless the output
+is double-sided.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="page.margin.outer">
+  <xsl:choose>
+    <xsl:when test="$double.sided != 0">0.75in</xsl:when>
+    <xsl:otherwise>10pc</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<doc:param name="page.margin.outer" xmlns="">
+<refpurpose>The outer page margin</refpurpose>
+<refdescription>
+<para>The outer page margin is the distance from non-binding edge of the
+page to the last column of text. In the left-to-right, top-to-bottom writing
+direction, this is the right margin of recto pages.</para>
+<para>The inner and outer margins are usually the same unless the output
+is double-sided.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="body.margin.bottom">24pt</xsl:param>
+
+<doc:param name="body.margin.bottom" xmlns="">
+<refpurpose>The bottom margin of the body text</refpurpose>
+<refdescription>
+<para>The body bottom margin is the distance from the last line of text
+in the page body to the bottom page margin. Note that the page footer, if
+any, appears in the space between the body bottom margin and the page
+bottom margin.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="body.margin.top">24pt</xsl:param>
+
+<doc:param name="body.margin.top" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>The body top margin is the distance from the page top margin to
+the first line of text
+in the page body. Note that the page header, if
+any, appears in the space between the page top margin and the body
+top margin.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="body.font.family">Times Roman</xsl:param>
+
+<doc:param name="body.font.family" xmlns="">
+<refpurpose>The default font family for body text</refpurpose>
+<refdescription>
+<para>The body font family is the default font used for text in the page body.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="title.font.family">Helvetica</xsl:param>
+
+<doc:param name="title.font.family" xmlns="">
+<refpurpose>The default font family for titles</refpurpose>
+<refdescription>
+<para>The title font family is used for titles (chapter, section, figure,
+etc.)
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="monospace.font.family">Courier</xsl:param>
+
+<doc:param name="monospace.font.family" xmlns="">
+<refpurpose>The default font family for monospace environments</refpurpose>
+<refdescription>
+<para>The monospace font family is used for verbatim environments
+(program listings, screens, etc.).
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="sans.font.family">Helvetica</xsl:param>
+
+<doc:param name="sans.font.family" xmlns="">
+<refpurpose>The default sans-serif font family</refpurpose>
+<refdescription>
+<para>The default sans-serif font family. At the present, this isn't
+actually used by the stylesheets.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="body.font.master">10</xsl:param>
+
+<doc:param name="body.font.master" xmlns="">
+<refpurpose>Specifies the default point size for body text</refpurpose>
+<refdescription>
+<para>The body font size is specified in two parameters
+(<varname>body.font.master</varname> and <varname>body.font.size</varname>)
+so that math can be performed on the font size by XSLT.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="body.font.size">
+ <xsl:value-of select="$body.font.master"/><xsl:text>pt</xsl:text>
+</xsl:param>
+
+<doc:param name="body.font.size" xmlns="">
+<refpurpose>Specifies the default font size for body text</refpurpose>
+<refdescription>
+<para>The body font size is specified in two parameters
+(<varname>body.font.master</varname> and <varname>body.font.size</varname>)
+so that math can be performed on the font size by XSLT.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="footnote.font.size">
+ <xsl:value-of select="$body.font.master * 0.8"/><xsl:text>pt</xsl:text>
+</xsl:param>
+
+<doc:param name="footnote.font.size" xmlns="">
+<refpurpose>The font size for footnotes</refpurpose>
+<refdescription>
+<para>The footnote font size is used for...footnotes!
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<!-- general H&J setup -->
+<xsl:param name="hyphenate">true</xsl:param>
+
+<doc:param name="hyphenate" xmlns="">
+<refpurpose>Specify hyphenation behavior</refpurpose>
+<refdescription>
+<para>If true, words may be hyphenated. Otherwise, they may not.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="alignment">justify</xsl:param>
+
+<doc:param name="alignment" xmlns="">
+<refpurpose>Specify the default text alignment</refpurpose>
+<refdescription>
+<para>The default text alignment is used for most body text.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="stylesheet.result.type" select="'fo'"/>
+
+<doc:param name="stylesheet.result.type" xmlns="">
+<refpurpose>Identifies the output format of this stylesheet</refpurpose>
+<refdescription>
+<para>The extension functions need to know if the output format
+is HTML ('html') or XSL Formatting Objects ('fo'). This variable answers
+that question. Valid settings are 'html' or 'fo'.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.component.toc" select="0" doc:type='boolean'/>
+
+<doc:param name="generate.component.toc" xmlns="">
+<refpurpose>Generate a table of contents for components?</refpurpose>
+<refdescription>
+<para>If non-zero, a table of contents is generated at the beginning
+of each component (chapters, appendixes, etc.)
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.division.toc" select="1" doc:type='boolean'/>
+
+<doc:param name="generate.division.toc" xmlns="">
+<refpurpose>Generate a table of contents for divisions?</refpurpose>
+<refdescription>
+<para>If non-zero, a table of contents is generated at the beginning
+of each division (sets, books, etc.)
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.division.figure.lot" select="1" doc:type='boolean'/>
+
+<doc:param name="generate.division.figure.lot" xmlns="">
+<refpurpose>Generate a list of titles for Figures?</refpurpose>
+<refdescription>
+<para>If non-zero, a list of titles is generated for Figures.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.division.example.lot" select="1" doc:type='boolean'/>
+
+<doc:param name="generate.division.example.lot" xmlns="">
+<refpurpose>Generate a list of titles for Examples?</refpurpose>
+<refdescription>
+<para>If non-zero, a list of titles is generated for Examples.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.division.equation.lot" select="1" doc:type='boolean'/>
+
+<doc:param name="generate.division.equation.lot" xmlns="">
+<refpurpose>Generate a list of titles for Equations?</refpurpose>
+<refdescription>
+<para>If non-zero, a list of titles is generated for Equations.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.division.table.lot" select="1" doc:type='boolean'/>
+
+<doc:param name="generate.division.table.lot" xmlns="">
+<refpurpose>Generate a list of titles for Tables?</refpurpose>
+<refdescription>
+<para>If non-zero, a list of titles is generated for Tables.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="passivetex.extensions" select="0" doc:type='boolean'/>
+
+<doc:param name="passivetex.extensions" xmlns="">
+<refpurpose>Enable PassiveTeX extensions?</refpurpose>
+<refdescription>
+<para>If non-zero,
+<ulink url="http://users.ox.ac.uk/~rahtz/passivetex/">PassiveTeX</ulink>
+extensions will be used. At present, this consists of PDF bookmarks
+and sorted index terms.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="fop.extensions" select="0" doc:type='boolean'/>
+
+<doc:param name="fop.extensions" xmlns="">
+<refpurpose>Enable FOP extensions?</refpurpose>
+<refdescription>
+<para>If non-zero,
+<ulink url="http://xml.apache.org/fop/">FOP</ulink>
+extensions will be used. At present, this consists of PDF bookmarks.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="default.units" select="'pt'" doc:type='list'
+           doc:list='cm mm in pt pc px em'/>
+
+<doc:param name="default.units" xmlns="">
+<refpurpose>Default units for an unqualified dimension</refpurpose>
+<refdescription>
+<para>If an unqualified dimension is encountered (for example, in a
+graphic width), the <parameter>default-units</parameter> will be used for the
+units. Unqualified dimensions are not allowed in XSL Formatting Objects.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+
+<xsl:param name="generate.index" select="1" doc:type='boolean'/>
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/pi.xsl b/xsl/fo/pi.xsl
new file mode 100644 (file)
index 0000000..72c574c
--- /dev/null
@@ -0,0 +1,183 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="processing-instruction()">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="dbfo-attribute">
+  <xsl:param name="pis" select="processing-instruction('dbfo')"/>
+  <xsl:param name="attribute">filename</xsl:param>
+  <xsl:param name="count">1</xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($pis)">
+      <!-- not found -->
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="pi">
+        <xsl:value-of select="$pis[$count]"/>
+      </xsl:variable>
+      <xsl:choose>
+        <xsl:when test="contains($pi,concat($attribute, '='))">
+          <xsl:variable name="rest" select="substring-after($pi,concat($attribute,'='))"/>
+          <xsl:variable name="quote" select="substring($rest,1,1)"/>
+          <xsl:value-of select="substring-before(substring($rest,2),$quote)"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="dbfo-attribute">
+            <xsl:with-param name="pis" select="$pis"/>
+            <xsl:with-param name="attribute" select="$attribute"/>
+            <xsl:with-param name="count" select="$count + 1"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="dbfo-filename">
+  <xsl:param name="pis" select="./processing-instruction('dbfo')"/>
+  <xsl:call-template name="dbfo-attribute">
+    <xsl:with-param name="pis" select="$pis"/>
+    <xsl:with-param name="attribute">filename</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="dbfo-dir">
+  <xsl:param name="pis" select="./processing-instruction('dbfo')"/>
+  <xsl:call-template name="dbfo-attribute">
+    <xsl:with-param name="pis" select="$pis"/>
+    <xsl:with-param name="attribute">dir</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process.cmdsynopsis.list">
+  <xsl:param name="cmdsynopses"/><!-- empty node list by default -->
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($cmdsynopses)"></xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="cmdsyn" select="$cmdsynopses[$count]"/>
+
+       <dt>
+       <a>
+         <xsl:attribute name="href">
+           <xsl:call-template name="object.id">
+             <xsl:with-param name="object" select="$cmdsyn"/>
+           </xsl:call-template>
+         </xsl:attribute>
+
+         <xsl:choose>
+           <xsl:when test="$cmdsyn/@xreflabel">
+             <xsl:call-template name="xref.xreflabel">
+               <xsl:with-param name="target" select="$cmdsyn"/>
+             </xsl:call-template>
+           </xsl:when>
+           <xsl:otherwise>
+             <xsl:apply-templates select="$cmdsyn" mode="xref-to">
+               <xsl:with-param name="target" select="$cmdsyn"/>
+             </xsl:apply-templates>
+           </xsl:otherwise>
+         </xsl:choose>
+       </a>
+       </dt>
+
+        <xsl:call-template name="process.cmdsynopsis.list">
+          <xsl:with-param name="cmdsynopses" select="$cmdsynopses"/>
+          <xsl:with-param name="count" select="$count+1"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="processing-instruction('dbcmdlist')">
+  <xsl:variable name="cmdsynopses" select="..//cmdsynopsis"/>
+
+  <xsl:if test="count($cmdsynopses)&lt;1">
+    <xsl:message><xsl:text>No cmdsynopsis elements matched dbcmdlist PI, perhaps it's nested too deep?</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <dl>
+    <xsl:call-template name="process.cmdsynopsis.list">
+      <xsl:with-param name="cmdsynopses" select="$cmdsynopses"/>
+    </xsl:call-template>
+  </dl>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process.funcsynopsis.list">
+  <xsl:param name="funcsynopses"/><!-- empty node list by default -->
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($funcsynopses)"></xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="cmdsyn" select="$funcsynopses[$count]"/>
+
+       <dt>
+       <a>
+         <xsl:attribute name="href">
+           <xsl:call-template name="object.id">
+             <xsl:with-param name="object" select="$cmdsyn"/>
+           </xsl:call-template>
+         </xsl:attribute>
+
+         <xsl:choose>
+           <xsl:when test="$cmdsyn/@xreflabel">
+             <xsl:call-template name="xref.xreflabel">
+               <xsl:with-param name="target" select="$cmdsyn"/>
+             </xsl:call-template>
+           </xsl:when>
+           <xsl:otherwise>
+              <xsl:apply-templates select="$cmdsyn" mode="xref-to">
+                <xsl:with-param name="target" select="$cmdsyn"/>
+              </xsl:apply-templates>
+           </xsl:otherwise>
+         </xsl:choose>
+       </a>
+       </dt>
+
+        <xsl:call-template name="process.funcsynopsis.list">
+          <xsl:with-param name="funcsynopses" select="$funcsynopses"/>
+          <xsl:with-param name="count" select="$count+1"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="processing-instruction('dbfunclist')">
+  <xsl:variable name="funcsynopses" select="..//funcsynopsis"/>
+
+  <xsl:if test="count($funcsynopses)&lt;1">
+    <xsl:message><xsl:text>No funcsynopsis elements matched dbfunclist PI, perhaps it's nested too deep?</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <dl>
+    <xsl:call-template name="process.funcsynopsis.list">
+      <xsl:with-param name="funcsynopses" select="$funcsynopses"/>
+    </xsl:call-template>
+  </dl>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/qandaset.xsl b/xsl/fo/qandaset.xsl
new file mode 100644 (file)
index 0000000..412f682
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:variable name="qanda.defaultlabel">number</xsl:variable>
+<xsl:variable name="generate.qandaset.toc" select="true()"/>
+<xsl:variable name="generate.qandadiv.toc" select="false()"/>
+
+<!-- ==================================================================== -->
+
+<!-- FIXME: WRITE THIS! -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/refentry.xsl b/xsl/fo/refentry.xsl
new file mode 100644 (file)
index 0000000..b1ccdc0
--- /dev/null
@@ -0,0 +1,236 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="reference">
+   <xsl:if test="not(partintro)">
+    <xsl:variable name="id">
+      <xsl:call-template name="object.id"/>
+    </xsl:variable>
+    <xsl:variable name="master-name">
+      <xsl:call-template name="select.pagemaster"/>
+    </xsl:variable>
+
+    <fo:page-sequence id="{$id}"
+                      hyphenate="{$hyphenate}"
+                      master-name="{$master-name}">
+      <xsl:attribute name="language">
+        <xsl:call-template name="l10n.language"/>
+      </xsl:attribute>
+      <xsl:if test="$double.sided != 0">
+        <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="running.head.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+      <xsl:apply-templates select="." mode="running.foot.mode">
+        <xsl:with-param name="master-name" select="$master-name"/>
+      </xsl:apply-templates>
+
+      <fo:flow flow-name="xsl-region-body">
+        <xsl:call-template name="reference.titlepage"/>
+      </fo:flow>
+    </fo:page-sequence>
+  </xsl:if>
+  <xsl:apply-templates select="partintro|refentry"/>
+</xsl:template>
+
+<xsl:template match="reference" mode="reference.titlepage.mode">
+  <xsl:call-template name="reference.titlepage"/>
+</xsl:template>
+
+<xsl:template match="reference/partintro">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="ancestor::reference"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:apply-templates select=".." mode="reference.titlepage.mode"/>
+      <xsl:if test="title">
+        <xsl:call-template name="partintro.titlepage"/>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="reference/docinfo"></xsl:template>
+<xsl:template match="reference/title"></xsl:template>
+<xsl:template match="reference/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="refentry">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <fo:block font-size="20pt" font-weight="bold">
+        <!-- FIXME: is this right? -->
+        <xsl:choose>
+          <xsl:when test="refmeta/refentrytitle">
+            <xsl:apply-templates select="refmeta/refentrytitle" mode="title"/>
+          </xsl:when>
+          <xsl:when test="refnamediv/refname">
+            <xsl:apply-templates select="refnamediv/refname" mode="title"/>
+          </xsl:when>
+        </xsl:choose>
+      </fo:block>
+      <xsl:apply-templates/>
+    </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="refmeta">
+</xsl:template>
+
+<xsl:template match="manvolnum">
+  <xsl:if test="$refentry.xref.manvolnum != 0">
+    <xsl:text>(</xsl:text>
+    <xsl:apply-templates/>
+    <xsl:text>)</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="refmiscinfo">
+</xsl:template>
+
+<xsl:template match="refentrytitle">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="refnamediv">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="refname">
+  <xsl:if test="$refentry.generate.name != 0">
+    <fo:block font-size="18pt" font-weight="bold">
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'RefName'"/>
+      </xsl:call-template>
+     </fo:block>
+  </xsl:if>
+  <xsl:apply-templates/>
+  <xsl:if test="following-sibling::refname">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="refpurpose">
+  <xsl:text> </xsl:text>
+  <xsl:call-template name="dingbat">
+    <xsl:with-param name="dingbat">em-dash</xsl:with-param>
+  </xsl:call-template>
+  <xsl:text> </xsl:text>
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="refdescriptor">
+  <!-- todo: finish this -->
+</xsl:template>
+
+<xsl:template match="refclass">
+  <fo:block font-weight="bold">
+    <xsl:if test="@role">
+      <xsl:value-of select="@role"/>
+      <xsl:text>: </xsl:text>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="refsynopsisdiv">
+  <fo:block>
+    <fo:block font-size="18pt" font-weight="bold">
+      <xsl:text>Synopsis (what about the title?)</xsl:text>
+    </fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+<xsl:template match="refsynopsisdiv/title">
+</xsl:template>
+
+<xsl:template match="refsect1|refsect2|refsect3">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="refsect1/title">
+  <fo:block font-size="18pt" font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="refsect2/title">
+  <fo:block font-size="16pt" font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="refsect3/title">
+  <fo:block font-size="14pt" font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/sections.xsl b/xsl/fo/sections.xsl
new file mode 100644 (file)
index 0000000..a544f08
--- /dev/null
@@ -0,0 +1,281 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="section">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="section.titlepage"/>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="/section">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="ancestor::reference"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="section.titlepage"/>
+      <xsl:apply-templates/>
+   </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="title" mode="section.titlepage.recto.mode">
+  <xsl:variable name="section" select="(ancestor::section
+                                        |ancestor::simplesect
+                                        |ancestor::sect1
+                                        |ancestor::sect2
+                                        |ancestor::sect3
+                                        |ancestor::sect4
+                                        |ancestor::sect5)[last()]"/>
+  <fo:block keep-with-next.within-column="always">
+    <xsl:variable name="id">
+      <xsl:call-template name="object.id">
+        <xsl:with-param name="object" select="$section"/>
+      </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:variable name="level">
+      <xsl:call-template name="section.level">
+        <xsl:with-param name="node" select="$section"/>
+      </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:variable name="title">
+      <xsl:apply-templates select="$section" mode="title.markup"/>
+    </xsl:variable>
+
+    <xsl:if test="$passivetex.extensions != 0">
+      <fotex:bookmark xmlns:fotex="http://www.tug.org/fotex" 
+                      fotex-bookmark-level="{$level + 1}" 
+                      fotex-bookmark-label="{$id}">
+        <xsl:value-of select="$title"/>
+      </fotex:bookmark>
+    </xsl:if>
+
+    <xsl:call-template name="section.heading">
+      <xsl:with-param name="level" select="$level"/>
+      <xsl:with-param name="title" select="$title"/>
+    </xsl:call-template>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="sect1">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="sect1.titlepage"/>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="/sect1">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="ancestor::reference"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="master-name">
+    <xsl:call-template name="select.pagemaster"/>
+  </xsl:variable>
+
+  <fo:page-sequence id="{$id}"
+                    hyphenate="{$hyphenate}"
+                    master-name="{$master-name}">
+    <xsl:attribute name="language">
+      <xsl:call-template name="l10n.language"/>
+    </xsl:attribute>
+    <xsl:if test="$double.sided != 0">
+      <xsl:attribute name="force-page-count">end-on-even</xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates select="." mode="running.head.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+    <xsl:apply-templates select="." mode="running.foot.mode">
+      <xsl:with-param name="master-name" select="$master-name"/>
+    </xsl:apply-templates>
+
+    <fo:flow flow-name="xsl-region-body">
+      <xsl:call-template name="sect1.titlepage"/>
+      <xsl:apply-templates/>
+   </fo:flow>
+  </fo:page-sequence>
+</xsl:template>
+
+<xsl:template match="title" mode="sect1.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="sect2">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="sect2.titlepage"/>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="title" mode="sect2.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="sect3">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="sect3.titlepage"/>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="title" mode="sect3.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="sect4">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="sect4.titlepage"/>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="title" mode="sect4.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="sect5">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="sect5.titlepage"/>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="title" mode="sect5.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="simplesect">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <fo:block id="{$id}">
+    <xsl:call-template name="simplesect.titlepage"/>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="title" mode="simplesect.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="section/title"></xsl:template>
+<xsl:template match="sectioninfo"></xsl:template>
+
+<xsl:template match="sect1/title"></xsl:template>
+<xsl:template match="sect1info"></xsl:template>
+
+<xsl:template match="sect2/title"></xsl:template>
+<xsl:template match="sect2info"></xsl:template>
+
+<xsl:template match="sect3/title"></xsl:template>
+<xsl:template match="sect3info"></xsl:template>
+
+<xsl:template match="sect4/title"></xsl:template>
+<xsl:template match="sect4info"></xsl:template>
+
+<xsl:template match="sect5/title"></xsl:template>
+<xsl:template match="sect5info"></xsl:template>
+
+<xsl:template match="simplesect/title"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="section.heading">
+  <xsl:param name="level">1</xsl:param>
+  <xsl:param name="title"></xsl:param>
+  <xsl:variable name="fsize">
+    <xsl:choose>
+      <xsl:when test="$level=1">18</xsl:when>
+      <xsl:when test="$level=2">16</xsl:when>
+      <xsl:when test="$level=3">14</xsl:when>
+      <xsl:when test="$level=4">12</xsl:when>
+      <xsl:when test="$level=5">12</xsl:when>
+      <xsl:otherwise>10</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <fo:block font-size="{$fsize}pt" 
+            font-weight="bold"
+            space-before.minimum="1em"
+            space-before.optimum="1.5em"
+            space-before.maximum="2em">
+    <xsl:copy-of select="$title"/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="bridgehead">
+  <!-- need to calculate depth! -->
+  <fo:block font-size="16pt" font-weight="bold">
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/fo/synop.xsl b/xsl/fo/synop.xsl
new file mode 100644 (file)
index 0000000..4eb9a04
--- /dev/null
@@ -0,0 +1,240 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="synopsis">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="cmdsynopsis">
+  <fo:block>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="cmdsynopsis/command">
+  <xsl:call-template name="inline.monoseq"/>
+  <xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template match="cmdsynopsis/command[1]" priority="2">
+  <xsl:call-template name="inline.monoseq"/>
+  <xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template match="group|arg">
+  <xsl:variable name="choice" select="@choice"/>
+  <xsl:variable name="rep" select="@rep"/>
+  <xsl:variable name="sepchar">
+    <xsl:choose>
+      <xsl:when test="ancestor-or-self::*/@sepchar">
+        <xsl:value-of select="ancestor-or-self::*/@sepchar"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:text> </xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:if test="position()>1"><xsl:value-of select="$sepchar"/></xsl:if>
+  <xsl:choose>
+    <xsl:when test="$choice='plain'">
+      <xsl:value-of select="$arg.choice.plain.open.str"/>
+    </xsl:when>
+    <xsl:when test="$choice='req'">
+      <xsl:value-of select="$arg.choice.req.open.str"/>
+    </xsl:when>
+    <xsl:when test="$choice='opt'">
+      <xsl:value-of select="$arg.choice.opt.open.str"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$arg.choice.def.open.str"/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:apply-templates/>
+  <xsl:choose>
+    <xsl:when test="$rep='repeat'">
+      <xsl:value-of select="$arg.rep.repeat.str"/>
+    </xsl:when>
+    <xsl:when test="$rep='norepeat'">
+      <xsl:value-of select="$arg.rep.norepeat.str"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$arg.rep.def.str"/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:choose>
+    <xsl:when test="$choice='plain'">
+      <xsl:value-of select="$arg.choice.plain.close.str"/>
+    </xsl:when>
+    <xsl:when test="$choice='req'">
+      <xsl:value-of select="$arg.choice.req.close.str"/>
+    </xsl:when>
+    <xsl:when test="$choice='opt'">
+      <xsl:value-of select="$arg.choice.opt.close.str"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$arg.choice.def.close.str"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="group/arg">
+  <xsl:variable name="choice" select="@choice"/>
+  <xsl:variable name="rep" select="@rep"/>
+  <xsl:if test="position()>1"><xsl:value-of select="$arg.or.sep"/></xsl:if>
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="sbr">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="synopfragmentref">
+  <xsl:variable name="target" select="id(@linkend)"/>
+  <xsl:variable name="snum">
+    <xsl:apply-templates select="$target" mode="synopfragment.number"/>
+  </xsl:variable>
+  <fo:inline font-style="italic">
+    <xsl:text>(</xsl:text>
+    <xsl:value-of select="$snum"/>
+    <xsl:text>)</xsl:text>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="synopfragment" mode="synopfragment.number">
+  <xsl:number format="1"/>
+</xsl:template>
+
+<xsl:template match="synopfragment">
+  <xsl:variable name="snum">
+    <xsl:apply-templates select="." mode="synopfragment.number"/>
+  </xsl:variable>
+  <fo:block>
+    <xsl:text>(</xsl:text>
+    <xsl:value-of select="$snum"/>
+    <xsl:text>)</xsl:text>
+    <xsl:text> </xsl:text>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>   
+
+<xsl:template match="funcsynopsis">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+<xsl:template match="funcsynopsisinfo">
+  <fo:block><xsl:apply-templates/></fo:block>
+</xsl:template>
+
+<xsl:template match="funcprototype">
+  <fo:block font-family="monospace">
+    <xsl:apply-templates/>
+    <xsl:if test="$funcsynopsis.style='kr'">
+      <xsl:apply-templates select="./paramdef" mode="kr-funcsynopsis-mode"/>
+    </xsl:if>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="funcdef">
+  <fo:inline font-family="monospace">
+    <xsl:apply-templates/>
+  </fo:inline>
+</xsl:template>
+
+<xsl:template match="funcdef/function">
+  <xsl:choose>
+    <xsl:when test="$funcsynopsis.decoration != 0">
+      <fo:inline font-weight="bold">
+        <xsl:apply-templates/>
+      </fo:inline>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="void">
+  <xsl:choose>
+    <xsl:when test="$funcsynopsis.style='ansi'">
+      <xsl:text>(void);</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>();</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="varargs">
+  <xsl:text>(...);</xsl:text>
+</xsl:template>
+
+<xsl:template match="paramdef">
+  <xsl:variable name="paramnum">
+    <xsl:number count="paramdef" format="1"/>
+  </xsl:variable>
+  <xsl:if test="$paramnum=1">(</xsl:if>
+  <xsl:choose>
+    <xsl:when test="$funcsynopsis.style='ansi'">
+      <xsl:apply-templates/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates select="./parameter"/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:choose>
+    <xsl:when test="following-sibling::paramdef">
+      <xsl:text>, </xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>);</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="paramdef/parameter">
+  <xsl:choose>
+    <xsl:when test="$funcsynopsis.decoration != 0">
+      <xsl:apply-templates/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:if test="following-sibling::parameter">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+</xsl:template>  
+
+<xsl:template match="paramdef" mode="kr-funcsynopsis-mode">
+  <xsl:apply-templates/>
+  <xsl:text>;</xsl:text>
+</xsl:template>
+
+<xsl:template match="funcparams">
+  <xsl:text>(</xsl:text>
+  <xsl:apply-templates/>
+  <xsl:text>)</xsl:text>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/table.xsl b/xsl/fo/table.xsl
new file mode 100644 (file)
index 0000000..d677e45
--- /dev/null
@@ -0,0 +1,711 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                xmlns:stbl="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Table"
+                xmlns:xtbl="com.nwalsh.xalan.Table"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="doc stbl xtbl lxslt"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<doc:reference xmlns="">
+<referenceinfo>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<copyright><year>1999</year><year>2000</year>
+<holder>Norman Walsh</holder>
+</copyright>
+</referenceinfo>
+<title>Formatting Object Table Reference</title>
+
+<partintro>
+<section><title>Introduction</title>
+
+<para>This is technical reference documentation for the DocBook XSL
+Stylesheets; it documents (some of) the parameters, templates, and
+other elements of the stylesheets.</para>
+
+<para>This is not intended to be <quote>user</quote> documentation.
+It is provided for developers writing customization layers for the
+stylesheets, and for anyone who's interested in <quote>how it
+works</quote>.</para>
+
+<para>Although I am trying to be thorough, this documentation is known
+to be incomplete. Don't forget to read the source, too :-)</para>
+</section>
+</partintro>
+</doc:reference>
+
+<!-- ==================================================================== -->
+
+<lxslt:component prefix="xtbl"
+                 functions="adjustColumnWidths"/>
+
+<!-- ==================================================================== -->
+
+<xsl:param name="table-border-thickness" select="'0.5pt'"/>
+<xsl:param name="table-border-padding" select="'2pt'"/>
+<xsl:param name="table-border-style" select="'solid'"/>
+<xsl:param name="table-border-color" select="'black'"/>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="border">
+  <xsl:param name="side" select="'left'"/>
+  <xsl:param name="padding" select="0"/>
+
+  <xsl:attribute name="border-{$side}">
+    <xsl:value-of select="$table-border-thickness"/>
+    <xsl:text> </xsl:text>
+    <xsl:value-of select="$table-border-style"/>
+    <xsl:text> </xsl:text>
+    <xsl:value-of select="$table-border-color"/>
+    <xsl:text> </xsl:text>
+  </xsl:attribute>
+  <xsl:if test="$padding != 0">
+    <xsl:attribute name="padding-{$side}">
+      <xsl:value-of select="$table-border-padding"/>
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="tgroup">
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:variable name="explicit.table.width">
+    <xsl:call-template name="dbfo-attribute">
+      <xsl:with-param name="pis"
+                      select="../processing-instruction('dbfo')"/>
+      <xsl:with-param name="attribute" select="'table-width'"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:variable name="table.width">
+    <xsl:choose>
+      <xsl:when test="$explicit.table.width != ''">
+        <xsl:value-of select="$explicit.table.width"/>
+      </xsl:when>
+      <xsl:when test="$default.table.width = ''">
+        <xsl:text>100%</xsl:text>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$default.table.width"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="colspecs">
+    <xsl:choose>
+      <xsl:when test="$use.extensions != 0
+                      and $tablecolumns.extension != 0">
+        <xsl:call-template name="generate.colgroup.raw">
+          <xsl:with-param name="cols" select="@cols"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="generate.colgroup">
+          <xsl:with-param name="cols" select="@cols"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$use.extensions != 0
+                    and $tablecolumns.extension != 0">
+      <xsl:choose>
+        <xsl:when test="contains($vendor, 'SAXON 6')">
+          <xsl:copy-of select="stbl:adjustColumnWidths($colspecs)"/>
+        </xsl:when>
+        <xsl:when test="contains($vendor, 'SAXON 5')">
+          <!-- the saxon5 extension doesn't support this (yet) -->
+          <xsl:call-template name="generate.colgroup">
+            <xsl:with-param name="cols" select="@cols"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+          <xsl:copy-of select="xtbl:adjustColumnWidths($colspecs)"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:message terminate="yes">
+            <xsl:text>Don't know how to do adjust column widths with </xsl:text>
+            <xsl:value-of select="$vendor"/>
+          </xsl:message>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:copy-of select="$colspecs"/>
+    </xsl:otherwise>
+  </xsl:choose>
+
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="colspec"></xsl:template>
+
+<xsl:template match="spanspec"></xsl:template>
+
+<xsl:template match="thead">
+  <xsl:variable name="tgroup" select="parent::*"/>
+  <xsl:variable name="frame" select="$tgroup/parent::*/@frame"/>
+
+  <fo:table-header>
+    <xsl:choose>
+      <xsl:when test="$frame='topbot' or $frame='top'">
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'top'"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:when test="$frame='sides'">
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'left'"/>
+        </xsl:call-template>
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'right'"/>
+        </xsl:call-template>
+      </xsl:when>
+    </xsl:choose>
+    <xsl:apply-templates/>
+  </fo:table-header>
+</xsl:template>
+
+<xsl:template match="tbody">
+  <xsl:variable name="tgroup" select="parent::*"/>
+  <xsl:variable name="frame" select="$tgroup/parent::*/@frame"/>
+  <fo:table-body>
+    <xsl:choose>
+      <xsl:when test="$frame='top'">
+        <xsl:choose>
+          <xsl:when test="preceding-sibling::thead">
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="border">
+              <xsl:with-param name="side" select="'top'"/>
+            </xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:when test="$frame='bottom'">
+        <xsl:choose>
+          <xsl:when test="preceding-sibling::tfoot">
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="border">
+              <xsl:with-param name="side" select="'bottom'"/>
+            </xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:when test="$frame='topbot'">
+        <xsl:choose>
+          <xsl:when test="preceding-sibling::thead">
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="border">
+              <xsl:with-param name="side" select="'top'"/>
+            </xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose>
+          <xsl:when test="preceding-sibling::tfoot">
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:call-template name="border">
+              <xsl:with-param name="side" select="'bottom'"/>
+            </xsl:call-template>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:when test="$frame='sides'">
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'left'"/>
+        </xsl:call-template>
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'right'"/>
+        </xsl:call-template>
+      </xsl:when>
+    </xsl:choose>
+    <xsl:apply-templates/>
+  </fo:table-body>
+</xsl:template>
+
+<xsl:template match="row">
+  <fo:table-row>
+    <xsl:if test="@rowsep='1'">
+      <xsl:call-template name="border">
+        <xsl:with-param name="side" select="'bottom'"/>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </fo:table-row>
+</xsl:template>
+
+<xsl:template match="thead/row/entry">
+  <xsl:call-template name="process.cell"/>
+</xsl:template>
+
+<xsl:template match="tbody/row/entry">
+  <xsl:call-template name="process.cell"/>
+</xsl:template>
+
+<xsl:template match="tfoot/row/entry">
+  <xsl:call-template name="process.cell"/>
+</xsl:template>
+
+<xsl:template name="process.cell">
+  <xsl:variable name="row" select="parent::row"/>
+  <xsl:variable name="group" select="$row/parent::*[1]"/>
+  <xsl:variable name="frame" select="ancestor::tgroup/parent::*/@frame"/>
+
+  <xsl:param name="content">
+    <xsl:apply-templates/>
+  </xsl:param>
+
+  <fo:table-cell>
+    <xsl:choose>
+      <xsl:when test="$frame='all'">
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'left'"/>
+          <xsl:with-param name="padding" select="1"/>
+        </xsl:call-template>
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'right'"/>
+          <xsl:with-param name="padding" select="1"/>
+        </xsl:call-template>
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'top'"/>
+          <xsl:with-param name="padding" select="1"/>
+        </xsl:call-template>
+        <xsl:call-template name="border">
+          <xsl:with-param name="side" select="'bottom'"/>
+          <xsl:with-param name="padding" select="1"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:if test="@colsep='1'">
+          <xsl:call-template name="border">
+            <xsl:with-param name="side" select="'right'"/>
+            <xsl:with-param name="padding" select="1"/>
+          </xsl:call-template>
+        </xsl:if>
+        <xsl:if test="@rowsep='1'">
+          <xsl:call-template name="border">
+            <xsl:with-param name="side" select="'bottom'"/>
+            <xsl:with-param name="padding" select="1"/>
+          </xsl:call-template>
+        </xsl:if>
+      </xsl:otherwise>
+    </xsl:choose>
+
+    <xsl:if test="@morerows">
+      <xsl:attribute name="number-rows-spanned">
+        <xsl:value-of select="@morerows+1"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@namest">
+      <xsl:attribute name="number-columns-spanned">
+        <xsl:call-template name="calculate.colspan"/>
+      </xsl:attribute>
+    </xsl:if>
+
+    <fo:block>
+      <xsl:copy-of select="$content"/>
+    </fo:block>
+  </fo:table-cell>
+</xsl:template>
+
+<xsl:template name="generate.colgroup.raw">
+  <xsl:param name="cols" select="1"/>
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count>$cols"></xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="generate.col.raw">
+        <xsl:with-param name="countcol" select="$count"/>
+      </xsl:call-template>
+      <xsl:call-template name="generate.colgroup.raw">
+        <xsl:with-param name="cols" select="$cols"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="generate.colgroup">
+  <xsl:param name="cols" select="1"/>
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count>$cols"></xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="generate.col">
+        <xsl:with-param name="countcol" select="$count"/>
+      </xsl:call-template>
+      <xsl:call-template name="generate.colgroup">
+        <xsl:with-param name="cols" select="$cols"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="generate.col.raw">
+  <!-- generate the table-column for column countcol -->
+  <xsl:param name="countcol">1</xsl:param>
+  <xsl:param name="colspecs" select="./colspec"/>
+  <xsl:param name="count">1</xsl:param>
+  <xsl:param name="colnum">1</xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($colspecs)">
+      <fo:table-column column-number="{$countcol}"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
+
+      <xsl:variable name="colspec.colnum">
+        <xsl:choose>
+          <xsl:when test="$colspec/@colnum">
+            <xsl:value-of select="$colspec/@colnum"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$colnum"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:variable name="colspec.colwidth">
+        <xsl:choose>
+          <xsl:when test="$colspec/@colwidth">
+            <xsl:value-of select="$colspec/@colwidth"/>
+          </xsl:when>
+          <xsl:otherwise>1*</xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:choose>
+        <xsl:when test="$colspec.colnum=$countcol">
+          <fo:table-column column-number="{$countcol}">
+            <xsl:attribute name="column-width">
+              <xsl:value-of select="$colspec.colwidth"/>
+            </xsl:attribute>
+          </fo:table-column>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="generate.col.raw">
+            <xsl:with-param name="countcol" select="$countcol"/>
+            <xsl:with-param name="colspecs" select="$colspecs"/>
+            <xsl:with-param name="count" select="$count+1"/>
+            <xsl:with-param name="colnum">
+              <xsl:choose>
+                <xsl:when test="$colspec/@colnum">
+                  <xsl:value-of select="$colspec/@colnum + 1"/>
+                </xsl:when>
+                <xsl:otherwise>
+                  <xsl:value-of select="$colnum + 1"/>
+                </xsl:otherwise>
+              </xsl:choose>
+            </xsl:with-param>
+           </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="generate.col">
+  <!-- generate the table-column for column countcol -->
+  <xsl:param name="countcol">1</xsl:param>
+  <xsl:param name="colspecs" select="./colspec"/>
+  <xsl:param name="count">1</xsl:param>
+  <xsl:param name="colnum">1</xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($colspecs)">
+      <fo:table-column column-number="{$countcol}">
+       <xsl:variable name="colwidth">
+         <xsl:call-template name="calc.column.width"/>
+       </xsl:variable>
+       <xsl:if test="$colwidth != 'proportional-column-width(1)'">
+         <xsl:attribute name="column-width">
+           <xsl:value-of select="$colwidth"/>
+         </xsl:attribute>
+       </xsl:if>
+      </fo:table-column>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
+
+      <xsl:variable name="colspec.colnum">
+        <xsl:choose>
+          <xsl:when test="$colspec/@colnum">
+            <xsl:value-of select="$colspec/@colnum"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$colnum"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:variable name="colspec.colwidth">
+        <xsl:choose>
+          <xsl:when test="$colspec/@colwidth">
+            <xsl:value-of select="$colspec/@colwidth"/>
+          </xsl:when>
+          <xsl:otherwise>1*</xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:choose>
+        <xsl:when test="$colspec.colnum=$countcol">
+          <fo:table-column column-number="{$countcol}">
+           <xsl:variable name="colwidth">
+              <xsl:call-template name="calc.column.width">
+                <xsl:with-param name="colwidth">
+                  <xsl:value-of select="$colspec.colwidth"/>
+                </xsl:with-param>
+             </xsl:call-template>
+           </xsl:variable>
+           <xsl:if test="$colwidth != 'proportional-column-width(1)'">
+             <xsl:attribute name="column-width">
+               <xsl:value-of select="$colwidth"/>
+             </xsl:attribute>
+           </xsl:if>
+         </fo:table-column>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="generate.col">
+            <xsl:with-param name="countcol" select="$countcol"/>
+            <xsl:with-param name="colspecs" select="$colspecs"/>
+            <xsl:with-param name="count" select="$count+1"/>
+            <xsl:with-param name="colnum">
+              <xsl:choose>
+                <xsl:when test="$colspec/@colnum">
+                  <xsl:value-of select="$colspec/@colnum + 1"/>
+                </xsl:when>
+                <xsl:otherwise>
+                  <xsl:value-of select="$colnum + 1"/>
+                </xsl:otherwise>
+              </xsl:choose>
+            </xsl:with-param>
+           </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<doc:template name="calc.column.width" xmlns="">
+<refpurpose>Calculate an XSL FO table column width specification from a
+CALS table column width specification.</refpurpose>
+
+<refdescription>
+<para>CALS expresses table column widths in the following basic
+forms:</para>
+
+<itemizedlist>
+<listitem>
+<para><emphasis>99.99units</emphasis>, a fixed length specifier.</para>
+</listitem>
+<listitem>
+<para><emphasis>99.99</emphasis>, a fixed length specifier without any units.</para>
+</listitem>
+<listitem>
+<para><emphasis>99.99*</emphasis>, a relative length specifier.</para>
+</listitem>
+<listitem>
+<para><emphasis>99.99*+99.99units</emphasis>, a combination of both.</para>
+</listitem>
+</itemizedlist>
+
+<para>The CALS units are points (pt), picas (pi), centimeters (cm),
+millimeters (mm), and inches (in). These are the same units as XSL,
+except that XSL abbreviates picas "pc" instead of "pi". If a length
+specifier has no units, the CALS default unit (pt) is assumed.</para>
+
+<para>Relative length specifiers are represented in XSL with the
+proportional-column-width() function.</para>
+
+<para>Here are some examples:</para>
+
+<itemizedlist>
+<listitem>
+<para>"36pt" becomes "36pt"</para>
+</listitem>
+<listitem>
+<para>"3pi" becomes "3pc"</para>
+</listitem>
+<listitem>
+<para>"36" becomes "36pt"</para>
+</listitem>
+<listitem>
+<para>"3*" becomes "proportional-column-width(3)"</para>
+</listitem>
+<listitem>
+<para>"3*+2pi" becomes "proportional-column-width(3)+2pc"</para>
+</listitem>
+<listitem>
+<para>"1*+2" becomes "proportional-column-width(1)+2pt"</para>
+</listitem>
+</itemizedlist>
+</refdescription>
+
+<refparameter>
+<variablelist>
+<varlistentry><term>colwidth</term>
+<listitem>
+<para>The CALS column width specification.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</refparameter>
+
+<refreturn>
+<para>The XSL column width specification.</para>
+</refreturn>
+</doc:template>
+
+<xsl:template name="calc.column.width">
+  <xsl:param name="colwidth">1*</xsl:param>
+
+  <!-- Ok, the colwidth could have any one of the following forms: -->
+  <!--        1*       = proportional width -->
+  <!--     1unit       = 1.0 units wide -->
+  <!--         1       = 1pt wide -->
+  <!--  1*+1unit       = proportional width + some fixed width -->
+  <!--      1*+1       = proportional width + some fixed width -->
+
+  <!-- If it has a proportional width, translate it to XSL -->
+  <xsl:if test="contains($colwidth, '*')">
+    <xsl:text>proportional-column-width(</xsl:text>
+    <xsl:value-of select="substring-before($colwidth, '*')"/>
+    <xsl:text>)</xsl:text>
+  </xsl:if>
+
+  <!-- Now grab the non-proportional part of the specification -->
+  <xsl:variable name="width-units">
+    <xsl:choose>
+      <xsl:when test="contains($colwidth, '*')">
+        <xsl:value-of
+             select="normalize-space(substring-after($colwidth, '*'))"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="normalize-space($colwidth)"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!-- Ok, now the width-units could have any one of the following forms: -->
+  <!--                 = <empty string> -->
+  <!--     1unit       = 1.0 units wide -->
+  <!--         1       = 1pt wide -->
+  <!-- with an optional leading sign -->
+
+  <!-- Grab the width part by blanking out the units part and discarding -->
+  <!-- whitespace. It's not pretty, but it works. -->
+  <xsl:variable name="width"
+       select="normalize-space(translate($width-units,
+                                         '+-0123456789.abcdefghijklmnopqrstuvwxyz',
+                                         '+-0123456789.'))"/>
+
+  <!-- Grab the units part by blanking out the width part and discarding -->
+  <!-- whitespace. It's not pretty, but it works. -->
+  <xsl:variable name="units"
+       select="normalize-space(translate($width-units,
+                                         'abcdefghijklmnopqrstuvwxyz+-0123456789.',
+                                         'abcdefghijklmnopqrstuvwxyz'))"/>
+
+  <!-- Output the width -->
+  <xsl:value-of select="$width"/>
+
+  <!-- Output the units, translated appropriately -->
+  <xsl:choose>
+    <xsl:when test="$units = 'pi'">pc</xsl:when>
+    <xsl:when test="$units = '' and $width != ''">pt</xsl:when>
+    <xsl:otherwise><xsl:value-of select="$units"/></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="colspec.colnum">
+  <!-- when this macro is called, the current context must be an entry -->
+  <xsl:param name="colname"></xsl:param>
+  <!-- .. = row, ../.. = thead|tbody, ../../.. = tgroup -->
+  <xsl:param name="colspecs" select="../../../../tgroup/colspec"/>
+  <xsl:param name="count">1</xsl:param>
+  <xsl:param name="colnum">1</xsl:param>
+  <xsl:choose>
+    <xsl:when test="$count>count($colspecs)"></xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
+<!--
+      <xsl:value-of select="$count"/>:
+      <xsl:value-of select="$colspec/@colname"/>=
+      <xsl:value-of select="$colnum"/>
+-->
+      <xsl:choose>
+        <xsl:when test="$colspec/@colname=$colname">
+          <xsl:choose>
+            <xsl:when test="$colspec/@colnum">
+              <xsl:value-of select="$colspec/@colnum"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:value-of select="$colnum"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="colspec.colnum">
+            <xsl:with-param name="colname" select="$colname"/>
+            <xsl:with-param name="colspecs" select="$colspecs"/>
+            <xsl:with-param name="count" select="$count+1"/>
+            <xsl:with-param name="colnum">
+              <xsl:choose>
+                <xsl:when test="$colspec/@colnum">
+                  <xsl:value-of select="$colspec/@colnum + 1"/>
+                </xsl:when>
+                <xsl:otherwise>
+                  <xsl:value-of select="$colnum + 1"/>
+                </xsl:otherwise>
+              </xsl:choose>
+            </xsl:with-param>
+           </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="calculate.colspan">
+  <xsl:variable name="scol">
+    <xsl:call-template name="colspec.colnum">
+      <xsl:with-param name="colname" select="@namest"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="ecol">
+    <xsl:call-template name="colspec.colnum">
+      <xsl:with-param name="colname" select="@nameend"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:value-of select="$ecol - $scol + 1"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/titlepage.templates.xml b/xsl/fo/titlepage.templates.xml
new file mode 100644 (file)
index 0000000..f479b22
--- /dev/null
@@ -0,0 +1,877 @@
+<!DOCTYPE t:templates [
+<!ENTITY hsize0 "10pt">
+<!ENTITY hsize1 "12pt">
+<!ENTITY hsize2 "14.4pt">
+<!ENTITY hsize3 "17.28pt">
+<!ENTITY hsize4 "20.736pt">
+<!ENTITY hsize5 "24.8832pt">
+<!ENTITY hsize0space "7.5pt"> <!-- 0.75 * hsize0 -->
+<!ENTITY hsize1space "9pt"> <!-- 0.75 * hsize1 -->
+<!ENTITY hsize2space "10.8pt"> <!-- 0.75 * hsize2 -->
+<!ENTITY hsize3space "12.96pt"> <!-- 0.75 * hsize3 -->
+<!ENTITY hsize4space "15.552pt"> <!-- 0.75 * hsize4 -->
+<!ENTITY hsize5space "18.6624pt"> <!-- 0.75 * hsize5 -->
+]>
+<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
+            xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param"
+             xmlns:fo="http://www.w3.org/1999/XSL/Format"
+             xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="article" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            named-template="component.title"
+            param:node="ancestor-or-self::article[1]"
+            fo:margin-left="-4pc"
+            fo:keep-with-next="always"
+            fo:font-size="&hsize5;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="set" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            named-template="division.title"
+            param:node="ancestor-or-self::set[1]"
+            fo:font-size="&hsize5;"
+            fo:space-before="&hsize5space;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="book" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            named-template="division.title"
+            param:node="ancestor-or-self::book[1]"
+            fo:font-size="&hsize5;"
+            fo:space-before="&hsize5space;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+      <subtitle predicate="[1]"
+               fo:font-size="&hsize4;"
+               fo:space-before="&hsize4space;"
+               fo:font-family="{$title.font.family}"/>
+      <corpauthor fo:font-size="&hsize3;"
+                 fo:keep-with-next="always"
+                 fo:space-before="2in"/>
+      <authorgroup fo:space-before="2in"/>
+      <author fo:font-size="&hsize3;"
+             fo:space-before="&hsize2space;"
+             fo:keep-with-next="always"/>
+    </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+      <title predicate="[1]"
+            fo:font-size="&hsize2;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+      <corpauthor/>
+      <authorgroup/>
+      <author/>
+      <pubdate fo:space-before="1em"/>
+      <copyright/>
+      <abstract/>
+      <legalnotice fo:font-size="8pt"/>
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+      <fo:block break-after="page"/>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+      <fo:block break-after="page"/>
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="part" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            named-template="division.title"
+            param:node="ancestor-or-self::part[1]"
+            fo:font-size="&hsize5;"
+            fo:space-before="&hsize5space;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-size="&hsize4;"
+             fo:space-before="&hsize4space;"
+             fo:font-weight='bold'
+             fo:font-style='italic'
+             fo:font-family="{$title.font.family}"/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="partintro" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          fo:font-size="&hsize3;"
+          fo:font-weight="bold"
+          fo:margin-left="-4pc"
+          fo:space-before="1em"
+          fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-size="&hsize2;"
+             fo:font-weight="bold"
+             fo:font-style="italic"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="reference" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            named-template="division.title"
+            param:node="ancestor-or-self::reference[1]"
+            fo:font-size="&hsize5;"
+            fo:space-before="&hsize5space;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="dedication" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="component.title"
+            param:node="ancestor-or-self::dedication[1]"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-family="{$title.font.family}"
+            fo:font-weight="bold"/>
+      <subtitle predicate="[1]"
+               fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="preface" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="component.title"
+            param:node="ancestor-or-self::preface[1]"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-family="{$title.font.family}"
+            fo:font-weight="bold"/>
+      <subtitle predicate="[1]"
+               fo:font-family="{$title.font.family}"/>
+      <corpauthor/>
+      <authorgroup/>
+      <author/>
+      <releaseinfo/>
+      <copyright/>
+      <legalnotice/>
+      <pubdate/>
+      <revision/>
+      <revhistory/>
+      <abstract/>
+    </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="chapter" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            named-template="component.title"
+            param:node="ancestor-or-self::chapter[1]"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+      <subtitle predicate="[1]"
+               fo:space-before="0.5em"
+               fo:margin-left="-4pc"
+               fo:font-style="italic"
+               fo:font-size="&hsize2;"
+               fo:font-weight="bold"
+               fo:font-family="{$title.font.family}"/>
+      <corpauthor/>
+      <authorgroup/>
+      <author/>
+      <releaseinfo/>
+      <copyright/>
+      <legalnotice/>
+      <pubdate/>
+      <revision/>
+      <revhistory/>
+      <abstract/>
+    </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="appendix" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            named-template="component.title"
+            param:node="ancestor-or-self::appendix[1]"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+      <subtitle predicate="[1]"
+               fo:font-family="{$title.font.family}"/>
+      <corpauthor/>
+      <authorgroup/>
+      <author/>
+      <releaseinfo/>
+      <copyright/>
+      <legalnotice/>
+      <pubdate/>
+      <revision/>
+      <revhistory/>
+      <abstract/>
+    </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="section" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          fo:margin-left="-4pc"
+          fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect1" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          fo:margin-left="-4pc"
+          fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect2" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          fo:margin-left="-4pc"
+          fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect3" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          fo:margin-left="-4pc"
+          fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect4" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          fo:margin-left="-4pc"
+          fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect5" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          fo:margin-left="-4pc"
+          fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="simplesect" wrapper="fo:block">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          fo:margin-left="-4pc"
+          fo:font-family="{$title.font.family}"/>
+    <subtitle predicate="[1]"
+             fo:font-family="{$title.font.family}"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="bibliography" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="component.title"
+            param:node="ancestor-or-self::bibliography[1]"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-family="{$title.font.family}"
+            fo:font-weight="bold"/>
+      <subtitle predicate="[1]"
+               fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="glossary" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="component.title"
+            param:node="ancestor-or-self::glossary[1]"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-family="{$title.font.family}"
+            fo:font-weight="bold"/>
+      <subtitle predicate="[1]"
+               fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="index" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="component.title"
+            param:node="ancestor-or-self::index[1]"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-family="{$title.font.family}"
+            fo:font-weight="bold"/>
+      <subtitle predicate="[1]"
+               fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="table.of.contents" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="gentext"
+            param:key="'TableofContents'"
+            fo:space-after="1em"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+  <t:titlepage element="list.of.tables" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="gentext"
+            param:key="'ListofTables'"
+            fo:space-after="1em"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+  <t:titlepage element="list.of.figures" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="gentext"
+            param:key="'ListofFigures'"
+            fo:space-after="1em"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+  <t:titlepage element="list.of.examples" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="gentext"
+            param:key="'ListofExamples'"
+            fo:space-after="1em"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+  <t:titlepage element="list.of.equations" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="gentext"
+            param:key="'ListofEquations'"
+            fo:space-after="1em"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+  <t:titlepage element="list.of.unknowns" wrapper="fo:block">
+    <t:titlepage-content side="recto">
+      <title predicate="[1]"
+            force="1"
+            named-template="gentext"
+            param:key="'ListofUnknown'"
+            fo:space-after="1em"
+            fo:margin-left="-4pc"
+            fo:font-size="&hsize3;"
+            fo:font-weight="bold"
+            fo:font-family="{$title.font.family}"/>
+    </t:titlepage-content>
+
+    <t:titlepage-content side="verso">
+    </t:titlepage-content>
+
+    <t:titlepage-separator>
+    </t:titlepage-separator>
+
+    <t:titlepage-before side="recto">
+    </t:titlepage-before>
+
+    <t:titlepage-before side="verso">
+    </t:titlepage-before>
+  </t:titlepage>
+
+<!-- ==================================================================== -->
+
+</t:templates>
diff --git a/xsl/fo/titlepage.xsl b/xsl/fo/titlepage.xsl
new file mode 100644 (file)
index 0000000..eeebfd9
--- /dev/null
@@ -0,0 +1,650 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:attribute-set name="book.titlepage.recto.style">
+  <xsl:attribute name="font-family">
+    <xsl:value-of select="$title.font.family"/>
+  </xsl:attribute>
+  <xsl:attribute name="font-weight">bold</xsl:attribute>
+  <xsl:attribute name="font-size">12pt</xsl:attribute>
+  <xsl:attribute name="text-align">center</xsl:attribute>
+</xsl:attribute-set>
+
+<xsl:attribute-set name="book.titlepage.verso.style">
+  <xsl:attribute name="font-size">10pt</xsl:attribute>
+</xsl:attribute-set>
+
+<xsl:attribute-set name="article.titlepage.recto.style"/>
+<xsl:attribute-set name="article.titlepage.verso.style"/>
+
+<xsl:attribute-set name="set.titlepage.recto.style"/>
+<xsl:attribute-set name="set.titlepage.verso.style"/>
+
+<xsl:attribute-set name="part.titlepage.recto.style">
+  <xsl:attribute name="text-align">center</xsl:attribute>
+</xsl:attribute-set>
+
+<xsl:attribute-set name="part.titlepage.verso.style"/>
+
+<xsl:attribute-set name="partintro.titlepage.recto.style"/>
+<xsl:attribute-set name="partintro.titlepage.verso.style"/>
+
+<xsl:attribute-set name="reference.titlepage.recto.style"/>
+<xsl:attribute-set name="reference.titlepage.verso.style"/>
+
+<xsl:attribute-set name="dedication.titlepage.recto.style"/>
+<xsl:attribute-set name="dedication.titlepage.verso.style"/>
+
+<xsl:attribute-set name="preface.titlepage.recto.style"/>
+<xsl:attribute-set name="preface.titlepage.verso.style"/>
+
+<xsl:attribute-set name="chapter.titlepage.recto.style"/>
+<xsl:attribute-set name="chapter.titlepage.verso.style"/>
+
+<xsl:attribute-set name="appendix.titlepage.recto.style"/>
+<xsl:attribute-set name="appendix.titlepage.verso.style"/>
+
+<xsl:attribute-set name="bibliography.titlepage.recto.style"/>
+<xsl:attribute-set name="bibliography.titlepage.verso.style"/>
+
+<xsl:attribute-set name="glossary.titlepage.recto.style"/>
+<xsl:attribute-set name="glossary.titlepage.verso.style"/>
+
+<xsl:attribute-set name="index.titlepage.recto.style"/>
+<xsl:attribute-set name="index.titlepage.verso.style"/>
+
+<xsl:attribute-set name="section.titlepage.recto.style"/>
+<xsl:attribute-set name="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect1.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect1.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect2.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect2.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect3.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect3.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect4.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect4.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect5.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect5.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="simplesect.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="simplesect.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="table.of.contents.titlepage.recto.style"/>
+<xsl:attribute-set name="table.of.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.tables.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.tables.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.figures.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.figures.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.equations.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.equations.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.examples.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.examples.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.unknowns.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.unknowns.contents.titlepage.verso.style"/>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="titlepage.mode">
+  <!-- if an element isn't found in this mode, try the default mode -->
+  <xsl:apply-templates select="."/>
+</xsl:template>
+
+<xsl:template match="abbrev" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="abstract" mode="titlepage.mode">
+  <fo:block>
+    <xsl:if test="title"> <!-- FIXME: add param for using default title? -->
+      <xsl:call-template name="formal.object.heading">
+        <xsl:with-param name="title">
+          <xsl:apply-templates select="." mode="title.markup"/>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="abstract/title" mode="titlepage.mode"/>
+
+<xsl:template match="abstract/title" mode="titlepage.abstract.title.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="address" mode="titlepage.mode">
+  <!-- use the normal address handling code -->
+  <xsl:apply-templates select="."/>
+</xsl:template>
+
+<xsl:template match="affiliation" mode="titlepage.mode">
+  <fo:block>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="artpagenums" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="author" mode="titlepage.mode">
+  <xsl:call-template name="person.name"/>
+  <xsl:apply-templates select="affiliation" mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="authorblurb" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="authorgroup" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="authorinitials" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="bibliomisc" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="bibliomset" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="collab" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="confgroup" mode="titlepage.mode">
+  <fo:block>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="confdates" mode="titlepage.mode">
+  <fo:block>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="conftitle" mode="titlepage.mode">
+  <fo:block>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="confnum" mode="titlepage.mode">
+  <!-- suppress -->
+</xsl:template>
+
+<xsl:template match="contractnum" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="contractsponsor" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="contrib" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="copyright" mode="titlepage.mode">
+  <xsl:variable name="years" select="year"/>
+  <xsl:variable name="holders" select="holder"/>
+
+  <xsl:call-template name="gentext">
+    <xsl:with-param name="key" select="'Copyright'"/>
+  </xsl:call-template>
+  <xsl:call-template name="gentext.space"/>
+  <xsl:call-template name="dingbat">
+    <xsl:with-param name="dingbat">copyright</xsl:with-param>
+  </xsl:call-template>
+  <xsl:call-template name="gentext.space"/>
+  <xsl:apply-templates select="$years" mode="titlepage.mode"/>
+  <xsl:if test="holder">
+    <xsl:call-template name="gentext.space"/>
+    <xsl:apply-templates select="$holders" mode="titlepage.mode"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="year" mode="titlepage.mode">
+  <xsl:apply-templates/><xsl:text>, </xsl:text>
+</xsl:template>
+
+<xsl:template match="year[position()=last()]" mode="titlepage.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="holder" mode="titlepage.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="corpauthor" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="corpname" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="date" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="edition" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+  <xsl:call-template name="gentext.space"/>
+  <xsl:call-template name="gentext">
+    <xsl:with-param name="key" select="'Edition'"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="editor" mode="titlepage.mode">
+  <xsl:call-template name="person.name"/>
+</xsl:template>
+
+<xsl:template match="editor[position()=1]" priority="2" mode="titlepage.mode">
+  <xsl:call-template name="gentext.edited.by"/>
+  <xsl:call-template name="person.name"/>
+</xsl:template>
+
+<xsl:template match="firstname" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="graphic" mode="titlepage.mode">
+  <!-- use the normal graphic handling code -->
+  <xsl:apply-templates select="."/>
+</xsl:template>
+
+<xsl:template match="honorific" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="isbn" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="issn" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="itermset" mode="titlepage.mode">
+  <!-- discard -->
+</xsl:template>
+
+<xsl:template match="invpartnumber" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="issuenum" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="jobtitle" mode="titlepage.mode">
+  <fo:block>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="keywordset" mode="titlepage.mode">
+</xsl:template>
+
+<xsl:template match="legalnotice" mode="titlepage.mode">
+  <fo:block>
+    <xsl:if test="title"> <!-- FIXME: add param for using default title? -->
+    <xsl:call-template name="formal.object.heading">
+        <xsl:with-param name="title">
+          <xsl:apply-templates select="." mode="title.markup"/>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="legalnotice/title" mode="titlepage.mode">
+</xsl:template>
+
+<xsl:template match="legalnotice/title" mode="titlepage.legalnotice.title.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="lineage" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="modespec" mode="titlepage.mode">
+  <!-- discard -->
+</xsl:template>
+
+<xsl:template match="orgdiv" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="orgname" mode="titlepage.mode">
+  <fo:block>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="othercredit" mode="titlepage.mode">
+  <xsl:call-template name="person.name"/>
+  <xsl:apply-templates mode="titlepage.mode" select="affiliation"/>
+</xsl:template>
+
+<xsl:template match="othername" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="pagenums" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="printhistory" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="productname" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="productnumber" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="pubdate" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="publishername" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="pubsnumber" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="releaseinfo" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="revhistory" mode="titlepage.mode">
+  <fo:table table-layout="fixed">
+    <fo:table-column column-number="1" column-width="33%"/>
+    <fo:table-column column-number="2" column-width="33%"/>
+    <fo:table-column column-number="3" column-width="33%"/>
+    <fo:table-body>
+      <fo:table-row>
+        <fo:table-cell number-columns-spanned="3">
+          <fo:block>
+            <xsl:call-template name="gentext">
+              <xsl:with-param name="key" select="'RevHistory'"/>
+            </xsl:call-template>
+          </fo:block>
+        </fo:table-cell>
+      </fo:table-row>
+      <xsl:apply-templates mode="titlepage.mode"/>
+    </fo:table-body>
+  </fo:table>
+</xsl:template>
+
+<xsl:template match="revhistory/revision" mode="titlepage.mode">
+  <xsl:variable name="revnumber" select=".//revnumber"/>
+  <xsl:variable name="revdate"   select=".//date"/>
+  <xsl:variable name="revauthor" select=".//authorinitials"/>
+  <xsl:variable name="revremark" select=".//revremark"/>
+  <fo:table-row>
+    <fo:table-cell>
+      <fo:block>
+        <xsl:if test="$revnumber">
+          <xsl:call-template name="gentext">
+            <xsl:with-param name="key" select="'Revision'"/>
+          </xsl:call-template>
+          <xsl:call-template name="gentext.space"/>
+          <xsl:apply-templates select="$revnumber[1]" mode="titlepage.mode"/>
+        </xsl:if>
+      </fo:block>
+    </fo:table-cell>
+    <fo:table-cell>
+      <fo:block>
+        <xsl:apply-templates select="$revdate[1]" mode="titlepage.mode"/>
+      </fo:block>
+    </fo:table-cell>
+    <fo:table-cell>
+      <fo:block>
+        <xsl:apply-templates select="$revauthor[1]" mode="titlepage.mode"/>
+      </fo:block>
+    </fo:table-cell>
+  </fo:table-row>
+  <xsl:if test="$revremark">
+    <fo:table-row>
+      <fo:table-cell number-columns-spanned="3">
+        <fo:block>
+          <xsl:apply-templates select="$revremark[1]" mode="titlepage.mode"/>
+        </fo:block>
+      </fo:table-cell>
+    </fo:table-row>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="revision/revnumber" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="revision/date" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="revision/authorinitials" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="revision/revremark" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="seriesvolnums" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="shortaffil" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="subjectset" mode="titlepage.mode">
+  <!-- discard -->
+</xsl:template>
+
+<xsl:template match="subtitle" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="surname" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="title" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="titleabbrev" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="volumenum" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+<!-- Book templates -->
+
+<!-- book recto -->
+
+<xsl:template match="authorgroup" mode="book.titlepage.recto.mode">
+  <xsl:apply-templates mode="book.titlepage.recto.auto.mode"/>
+</xsl:template>
+
+<!-- book verso -->
+
+<xsl:template match="title" mode="book.titlepage.verso.mode">
+  <fo:block>
+    <xsl:apply-templates mode="book.titlepage.verso.mode"/>
+
+    <xsl:if test="following-sibling::subtitle
+                  |following-sibling::bookinfo/subtitle">
+      <xsl:text>: </xsl:text>
+
+      <xsl:apply-templates select="(following-sibling::subtitle
+                                   |following-sibling::bookinfo/subtitle)[1]"
+                           mode="book.titlepage.verso.mode"/>
+    </xsl:if>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="book.titlepage.verso.mode">
+  <xsl:apply-templates mode="book.titlepage.verso.mode"/>
+  <xsl:if test="following-sibling::subtitle">
+    <xsl:text>: </xsl:text>
+    <xsl:apply-templates select="following-sibling::subtitle[1]"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="bookinfo/author" mode="book.titlepage.verso.mode">
+  <fo:block>
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'by'"/>
+    </xsl:call-template>
+    <xsl:text> </xsl:text>
+    <xsl:call-template name="person.name"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="bookinfo/corpauthor" mode="book.titlepage.verso.mode">
+  <fo:block>
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'by'"/>
+    </xsl:call-template>
+    <xsl:text> </xsl:text>
+    <xsl:apply-templates/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="authorgroup" mode="book.titlepage.verso.mode">
+  <fo:block>
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'by'"/>
+    </xsl:call-template>
+    <xsl:text> </xsl:text>
+    <xsl:apply-templates mode="book.titlepage.verso.mode"/>
+  </fo:block>
+</xsl:template>
+
+<xsl:template match="authorgroup/author" mode="book.titlepage.verso.mode">
+  <xsl:variable name="before" select="count(preceding-sibling::*)"/>
+  <xsl:variable name="after" select="count(following-sibling::*)"/>
+
+  <xsl:choose>
+    <xsl:when test="$before &gt; 1">
+      <xsl:text>, </xsl:text>
+    </xsl:when>
+    <xsl:when test="$before = 1 and $after &gt; 0">
+      <xsl:text>, </xsl:text>
+    </xsl:when>
+  </xsl:choose>
+
+  <xsl:if test="$before &gt; 0 and $after = 0">
+    <xsl:text> </xsl:text>
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'and'"/>
+    </xsl:call-template>
+    <xsl:text> </xsl:text>
+  </xsl:if>
+
+  <xsl:call-template name="person.name"/>
+</xsl:template>
+
+<xsl:template match="authorgroup/corpauthor" mode="book.titlepage.verso.mode">
+  <xsl:variable name="before" select="count(preceding-sibling::*)"/>
+  <xsl:variable name="after" select="count(preceding-sibling::*)"/>
+
+  <xsl:choose>
+    <xsl:when test="$before &gt; 1">
+      <xsl:text>, </xsl:text>
+    </xsl:when>
+    <xsl:when test="$before = 1 and $after &gt; 0">
+      <xsl:text>, </xsl:text>
+    </xsl:when>
+  </xsl:choose>
+
+  <xsl:if test="$after = 0">
+    <xsl:text> </xsl:text>
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'and'"/>
+    </xsl:call-template>
+    <xsl:text> </xsl:text>
+  </xsl:if>
+
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="pubdate" mode="book.titlepage.verso.mode">
+  <fo:block>
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'published'"/>
+    </xsl:call-template>
+    <xsl:text> </xsl:text>
+    <xsl:apply-templates mode="book.titlepage.verso.mode"/>
+  </fo:block>
+</xsl:template>
+
+<!-- ==================================================================== -->
+<!-- Part templates -->
+
+<!-- part recto -->
+
+<xsl:template match="title" mode="part.titlepage.recto.mode">
+  <xsl:apply-templates select="ancestor::part" mode="title.markup"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/fo/toc.xsl b/xsl/fo/toc.xsl
new file mode 100644 (file)
index 0000000..ea8c93f
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="toc">
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/verbatim.xsl b/xsl/fo/verbatim.xsl
new file mode 100644 (file)
index 0000000..693a117
--- /dev/null
@@ -0,0 +1,260 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                xmlns:sverb="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Verbatim"
+                xmlns:xverb="com.nwalsh.xalan.Verbatim"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="sverb xverb lxslt"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<lxslt:component prefix="xverb"
+                 functions="numberLines"/>
+
+<xsl:template match="programlisting|screen">
+  <xsl:param name="suppress-numbers" select="'0'"/>
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <!-- Obey the <?dbfo linenumbering.everyNth="x"?> PI -->
+  <xsl:variable name="pi.linenumbering.everyNth">
+    <xsl:call-template name="dbfo-attribute">
+      <xsl:with-param name="attribute" select="'everyNth'"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:variable name="everyNth">
+    <xsl:choose>
+      <xsl:when test="$pi.linenumbering.everyNth != ''">
+        <xsl:value-of select="$pi.linenumbering.everyNth"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$linenumbering.everyNth"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!-- Obey the <?dbfo linenumbering.separator="x"?> PI -->
+  <xsl:variable name="pi.linenumbering.separator">
+    <xsl:call-template name="dbfo-attribute">
+      <xsl:with-param name="attribute" select="'linenumbering.separator'"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:variable name="separator">
+    <xsl:choose>
+      <xsl:when test="$pi.linenumbering.separator != ''">
+        <xsl:value-of select="$pi.linenumbering.separator"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$linenumbering.separator"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$suppress-numbers = '0'
+                    and @linenumbering = 'numbered'
+                    and $use.extensions != '0'
+                    and $linenumbering.extension != '0'">
+      <xsl:variable name="rtf">
+        <xsl:apply-templates/>
+      </xsl:variable>
+      <fo:block wrap-option='no-wrap'
+                text-align='start'
+                white-space-collapse='false'
+                linefeed-treatment="preserve"
+                font-family='{$monospace.font.family}'
+                space-before.minimum="0.8em"
+                space-before.optimum="1em"
+                space-before.maximum="1.2em">
+        <xsl:call-template name="number.rtf.lines">
+          <xsl:with-param name="rtf" select="$rtf"/>
+          <xsl:with-param name="linenumbering.everyNth"
+                          select="$everyNth"/>
+          <xsl:with-param name="linenumbering.width"
+                          select="$linenumbering.width"/>
+          <xsl:with-param name="linenumbering.separator"
+                          select="$separator"/>
+        </xsl:call-template>
+      </fo:block>
+    </xsl:when>
+    <xsl:otherwise>
+      <fo:block wrap-option='no-wrap'
+                text-align='start'
+                white-space-collapse='false'
+                linefeed-treatment="preserve"
+                font-family='{$monospace.font.family}'
+                space-before.minimum="0.8em"
+                space-before.optimum="1em"
+                space-before.maximum="1.2em">
+        <xsl:apply-templates/>
+      </fo:block>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="literallayout">
+  <xsl:param name="suppress-numbers" select="'0'"/>
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:variable name="rtf">
+    <xsl:apply-templates/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$suppress-numbers = '0'
+                    and @linenumbering = 'numbered'
+                    and $use.extensions != '0'
+                    and $linenumbering.extension != '0'">
+      <xsl:choose>
+        <xsl:when test="@class='monospaced'">
+          <fo:block wrap-option='no-wrap'
+                    text-align='start'
+                    linefeed-treatment="preserve"
+                    font-family='{$monospace.font.family}'
+                    white-space-collapse='false'
+                    space-before.minimum="0.8em"
+                    space-before.optimum="1em"
+                    space-before.maximum="1.2em">
+            <xsl:call-template name="number.rtf.lines">
+              <xsl:with-param name="rtf" select="$rtf"/>
+              <xsl:with-param name="linenumbering.everyNth"
+                              select="$linenumbering.everyNth"/>
+              <xsl:with-param name="linenumbering.width"
+                              select="$linenumbering.width"/>
+              <xsl:with-param name="linenumbering.separator"
+                              select="$linenumbering.separator"/>
+            </xsl:call-template>
+          </fo:block>
+        </xsl:when>
+        <xsl:otherwise>
+          <fo:block wrap-option='no-wrap'
+                    text-align='start'
+                    linefeed-treatment="preserve"
+                    white-space-collapse='false'
+                    space-before.minimum="0.8em"
+                    space-before.optimum="1em"
+                    space-before.maximum="1.2em">
+            <xsl:call-template name="number.rtf.lines">
+              <xsl:with-param name="rtf" select="$rtf"/>
+              <xsl:with-param name="linenumbering.everyNth"
+                              select="$linenumbering.everyNth"/>
+              <xsl:with-param name="linenumbering.width"
+                              select="$linenumbering.width"/>
+              <xsl:with-param name="linenumbering.separator"
+                              select="$linenumbering.separator"/>
+            </xsl:call-template>
+          </fo:block>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:choose>
+        <xsl:when test="@class='monospaced'">
+          <fo:block wrap-option='no-wrap'
+                    text-align='start'
+                    font-family='{$monospace.font.family}'
+                    linefeed-treatment="preserve"
+                    white-space-collapse='false'
+                    space-before.minimum="0.8em"
+                    space-before.optimum="1em"
+                    space-before.maximum="1.2em">
+            <xsl:copy-of select="$rtf"/>
+          </fo:block>
+        </xsl:when>
+        <xsl:otherwise>
+          <fo:block wrap-option='no-wrap'
+                    text-align='start'
+                    linefeed-treatment="preserve"
+                    white-space-collapse='false'
+                    space-before.minimum="0.8em"
+                    space-before.optimum="1em"
+                    space-before.maximum="1.2em">
+            <xsl:copy-of select="$rtf"/>
+          </fo:block>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="address">
+  <xsl:param name="suppress-numbers" select="'0'"/>
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:variable name="rtf">
+    <xsl:apply-templates/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$suppress-numbers = '0'
+                    and @linenumbering = 'numbered'
+                    and $use.extensions != '0'
+                    and $linenumbering.extension != '0'">
+      <fo:block wrap-option='no-wrap'
+                white-space-collapse='false'
+                linefeed-treatment="preserve"
+                space-before.minimum="0.8em"
+                space-before.optimum="1em"
+                space-before.maximum="1.2em">
+        <xsl:call-template name="number.rtf.lines">
+          <xsl:with-param name="rtf" select="$rtf"/>
+          <xsl:with-param name="linenumbering.everyNth"
+                          select="$linenumbering.everyNth"/>
+          <xsl:with-param name="linenumbering.width"
+                          select="$linenumbering.width"/>
+          <xsl:with-param name="linenumbering.separator"
+                          select="$linenumbering.separator"/>
+        </xsl:call-template>
+      </fo:block>
+    </xsl:when>
+    <xsl:otherwise>
+      <fo:block wrap-option='no-wrap'
+                text-align='start'
+                linefeed-treatment="preserve"
+                white-space-collapse='false'
+                space-before.minimum="0.8em"
+                space-before.optimum="1em"
+                space-before.maximum="1.2em">
+        <xsl:apply-templates/>
+      </fo:block>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="number.rtf.lines">
+  <xsl:param name="rtf" select="''"/>
+  <!-- the following parameters must have these names ... -->
+  <xsl:param name="linenumbering.everyNth" select="1"/>
+  <xsl:param name="linenumbering.width" select="3"/>
+  <xsl:param name="linenumbering.separator" select="' |'"/>
+
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:choose>
+    <xsl:when test="contains($vendor, 'SAXON ')">
+      <xsl:copy-of select="sverb:numberLines($rtf)"/>
+    </xsl:when>
+    <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+      <xsl:copy-of select="xverb:numberLines($rtf)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message terminate="yes">
+        <xsl:text>Don't know how to do line numbering with </xsl:text>
+        <xsl:value-of select="$vendor"/>
+      </xsl:message>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/fo/xref.xsl b/xsl/fo/xref.xsl
new file mode 100644 (file)
index 0000000..21188b4
--- /dev/null
@@ -0,0 +1,305 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="xref">
+  <xsl:variable name="targets" select="id(@linkend)"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+  <xsl:variable name="refelem" select="name($target)"/>
+
+  <xsl:call-template name="check.id.unique">
+    <xsl:with-param name="linkend" select="@linkend"/>
+  </xsl:call-template>
+
+  <xsl:choose>
+    <xsl:when test="$refelem=''">
+      <xsl:message>
+       <xsl:text>XRef to nonexistent id: </xsl:text>
+       <xsl:value-of select="@linkend"/>
+      </xsl:message>
+      <xsl:text>???</xsl:text>
+    </xsl:when>
+
+    <xsl:when test="$target/@xreflabel">
+      <fo:basic-link internal-destination="{@linkend}"
+                     xsl:use-attribute-sets="xref.properties">
+       <xsl:call-template name="xref.xreflabel">
+         <xsl:with-param name="target" select="$target"/>
+       </xsl:call-template>
+      </fo:basic-link>
+    </xsl:when>
+
+    <xsl:otherwise>
+      <fo:basic-link internal-destination="{@linkend}"
+                     xsl:use-attribute-sets="xref.properties">
+        <xsl:choose>
+         <xsl:when test="@endterm">
+           <xsl:variable name="etargets" select="id(@endterm)"/>
+           <xsl:variable name="etarget" select="$etargets[1]"/>
+           <xsl:choose>
+             <xsl:when test="count($etarget) = 0">
+               <xsl:message>
+                 <xsl:value-of select="count($etargets)"/>
+                 <xsl:text>Endterm points to nonexistent ID: </xsl:text>
+                 <xsl:value-of select="@endterm"/>
+               </xsl:message>
+               <xsl:text>???</xsl:text>
+             </xsl:when>
+             <xsl:otherwise>
+               <xsl:apply-templates select="$etarget" mode="xref.text"/>
+             </xsl:otherwise>
+           </xsl:choose>
+         </xsl:when>
+
+          <xsl:otherwise>
+            <xsl:apply-templates select="$target" mode="xref-to"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </fo:basic-link>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!--- ==================================================================== -->
+
+<xsl:template match="*" mode="xref-to">
+  <xsl:param name="target" select="."/>
+  <xsl:param name="refelem" select="local-name($target)"/>
+
+  <xsl:message>
+    <xsl:text>Don't know what gentext to create for xref to: "</xsl:text>
+    <xsl:value-of select="$refelem"/>
+    <xsl:text>"</xsl:text>
+  </xsl:message>
+  <xsl:text>???</xsl:text>
+</xsl:template>
+
+<xsl:template match="author" mode="xref-to">
+  <xsl:call-template name="person.name"/>
+</xsl:template>
+
+<xsl:template match="figure" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="example" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="table" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="equation" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="cmdsynopsis" mode="xref-to">
+  <xsl:apply-templates select="(.//command)[1]" mode="xref"/>
+</xsl:template>
+
+<xsl:template match="funcsynopsis" mode="xref-to">
+  <xsl:apply-templates select="(.//function)[1]" mode="xref"/>
+</xsl:template>
+
+<xsl:template match="dedication" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="preface" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="chapter" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="appendix" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="bibliography" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="biblioentry|bibliomixed" mode="xref-to">
+  <!-- handles both biblioentry and bibliomixed -->
+  <xsl:text>[</xsl:text>
+  <xsl:choose>
+    <xsl:when test="local-name(*[1]) = 'abbrev'">
+      <xsl:apply-templates select="*[1]"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="@id"/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:text>]</xsl:text>
+</xsl:template>
+
+<xsl:template match="glossary" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="index" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="section|simplesect
+                     |sect1|sect2|sect3|sect4|sect5
+                     |refsect1|refsect2|refsect3" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+  <!-- What about "in Chapter X"? -->
+</xsl:template>
+
+<xsl:template match="question" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="answer" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="part" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="reference" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="co" mode="xref-to">
+  <xsl:apply-templates select="." mode="callout-bug"/>
+</xsl:template>
+
+<xsl:template match="book" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="link">
+  <xsl:variable name="targets" select="id(@linkend)"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+
+  <xsl:call-template name="check.id.unique">
+    <xsl:with-param name="linkend" select="@linkend"/>
+  </xsl:call-template>
+
+  <fo:basic-link internal-destination="{@linkend}"
+                 xsl:use-attribute-sets="xref.properties">
+    <xsl:apply-templates/>
+  </fo:basic-link>
+</xsl:template>
+
+<xsl:template match="ulink">
+  <fo:basic-link external-destination="{@url}"
+                 xsl:use-attribute-sets="xref.properties">
+    <xsl:choose>
+      <xsl:when test="count(child::node())=0">
+       <xsl:value-of select="@url"/>
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </fo:basic-link>
+  <xsl:if test="count(child::node()) != 0">
+    <fo:inline hyphenate="false">
+      <xsl:text> [</xsl:text>
+      <xsl:value-of select="@url"/>
+      <xsl:text>]</xsl:text>
+    </fo:inline>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="olink">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="title.xref">
+  <xsl:param name="target" select="."/>
+  <xsl:choose>
+    <xsl:when test="local-name($target) = 'figure'
+                    or local-name($target) = 'example'
+                    or local-name($target) = 'equation'
+                    or local-name($target) = 'table'
+                    or local-name($target) = 'dedication'
+                    or local-name($target) = 'preface'
+                    or local-name($target) = 'bibliography'
+                    or local-name($target) = 'glossary'
+                    or local-name($target) = 'index'
+                    or local-name($target) = 'setindex'
+                    or local-name($target) = 'colophon'">
+      <xsl:call-template name="gentext.startquote"/>
+      <xsl:apply-templates select="$target" mode="title.markup"/>
+      <xsl:call-template name="gentext.endquote"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <fo:inline font-style="italic">
+        <xsl:apply-templates select="$target" mode="title.markup"/>
+      </fo:inline>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="number.xref">
+  <xsl:param name="target" select="."/>
+  <xsl:apply-templates select="$target" mode="label.markup"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="xref.xreflabel">
+  <!-- called to process an xreflabel...you might use this to make  -->
+  <!-- xreflabels come out in the right font for different targets, -->
+  <!-- for example. -->
+  <xsl:param name="target" select="."/>
+  <xsl:value-of select="$target/@xreflabel"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="title" mode="xref">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="command" mode="xref">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+<xsl:template match="function" mode="xref">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template name="insert.page.citation">
+  <xsl:param name="id" select="'???'"/>
+  <xsl:if test="$insert.xref.page.number">
+    <xsl:text> </xsl:text>
+    <fo:inline keep-together.within-line="always">
+      <xsl:text>[</xsl:text>
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'page.citation'"/>
+      </xsl:call-template>
+      <xsl:text> </xsl:text>
+      <fo:page-number-citation ref-id="{$id}"/>
+      <xsl:text>]</xsl:text>
+    </fo:inline>
+  </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/.cvsignore b/xsl/html/.cvsignore
new file mode 100644 (file)
index 0000000..c7dc21b
--- /dev/null
@@ -0,0 +1 @@
+titlepage.templates.xsl
diff --git a/xsl/html/Makefile b/xsl/html/Makefile
new file mode 100644 (file)
index 0000000..0afd45c
--- /dev/null
@@ -0,0 +1,4 @@
+all: titlepage.templates.xsl
+
+titlepage.templates.xsl: titlepage.templates.xml ../template/titlepage.xsl
+       saxon $< ../template/titlepage.xsl $@
diff --git a/xsl/html/admon.xsl b/xsl/html/admon.xsl
new file mode 100644 (file)
index 0000000..09eae16
--- /dev/null
@@ -0,0 +1,135 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template name="admon.graphic.width">
+  <xsl:param name="node" select="."/>
+  <xsl:text>25</xsl:text>
+</xsl:template>
+
+<xsl:template match="note|important|warning|caution|tip">
+  <xsl:choose>
+    <xsl:when test="$admon.graphics != 0">
+      <xsl:call-template name="graphical.admonition"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="nongraphical.admonition"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="admon.graphic">
+  <xsl:param name="node" select="."/>
+  <xsl:value-of select="$admon.graphics.path"/>
+  <xsl:choose>
+    <xsl:when test="name($node)='note'">note</xsl:when>
+    <xsl:when test="name($node)='warning'">warning</xsl:when>
+    <xsl:when test="name($node)='caution'">caution</xsl:when>
+    <xsl:when test="name($node)='tip'">tip</xsl:when>
+    <xsl:when test="name($node)='important'">important</xsl:when>
+    <xsl:otherwise>note</xsl:otherwise>
+  </xsl:choose>
+  <xsl:value-of select="$admon.graphics.extension"/>
+</xsl:template>
+
+<xsl:template name="graphical.admonition">
+  <div class="{name(.)}">
+  <xsl:if test="$admon.style != ''">
+    <xsl:attribute name="style">
+      <xsl:value-of select="$admon.style"/>
+    </xsl:attribute>
+  </xsl:if>
+  <table border="0">
+    <tr>
+      <td rowspan="2" align="center" valign="top">
+        <xsl:attribute name="width">
+          <xsl:call-template name="admon.graphic.width"/>
+        </xsl:attribute>
+        <img>
+          <xsl:attribute name="src">
+            <xsl:call-template name="admon.graphic"/>
+          </xsl:attribute>
+        </img>
+      </td>
+      <th>
+        <a>
+          <xsl:attribute name="name">
+            <xsl:call-template name="object.id"/>
+          </xsl:attribute>
+        </a>
+        <xsl:apply-templates select="." mode="object.title.markup"/>
+      </th>
+    </tr>
+    <tr>
+      <td colspan="2" align="left" valign="top">
+        <xsl:apply-templates/>
+      </td>
+    </tr>
+  </table>
+  </div>
+</xsl:template>
+
+<xsl:template name="nongraphical.admonition">
+  <div class="{name(.)}">
+    <xsl:if test="$admon.style">
+      <xsl:attribute name="style">
+        <xsl:value-of select="$admon.style"/>
+      </xsl:attribute>
+    </xsl:if>
+
+    <h3 class="title">
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:apply-templates select="." mode="object.title.markup"/>
+    </h3>
+
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="note/title"></xsl:template>
+<xsl:template match="important/title"></xsl:template>
+<xsl:template match="warning/title"></xsl:template>
+<xsl:template match="caution/title"></xsl:template>
+<xsl:template match="tip/title"></xsl:template>
+
+<xsl:template match="title" mode="admonition.title.mode">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <h3 class="title">
+    <a name="{$id}">
+      <xsl:apply-templates/>
+    </a>
+  </h3>
+</xsl:template>
+
+<xsl:template match="title" mode="graphic.admonition.title.mode">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <b class="title">
+    <a name="{$id}">
+      <xsl:apply-templates/>
+    </a>
+  </b>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/autoidx.xsl b/xsl/html/autoidx.xsl
new file mode 100644 (file)
index 0000000..73eedd8
--- /dev/null
@@ -0,0 +1,296 @@
+<?xml version="1.0"?>
+<!DOCTYPE xsl:stylesheet [
+
+<!ENTITY lowercase "abcdefghijklmnopqrstuvwxyz">
+<!ENTITY uppercase "ABCDEFGHIJKLMNOPQRSTUVWXYZ">
+
+<!ENTITY primary   'concat(primary/@sortas, primary[not(@sortas)])'>
+<!ENTITY secondary 'concat(secondary/@sortas, secondary[not(@sortas)])'>
+<!ENTITY tertiary  'concat(tertiary/@sortas, tertiary[not(@sortas)])'>
+
+<!ENTITY section   '(ancestor-or-self::set
+                     |ancestor-or-self::book
+                     |ancestor-or-self::part
+                     |ancestor-or-self::reference
+                     |ancestor-or-self::partintro
+                     |ancestor-or-self::chapter
+                     |ancestor-or-self::appendix
+                     |ancestor-or-self::preface
+                     |ancestor-or-self::section
+                     |ancestor-or-self::sect1
+                     |ancestor-or-self::sect2
+                     |ancestor-or-self::sect3
+                     |ancestor-or-self::sect4
+                     |ancestor-or-self::sect5
+                     |ancestor-or-self::refsect1
+                     |ancestor-or-self::refsect2
+                     |ancestor-or-self::refsect3
+                     |ancestor-or-self::simplesect
+                     |ancestor-or-self::bibliography
+                     |ancestor-or-self::glossary
+                     |ancestor-or-self::index)[last()]'>
+
+<!ENTITY section.id 'generate-id(&section;)'>
+<!ENTITY sep '" "'>
+]>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0">
+
+<xsl:import href="docbook.xsl"/>
+
+<!-- ==================================================================== -->
+<!-- Jeni Tennison gets all the credit for what follows.
+     I think I understand it :-) Anyway, I've hacked it a bit, so the
+     bugs are mine. -->
+
+<xsl:key name="letter"
+         match="indexterm"
+         use="translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;)"/>
+
+<xsl:key name="primary"
+         match="indexterm"
+         use="&primary;"/>
+
+<xsl:key name="secondary"
+         match="indexterm"
+         use="concat(&primary;, &sep;, &secondary;)"/>
+
+<xsl:key name="tertiary"
+         match="indexterm"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
+
+<xsl:key name="primary-section"
+         match="indexterm[not(secondary) and not(see)]"
+         use="concat(&primary;, &sep;, &section.id;)"/>
+
+<xsl:key name="secondary-section"
+         match="indexterm[not(tertiary) and not(see)]"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &section.id;)"/>
+
+<xsl:key name="tertiary-section"
+         match="indexterm[not(see)]"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, &section.id;)"/>
+
+<xsl:key name="see-also"
+         match="indexterm[seealso]"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, seealso)"/>
+
+<xsl:key name="see"
+         match="indexterm[see]"
+         use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see)"/>
+
+<xsl:key name="sections" match="*[@id]" use="@id"/>
+
+<xsl:template name="generate-index">
+  <xsl:variable name="terms" select="//indexterm[count(.|key('letter',
+                                     translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;))[1]) = 1]"/>
+
+  <xsl:variable name="alphabetical"
+                select="$terms[contains(concat(&lowercase;, &uppercase;),
+                                        substring(&primary;, 1, 1))]"/>
+  <xsl:variable name="others" select="$terms[not(contains(concat(&lowercase;,
+                                                 &uppercase;),
+                                             substring(&primary;, 1, 1)))]"/>
+  <div class="index">
+    <xsl:if test="$others">
+      <div class="indexdiv">
+        <h3>
+          <xsl:call-template name="gentext">
+            <xsl:with-param name="key" select="'index symbols'"/>
+          </xsl:call-template>
+        </h3>
+        <dl>
+          <xsl:apply-templates select="$others[count(.|key('primary',
+                                       &primary;)[1]) = 1]"
+                               mode="index-primary">
+            <xsl:sort select="&primary;"/>
+          </xsl:apply-templates>
+        </dl>
+      </div>
+    </xsl:if>
+    <xsl:apply-templates select="$alphabetical[count(.|key('letter',
+                                 translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;))[1]) = 1]"
+                         mode="index-div">
+      <xsl:sort select="&primary;"/>
+    </xsl:apply-templates>
+  </div>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-div">
+  <xsl:variable name="key" select="translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;)"/>
+  <div class="indexdiv">
+    <h3>
+      <xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/>
+    </h3>
+    <dl>
+      <xsl:apply-templates select="key('letter', $key)[count(.|key('primary', &primary;)[1]) = 1]"
+                           mode="index-primary">
+        <xsl:sort select="&primary;"/>
+      </xsl:apply-templates>
+    </dl>
+  </div>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-primary">
+  <xsl:variable name="key" select="&primary;"/>
+  <xsl:variable name="refs" select="key('primary', $key)"/>
+  <dt>
+    <xsl:value-of select="primary"/>
+    <xsl:for-each select="$refs[generate-id() = generate-id(key('primary-section', concat($key, &sep;, &section.id;))[1])]">
+      <xsl:apply-templates select="." mode="reference"/>
+    </xsl:for-each>
+  </dt>
+  <xsl:if test="$refs/secondary or $refs[not(secondary)]/*[self::see or self::seealso]">
+    <dd>
+      <dl>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &sep;, &sep;, see))[1])]"
+                             mode="index-see">
+          <xsl:sort select="see"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &sep;, &sep;, seealso))[1])]"
+                             mode="index-seealso">
+          <xsl:sort select="seealso"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[secondary and count(.|key('secondary', concat($key, &sep;, &secondary;))[1]) = 1]" 
+                             mode="index-secondary">
+          <xsl:sort select="&secondary;"/>
+        </xsl:apply-templates>
+      </dl>
+    </dd>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-secondary">
+  <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;)"/>
+  <xsl:variable name="refs" select="key('secondary', $key)"/>
+  <dt>
+    <xsl:value-of select="secondary"/>
+    <xsl:for-each select="$refs[generate-id() = generate-id(key('secondary-section', concat($key, &sep;, &section.id;))[1])]">
+      <xsl:apply-templates select="." mode="reference"/>
+    </xsl:for-each>
+  </dt>
+  <xsl:if test="$refs/tertiary or $refs[not(tertiary)]/*[self::see or self::seealso]">
+    <dd>
+      <dl>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, see))[1])]"
+                             mode="index-see">
+          <xsl:sort select="see"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, seealso))[1])]"
+                             mode="index-seealso">
+          <xsl:sort select="seealso"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[tertiary and count(.|key('tertiary', concat($key, &sep;, &tertiary;))[1]) = 1]" 
+                             mode="index-tertiary">
+          <xsl:sort select="&tertiary;"/>
+        </xsl:apply-templates>
+      </dl>
+    </dd>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-tertiary">
+  <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
+  <xsl:variable name="refs" select="key('tertiary', $key)"/>
+  <dt>
+    <xsl:value-of select="tertiary"/>
+    <xsl:for-each select="$refs[generate-id() = generate-id(key('tertiary-section', concat($key, &sep;, &section.id;))[1])]">
+      <xsl:apply-templates select="." mode="reference"/>
+    </xsl:for-each>
+  </dt>
+  <xsl:variable name="see" select="$refs/see | $refs/seealso"/>
+  <xsl:if test="$see">
+    <dd>
+      <dl>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see))[1])]"
+                             mode="index-see">
+          <xsl:sort select="see"/>
+        </xsl:apply-templates>
+        <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, seealso))[1])]"
+                             mode="index-seealso">
+          <xsl:sort select="seealso"/>
+        </xsl:apply-templates>
+      </dl>
+    </dd>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="reference">
+  <xsl:text>, </xsl:text>
+  <xsl:choose>
+    <xsl:when test="@zone and string(@zone)">
+      <xsl:call-template name="reference">
+        <xsl:with-param name="zones" select="normalize-space(@zone)"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <a>
+        <xsl:variable name="title">
+          <xsl:apply-templates select="&section;" mode="title.markup"/>
+        </xsl:variable>
+
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="&section;"/>
+          </xsl:call-template>
+        </xsl:attribute>
+
+        <xsl:value-of select="$title"/> <!-- text only -->
+      </a>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="reference">
+  <xsl:param name="zones"/>
+  <xsl:choose>
+    <xsl:when test="contains($zones, ' ')">
+      <xsl:variable name="zone" select="substring-before($zones, ' ')"/>
+      <xsl:variable name="target" select="key('sections', $zone)"/>
+
+      <a>
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="$target[1]"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:apply-templates select="$target[1]" mode="index-title-content"/>
+      </a>
+      <xsl:text>, </xsl:text>
+      <xsl:call-template name="reference">
+        <xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="zone" select="$zones"/>
+      <xsl:variable name="target" select="key('sections', $zone)"/>
+
+      <a>
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="$target[1]"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:apply-templates select="$target[1]" mode="index-title-content"/>
+      </a>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-see">
+   <dt><xsl:value-of select="see"/></dt>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-seealso">
+   <dt><xsl:value-of select="seealso"/></dt>
+</xsl:template>
+
+<xsl:template match="*" mode="index-title-content">
+  <xsl:variable name="title">
+    <xsl:apply-templates select="&section;" mode="title.markup"/>
+  </xsl:variable>
+
+  <xsl:value-of select="$title"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/autotoc.xsl b/xsl/html/autotoc.xsl
new file mode 100644 (file)
index 0000000..45db0c6
--- /dev/null
@@ -0,0 +1,543 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template name="href.target">
+  <xsl:param name="object" select="."/>
+  <xsl:text>#</xsl:text>
+  <xsl:call-template name="object.id">
+    <xsl:with-param name="object" select="$object"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:variable name="toc.listitem.type">
+  <xsl:choose>
+    <xsl:when test="$toc.list.type = 'dl'">dt</xsl:when>
+    <xsl:otherwise>li</xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+
+<!-- this is just hack because dl and ul aren't completely isomorphic -->
+<xsl:variable name="toc.dd.type">
+  <xsl:choose>
+    <xsl:when test="$toc.list.type = 'dl'">dd</xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+
+<xsl:template name="set.toc">
+  <xsl:variable name="nodes" select="book|setindex"/>
+  <xsl:if test="$nodes">
+    <div class="toc">
+      <p>
+        <b>
+          <xsl:call-template name="gentext">
+            <xsl:with-param name="key">TableofContents</xsl:with-param>
+          </xsl:call-template>
+        </b>
+      </p>
+      <xsl:element name="{$toc.list.type}">
+        <xsl:apply-templates select="$nodes" mode="toc"/>
+      </xsl:element>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="division.toc">
+  <xsl:if test="$generate.division.toc != 0">
+    <xsl:variable name="nodes" select="part|reference
+                                       |preface|chapter|appendix
+                                       |article
+                                       |bibliography|glossary|index
+                                       |refentry"/>
+    <xsl:if test="$nodes">
+      <div class="toc">
+        <p>
+          <b>
+           <xsl:call-template name="gentext">
+             <xsl:with-param name="key">TableofContents</xsl:with-param>
+           </xsl:call-template>
+          </b>
+        </p>
+        <xsl:element name="{$toc.list.type}">
+          <xsl:apply-templates select="$nodes" mode="toc"/>
+        </xsl:element>
+      </div>
+    </xsl:if>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="component.toc">
+  <xsl:if test="$generate.component.toc != 0">
+    <xsl:variable name="nodes" select="section|sect1|refentry
+                                       |article|bibliography|glossary
+                                       |appendix"/>
+    <xsl:if test="$nodes">
+      <div class="toc">
+        <p>
+          <b>
+           <xsl:call-template name="gentext">
+             <xsl:with-param name="key">TableofContents</xsl:with-param>
+           </xsl:call-template>
+          </b>
+        </p>
+        <xsl:element name="{$toc.list.type}">
+          <xsl:apply-templates select="$nodes" mode="toc"/>
+        </xsl:element>
+      </div>
+    </xsl:if>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="section.toc">
+  <xsl:variable name="nodes" select="section|sect1|sect2|sect3|sect4|sect5|refentry"/>
+  <xsl:if test="$nodes">
+    <div class="toc">
+      <p>
+        <b>
+          <xsl:call-template name="gentext">
+            <xsl:with-param name="key">TableofContents</xsl:with-param>
+          </xsl:call-template>
+        </b>
+      </p>
+      <xsl:element name="{$toc.list.type}">
+        <xsl:apply-templates select="$nodes" mode="toc"/>
+      </xsl:element>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="book|setindex" mode="toc">
+  <xsl:variable name="nodes" select="part|reference
+                                     |preface|chapter|appendix
+                                     |article
+                                     |bibliography|glossary|index
+                                     |refentry"/>
+
+  <xsl:variable name="subtoc">
+    <xsl:element name="{$toc.list.type}">
+      <xsl:apply-templates mode="toc" select="$nodes"/>
+    </xsl:element>
+  </xsl:variable>
+
+  <xsl:variable name="subtoc.list">
+    <xsl:choose>
+      <xsl:when test="$toc.dd.type = ''">
+        <xsl:copy-of select="$subtoc"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="{$toc.dd.type}">
+          <xsl:copy-of select="$subtoc"/>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+    <xsl:if test="$toc.listitem.type = 'li'
+                  and $toc.section.depth>0 and count($nodes)&gt;0">
+      <xsl:copy-of select="$subtoc.list"/>
+    </xsl:if>
+  </xsl:element>
+  <xsl:if test="$toc.listitem.type != 'li'
+                and $toc.section.depth>0 and count($nodes)&gt;0">
+    <xsl:copy-of select="$subtoc.list"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="part|reference" mode="toc">
+  <xsl:variable name="nodes" select="appendix|chapter|article
+                                     |index|glossary|bibliography
+                                     |preface|reference|refentry"/>
+
+  <xsl:variable name="subtoc">
+    <xsl:element name="{$toc.list.type}">
+      <xsl:apply-templates select="$nodes" mode="toc"/>
+    </xsl:element>
+  </xsl:variable>
+
+  <xsl:variable name="subtoc.list">
+    <xsl:choose>
+      <xsl:when test="$toc.dd.type = ''">
+        <xsl:copy-of select="$subtoc"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="{$toc.dd.type}">
+          <xsl:copy-of select="$subtoc"/>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+    <xsl:if test="$toc.listitem.type = 'li'
+                  and $toc.section.depth>0 and count($nodes) &gt; 0">
+      <xsl:copy-of select="$subtoc.list"/>
+    </xsl:if>
+  </xsl:element>
+  <xsl:if test="$toc.listitem.type != 'li'
+                and $toc.section.depth>0 and count($nodes) &gt; 0">
+    <xsl:copy-of select="$subtoc.list"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="preface|chapter|appendix|article" mode="toc">
+  <xsl:variable name="subtoc">
+    <xsl:element name="{$toc.list.type}">
+      <xsl:apply-templates select="section|sect1" mode="toc"/>
+    </xsl:element>
+  </xsl:variable>
+
+  <xsl:variable name="subtoc.list">
+    <xsl:choose>
+      <xsl:when test="$toc.dd.type = ''">
+        <xsl:copy-of select="$subtoc"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="{$toc.dd.type}">
+          <xsl:copy-of select="$subtoc"/>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+    <xsl:if test="$toc.listitem.type = 'li'
+                  and $toc.section.depth>0 and section|sect1">
+      <xsl:copy-of select="$subtoc.list"/>
+    </xsl:if>
+  </xsl:element>
+  <xsl:if test="$toc.listitem.type != 'li'
+                and $toc.section.depth>0 and section|sect1">
+    <xsl:copy-of select="$subtoc.list"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="sect1" mode="toc">
+  <xsl:variable name="subtoc">
+    <xsl:element name="{$toc.list.type}">
+      <xsl:apply-templates select="sect2" mode="toc"/>
+    </xsl:element>
+  </xsl:variable>
+
+  <xsl:variable name="subtoc.list">
+    <xsl:choose>
+      <xsl:when test="$toc.dd.type = ''">
+        <xsl:copy-of select="$subtoc"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="{$toc.dd.type}">
+          <xsl:copy-of select="$subtoc"/>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+    <xsl:if test="$toc.listitem.type = 'li'
+                  and $toc.section.depth>1 and sect2">
+      <xsl:copy-of select="$subtoc.list"/>
+    </xsl:if>
+  </xsl:element>
+  <xsl:if test="$toc.listitem.type != 'li'
+                and $toc.section.depth>1 and sect2">
+    <xsl:copy-of select="$subtoc.list"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="sect2" mode="toc">
+  <xsl:variable name="subtoc">
+    <xsl:element name="{$toc.list.type}">
+      <xsl:apply-templates select="sect3" mode="toc"/>
+    </xsl:element>
+  </xsl:variable>
+
+  <xsl:variable name="subtoc.list">
+    <xsl:choose>
+      <xsl:when test="$toc.dd.type = ''">
+        <xsl:copy-of select="$subtoc"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="{$toc.dd.type}">
+          <xsl:copy-of select="$subtoc"/>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+    <xsl:if test="$toc.listitem.type = 'li'
+                  and $toc.section.depth>2 and sect3">
+      <xsl:copy-of select="$subtoc.list"/>
+    </xsl:if>
+  </xsl:element>
+  <xsl:if test="$toc.listitem.type != 'li'
+                and $toc.section.depth>2 and sect3">
+    <xsl:copy-of select="$subtoc.list"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="sect3" mode="toc">
+  <xsl:variable name="subtoc">
+    <xsl:element name="{$toc.list.type}">
+      <xsl:apply-templates select="sect4" mode="toc"/>
+    </xsl:element>
+  </xsl:variable>
+
+  <xsl:variable name="subtoc.list">
+    <xsl:choose>
+      <xsl:when test="$toc.dd.type = ''">
+        <xsl:copy-of select="$subtoc"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="{$toc.dd.type}">
+          <xsl:copy-of select="$subtoc"/>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+    <xsl:if test="$toc.listitem.type = 'li'
+                  and $toc.section.depth>3 and sect4">
+      <xsl:copy-of select="$subtoc.list"/>
+    </xsl:if>
+  </xsl:element>
+  <xsl:if test="$toc.listitem.type != 'li'
+                and $toc.section.depth>3 and sect4">
+    <xsl:copy-of select="$subtoc.list"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="sect4" mode="toc">
+  <xsl:variable name="subtoc">
+    <xsl:element name="{$toc.list.type}">
+      <xsl:apply-templates select="sect5" mode="toc"/>
+    </xsl:element>
+  </xsl:variable>
+
+  <xsl:variable name="subtoc.list">
+    <xsl:choose>
+      <xsl:when test="$toc.dd.type = ''">
+        <xsl:copy-of select="$subtoc"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="{$toc.dd.type}">
+          <xsl:copy-of select="$subtoc"/>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+    <xsl:if test="$toc.listitem.type = 'li'
+                  and $toc.section.depth>4 and sect5">
+      <xsl:copy-of select="$subtoc.list"/>
+    </xsl:if>
+  </xsl:element>
+  <xsl:if test="$toc.listitem.type != 'li'
+                and $toc.section.depth>4 and sect5">
+    <xsl:copy-of select="$subtoc.list"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="sect5" mode="toc">
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="section" mode="toc">
+  <xsl:variable name="subtoc">
+    <xsl:element name="{$toc.list.type}">
+      <xsl:apply-templates select="section" mode="toc"/>
+    </xsl:element>
+  </xsl:variable>
+
+  <xsl:variable name="subtoc.list">
+    <xsl:choose>
+      <xsl:when test="$toc.dd.type = ''">
+        <xsl:copy-of select="$subtoc"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="{$toc.dd.type}">
+          <xsl:copy-of select="$subtoc"/>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="toodeep">
+    <xsl:choose>
+      <!-- if the depth is less than 2, we're already deep enough -->
+      <xsl:when test="$toc.section.depth &lt; 2">yes</xsl:when>
+      <!-- if the current section has n-1 section ancestors -->
+      <!-- then we've already reached depth n -->
+      <xsl:when test="ancestor::section[position()=$toc.section.depth - 1]">
+        <xsl:text>yes</xsl:text>
+      </xsl:when>
+      <!-- otherwise, keep going -->
+      <xsl:otherwise>no</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+    <xsl:if test="$toc.listitem.type = 'li'
+                  and $toodeep='no' and section">
+      <xsl:copy-of select="$subtoc.list"/>
+    </xsl:if>
+  </xsl:element>
+  <xsl:if test="$toc.listitem.type != 'li'
+                and $toodeep='no' and section">
+    <xsl:copy-of select="$subtoc.list"/>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="bibliography|glossary" mode="toc">
+  <xsl:element name="{$toc.listitem.type}">
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:apply-templates select="." mode="title.markup"/>
+    </a>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="index" mode="toc">
+  <!-- If the index tag is empty, don't point at it from the TOC -->
+  <xsl:if test="* or $generate.index">
+    <xsl:element name="{$toc.listitem.type}">
+      <a>
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target"/>
+        </xsl:attribute>
+        <xsl:apply-templates select="." mode="title.markup"/>
+      </a>
+    </xsl:element>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="refentry" mode="toc">
+  <xsl:variable name="refmeta" select=".//refmeta"/>
+  <xsl:variable name="refentrytitle" select="$refmeta//refentrytitle"/>
+  <xsl:variable name="refnamediv" select=".//refnamediv"/>
+  <xsl:variable name="refname" select="$refnamediv//refname"/>
+  <xsl:variable name="title">
+    <xsl:choose>
+      <xsl:when test="$refentrytitle">
+        <xsl:apply-templates select="$refentrytitle[1]" mode="title"/>
+      </xsl:when>
+      <xsl:when test="$refname">
+        <xsl:apply-templates select="$refname[1]" mode="title"/>
+      </xsl:when>
+      <xsl:otherwise></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:element name="{$toc.listitem.type}">
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target"/>
+      </xsl:attribute>
+      <xsl:copy-of select="$title"/>
+    </a>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="title" mode="toc">
+  <a>
+    <xsl:attribute name="href">
+      <xsl:call-template name="href.target">
+        <xsl:with-param name="object" select=".."/>
+      </xsl:call-template>
+    </xsl:attribute>
+    <xsl:apply-templates/>
+  </a>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/html/biblio.xsl b/xsl/html/biblio.xsl
new file mode 100644 (file)
index 0000000..2205749
--- /dev/null
@@ -0,0 +1,932 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="bibliography">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="bibliography.titlepage"/>
+    <xsl:apply-templates/>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="bibliography/bibliographyinfo"></xsl:template>
+<xsl:template match="bibliography/title"></xsl:template>
+<xsl:template match="bibliography/subtitle"></xsl:template>
+<xsl:template match="bibliography/titleabbrev"></xsl:template>
+
+<xsl:template match="bibliography/title" mode="component.title.mode">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <h2 class="title">
+    <a name="{$id}">
+      <xsl:apply-templates/>
+    </a>
+  </h2>
+</xsl:template>
+
+<xsl:template match="bibliography/subtitle" mode="component.title.mode">
+  <h3>
+    <i><xsl:apply-templates/></i>
+  </h3>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="bibliodiv">
+  <div class="{name(.)}">
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="bibliodiv/title">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <h3 class="{name(.)}">
+    <a name="{$id}">
+      <xsl:apply-templates/>
+    </a>
+  </h3>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="biblioentry">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <div id="{$id}" class="{name(.)}">
+    <a name="{$id}"/>
+    <p>
+      <xsl:apply-templates mode="bibliography.mode"/>
+    </p>
+  </div>
+</xsl:template>
+
+<xsl:template match="bibliomixed">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <div id="{$id}" class="{name(.)}">
+    <a name="{$id}"/>
+    <p>
+      <xsl:choose>
+       <xsl:when test="local-name(*[1]) = 'abbrev'">
+         <xsl:apply-templates select="*[position()>1]|text()"
+                               mode="bibliomixed.mode"/>
+       </xsl:when>
+       <xsl:otherwise>
+         <xsl:apply-templates mode="bibliomixed.mode"/>
+       </xsl:otherwise>
+      </xsl:choose>
+    </p>
+  </div>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="bibliography.mode">
+  <xsl:apply-templates select="."/><!-- try the default mode -->
+</xsl:template>
+
+<xsl:template match="abbrev" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:text>[</xsl:text>
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:text>] </xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="abstract" mode="bibliography.mode">
+  <!-- suppressed -->
+</xsl:template>
+
+<xsl:template match="address" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="affiliation" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="shortaffil" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="jobtitle" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="artheader|articleinfo" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="artpagenums" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="author" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:call-template name="person.name"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="authorblurb" mode="bibliography.mode">
+  <!-- suppressed -->
+</xsl:template>
+
+<xsl:template match="authorgroup" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:call-template name="person.name.list"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="authorinitials" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="bibliomisc" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="bibliomset" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="biblioset" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="biblioset/title|biblioset/citetitle" 
+              mode="bibliography.mode">
+  <xsl:variable name="relation" select="../@relation"/>
+  <xsl:choose>
+    <xsl:when test="$relation='article'">
+      <xsl:call-template name="dingbat">
+        <xsl:with-param name="dingbat">ldquo</xsl:with-param>
+      </xsl:call-template>
+      <xsl:apply-templates/>
+      <xsl:call-template name="dingbat">
+        <xsl:with-param name="dingbat">rdquo</xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <I><xsl:apply-templates/></I>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:value-of select="$biblioentry.item.separator"/>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="bookbiblio" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="citetitle" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <i><xsl:apply-templates mode="bibliography.mode"/></i>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="collab" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="collabname" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="confgroup" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="confdates" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="conftitle" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="confnum" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="confsponsor" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="contractnum" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="contractsponsor" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="contrib" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="copyright" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'Copyright'"/>
+    </xsl:call-template>
+    <xsl:call-template name="gentext.space"/>
+    <xsl:call-template name="dingbat">
+      <xsl:with-param name="dingbat">copyright</xsl:with-param>
+    </xsl:call-template>
+    <xsl:call-template name="gentext.space"/>
+    <xsl:apply-templates select="year" mode="bibliography.mode"/>
+    <xsl:if test="holder">
+      <xsl:call-template name="gentext.space"/>
+      <xsl:apply-templates select="holder" mode="bibliography.mode"/>
+    </xsl:if>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="year" mode="bibliography.mode">
+  <xsl:apply-templates/><xsl:text>, </xsl:text>
+</xsl:template>
+
+<xsl:template match="year[position()=last()]" mode="bibliography.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="holder" mode="bibliography.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="corpauthor" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="corpname" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="date" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="edition" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="editor" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:call-template name="person.name"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="firstname" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="honorific" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="invpartnumber" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="isbn" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="issn" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="issuenum" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="lineage" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="orgname" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="orgdiv" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="othercredit" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="othername" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pagenums" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="printhistory" mode="bibliography.mode">
+  <!-- suppressed -->
+</xsl:template>
+
+<xsl:template match="productname" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="productnumber" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pubdate" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="publisher" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="publishername" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pubsnumber" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="releaseinfo" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="revhistory" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="seriesinfo" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="seriesvolnums" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="surname" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="title" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <I><xsl:apply-templates mode="bibliography.mode"/></I>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="titleabbrev" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="volumenum" mode="bibliography.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliography.mode"/>
+    <xsl:value-of select="$biblioentry.item.separator"/>
+  </span>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="bibliomixed.mode">
+  <xsl:apply-templates select="."/><!-- try the default mode -->
+</xsl:template>
+
+<xsl:template match="abbrev" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="abstract" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="address" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="affiliation" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="shortaffil" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="jobtitle" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="artpagenums" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="author" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="authorblurb" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="authorgroup" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="authorinitials" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="bibliomisc" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="bibliomset" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="bibliomset/title|bibliomset/citetitle" 
+              mode="bibliomixed.mode">
+  <xsl:variable name="relation" select="../@relation"/>
+  <xsl:choose>
+    <xsl:when test="$relation='article'">
+      <xsl:call-template name="dingbat">
+        <xsl:with-param name="dingbat">ldquo</xsl:with-param>
+      </xsl:call-template>
+      <xsl:apply-templates/>
+      <xsl:call-template name="dingbat">
+        <xsl:with-param name="dingbat">rdquo</xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <I><xsl:apply-templates/></I>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ================================================== -->
+
+<xsl:template match="biblioset" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="citetitle" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <i><xsl:apply-templates mode="bibliomixed.mode"/></i>
+  </span>
+</xsl:template>
+
+<xsl:template match="collab" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="confgroup" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="contractnum" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="contractsponsor" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="contrib" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="copyright" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="corpauthor" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="corpname" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="date" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="edition" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="editor" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="firstname" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="honorific" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="invpartnumber" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="isbn" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="issn" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="issuenum" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="lineage" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="orgname" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="othercredit" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="othername" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pagenums" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="printhistory" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="productname" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="productnumber" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pubdate" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="publisher" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="publishername" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pubsnumber" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="releaseinfo" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="revhistory" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="seriesvolnums" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="surname" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="title" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="titleabbrev" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="volumenum" mode="bibliomixed.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="bibliomixed.mode"/>
+  </span>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/block.xsl b/xsl/html/block.xsl
new file mode 100644 (file)
index 0000000..9b171ee
--- /dev/null
@@ -0,0 +1,357 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template name="block.object">
+  <div class="{name(.)}">
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id"/>
+      </xsl:attribute>
+    </a>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="para">
+  <p>
+    <xsl:if test="position() = 1 and parent::listitem">
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id">
+            <xsl:with-param name="object" select="parent::listitem"/>
+          </xsl:call-template>
+        </xsl:attribute>
+      </a>
+    </xsl:if>
+
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<xsl:template match="simpara">
+  <p>
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<xsl:template match="formalpara">
+  <p>
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<xsl:template match="formalpara/title">
+  <b><xsl:apply-templates/></b>
+  <xsl:call-template name="gentext.space"/>
+</xsl:template>
+
+<xsl:template match="formalpara/para">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="blockquote">
+  <xsl:if test="@id">
+    <a name="{@id}"/>
+  </xsl:if>
+  <xsl:choose>
+    <xsl:when test="attribution">
+      <table border="0" width="100%"
+            cellspacing="0" cellpadding="0" class="blockquote"
+             summary="Block quote">
+       <tr>
+         <td width="10%" valign="top">&#160;</td>
+         <td width="80%" valign="top">
+           <xsl:apply-templates
+             select="child::*[local-name(.)!='attribution']"/>
+         </td>
+         <td width="10%" valign="top">&#160;</td>
+       </tr>
+       <tr>
+         <td colspan="2" align="right" valign="top">
+           <xsl:text>--</xsl:text>
+           <xsl:apply-templates select="attribution"/>
+         </td>
+         <td width="10%" valign="top">&#160;</td>
+       </tr>
+      </table>
+    </xsl:when>
+    <xsl:otherwise>
+      <blockquote class="blockquote">
+       <xsl:apply-templates/>
+      </blockquote>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="epigraph">
+  <div class="{name(.)}">
+    <xsl:apply-templates select="para"/>
+    <span>--<xsl:apply-templates select="attribution"/></span>
+  </div>
+</xsl:template>
+
+<xsl:template match="attribution">
+  <span class="{name(.)}"><xsl:apply-templates/></span>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="sidebar">
+  <div class="{name(.)}">
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id"/>
+      </xsl:attribute>
+    </a>
+  
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="sidebar/title">
+  <p class="title">
+    <b><xsl:apply-templates/></b>
+  </p>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="abstract">
+  <div class="{name(.)}">
+    <xsl:call-template name="formal.object.heading">
+      <xsl:with-param name="title">
+        <xsl:apply-templates select="." mode="title.markup">
+          <xsl:with-param name="allow-anchors" select="'1'"/>
+        </xsl:apply-templates>
+      </xsl:with-param>
+    </xsl:call-template>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="abstract/title">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="msgset">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msgentry">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="simplemsgentry">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="msg">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="msgmain">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msgmain/title">
+  <b><xsl:apply-templates/></b>
+</xsl:template>
+
+<xsl:template match="msgsub">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msgsub/title">
+  <b><xsl:apply-templates/></b>
+</xsl:template>
+
+<xsl:template match="msgrel">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msgrel/title">
+  <b><xsl:apply-templates/></b>
+</xsl:template>
+
+<xsl:template match="msgtext">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="msginfo">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="msglevel">
+  <p>
+    <b>
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'msgset'"/>
+        <xsl:with-param name="name" select="'MsgLevel'"/>
+      </xsl:call-template>
+    </b>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<xsl:template match="msgorig">
+  <p>
+    <b>
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'msgset'"/>
+        <xsl:with-param name="name" select="'MsgOrig'"/>
+      </xsl:call-template>
+    </b>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<xsl:template match="msgaud">
+  <p>
+    <b>
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'msgset'"/>
+        <xsl:with-param name="name" select="'MsgAud'"/>
+      </xsl:call-template>
+    </b>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<xsl:template match="msgexplan">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="msgexplan/title">
+  <p><b><xsl:apply-templates/></b></p>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="revhistory">
+  <div class="{name(.)}">
+    <table border="0" width="100%" summary="Revision history">
+      <tr>
+        <th align="left" valign="top" colspan="3">
+          <b>
+            <xsl:call-template name="gentext">
+              <xsl:with-param name="key" select="'RevHistory'"/>
+            </xsl:call-template>
+          </b>
+        </th>
+      </tr>
+      <xsl:apply-templates/>
+    </table>
+  </div>
+</xsl:template>
+
+<xsl:template match="revhistory/revision">
+  <xsl:variable name="revnumber" select=".//revnumber"/>
+  <xsl:variable name="revdate"   select=".//date"/>
+  <xsl:variable name="revauthor" select=".//authorinitials"/>
+  <xsl:variable name="revremark" select=".//revremark|../revdescription"/>
+  <tr>
+    <td align="left">
+      <xsl:if test="$revnumber">
+        <xsl:call-template name="gentext">
+          <xsl:with-param name="key" select="'Revision'"/>
+        </xsl:call-template>
+        <xsl:call-template name="gentext.space"/>
+        <xsl:apply-templates select="$revnumber"/>
+      </xsl:if>
+    </td>
+    <td align="left">
+      <xsl:apply-templates select="$revdate"/>
+    </td>
+    <xsl:choose>
+      <xsl:when test="count($revauthor)=0">
+        <td align="left">
+          <xsl:call-template name="dingbat">
+            <xsl:with-param name="dingbat">nbsp</xsl:with-param>
+          </xsl:call-template>
+        </td>
+      </xsl:when>
+      <xsl:otherwise>
+        <td align="left">
+          <xsl:apply-templates select="$revauthor"/>
+        </td>
+      </xsl:otherwise>
+    </xsl:choose>
+  </tr>
+  <xsl:if test="$revremark">
+    <tr>
+      <td align="left" colspan="3">
+        <xsl:apply-templates select="$revremark"/>
+      </td>
+    </tr>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="revision/revnumber">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="revision/date">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="revision/authorinitials">
+  <xsl:text>, </xsl:text>
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="revision/authorinitials[1]" priority="2">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="revision/revremark">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="revision/revdescription">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="ackno">
+  <p class="{name(.)}">
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="highlights">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/callout.xsl b/xsl/html/callout.xsl
new file mode 100644 (file)
index 0000000..242b3a4
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:sverb="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Verbatim"
+                xmlns:xverb="com.nwalsh.xalan.Verbatim"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="sverb xverb lxslt"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<lxslt:component prefix="xverb"
+                 functions="insertCallouts"/>
+
+<xsl:template match="programlistingco|screenco">
+  <xsl:variable name="verbatim" select="programlisting|screen"/>
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:choose>
+    <xsl:when test="$use.extensions != '0'
+                    and $callouts.extension != '0'">
+      <xsl:variable name="rtf">
+        <xsl:apply-templates select="$verbatim">
+          <xsl:with-param name="suppress-numbers" select="'1'"/>
+        </xsl:apply-templates>
+      </xsl:variable>
+
+      <xsl:variable name="rtf-with-callouts">
+        <xsl:choose>
+          <xsl:when test="contains($vendor, 'SAXON ')">
+            <xsl:copy-of select="sverb:insertCallouts(areaspec,$rtf)"/>
+          </xsl:when>
+          <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+            <xsl:copy-of select="xverb:insertCallouts(areaspec,$rtf)"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:message terminate="yes">
+              <xsl:text>Don't know how to do callouts with </xsl:text>
+              <xsl:value-of select="$vendor"/>
+            </xsl:message>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:choose>
+        <xsl:when test="$verbatim/@linenumbering = 'numbered'
+                        and $linenumbering.extension != '0'">
+          <div class="{name(.)}">
+            <xsl:call-template name="number.rtf.lines">
+              <xsl:with-param name="rtf" select="$rtf-with-callouts"/>
+              <xsl:with-param name="linenumbering.everyNth"
+                              select="$linenumbering.everyNth"/>
+              <xsl:with-param name="linenumbering.width"
+                              select="$linenumbering.width"/>
+              <xsl:with-param name="linenumbering.separator"
+                              select="$linenumbering.separator"/>
+            </xsl:call-template>
+            <xsl:apply-templates select="calloutlist"/>
+          </div>
+        </xsl:when>
+        <xsl:otherwise>
+          <div class="{name(.)}">
+            <xsl:copy-of select="$rtf-with-callouts"/>
+            <xsl:apply-templates select="calloutlist"/>
+          </div>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <div class="{name(.)}">
+        <xsl:apply-templates/>
+      </div>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="areaspec|areaset|area">
+</xsl:template>
+
+<xsl:template match="areaset" mode="conumber">
+  <xsl:number count="area|areaset" format="1"/>
+</xsl:template>
+
+<xsl:template match="area" mode="conumber">
+  <xsl:number count="area|areaset" format="1"/>
+</xsl:template>
+
+<xsl:template match="co">
+  <a name="{@id}"/>
+  <xsl:apply-templates select="." mode="callout-bug"/>
+</xsl:template>
+
+<xsl:template match="co" mode="callout-bug">
+  <xsl:call-template name="callout-bug">
+    <xsl:with-param name="conum">
+      <xsl:number count="co" format="1"/>
+    </xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="callout-bug">
+  <xsl:param name="conum" select='1'/>
+
+  <xsl:choose>
+    <xsl:when test="$callout.graphics = '0'
+                    or $conum > $callout.graphics.number.limit">
+
+      <xsl:text>(</xsl:text>
+      <xsl:value-of select="$conum"/>
+      <xsl:text>)</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <img src="{$callout.graphics.path}{$conum}{$callout.graphics.extension}"
+           alt="{$conum}" border="0"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/changebars.xsl b/xsl/html/changebars.xsl
new file mode 100644 (file)
index 0000000..fee001a
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0">
+
+<xsl:import href="docbook.xsl"/>
+
+<xsl:param name="show.revisionflag" select="'1'"/>
+
+<xsl:template name="user.head.content">
+<style type="text/css">
+<xsl:text>
+div.added    { background-color: yellow; }
+div.deleted  { text-decoration: line-through;
+               background-color: #FF7F7F; }
+div.changed  { background-color: lime; }
+div.off      {  }
+
+span.added   { background-color: yellow; }
+span.deleted { text-decoration: line-through;
+               background-color: #FF7F7F; }
+span.changed { background-color: lime; }
+span.off     {  }
+</xsl:text>
+</style>
+</xsl:template>
+
+<xsl:template match="*[@revisionflag]">
+  <xsl:choose>
+    <xsl:when test="local-name(.) = 'para'
+                    or local-name(.) = 'section'
+                    or local-name(.) = 'sect1'
+                    or local-name(.) = 'sect2'
+                    or local-name(.) = 'sect3'
+                    or local-name(.) = 'sect4'
+                    or local-name(.) = 'sect5'
+                    or local-name(.) = 'chapter'
+                    or local-name(.) = 'preface'
+                    or local-name(.) = 'itemizedlist'
+                    or local-name(.) = 'appendix'">
+      <div class='{@revisionflag}'>
+       <xsl:apply-imports/>
+      </div>
+    </xsl:when>
+    <xsl:when test="local-name(.) = 'phrase'
+                    or local-name(.) = 'ulink'
+                    or local-name(.) = 'filename'
+                    or local-name(.) = 'literal'
+                    or local-name(.) = 'emphasis'
+                    or local-name(.) = 'command'
+                    or local-name(.) = 'xref'">
+      <span class='{@revisionflag}'>
+       <xsl:apply-imports/>
+      </span>
+    </xsl:when>
+    <xsl:when test="local-name(.) = 'listitem'
+                    or local-name(.) = 'title'">
+      <!-- nop; these are handled directly in the stylesheet -->
+      <xsl:apply-imports/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message>
+       <xsl:text>Revisionflag on unexpected element: </xsl:text>
+       <xsl:value-of select="local-name(.)"/>
+       <xsl:text>(Assuming block)</xsl:text>
+      </xsl:message>
+      <div class='{@revisionflag}'>
+       <xsl:apply-imports/>
+      </div>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/chunk-common.xsl b/xsl/html/chunk-common.xsl
new file mode 100644 (file)
index 0000000..f655bac
--- /dev/null
@@ -0,0 +1,800 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:saxon="http://icl.com/saxon"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                xmlns:xalanredirect="org.apache.xalan.xslt.extensions.Redirect"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+               version="1.0"
+                exclude-result-prefixes="doc"
+                extension-element-prefixes="saxon xalanredirect lxslt">
+
+<xsl:import href="docbook.xsl"/>
+
+<xsl:output method="html"
+            encoding="ISO-8859-1"
+            indent="no"/>
+
+<xsl:param name="html.ext" select="'.html'"/>
+<xsl:param name="root.filename" select="'index'"/>
+<xsl:param name="base.dir" select="''"/>
+<doc:param name="base.dir" xmlns="">
+<refpurpose>Output directory for chunks</refpurpose>
+<refdescription>
+<para>If specified, the <literal>base.dir</literal> identifies
+the output directory for chunks. (If not specified, the output directory
+is system dependent.)</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<!-- What's a chunk?
+
+     appendix
+     article
+     bibliography  in article or book
+     book
+     chapter
+     colophon
+     glossary      in article or book
+     index         in article or book
+     part
+     preface
+     refentry
+     reference
+     sect1         if position()>1
+     section       if position()>1 && parent != section
+     set
+     setindex
+                                                                          -->
+<!-- ==================================================================== -->
+
+<xsl:template name="chunk">
+  <xsl:param name="node" select="."/>
+  <!-- returns 1 if $node is a chunk -->
+
+  <xsl:choose>
+    <xsl:when test="name($node)='sect1'
+                    and count($node/preceding-sibling::sect1) > 0">1</xsl:when>
+    <xsl:when test="name($node)='section'
+                    and count($node/parent::section) = 0
+                    and count($node/preceding-sibling::section) > 0">1</xsl:when>
+    <xsl:when test="name($node)='preface'">1</xsl:when>
+    <xsl:when test="name($node)='chapter'">1</xsl:when>
+    <xsl:when test="name($node)='appendix'">1</xsl:when>
+    <xsl:when test="name($node)='article'">1</xsl:when>
+    <xsl:when test="name($node)='part'">1</xsl:when>
+    <xsl:when test="name($node)='reference'">1</xsl:when>
+    <xsl:when test="name($node)='refentry'">1</xsl:when>
+    <xsl:when test="name($node)='index'
+                    and (name($node/parent::*) = 'article'
+                         or name($node/parent::*) = 'book')">1</xsl:when>
+    <xsl:when test="name($node)='bibliography'
+                    and (name($node/parent::*) = 'article'
+                         or name($node/parent::*) = 'book')">1</xsl:when>
+    <xsl:when test="name($node)='glossary'
+                    and (name($node/parent::*) = 'article'
+                         or name($node/parent::*) = 'book')">1</xsl:when>
+    <xsl:when test="name($node)='colophon'">1</xsl:when>
+    <xsl:when test="name($node)='book'">1</xsl:when>
+    <xsl:when test="name($node)='set'">1</xsl:when>
+    <xsl:when test="name($node)='setindex'">1</xsl:when>
+    <xsl:otherwise>0</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="chunk-filename">
+  <xsl:param name="recursive" select="false()"/>
+
+  <!-- returns the filename of a chunk -->
+  <xsl:variable name="ischunk">
+    <xsl:call-template name="chunk"/>
+  </xsl:variable>
+
+  <xsl:variable name="dbhtml-filename">
+    <xsl:call-template name="dbhtml-filename"/>
+  </xsl:variable>
+
+  <xsl:variable name="filename">
+    <xsl:choose>
+      <xsl:when test="$dbhtml-filename != ''">
+        <xsl:value-of select="$dbhtml-filename"/>
+      </xsl:when>
+      <!-- if there's no dbhtml filename, and if we're to use IDs as -->
+      <!-- filenames, *and* this isn't the root node, then use the ID -->
+      <!-- to generate the filename. -->
+      <xsl:when test="@id and $use.id.as.filename != 0
+                      and . != /*">
+        <xsl:value-of select="@id"/>
+        <xsl:value-of select="$html.ext"/>
+      </xsl:when>
+      <xsl:otherwise></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="dir">
+    <xsl:call-template name="dbhtml-dir"/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$ischunk='0'">
+      <!-- if called on something that isn't a chunk, walk up... -->
+      <xsl:choose>
+        <xsl:when test="count(parent::*)>0">
+          <xsl:apply-templates mode="chunk-filename" select="parent::*">
+            <xsl:with-param name="recursive" select="$recursive"/>
+          </xsl:apply-templates>
+        </xsl:when>
+        <!-- unless there is no up, in which case return "" -->
+        <xsl:otherwise></xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <xsl:when test="not($recursive) and $filename != ''">
+      <!-- if this chunk has an explicit name, use it -->
+      <xsl:if test="$dir != ''">
+        <xsl:value-of select="$dir"/>
+        <xsl:text>/</xsl:text>
+      </xsl:if>
+      <xsl:value-of select="$filename"/>
+    </xsl:when>
+
+    <xsl:when test="name(.)='set'">
+      <xsl:value-of select="$root.filename"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='book'">
+      <xsl:choose>
+        <xsl:when test="count(parent::*)>0">
+          <xsl:text>bk</xsl:text>
+          <xsl:number level="any" format="01"/>
+        </xsl:when>
+        <xsl:otherwise>
+         <xsl:value-of select="$root.filename"/>
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='article'">
+      <xsl:if test="/set">
+        <!-- in a set, make sure we inherit the right book info... -->
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:choose>
+        <xsl:when test="count(parent::*)>0">
+          <!-- if we aren't the root, name them numerically ... -->
+          <xsl:text>ar</xsl:text>
+          <xsl:number level="any" format="01" from="book"/>
+        </xsl:when>
+        <xsl:otherwise>
+         <xsl:value-of select="$root.filename"/>
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='preface'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>pr</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='chapter'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>ch</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='appendix'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>ap</xsl:text>
+      <xsl:number level="any" format="a" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='part'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>pt</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='reference'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>rn</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='refentry'">
+      <xsl:if test="parent::reference">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>re</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='colophon'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>co</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='sect1' or name(.)='section'">
+      <xsl:apply-templates mode="chunk-filename" select="parent::*">
+        <xsl:with-param name="recursive" select="true()"/>
+      </xsl:apply-templates>
+      <xsl:text>s</xsl:text>
+      <xsl:number level="any" format="01" from="preface|chapter|appendix"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='bibliography'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>bi</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='glossary'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>go</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='index'">
+      <xsl:if test="/set">
+        <xsl:apply-templates mode="chunk-filename" select="parent::*">
+          <xsl:with-param name="recursive" select="true()"/>
+        </xsl:apply-templates>
+      </xsl:if>
+      <xsl:text>ix</xsl:text>
+      <xsl:number level="any" format="01" from="book"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:when test="name(.)='setindex'">
+      <xsl:text>si</xsl:text>
+      <xsl:number level="any" format="01" from="set"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:when>
+
+    <xsl:otherwise>
+      <xsl:text>chunk-filename-error-</xsl:text>
+      <xsl:value-of select="name(.)"/>
+      <xsl:number level="any" format="01" from="set"/>
+      <xsl:if test="not($recursive)">
+        <xsl:value-of select="$html.ext"/>
+      </xsl:if>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="href.target">
+  <xsl:param name="object" select="."/>
+  <xsl:variable name="ischunk">
+    <xsl:call-template name="chunk">
+      <xsl:with-param name="node" select="$object"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:apply-templates mode="chunk-filename" select="$object"/>
+
+  <xsl:if test="$ischunk='0'">
+    <xsl:text>#</xsl:text>
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="$object"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="html.head">
+  <xsl:param name="prev" select="/foo"/>
+  <xsl:param name="next" select="/foo"/>
+  <xsl:variable name="home" select="/*[1]"/>
+  <xsl:variable name="up" select="parent::*"/>
+
+  <head>
+    <xsl:call-template name="head.content"/>
+    <xsl:call-template name="user.head.content"/>
+
+    <xsl:if test="$home">
+      <link rel="home">
+        <xsl:variable name="home-title">
+          <xsl:apply-templates select="$home" mode="title.markup"/>
+        </xsl:variable>
+
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="$home"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:attribute name="title">
+          <xsl:value-of select="$home-title"/> <!-- node-set ==> text only! -->
+        </xsl:attribute>
+      </link>
+    </xsl:if>
+
+    <xsl:if test="$up">
+      <link rel="up">
+        <xsl:variable name="up-title">
+          <xsl:apply-templates select="$up" mode="title.markup"/>
+        </xsl:variable>
+
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="$up"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:attribute name="title">
+          <xsl:value-of select="$up-title"/> <!-- node-set ==> text only! -->
+        </xsl:attribute>
+      </link>
+    </xsl:if>
+
+    <xsl:if test="$prev">
+      <link rel="previous">
+        <xsl:variable name="prev-title">
+          <xsl:apply-templates select="$prev" mode="title.markup"/>
+        </xsl:variable>
+
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="$prev"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:attribute name="title">
+          <xsl:value-of select="$prev-title"/> <!-- node-set ==> text only! -->
+        </xsl:attribute>
+      </link>
+    </xsl:if>
+
+    <xsl:if test="$next">
+      <link rel="next">
+        <xsl:variable name="next-title">
+          <xsl:apply-templates select="$next" mode="title.markup"/>
+        </xsl:variable>
+
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="$next"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:attribute name="title">
+          <xsl:value-of select="$next-title"/> <!-- node-set ==> text only! -->
+        </xsl:attribute>
+      </link>
+    </xsl:if>
+  </head>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="header.navigation">
+  <xsl:param name="prev" select="/foo"/>
+  <xsl:param name="next" select="/foo"/>
+  <xsl:variable name="home" select="/*[1]"/>
+  <xsl:variable name="up" select="parent::*"/>
+
+  <xsl:if test="$suppress.navigation = '0'">
+    <div class="navheader">
+      <table width="100%">
+        <tr>
+          <th colspan="3" align="center">
+            <xsl:apply-templates select="." mode="title.markup"/>
+          </th>
+        </tr>
+        <tr>
+          <td width="20%" align="left">
+            <xsl:if test="count($prev)>0">
+              <a>
+                <xsl:attribute name="href">
+                  <xsl:call-template name="href.target">
+                    <xsl:with-param name="object" select="$prev"/>
+                  </xsl:call-template>
+                </xsl:attribute>
+                <xsl:call-template name="gentext">
+                  <xsl:with-param name="key">nav-prev</xsl:with-param>
+                </xsl:call-template>
+              </a>
+            </xsl:if>
+            <xsl:text>&#160;</xsl:text>
+          </td>
+          <th width="60%" align="center">
+            <xsl:choose>
+              <xsl:when test="count($up) > 0 and $up != $home">
+                <xsl:apply-templates select="$up" mode="title.markup"/>
+              </xsl:when>
+              <xsl:otherwise>&#160;</xsl:otherwise>
+            </xsl:choose>
+          </th>
+          <td width="20%" align="right">
+            <xsl:text>&#160;</xsl:text>
+            <xsl:if test="count($next)>0">
+              <a>
+                <xsl:attribute name="href">
+                  <xsl:call-template name="href.target">
+                    <xsl:with-param name="object" select="$next"/>
+                  </xsl:call-template>
+                </xsl:attribute>
+                <xsl:call-template name="gentext">
+                  <xsl:with-param name="key">nav-next</xsl:with-param>
+                </xsl:call-template>
+              </a>
+            </xsl:if>
+          </td>
+        </tr>
+      </table>
+      <hr/>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="footer.navigation">
+  <xsl:param name="prev" select="/foo"/>
+  <xsl:param name="next" select="/foo"/>
+  <xsl:variable name="home" select="/*[1]"/>
+  <xsl:variable name="up" select="parent::*"/>
+
+  <xsl:if test="$suppress.navigation = '0'">
+    <div class="navfooter">
+      <hr/>
+      <table width="100%">
+        <tr>
+          <td width="40%" align="left">
+            <xsl:if test="count($prev)>0">
+              <a>
+                <xsl:attribute name="href">
+                  <xsl:call-template name="href.target">
+                    <xsl:with-param name="object" select="$prev"/>
+                  </xsl:call-template>
+                </xsl:attribute>
+                <xsl:call-template name="gentext">
+                  <xsl:with-param name="key">nav-prev</xsl:with-param>
+                </xsl:call-template>
+              </a>
+            </xsl:if>
+            <xsl:text>&#160;</xsl:text>
+          </td>
+          <td width="20%" align="center">
+            <xsl:choose>
+              <xsl:when test="$home != .">
+                <a>
+                  <xsl:attribute name="href">
+                    <xsl:call-template name="href.target">
+                      <xsl:with-param name="object" select="$home"/>
+                    </xsl:call-template>
+                  </xsl:attribute>
+                  <xsl:call-template name="gentext">
+                    <xsl:with-param name="key">nav-home</xsl:with-param>
+                  </xsl:call-template>
+                </a>
+              </xsl:when>
+              <xsl:otherwise>&#160;</xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td width="40%" align="right">
+            <xsl:text>&#160;</xsl:text>
+            <xsl:if test="count($next)>0">
+              <a>
+                <xsl:attribute name="href">
+                  <xsl:call-template name="href.target">
+                    <xsl:with-param name="object" select="$next"/>
+                  </xsl:call-template>
+                </xsl:attribute>
+                <xsl:call-template name="gentext">
+                  <xsl:with-param name="key">nav-next</xsl:with-param>
+                </xsl:call-template>
+              </a>
+            </xsl:if>
+          </td>
+        </tr>
+
+        <tr>
+          <td width="40%" align="left">
+            <xsl:apply-templates select="$prev" mode="title.markup"/>
+            <xsl:text>&#160;</xsl:text>
+          </td>
+          <td width="20%" align="center">
+            <xsl:choose>
+              <xsl:when test="count($up)>0">
+                <a>
+                  <xsl:attribute name="href">
+                    <xsl:call-template name="href.target">
+                      <xsl:with-param name="object" select="$up"/>
+                    </xsl:call-template>
+                  </xsl:attribute>
+                  <xsl:call-template name="gentext">
+                    <xsl:with-param name="key">nav-up</xsl:with-param>
+                  </xsl:call-template>
+                </a>
+              </xsl:when>
+              <xsl:otherwise>&#160;</xsl:otherwise>
+            </xsl:choose>
+          </td>
+          <td width="40%" align="right">
+            <xsl:text>&#160;</xsl:text>
+            <xsl:apply-templates select="$next" mode="title.markup"/>
+          </td>
+        </tr>
+      </table>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="processing-instruction('dbhtml')">
+  <!-- nop -->
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process-chunk-element">
+  <xsl:variable name="root" select="count(parent::*) &gt; 0"/>
+
+  <xsl:variable name="prev"
+    select="(preceding::book[1]
+             |preceding::preface[1]
+             |preceding::chapter[1]
+             |preceding::appendix[1]
+             |preceding::part[1]
+             |preceding::reference[1]
+             |preceding::refentry[1]
+             |preceding::colophon[1]
+             |preceding::sect1[name(preceding-sibling::*[1]) = 'sect1'][1]
+             |preceding::section[name(preceding-sibling::*[1]) = 'section'
+                                 and name(parent::*) != 'section'][1]
+             |preceding::article[1]
+             |preceding::bibliography[1]
+             |preceding::glossary[1]
+             |preceding::index[1]
+             |preceding::setindex[1]
+             |ancestor::set
+             |ancestor::book[1]
+             |ancestor::preface[1]
+             |ancestor::chapter[1]
+             |ancestor::appendix[1]
+             |ancestor::part[1]
+             |ancestor::reference[1]
+             |ancestor::article[1])[last()]"/>
+
+  <xsl:variable name="next"
+    select="(following::book[1]
+             |following::preface[1]
+             |following::chapter[1]
+             |following::appendix[1]
+             |following::part[1]
+             |following::reference[1]
+             |following::refentry[1]
+             |following::colophon[1]
+             |following::sect1[1]
+             |following::section[name(parent::*) != 'section'][1]
+             |following::bibliography[1]
+             |following::glossary[1]
+             |following::index[1]
+             |following::article[1]
+             |following::setindex[1]
+             |descendant::book[1]
+             |descendant::preface[1]
+             |descendant::chapter[1]
+             |descendant::appendix[1]
+             |descendant::article[1]
+             |descendant::bibliography[1]
+             |descendant::glossary[1]
+             |descendant::index[1]
+             |descendant::colophon[1]
+             |descendant::setindex[1]
+             |descendant::part[1]
+             |descendant::reference[1]
+             |descendant::refentry[1]
+             |descendant::sect1[2]
+             |descendant::section[name(parent::*) != 'section'][2])[1]"/>
+
+  <xsl:variable name="ischunk">
+    <xsl:call-template name="chunk"/>
+  </xsl:variable>
+
+  <xsl:variable name="chunkfn">
+    <xsl:if test="$ischunk='1'">
+      <xsl:apply-templates mode="chunk-filename" select="."/>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:if test="$ischunk='0'">
+    <xsl:message>
+      <xsl:text>Error </xsl:text>
+      <xsl:value-of select="name(.)"/>
+      <xsl:text> is not a chunk!</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <xsl:variable name="filename">
+    <xsl:call-template name="make-relative-filename">
+      <xsl:with-param name="base.dir" select="$base.dir"/>
+      <xsl:with-param name="base.name" select="$chunkfn"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:message>
+    <xsl:text>Writing </xsl:text>
+    <xsl:value-of select="$filename"/>
+    <xsl:text> for </xsl:text>
+    <xsl:value-of select="name(.)"/>
+  </xsl:message>
+
+  <xsl:call-template name="write.chunk">
+    <xsl:with-param name="filename" select="$filename"/>
+    <xsl:with-param name="content">
+      <xsl:call-template name="chunk-element-content">
+        <xsl:with-param name="prev" select="$prev"/>
+        <xsl:with-param name="next" select="$next"/>
+      </xsl:call-template>
+    </xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="chunk-element-content">
+  <xsl:param name="prev"></xsl:param>
+  <xsl:param name="next"></xsl:param>
+
+  <html>
+    <xsl:call-template name="html.head">
+      <xsl:with-param name="prev" select="$prev"/>
+      <xsl:with-param name="next" select="$next"/>
+    </xsl:call-template>
+
+    <body xsl:use-attribute-sets="body.attrs">
+      <xsl:call-template name="user.header.navigation"/>
+
+      <xsl:call-template name="header.navigation">
+       <xsl:with-param name="prev" select="$prev"/>
+       <xsl:with-param name="next" select="$next"/>
+      </xsl:call-template>
+
+      <xsl:call-template name="user.header.content"/>
+
+      <xsl:apply-imports/>
+
+      <xsl:call-template name="user.footer.content"/>
+
+      <xsl:call-template name="footer.navigation">
+       <xsl:with-param name="prev" select="$prev"/>
+       <xsl:with-param name="next" select="$next"/>
+      </xsl:call-template>
+
+      <xsl:call-template name="user.footer.navigation"/>
+    </body>
+  </html>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="/">
+  <xsl:choose>
+    <xsl:when test="$rootid != ''">
+      <xsl:choose>
+        <xsl:when test="count(id($rootid)) = 0">
+          <xsl:message terminate="yes">
+            <xsl:text>ID '</xsl:text>
+            <xsl:value-of select="$rootid"/>
+            <xsl:text>' not found in document.</xsl:text>
+          </xsl:message>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates select="id($rootid)"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="set|book|part|preface|chapter|appendix
+                     |article
+                     |reference|refentry
+                     |sect1[position()>1]
+                     |section[position()>1 and name(parent::*) != 'section']
+                     |book/glossary|article/glossary
+                     |book/bibliography|article/bibliography
+                     |colophon">
+  <xsl:call-template name="process-chunk-element"/>
+</xsl:template>
+
+<xsl:template match="setindex
+                     |book/index
+                     |article/index">
+  <!-- some implementations use completely empty index tags to indicate -->
+  <!-- where an automatically generated index should be inserted. so -->
+  <!-- if the index is completely empty, skip it. -->
+  <xsl:if test="count(*)>0">
+    <xsl:call-template name="process-chunk-element"/>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/chunk.xsl b/xsl/html/chunk.xsl
new file mode 100644 (file)
index 0000000..fe7b24b
--- /dev/null
@@ -0,0 +1,15 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:saxon="http://icl.com/saxon"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                xmlns:xalanredirect="org.apache.xalan.xslt.extensions.Redirect"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+               version="1.1"
+                exclude-result-prefixes="doc"
+                extension-element-prefixes="saxon xalanredirect lxslt">
+
+<!-- This stylesheet works with Saxon and Xalan; for XT use xtchunk.xsl -->
+
+<xsl:include href="chunk-common.xsl"/>
+<xsl:include href="chunker.xsl"/>
+
+</xsl:stylesheet>
diff --git a/xsl/html/chunker.xsl b/xsl/html/chunker.xsl
new file mode 100644 (file)
index 0000000..15d1517
--- /dev/null
@@ -0,0 +1,81 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:saxon="http://icl.com/saxon"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                xmlns:xalanredirect="org.apache.xalan.xslt.extensions.Redirect"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+               version="1.1"
+                exclude-result-prefixes="doc"
+                extension-element-prefixes="saxon xalanredirect lxslt">
+
+<!-- This stylesheet works with Saxon and Xalan; for XT use xtchunker.xsl -->
+
+<!-- ==================================================================== -->
+
+<xsl:template name="make-relative-filename">
+  <xsl:param name="base.dir" select="'./'"/>
+  <xsl:param name="base.name" select="''"/>
+
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:choose>
+    <xsl:when test="contains($vendor, 'SAXON')">
+      <!-- Saxon doesn't make the chunks relative -->
+      <xsl:value-of select="concat($base.dir,$base.name)"/>
+    </xsl:when>
+    <xsl:when test="contains($vendor, 'Apache')">
+      <!-- Xalan doesn't make the chunks relative -->
+      <xsl:value-of select="concat($base.dir,$base.name)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message terminate="yes">
+        <xsl:text>Chunking isn't supported with </xsl:text>
+        <xsl:value-of select="$vendor"/>
+      </xsl:message>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="write.chunk">
+  <xsl:param name="filename" select="''"/>
+  <xsl:param name="method" select="'html'"/>
+  <xsl:param name="encoding" select="'ISO-8859-1'"/>
+  <xsl:param name="content" select="''"/>
+
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:choose>
+    <xsl:when test="contains($vendor, 'SAXON 6.2')">
+      <!-- Saxon 6.2.x uses xsl:document -->
+      <xsl:document version="1.1" href="{$filename}"
+                    method="{$method}"
+                    encoding="{$encoding}">
+        <xsl:copy-of select="$content"/>
+      </xsl:document>
+    </xsl:when>
+    <xsl:when test="contains($vendor, 'SAXON')">
+      <!-- Saxon uses saxon:output -->
+      <saxon:output file="{$filename}"
+                    href="{$filename}"
+                    method="{$method}"
+                    encoding="{$encoding}">
+        <xsl:copy-of select="$content"/>
+      </saxon:output>
+    </xsl:when>
+    <xsl:when test="contains($vendor, 'Apache')">
+      <!-- Xalan uses xalanredirect -->
+      <xalanredirect:write file="{$filename}">
+        <xsl:copy-of select="$content"/>
+      </xalanredirect:write>
+    </xsl:when>
+    <xsl:otherwise>
+      <!-- it doesn't matter since we won't be making chunks... -->
+      <xsl:message terminate="yes">
+        <xsl:text>Can't make chunks with </xsl:text>
+        <xsl:value-of select="$vendor"/>
+        <xsl:text>'s processor.</xsl:text>
+      </xsl:message>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/component.xsl b/xsl/html/component.xsl
new file mode 100644 (file)
index 0000000..14537c9
--- /dev/null
@@ -0,0 +1,322 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template name="component.title">
+  <xsl:param name="node" select="."/>
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="$node"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <h2 class="title">
+    <a name="{$id}"/>
+    <xsl:apply-templates select="$node" mode="object.title.markup"/>
+  </h2>
+</xsl:template>
+
+<xsl:template name="component.subtitle">
+  <xsl:param name="node" select="."/>
+  <xsl:variable name="subtitle"
+                select="($node/docinfo/subtitle
+                        |$node/prefaceinfo/subtitle
+                        |$node/chapterinfo/subtitle
+                        |$node/appendixinfo/subtitle
+                        |subtitle)[1]"/>
+
+  <xsl:if test="$subtitle">
+    <h3 class="subtitle">
+      <i>
+        <xsl:apply-templates select="$node" mode="object.subtitle.markup"/>
+      </i>
+    </h3>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="component.separator">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="dedication" mode="dedication">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="dedication.titlepage"/>
+    <xsl:apply-templates/>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="dedication.titlepage.recto.mode">
+  <xsl:call-template name="component.title">
+    <xsl:with-param name="node" select="ancestor::dedication[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="dedication.titlepage.recto.mode">
+  <xsl:call-template name="component.subtitle">
+    <xsl:with-param name="node" select="ancestor::dedication[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="dedication"></xsl:template> <!-- see mode="dedication" -->
+<xsl:template match="dedication/title"></xsl:template>
+<xsl:template match="dedication/subtitle"></xsl:template>
+<xsl:template match="dedication/titleabbrev"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="colophon">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="component.separator"/>
+    <xsl:call-template name="component.title"/>
+    <xsl:call-template name="component.subtitle"/>
+
+    <xsl:apply-templates/>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="colophon/title"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="preface">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="component.separator"/>
+    <xsl:call-template name="preface.titlepage"/>
+    <xsl:if test="$generate.preface.toc != '0'">
+      <xsl:call-template name="component.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="preface.titlepage.recto.mode">
+  <xsl:call-template name="component.title">
+    <xsl:with-param name="node" select="ancestor::preface[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="preface.titlepage.recto.mode">
+  <xsl:call-template name="component.subtitle">
+    <xsl:with-param name="node" select="ancestor::preface[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="preface/docinfo|prefaceinfo"></xsl:template>
+<xsl:template match="preface/title"></xsl:template>
+<xsl:template match="preface/titleabbrev"></xsl:template>
+<xsl:template match="preface/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="chapter">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="component.separator"/>
+    <xsl:call-template name="chapter.titlepage"/>
+    <xsl:if test="$generate.chapter.toc != '0'">
+      <xsl:call-template name="component.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="chapter.titlepage.recto.mode">
+  <xsl:call-template name="component.title">
+    <xsl:with-param name="node" select="ancestor::chapter[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="chapter.titlepage.recto.mode">
+  <xsl:call-template name="component.subtitle">
+    <xsl:with-param name="node" select="ancestor::chapter[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="chapter/docinfo|chapterinfo"></xsl:template>
+<xsl:template match="chapter/title"></xsl:template>
+<xsl:template match="chapter/titleabbrev"></xsl:template>
+<xsl:template match="chapter/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="appendix">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="component.separator"/>
+    <xsl:call-template name="appendix.titlepage"/>
+    <xsl:if test="$generate.appendix.toc != '0'">
+      <xsl:call-template name="component.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="appendix.titlepage.recto.mode">
+  <xsl:call-template name="component.title">
+    <xsl:with-param name="node" select="ancestor::appendix[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="appendix.titlepage.recto.mode">
+  <xsl:call-template name="component.subtitle">
+    <xsl:with-param name="node" select="ancestor::appendix[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="appendix/docinfo|appendixinfo"></xsl:template>
+<xsl:template match="appendix/title"></xsl:template>
+<xsl:template match="appendix/titleabbrev"></xsl:template>
+<xsl:template match="appendix/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="dedication" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="preface" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="chapter" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+      <xsl:text>.</xsl:text>
+      <xsl:if test="$add.space">
+        <xsl:call-template name="gentext.space"/>
+      </xsl:if>
+    </xsl:when>
+    <xsl:when test="$chapter.autolabel">
+      <xsl:number from="book" count="chapter" format="1."/>
+      <xsl:if test="$add.space">
+        <xsl:call-template name="gentext.space"/>
+      </xsl:if>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="appendix" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+
+  <xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label"/>
+      <xsl:text>.</xsl:text>
+      <xsl:if test="$add.space">
+        <xsl:call-template name="gentext.space"/>
+      </xsl:if>
+    </xsl:when>
+    <xsl:when test="$chapter.autolabel">
+      <xsl:number from="book" count="appendix" format="A."/>
+      <xsl:if test="$add.space">
+        <xsl:call-template name="gentext.space"/>
+      </xsl:if>
+    </xsl:when>
+    <xsl:otherwise></xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="article" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="bibliography" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="glossary" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<xsl:template match="index" mode="component.number">
+  <xsl:param name="add.space" select="false()"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="article">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="article.titlepage"/>
+    <xsl:if test="$generate.article.toc != '0'">
+      <xsl:call-template name="component.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="article.titlepage.recto.mode">
+  <xsl:call-template name="component.title">
+    <xsl:with-param name="node" select="ancestor::article[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="subtitle" mode="article.titlepage.recto.mode">
+  <xsl:call-template name="component.subtitle">
+    <xsl:with-param name="node" select="ancestor::article[1]"/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="article/artheader|article/articleinfo"></xsl:template>
+<xsl:template match="article/title"></xsl:template>
+<xsl:template match="article/titleabbrev"></xsl:template>
+<xsl:template match="article/subtitle"></xsl:template>
+
+<xsl:template match="article/appendix">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="section.heading">
+      <xsl:with-param name="level" select="2"/>
+      <xsl:with-param name="title">
+        <xsl:apply-templates select="." mode="title.markup"/>
+      </xsl:with-param>
+    </xsl:call-template>
+
+    <xsl:apply-templates/>
+
+    <xsl:if test="not(ancestor::article)">
+      <xsl:call-template name="process.footnotes"/>
+    </xsl:if>
+  </div>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/html/division.xsl b/xsl/html/division.xsl
new file mode 100644 (file)
index 0000000..63760ee
--- /dev/null
@@ -0,0 +1,134 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="set">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}" id="{$id}">
+    <xsl:call-template name="set.titlepage"/>
+    <xsl:if test="$generate.set.toc != '0'">
+      <xsl:call-template name="set.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="set/setinfo"></xsl:template>
+<xsl:template match="set/title"></xsl:template>
+<xsl:template match="set/titleabbrev"></xsl:template>
+<xsl:template match="set/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="book">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}" id="{$id}">
+    <xsl:call-template name="book.titlepage"/>
+    <xsl:apply-templates select="dedication" mode="dedication"/>
+    <xsl:if test="$generate.book.toc != '0'">
+      <xsl:call-template name="division.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="book/bookinfo"></xsl:template>
+<xsl:template match="book/title"></xsl:template>
+<xsl:template match="book/titleabbrev"></xsl:template>
+<xsl:template match="book/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="part">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}" id="{$id}">
+    <xsl:call-template name="part.titlepage"/>
+    <xsl:if test="not(partintro) and $generate.part.toc != '0'">
+      <xsl:call-template name="division.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="part" mode="make.part.toc">
+  <xsl:call-template name="division.toc"/>
+</xsl:template>
+
+<xsl:template match="reference" mode="make.part.toc">
+  <xsl:call-template name="division.toc"/>
+</xsl:template>
+
+<xsl:template match="part/docinfo"></xsl:template>
+<xsl:template match="part/partinfo"></xsl:template>
+<xsl:template match="part/title"></xsl:template>
+<xsl:template match="part/titleabbrev"></xsl:template>
+<xsl:template match="part/subtitle"></xsl:template>
+
+<xsl:template match="partintro">
+  <div class="{name(.)}">
+    <xsl:call-template name="partintro.titlepage"/>
+    <xsl:apply-templates/>
+    <xsl:if test="$generate.part.toc != '0'">
+      <!-- not ancestor::part because partintro appears in reference -->
+      <xsl:apply-templates select="parent::*" mode="make.part.toc"/>
+    </xsl:if>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="partintro/title"></xsl:template>
+<xsl:template match="partintro/titleabbrev"></xsl:template>
+<xsl:template match="partintro/subtitle"></xsl:template>
+
+<xsl:template match="partintro/title" mode="partintro.title.mode">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <h2>
+    <a name="{$id}">
+      <xsl:apply-templates/>
+    </a>
+  </h2>
+</xsl:template>
+
+<xsl:template match="partintro/subtitle" mode="partintro.title.mode">
+  <h3>
+    <i><xsl:apply-templates/></i>
+  </h3>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="book" mode="division.number">
+  <xsl:number from="set" count="book" format="1."/>
+</xsl:template>
+
+<xsl:template match="part" mode="division.number">
+  <xsl:number from="book" count="part" format="I."/>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/html/docbook.xsl b/xsl/html/docbook.xsl
new file mode 100644 (file)
index 0000000..13d2f5e
--- /dev/null
@@ -0,0 +1,203 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<xsl:output method="html"
+            encoding="ISO-8859-1"
+            indent="no"/>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:include href="../VERSION"/>
+<xsl:include href="../lib/lib.xsl"/>
+<xsl:include href="../common/l10n.xsl"/>
+<xsl:include href="../common/common.xsl"/>
+<xsl:include href="../common/labels.xsl"/>
+<xsl:include href="../common/titles.xsl"/>
+<xsl:include href="../common/subtitles.xsl"/>
+<xsl:include href="../common/gentext.xsl"/>
+<xsl:include href="param.xsl"/>
+<xsl:include href="autotoc.xsl"/>
+<xsl:include href="lists.xsl"/>
+<xsl:include href="callout.xsl"/>
+<xsl:include href="verbatim.xsl"/>
+<xsl:include href="graphics.xsl"/>
+<xsl:include href="xref.xsl"/>
+<xsl:include href="formal.xsl"/>
+<xsl:include href="table.xsl"/>
+<xsl:include href="sections.xsl"/>
+<xsl:include href="inline.xsl"/>
+<xsl:include href="footnote.xsl"/>
+<xsl:include href="html.xsl"/>
+<xsl:include href="info.xsl"/>
+<xsl:include href="keywords.xsl"/>
+<xsl:include href="division.xsl"/>
+<xsl:include href="toc.xsl"/>
+<xsl:include href="index.xsl"/>
+<xsl:include href="refentry.xsl"/>
+<xsl:include href="math.xsl"/>
+<xsl:include href="admon.xsl"/>
+<xsl:include href="component.xsl"/>
+<xsl:include href="biblio.xsl"/>
+<xsl:include href="glossary.xsl"/>
+<xsl:include href="block.xsl"/>
+<xsl:include href="qandaset.xsl"/>
+<xsl:include href="synop.xsl"/>
+<xsl:include href="titlepage.xsl"/>
+<xsl:include href="titlepage.templates.xsl"/>
+<xsl:include href="pi.xsl"/>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*">
+  <xsl:message>
+    <xsl:text>No template matches </xsl:text>
+    <xsl:value-of select="name(.)"/>
+    <xsl:text>.</xsl:text>
+  </xsl:message>
+
+  <font color="red">
+    <xsl:text>&lt;</xsl:text>
+    <xsl:value-of select="name(.)"/>
+    <xsl:text>&gt;</xsl:text>
+    <xsl:apply-templates/>
+    <xsl:text>&lt;/</xsl:text>
+    <xsl:value-of select="name(.)"/>
+    <xsl:text>&gt;</xsl:text>
+  </font>
+</xsl:template>
+
+<xsl:template match="text()">
+  <xsl:value-of select="."/>
+</xsl:template>
+
+<xsl:template name="head.content">
+  <xsl:param name="node" select="."/>
+  <xsl:variable name="info" select="($node/docinfo
+                                     |$node/chapterinfo
+                                     |$node/appendixinfo
+                                     |$node/prefaceinfo
+                                     |$node/bookinfo
+                                     |$node/setinfo
+                                     |$node/articleinfo
+                                     |$node/artheader
+                                     |$node/sect1info
+                                     |$node/sect2info
+                                     |$node/sect3info
+                                     |$node/sect4info
+                                     |$node/sect5info
+                                     |$node/refsect1info
+                                     |$node/refsect2info
+                                     |$node/refsect3info
+                                     |$node/bibliographyinfo
+                                     |$node/glossaryinfo
+                                     |$node/indexinfo
+                                     |$node/refentryinfo
+                                     |$node/partinfo
+                                     |$node/referenceinfo)[1]"/>
+
+  <title>
+    <xsl:variable name="title">
+      <xsl:apply-templates select="$node" mode="title.markup"/>
+    </xsl:variable>
+    <xsl:value-of select="$title"/> <!-- text only -->
+  </title>
+
+  <xsl:if test="$html.stylesheet">
+    <link rel="stylesheet"
+          href="{$html.stylesheet}"
+          type="{$html.stylesheet.type}"/>
+  </xsl:if>
+
+  <xsl:if test="$link.mailto.url != ''">
+    <link rev="made"
+          href="{$link.mailto.url}"/>
+  </xsl:if>
+
+  <xsl:if test="$html.base != ''">
+    <base href="{$html.base}"/>
+  </xsl:if>
+
+  <meta name="generator" content="DocBook XSL Stylesheets V{$VERSION}"/>
+
+  <xsl:apply-templates select="$info/keywordset" mode="html.header"/>
+</xsl:template>
+
+<xsl:template name="user.head.content">
+  <xsl:param name="node" select="."/>
+</xsl:template>
+
+<xsl:template name="user.header.navigation">
+  <xsl:param name="node" select="."/>
+</xsl:template>
+
+<xsl:template name="user.header.content">
+  <xsl:param name="node" select="."/>
+</xsl:template>
+
+<xsl:template name="user.footer.content">
+  <xsl:param name="node" select="."/>
+</xsl:template>
+
+<xsl:template name="user.footer.navigation">
+  <xsl:param name="node" select="."/>
+</xsl:template>
+
+<xsl:template match="/">
+  <xsl:choose>
+    <xsl:when test="$rootid != ''">
+      <xsl:choose>
+        <xsl:when test="count(id($rootid)) = 0">
+          <xsl:message terminate="yes">
+            <xsl:text>ID '</xsl:text>
+            <xsl:value-of select="$rootid"/>
+            <xsl:text>' not found in document.</xsl:text>
+          </xsl:message>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates select="id($rootid)" mode="process.root"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates select="/" mode="process.root"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*" mode="process.root">
+  <xsl:variable name="doc" select="self::*"/>
+  <html>
+  <head>
+    <xsl:call-template name="head.content">
+      <xsl:with-param name="node" select="$doc"/>
+    </xsl:call-template>
+    <xsl:call-template name="user.head.content"/>
+  </head>
+  <body xsl:use-attribute-sets="body.attrs">
+    <xsl:call-template name="user.header.content">
+      <xsl:with-param name="node" select="$doc"/>
+    </xsl:call-template>
+    <xsl:apply-templates select="."/>
+    <xsl:call-template name="user.footer.content">
+      <xsl:with-param name="node" select="$doc"/>
+    </xsl:call-template>
+  </body>
+  </html>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/ebnf.xsl b/xsl/html/ebnf.xsl
new file mode 100644 (file)
index 0000000..598d577
--- /dev/null
@@ -0,0 +1,350 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<doc:reference xmlns="">
+<referenceinfo>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<copyright><year>1999</year><year>2000</year>
+<holder>Norman Walsh</holder>
+</copyright>
+</referenceinfo>
+<title>HTML EBNF Reference</title>
+
+<partintro>
+<section><title>Introduction</title>
+
+<para>This is technical reference documentation for the DocBook XSL
+Stylesheets; it documents (some of) the parameters, templates, and
+other elements of the stylesheets.</para>
+
+<para>This reference describes the templates and parameters relevant
+to formatting EBNF markup.</para>
+
+<para>This is not intended to be <quote>user</quote> documentation.
+It is provided for developers writing customization layers for the
+stylesheets, and for anyone who's interested in <quote>how it
+works</quote>.</para>
+
+<para>Although I am trying to be thorough, this documentation is known
+to be incomplete. Don't forget to read the source, too :-)</para>
+</section>
+</partintro>
+</doc:reference>
+
+<!-- This module formats EBNF tables. The DTD that this supports is  -->
+<!-- under development by the DocBook community. This code is        -->
+<!-- experimental and is not (yet) part of the DocBook stylesheets.  -->
+
+<xsl:include href="docbook.xsl"/>
+
+<!-- ==================================================================== -->
+
+<xsl:param name="ebnf.table.bgcolor">#F5DCB3</xsl:param>
+
+<doc:param name="ebnf.table.bgcolor" xmlns="">
+<refpurpose>Background color for EBNF tables</refpurpose>
+<refdescription>
+<para>Sets the background color for EBNF tables. No <sgmltag>bgcolor</sgmltag>
+attribute is output if <varname>ebnf.table.bgcolor</varname> is set to
+the null string. The default value matches the value used in recent
+online versions of the W3C's XML Spec productions.</para>
+</refdescription>
+</doc:param>
+
+<xsl:param name="ebnf.table.border">1</xsl:param>
+
+<doc:param name="ebnf.table.border" xmlns="">
+<refpurpose>Selects border on EBNF tables</refpurpose>
+<refdescription>
+<para>Selects the border on EBNF tables. If non-zero, the tables have
+borders, otherwise they don't.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="productionset">
+  <table width="100%" cellpadding="5">
+    <xsl:if test="$ebnf.table.bgcolor != ''">
+      <xsl:attribute name="bgcolor">
+       <xsl:value-of select="$ebnf.table.bgcolor"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$ebnf.table.border != 0">
+      <xsl:attribute name="border">1</xsl:attribute>
+    </xsl:if>
+    <xsl:attribute name="class">
+      <xsl:value-of select="name(.)"/>
+    </xsl:attribute>
+    <xsl:attribute name="summary">
+      <xsl:text>EBNF</xsl:text>
+      <xsl:if test="title">
+       <xsl:text> for </xsl:text>
+       <xsl:value-of select="title"/>
+      </xsl:if>
+    </xsl:attribute>
+
+    <xsl:if test="title">
+      <tr>
+       <th align="left" valign="top" class="{name(.)}">
+         <xsl:apply-templates select="title"/>
+       </th>
+      </tr>
+    </xsl:if>
+    <tr>
+      <td>
+       <table border="0" width="99%" cellpadding="0">
+         <xsl:if test="$ebnf.table.bgcolor != ''">
+           <xsl:attribute name="bgcolor">
+             <xsl:value-of select="$ebnf.table.bgcolor"/>
+           </xsl:attribute>
+         </xsl:if>
+         <xsl:attribute name="class">
+           <xsl:value-of select="name(.)"/>
+         </xsl:attribute>
+         <xsl:attribute name="summary">EBNF productions</xsl:attribute>
+         <xsl:apply-templates select="production|productionrecap"/>
+       </table>
+      </td>
+    </tr>
+  </table>
+</xsl:template>
+
+<xsl:template match="productionset/title">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="production">
+  <xsl:param name="recap" select="false()"/>
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+  <tr>
+    <td align="left" valign="top" width="3%">
+      <xsl:text>[</xsl:text>
+      <xsl:number count="production" level="any"/>
+      <xsl:text>]</xsl:text>
+    </td>
+    <td align="right" valign="top" width="10%">
+      <xsl:choose>
+       <xsl:when test="$recap">
+         <a>
+           <xsl:attribute name="href">
+             <xsl:call-template name="href.target">
+               <xsl:with-param name="object" select="."/>
+             </xsl:call-template>
+           </xsl:attribute>
+           <xsl:apply-templates select="lhs"/>
+         </a>
+       </xsl:when>
+       <xsl:otherwise>
+         <a name="{$id}"/>
+         <xsl:apply-templates select="lhs"/>
+       </xsl:otherwise>
+      </xsl:choose>
+    </td>
+    <td valign="top" width="5%" align="center"><tt>::=</tt></td>
+    <td valign="top" width="52%">
+      <xsl:apply-templates select="rhs"/>
+    </td>
+    <td align="left" valign="top" width="30%">
+      <xsl:choose>
+       <xsl:when test="rhs/lineannotation|constraint">
+         <xsl:apply-templates select="rhs/lineannotation" mode="rhslo"/>
+         <xsl:apply-templates select="constraint"/>
+       </xsl:when>
+       <xsl:otherwise>
+         <xsl:text>&#160;</xsl:text>
+       </xsl:otherwise>
+      </xsl:choose>
+    </td>
+  </tr>
+</xsl:template>
+
+<xsl:template match="productionrecap">
+  <xsl:variable name="targets" select="id(@linkend)"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+
+  <xsl:if test="$check.idref = '1'">
+    <xsl:if test="count($targets)=0">
+      <xsl:message>
+        <xsl:text>Error: no ID for productionrecap linkend: </xsl:text>
+        <xsl:value-of select="@linkend"/>
+        <xsl:text>.</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="count($targets)>1">
+      <xsl:message>
+        <xsl:text>Warning: multiple "IDs" for productionrecap linkend: </xsl:text>
+        <xsl:value-of select="@linkend"/>
+        <xsl:text>.</xsl:text>
+      </xsl:message>
+    </xsl:if>
+  </xsl:if>
+  <xsl:apply-templates select="$target">
+    <xsl:with-param name="recap" select="true()"/>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="lhs">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="rhs">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="nonterminal">
+  <xsl:variable name="linkend">
+    <xsl:call-template name="xpointer.idref">
+      <xsl:with-param name="xpointer" select="@def"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:call-template name="check.id.unique">
+    <xsl:with-param name="linkend" select="$linkend"/>
+  </xsl:call-template>
+
+  <xsl:call-template name="check.idref.targets">
+    <xsl:with-param name="linkend" select="$linkend"/>
+    <xsl:with-param name="element-list">production</xsl:with-param>
+  </xsl:call-template>
+
+  <!-- If you don't provide content, you can't point outside this doc. -->
+  <xsl:choose>
+    <xsl:when test="*|text()"><!--nop--></xsl:when>
+    <xsl:otherwise>
+      <xsl:if test="$linkend = ''">
+       <xsl:message>
+         <xsl:text>Non-terminals with no content must point to </xsl:text>
+         <xsl:text>production elements in the current document.</xsl:text>
+       </xsl:message>
+       <xsl:message>
+         <xsl:text>Invalid xpointer for empty nt: </xsl:text>
+         <xsl:value-of select="@def"/>
+       </xsl:message>
+      </xsl:if>
+    </xsl:otherwise>
+  </xsl:choose>
+
+  <xsl:variable name="href">
+    <xsl:choose>
+      <xsl:when test="$linkend != ''">
+       <xsl:variable name="targets" select="id($linkend)"/>
+       <xsl:variable name="target" select="$targets[1]"/>
+       <xsl:call-template name="href.target">
+         <xsl:with-param name="object" select="$target"/>
+       </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:value-of select="@def"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <a href="{$href}">
+    <xsl:choose>
+      <xsl:when test="*|text()">
+       <xsl:apply-templates/>
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:choose>
+         <xsl:when test="$linkend != ''">
+           <xsl:variable name="targets" select="id($linkend)"/>
+           <xsl:variable name="target" select="$targets[1]"/>
+           <xsl:apply-templates select="$target/lhs"/>
+         </xsl:when>
+         <xsl:otherwise>
+           <xsl:text>???</xsl:text>
+         </xsl:otherwise>
+       </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </a>
+</xsl:template>
+
+<xsl:template match="rhs/lineannotation">
+  <!--nop-->
+</xsl:template>
+
+<xsl:template match="rhs/lineannotation" mode="rhslo">
+  <xsl:text>/*&#160;</xsl:text>
+  <xsl:apply-templates/>
+  <xsl:text>&#160;*/</xsl:text>
+</xsl:template>
+
+<xsl:template match="constraint">
+  <xsl:call-template name="check.id.unique">
+    <xsl:with-param name="linkend" select="@linkend"/>
+  </xsl:call-template>
+
+  <xsl:call-template name="check.idref.targets">
+    <xsl:with-param name="linkend" select="@linkend"/>
+    <xsl:with-param name="element-list">constraintdef</xsl:with-param>
+  </xsl:call-template>
+
+  <xsl:variable name="href">
+    <xsl:variable name="targets" select="id(@linkend)"/>
+    <xsl:variable name="target" select="$targets[1]"/>
+    <xsl:call-template name="href.target">
+      <xsl:with-param name="object" select="$target"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:if test="preceding-sibling::constraint">
+    <br/>
+  </xsl:if>
+  <xsl:text>[ </xsl:text>
+
+  <xsl:choose>
+    <xsl:when test="@role">
+      <xsl:value-of select="@role"/>
+      <xsl:text>: </xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="targets" select="id(@linkend)"/>
+      <xsl:variable name="target" select="$targets[1]"/>
+      <xsl:if test="$target/@role">
+       <xsl:value-of select="$target/@role"/>
+       <xsl:text>: </xsl:text>
+      </xsl:if>
+    </xsl:otherwise>
+  </xsl:choose>
+
+  <a href="{$href}">
+    <xsl:variable name="targets" select="id(@linkend)"/>
+    <xsl:variable name="target" select="$targets[1]"/>
+    <xsl:apply-templates select="$target" mode="title.markup"/>
+  </a>
+  <xsl:text> ]</xsl:text>
+</xsl:template>
+
+<xsl:template match="constraintdef">
+  <div class="{name(.)}">
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="constraintdef/title">
+  <p><b><xsl:apply-templates/></b></p>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/footnote.xsl b/xsl/html/footnote.xsl
new file mode 100644 (file)
index 0000000..a5c7ec7
--- /dev/null
@@ -0,0 +1,138 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="footnote">
+  <xsl:variable name="name">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="href">
+    <xsl:text>#ftn.</xsl:text>
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="ancestor::table|ancestor::informaltable">
+      <sup>
+        <xsl:text>[</xsl:text>
+        <a name="{$name}" href="{$href}">
+          <xsl:apply-templates select="." mode="footnote.number"/>
+        </a>
+        <xsl:text>]</xsl:text>
+      </sup>
+    </xsl:when>
+    <xsl:otherwise>
+      <sup>
+        <xsl:text>[</xsl:text>
+        <a name="{$name}" href="{$href}">
+          <xsl:apply-templates select="." mode="footnote.number"/>
+        </a>
+        <xsl:text>]</xsl:text>
+      </sup>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="footnoteref">
+  <xsl:variable name="targets" select="id(@linkend)"/>
+  <xsl:variable name="footnote" select="$targets[1]"/>
+  <xsl:variable name="href">
+    <xsl:text>#ftn.</xsl:text>
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="$footnote"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <sup>
+    <xsl:text>[</xsl:text>
+    <a href="{$href}">
+      <xsl:apply-templates select="$footnote" mode="footnote.number"/>
+    </a>
+    <xsl:text>]</xsl:text>
+  </sup>
+</xsl:template>
+
+<xsl:template match="footnote" mode="footnote.number">
+  <xsl:choose>
+    <xsl:when test="ancestor::table|ancestor::informaltable">
+      <xsl:number level="any" from="table|informaltable" format="a"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:number level="any" format="1"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="footnote/para[1]">
+  <!-- this only works if the first thing in a footnote is a para, -->
+  <!-- which is ok, because it usually is. -->
+  <xsl:variable name="name">
+    <xsl:text>ftn.</xsl:text>
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="ancestor::footnote"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="href">
+    <xsl:text>#</xsl:text>
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="ancestor::footnote"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <p>
+    <sup>
+      <xsl:text>[</xsl:text>
+      <a name="{$name}" href="{$href}">
+        <xsl:apply-templates select="ancestor::footnote"
+                             mode="footnote.number"/>
+      </a>
+      <xsl:text>] </xsl:text>
+    </sup>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process.footnotes">
+  <xsl:variable name="footnotes" select=".//footnote"/>
+  <xsl:variable name="table.footnotes"
+                select=".//table//footnote|.//informaltable//footnote"/>
+
+  <!-- Only bother to do this if there's at least one non-table footnote -->
+  <xsl:if test="count($footnotes)>count($table.footnotes)">
+    <div class="footnotes">
+      <br/>
+      <hr width="100" align="left"/>
+      <xsl:apply-templates select="$footnotes" mode="process.footnote.mode"/>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="footnote" mode="process.footnote.mode">
+  <div class="{name(.)}">
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="informaltable//footnote|table//footnote" 
+              mode="process.footnote.mode">
+</xsl:template>
+
+<xsl:template match="footnote" mode="table.footnote.mode">
+  <div class="{name(.)}">
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/formal.xsl b/xsl/html/formal.xsl
new file mode 100644 (file)
index 0000000..a53f159
--- /dev/null
@@ -0,0 +1,89 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template name="formal.object">
+  <div class="{name(.)}">
+    <xsl:call-template name="formal.object.heading">
+       <xsl:with-param name="title">
+         <xsl:apply-templates select="." mode="title.markup"/>
+       </xsl:with-param>
+    </xsl:call-template>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template name="formal.object.heading">
+  <xsl:param name="title"></xsl:param>
+  <p>
+    <a>
+      <xsl:attribute name="name">
+       <xsl:call-template name="object.id"/>
+      </xsl:attribute>
+    </a>
+    <b><xsl:copy-of select="$title"/></b>
+  </p>
+</xsl:template>
+
+<xsl:template name="informal.object">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <div class="{name(.)}" id="{$id}">
+    <xsl:if test="$spacing.paras != 0"><p/></xsl:if>
+    <a name="{$id}"/>
+    <xsl:apply-templates/>
+    <xsl:if test="$spacing.paras != 0"><p/></xsl:if>
+  </div>
+</xsl:template>
+
+<xsl:template name="semiformal.object">
+  <xsl:choose>
+    <xsl:when test="title">
+      <xsl:call-template name="formal.object"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="informal.object"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="figure|table|example">
+  <xsl:call-template name="formal.object"/>
+</xsl:template>
+
+<xsl:template match="equation">
+  <xsl:call-template name="semiformal.object"/>
+</xsl:template>
+
+<xsl:template match="figure/title"></xsl:template>
+<xsl:template match="table/title"></xsl:template>
+<xsl:template match="example/title"></xsl:template>
+<xsl:template match="equation/title"></xsl:template>
+
+<xsl:template match="informalfigure">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+<xsl:template match="informalexample">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+<xsl:template match="informaltable">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+<xsl:template match="informalequation">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/glossary.xsl b/xsl/html/glossary.xsl
new file mode 100644 (file)
index 0000000..be7c3e3
--- /dev/null
@@ -0,0 +1,183 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="glossary">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <div id="{$id}" class="{name(.)}">
+    <xsl:call-template name="bibliography.titlepage"/>
+    <dl>
+      <xsl:apply-templates/>
+    </dl>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="glossary/glossaryinfo"></xsl:template>
+<xsl:template match="glossary/title"></xsl:template>
+<xsl:template match="glossary/subtitle"></xsl:template>
+<xsl:template match="glossary/titleabbrev"></xsl:template>
+
+<xsl:template match="glossary/title" mode="component.title.mode">
+  <h2>
+    <xsl:apply-templates/>
+  </h2>
+</xsl:template>
+
+<xsl:template match="glossary/subtitle" mode="component.title.mode">
+  <h3>
+    <i><xsl:apply-templates/></i>
+  </h3>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="glosslist">
+  <div class="{name(.)}">
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id"/>
+      </xsl:attribute>
+    </a>
+
+    <dl>
+      <xsl:apply-templates/>
+    </dl>
+  </div>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="glossdiv">
+  <div class="{name(.)}">
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="glossdiv/title">
+  <h3 class="{name(.)}">
+    <xsl:apply-templates/>
+  </h3>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<!--
+GlossEntry ::=
+  GlossTerm, Acronym?, Abbrev?,
+  (IndexTerm)*,
+  RevHistory?,
+  (GlossSee | GlossDef+)
+-->
+
+<xsl:template match="glossentry">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="glossentry/glossterm">
+  <dt>
+    <xsl:apply-templates/>
+  </dt>
+</xsl:template>
+
+<xsl:template match="glossentry/glossterm[1]" priority="2">
+  <dt>
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id">
+           <xsl:with-param name="object" select=".."/>
+        </xsl:call-template>
+      </xsl:attribute>
+
+      <xsl:apply-templates/>
+    </a>
+  </dt>
+</xsl:template>
+
+<xsl:template match="glossentry/acronym">
+</xsl:template>
+
+<xsl:template match="glossentry/abbrev">
+</xsl:template>
+
+<xsl:template match="glossentry/revhistory">
+</xsl:template>
+
+<xsl:template match="glossentry/glosssee">
+  <xsl:variable name="otherterm" select="@otherterm"/>
+  <xsl:variable name="targets" select="//node()[@id=$otherterm]"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+  <dd>
+    <p>
+      <xsl:call-template name="gentext.template">
+        <xsl:with-param name="context" select="'glossary'"/>
+        <xsl:with-param name="name" select="'see'"/>
+      </xsl:call-template>
+      <xsl:choose>
+        <xsl:when test="@otherterm">
+          <a href="#{@otherterm}">
+            <xsl:apply-templates select="$target" mode="xref"/>
+          </a>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates/>
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:text>.</xsl:text>
+    </p>
+  </dd>
+</xsl:template>
+
+<xsl:template match="glossentry/glossdef">
+  <dd><xsl:apply-templates/></dd>
+</xsl:template>
+
+<xsl:template match="glossseealso">
+  <xsl:variable name="otherterm" select="@otherterm"/>
+  <xsl:variable name="targets" select="//node()[@id=$otherterm]"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+  <p>
+    <xsl:call-template name="gentext.template">
+      <xsl:with-param name="context" select="'glossary'"/>
+      <xsl:with-param name="name" select="'seealso'"/>
+    </xsl:call-template>
+    <xsl:choose>
+      <xsl:when test="@otherterm">
+        <a href="#{@otherterm}">
+          <xsl:apply-templates select="$target" mode="xref"/>
+        </a>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+    <xsl:text>.</xsl:text>
+  </p>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="glossentry" mode="xref">
+  <xsl:apply-templates select="./glossterm[1]" mode="xref"/>
+</xsl:template>
+
+<xsl:template match="glossterm" mode="xref">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/graphics.xsl b/xsl/html/graphics.xsl
new file mode 100644 (file)
index 0000000..d7b4e00
--- /dev/null
@@ -0,0 +1,291 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xlink="http://www.w3.org/1999/xlink"
+                xmlns:stext="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.TextFactory"
+                xmlns:xtext="com.nwalsh.xalan.Text"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="xlink stext xtext lxslt"
+                extension-element-prefixes="stext xtext"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     Contributors:
+     Colin Paul Adams, <colin@colina.demon.co.uk>
+
+     ******************************************************************** -->
+
+<lxslt:component prefix="xtext"
+                 elements="insertfile"/>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="screenshot">
+  <div class="{name(.)}">
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="screeninfo">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process.image">
+  <!-- When this template is called, the current node should be  -->
+  <!-- a graphic, inlinegraphic, imagedata, or videodata. All    -->
+  <!-- those elements have the same set of attributes, so we can -->
+  <!-- handle them all in one place.                             -->
+  <xsl:param name="tag" select="'img'"/>
+  <xsl:param name="alt"/>
+
+  <xsl:variable name="filename">
+    <xsl:choose>
+      <xsl:when test="local-name(.) = 'graphic'
+                      or local-name(.) = 'inlinegraphic'">
+        <xsl:choose>
+          <xsl:when test="@fileref">
+            <xsl:value-of select="@fileref"/>
+          </xsl:when>
+          <xsl:when test="@entityref">
+            <xsl:value-of select="unparsed-entity-uri(@entityref)"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:message>
+              <xsl:text>A fileref or entityref is required on </xsl:text>
+              <xsl:value-of select="local-name(.)"/>
+            </xsl:message>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:otherwise>
+        <!-- imagedata, videodata, audiodata -->
+        <xsl:call-template name="mediaobject.filename">
+          <xsl:with-param name="object" select=".."/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="width">
+    <xsl:choose>
+      <xsl:when test="@scale"><xsl:value-of select="@scale"/>%</xsl:when>
+      <xsl:when test="@width"><xsl:value-of select="@width"/></xsl:when>
+      <xsl:otherwise></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="height">
+    <xsl:choose>
+      <xsl:when test="@scale"></xsl:when>
+      <xsl:when test="@depth"><xsl:value-of select="@depth"/></xsl:when>
+      <xsl:otherwise></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="align">
+    <xsl:value-of select="@align"/>
+  </xsl:variable>
+
+  <xsl:element name="{$tag}">
+    <xsl:attribute name="src">
+      <xsl:value-of select="$filename"/>
+    </xsl:attribute>
+
+    <xsl:if test="$align != ''">
+      <xsl:attribute name="align">
+        <xsl:value-of select="$align"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$height != ''">
+      <xsl:attribute name="height">
+        <xsl:value-of select="$height"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$width != ''">
+      <xsl:attribute name="width">
+        <xsl:value-of select="$width"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$alt != ''">
+      <xsl:attribute name="alt">
+        <xsl:value-of select="$alt"/>
+      </xsl:attribute>
+    </xsl:if>
+  </xsl:element>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="graphic">
+  <p>
+    <xsl:call-template name="process.image"/>
+  </p>
+</xsl:template>
+
+<xsl:template match="inlinegraphic">
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+  <xsl:variable name="filename">
+    <xsl:choose>
+      <xsl:when test="@entityref">
+        <xsl:value-of select="unparsed-entity-uri(@entityref)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="@fileref"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="@format='linespecific'">
+      <xsl:choose>
+        <xsl:when test="$use.extensions != '0'
+                        and $textinsert.extension != '0'">
+          <xsl:choose>
+            <xsl:when test="contains($vendor, 'SAXON')">
+              <stext:insertfile href="{$filename}"/>
+            </xsl:when>
+            <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+              <xtext:insertfile href="{$filename}"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:message terminate="yes">
+                <xsl:text>Don't know how to insert files with </xsl:text>
+                <xsl:value-of select="$vendor"/>
+              </xsl:message>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise>
+          <a xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"
+             href="{$filename}"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="process.image"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="mediaobject|mediaobjectco">
+  <div class="{name(.)}">
+    <xsl:call-template name="select.mediaobject"/>
+    <xsl:apply-templates select="caption"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="inlinemediaobject">
+  <span class="{name(.)}">
+    <xsl:call-template name="select.mediaobject"/>
+  </span>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="imageobjectco">
+  <xsl:apply-templates select="imageobject"/>
+  <xsl:apply-templates select="calloutlist"/>
+</xsl:template>
+
+<xsl:template match="imageobject">
+  <xsl:apply-templates select="imagedata"/>
+</xsl:template>
+
+<xsl:template match="imagedata">
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+  <xsl:variable name="filename">
+    <xsl:call-template name="mediaobject.filename">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="@format='linespecific'">
+      <xsl:choose>
+        <xsl:when test="$use.extensions != '0'
+                        and $textinsert.extension != '0'">
+          <xsl:choose>
+            <xsl:when test="contains($vendor, 'SAXON')">
+              <stext:insertfile href="{$filename}"/>
+            </xsl:when>
+            <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+              <xtext:insertfile href="{$filename}"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:message terminate="yes">
+                <xsl:text>Don't know how to insert files with </xsl:text>
+                <xsl:value-of select="$vendor"/>
+              </xsl:message>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise>
+          <a xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"
+             href="{$filename}"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="process.image">
+        <xsl:with-param name="alt">
+          <xsl:apply-templates select="(../../textobject/phrase)[1]"/>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="videoobject">
+  <xsl:apply-templates select="videodata"/>
+</xsl:template>
+
+<xsl:template match="videodata">
+  <xsl:call-template name="process.image">
+    <xsl:with-param name="tag" select="'embed'"/>
+    <xsl:with-param name="alt">
+      <xsl:apply-templates select="(../../textobject/phrase)[1]"/>
+    </xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="audioobject">
+  <xsl:apply-templates select="audiodata"/>
+</xsl:template>
+
+<xsl:template match="audiodata">
+  <xsl:call-template name="process.image">
+    <xsl:with-param name="tag" select="'embed'"/>
+    <xsl:with-param name="alt">
+      <xsl:apply-templates select="(../../textobject/phrase)[1]"/>
+    </xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="textobject">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="caption">
+  <div class="{name(.)}">
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/html.xsl b/xsl/html/html.xsl
new file mode 100644 (file)
index 0000000..839c8ac
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template name="dingbat">
+  <xsl:param name="dingbat">bullet</xsl:param>
+  <xsl:choose>
+    <xsl:when test="false() and $using.chunker != 0">
+      <dingbat name="{$dingbat}"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="dingbat.characters">
+        <xsl:with-param name="dingbat" select="$dingbat"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="dingbat.characters">
+  <!-- now that I'm using the real serializer, all that dingbat malarky -->
+  <!-- isn't necessary anymore... -->
+  <xsl:param name="dingbat">bullet</xsl:param>
+  <xsl:choose>
+    <xsl:when test="$dingbat='bullet'">&#x2022;</xsl:when>
+    <xsl:when test="$dingbat='copyright'">&#x00A9;</xsl:when>
+    <xsl:when test="$dingbat='trademark'">&#x2122;</xsl:when>
+    <xsl:when test="$dingbat='trade'">&#x2122;</xsl:when>
+    <xsl:when test="$dingbat='registered'">&#x00AE;</xsl:when>
+    <xsl:when test="$dingbat='service'">(SM)</xsl:when>
+    <xsl:when test="$dingbat='nbsp'">&#x00A0;</xsl:when>
+    <xsl:when test="$dingbat='ldquo'">&#x201C;</xsl:when>
+    <xsl:when test="$dingbat='rdquo'">&#x201D;</xsl:when>
+    <xsl:when test="$dingbat='lsquo'">&#x2018;</xsl:when>
+    <xsl:when test="$dingbat='rsquo'">&#x2019;</xsl:when>
+    <xsl:when test="$dingbat='em-dash'">&#x2014;</xsl:when>
+    <xsl:when test="$dingbat='mdash'">&#x2014;</xsl:when>
+    <xsl:when test="$dingbat='en-dash'">&#x2013;</xsl:when>
+    <xsl:when test="$dingbat='ndash'">&#x2013;</xsl:when>
+    <xsl:otherwise>
+      <xsl:text>&#x2022;</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/html/index.xsl b/xsl/html/index.xsl
new file mode 100644 (file)
index 0000000..5035ce8
--- /dev/null
@@ -0,0 +1,183 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="index|setindex">
+  <!-- some implementations use completely empty index tags to indicate -->
+  <!-- where an automatically generated index should be inserted. so -->
+  <!-- if the index is completely empty, skip it. -->
+
+  <xsl:if test="count(*)>0 or $generate.index != '0'">
+    <xsl:variable name="id">
+      <xsl:call-template name="object.id"/>
+    </xsl:variable>
+
+    <div id="{$id}" class="{name(.)}">
+      <xsl:call-template name="index.titlepage"/>
+      <xsl:apply-templates/>
+
+      <xsl:if test="count(indexentry) = 0 and count(indexdiv) = 0">
+        <xsl:call-template name="generate-index"/>
+      </xsl:if>
+
+      <xsl:call-template name="process.footnotes"/>
+    </div>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="index/title"></xsl:template>
+<xsl:template match="index/subtitle"></xsl:template>
+<xsl:template match="index/titleabbrev"></xsl:template>
+
+<xsl:template match="index/title" mode="component.title.mode">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <h2 class="title">
+    <a name="{$id}">
+      <xsl:apply-templates/>
+    </a>
+  </h2>
+</xsl:template>
+
+<xsl:template match="index/subtitle" mode="component.title.mode">
+  <h3>
+    <i><xsl:apply-templates/></i>
+  </h3>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="indexdiv">
+  <div class="{name(.)}">
+    <xsl:apply-templates mode="not-indexentrys"/>
+    <dl>
+      <xsl:apply-templates select="indexentry"/>
+    </dl>
+  </div>
+</xsl:template>
+
+<xsl:template match="indexentry" mode="not-indexentrys">
+  <!-- suppress -->
+</xsl:template>
+
+<xsl:template match="indexdiv/title">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select=".."/>
+    </xsl:call-template>
+  </xsl:variable>
+  <h3 class="{name(.)}">
+    <a name="{$id}">
+      <xsl:apply-templates/>
+    </a>
+  </h3>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="indexterm">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <a class="indexterm" name="{$id}"/>
+</xsl:template>
+
+<xsl:template match="primary|secondary|tertiary|see|seealso">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="indexentry">
+  <xsl:apply-templates select="primaryie"/>
+</xsl:template>
+
+<xsl:template match="primaryie">
+  <dt>
+    <xsl:apply-templates/>
+  </dt>
+  <xsl:choose>
+    <xsl:when test="following-sibling::secondaryie">
+      <dd>
+        <dl>
+          <xsl:apply-templates select="following-sibling::secondaryie"/>
+        </dl>
+      </dd>
+    </xsl:when>
+    <xsl:when test="following-sibling::seeie
+                    |following-sibling::seealsoie">
+      <dd>
+        <dl>
+          <xsl:apply-templates select="following-sibling::seeie
+                                       |following-sibling::seealsoie"/>
+        </dl>
+      </dd>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="secondaryie">
+  <dt>
+    <xsl:apply-templates/>
+  </dt>
+  <xsl:choose>
+    <xsl:when test="following-sibling::tertiaryie">
+      <dd>
+        <dl>
+          <xsl:apply-templates select="following-sibling::tertiaryie"/>
+        </dl>
+      </dd>
+    </xsl:when>
+    <xsl:when test="following-sibling::seeie
+                    |following-sibling::seealsoie">
+      <dd>
+        <dl>
+          <xsl:apply-templates select="following-sibling::seeie
+                                       |following-sibling::seealsoie"/>
+        </dl>
+      </dd>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="tertiaryie">
+  <dt>
+    <xsl:apply-templates/>
+  </dt>
+  <xsl:if test="following-sibling::seeie
+                |following-sibling::seealsoie">
+    <dd>
+      <dl>
+        <xsl:apply-templates select="following-sibling::seeie
+                                     |following-sibling::seealsoie"/>
+      </dl>
+    </dd>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="seeie|seealsoie">
+  <dt>
+    <xsl:apply-templates/>
+  </dt>
+</xsl:template>
+
+<xsl:template name="generate-index">
+  <!-- nop: use autoidx.xsl to get automatic indexing -->
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/info.xsl b/xsl/html/info.xsl
new file mode 100644 (file)
index 0000000..b1d6649
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- These templates define the "default behavior" for info
+     elements.  Even if you don't process the *info wrappers,
+     some of these elements are needed because the elements are
+     processed from named templates that are called with modes.
+     Since modes aren't sticky, these rules apply. 
+     (TODO: clarify this comment) -->
+
+<!-- ==================================================================== -->
+<!-- called from named templates in a given mode -->
+
+<xsl:template match="corpauthor">
+  <span class="{name(.)}">
+    <xsl:apply-templates/>
+  </span>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="jobtitle">
+  <span class="{name(.)}">
+    <xsl:apply-templates/>
+  </span>
+</xsl:template>
+
+<xsl:template match="orgname">
+  <span class="{name(.)}">
+    <xsl:apply-templates/>
+  </span>
+</xsl:template>
+
+<xsl:template match="orgdiv">
+  <span class="{name(.)}">
+    <xsl:apply-templates/>
+  </span>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/inline.xsl b/xsl/html/inline.xsl
new file mode 100644 (file)
index 0000000..95358ba
--- /dev/null
@@ -0,0 +1,692 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template name="inline.charseq">
+  <xsl:param name="content">
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </xsl:param>
+  <xsl:copy-of select="$content"/>
+</xsl:template>
+
+<xsl:template name="inline.monoseq">
+  <xsl:param name="content">
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </xsl:param>
+  <tt><xsl:copy-of select="$content"/></tt>
+</xsl:template>
+
+<xsl:template name="inline.boldseq">
+  <xsl:param name="content">
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </xsl:param>
+  <!-- don't put <b> inside figure, example, or table titles -->
+  <xsl:choose>
+    <xsl:when test="local-name(..) = 'title'
+                    and (local-name(../..) = 'figure'
+                         or local-name(../..) = 'example'
+                         or local-name(../..) = 'table')">
+      <xsl:copy-of select="$content"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <b><xsl:copy-of select="$content"/></b>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="inline.italicseq">
+  <xsl:param name="content">
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </xsl:param>
+  <i><xsl:copy-of select="$content"/></i>
+</xsl:template>
+
+<xsl:template name="inline.boldmonoseq">
+  <xsl:param name="content">
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </xsl:param>
+  <!-- don't put <b> inside figure, example, or table titles -->
+  <!-- or other titles that may already be represented with <b>'s. -->
+  <xsl:choose>
+    <xsl:when test="local-name(..) = 'title'
+                    and (local-name(../..) = 'figure'
+                         or local-name(../..) = 'example'
+                         or local-name(../..) = 'table'
+                         or local-name(../..) = 'formalpara')">
+      <tt><xsl:copy-of select="$content"/></tt>
+    </xsl:when>
+    <xsl:otherwise>
+      <b><tt><xsl:copy-of select="$content"/></tt></b>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="inline.italicmonoseq">
+  <xsl:param name="content">
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </xsl:param>
+  <i><tt><xsl:copy-of select="$content"/></tt></i>
+</xsl:template>
+
+<xsl:template name="inline.superscriptseq">
+  <xsl:param name="content">
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </xsl:param>
+  <sup><xsl:copy-of select="$content"/></sup>
+</xsl:template>
+
+<xsl:template name="inline.subscriptseq">
+  <xsl:param name="content">
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </xsl:param>
+  <sub><xsl:copy-of select="$content"/></sub>
+</xsl:template>
+
+<!-- ==================================================================== -->
+<!-- some special cases -->
+
+<xsl:template match="author">
+  <span class="{name(.)}"><xsl:call-template name="person.name"/></span>
+</xsl:template>
+
+<xsl:template match="editor">
+  <span class="{name(.)}"><xsl:call-template name="person.name"/></span>
+</xsl:template>
+
+<xsl:template match="othercredit">
+  <span class="{name(.)}"><xsl:call-template name="person.name"/></span>
+</xsl:template>
+
+<xsl:template match="authorinitials">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="accel">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="action">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="application">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="classname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="exceptionname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="interfacename">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="methodname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="command">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+<xsl:template match="computeroutput">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="constant">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="database">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="errorcode">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="errorname">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="errortype">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="envar">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="filename">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="function">
+  <xsl:choose>
+    <xsl:when test="$function.parens != '0'
+                    and (parameter or function or replaceable)">
+      <xsl:variable name="nodes" select="text()|*"/>
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:apply-templates select="$nodes[1]"/>
+        </xsl:with-param>
+      </xsl:call-template>
+      <xsl:text>(</xsl:text>
+      <xsl:apply-templates select="$nodes[position()>1]"/>
+      <xsl:text>)</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+     <xsl:call-template name="inline.monoseq"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="function/parameter" priority="2">
+  <xsl:call-template name="inline.italicmonoseq"/>
+  <xsl:if test="following-sibling::*">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="function/replaceable" priority="2">
+  <xsl:call-template name="inline.italicmonoseq"/>
+  <xsl:if test="following-sibling::*">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="guibutton">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guiicon">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guilabel">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guimenu">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guimenuitem">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="guisubmenu">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="hardware">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="interface">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="interfacedefinition">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="keycap">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+<xsl:template match="keycode">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="keysym">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="literal">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="medialabel">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="shortcut">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+<xsl:template match="mousebutton">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="option">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="parameter">
+  <xsl:call-template name="inline.italicmonoseq"/>
+</xsl:template>
+
+<xsl:template match="property">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="prompt">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="replaceable" priority="1">
+  <xsl:call-template name="inline.italicmonoseq"/>
+</xsl:template>
+
+<xsl:template match="returnvalue">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="structfield">
+  <xsl:call-template name="inline.italicmonoseq"/>
+</xsl:template>
+
+<xsl:template match="structname">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="symbol">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="systemitem">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="token">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="type">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="userinput">
+  <xsl:call-template name="inline.boldmonoseq"/>
+</xsl:template>
+
+<xsl:template match="abbrev">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="acronym">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="citerefentry">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="citetitle">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="emphasis">
+  <xsl:choose>
+    <xsl:when test="@role='bold'">
+      <xsl:call-template name="inline.boldseq"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="inline.italicseq"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="foreignphrase">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="markup">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="phrase">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="quote">
+  <xsl:variable name="depth">
+    <xsl:call-template name="dot.count">
+      <xsl:with-param name="string"><xsl:number level="multiple"/></xsl:with-param>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:choose>
+    <xsl:when test="$depth mod 2 = 0">
+      <xsl:call-template name="gentext.startquote"/>
+      <xsl:call-template name="inline.charseq"/>
+      <xsl:call-template name="gentext.endquote"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="gentext.nestedstartquote"/>
+      <xsl:call-template name="inline.charseq"/>
+      <xsl:call-template name="gentext.nestedendquote"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="varname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="wordasword">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="lineannotation">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="superscript">
+  <xsl:call-template name="inline.superscriptseq"/>
+</xsl:template>
+
+<xsl:template match="subscript">
+  <xsl:call-template name="inline.subscriptseq"/>
+</xsl:template>
+
+<xsl:template match="trademark">
+  <xsl:call-template name="inline.charseq"/>
+  <xsl:if test="@class">
+    <xsl:call-template name="dingbat">
+      <xsl:with-param name="dingbat" select="@class"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="firstterm">
+  <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="glossterm">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="sgmltag">
+  <xsl:call-template name="format.sgmltag"/>
+</xsl:template>
+
+<xsl:template name="format.sgmltag">
+  <xsl:param name="class">
+    <xsl:choose>
+      <xsl:when test="@class">
+        <xsl:value-of select="@class"/>
+      </xsl:when>
+      <xsl:otherwise>element</xsl:otherwise>
+    </xsl:choose>
+  </xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="$class='attribute'">
+      <xsl:call-template name="inline.monoseq"/>
+    </xsl:when>
+    <xsl:when test="$class='attvalue'">
+      <xsl:call-template name="inline.monoseq"/>
+    </xsl:when>
+    <xsl:when test="$class='element'">
+      <xsl:call-template name="inline.monoseq"/>
+    </xsl:when>
+    <xsl:when test="$class='endtag'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;/</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='genentity'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&amp;</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='numcharref'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&amp;#</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='paramentity'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>%</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='pi'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;?</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='xmlpi'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;?</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>?&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='starttag'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='emptytag'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>/&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$class='sgmlcomment'">
+      <xsl:call-template name="inline.monoseq">
+        <xsl:with-param name="content">
+          <xsl:text>&lt;!--</xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>--&gt;</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="inline.charseq"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="email">
+  <xsl:call-template name="inline.monoseq">
+    <xsl:with-param name="content">
+      <xsl:text>&lt;</xsl:text>
+      <a>
+       <xsl:attribute name="href">mailto:<xsl:value-of select="."/></xsl:attribute>
+       <xsl:apply-templates/>
+      </a>
+      <xsl:text>&gt;</xsl:text>
+    </xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="keycombo">
+  <xsl:variable name="action" select="@action"/>
+  <xsl:variable name="joinchar">
+    <xsl:choose>
+      <xsl:when test="$action='seq'"><xsl:text> </xsl:text></xsl:when>
+      <xsl:when test="$action='simul'">+</xsl:when>
+      <xsl:when test="$action='press'">-</xsl:when>
+      <xsl:when test="$action='click'">-</xsl:when>
+      <xsl:when test="$action='double-click'">-</xsl:when>
+      <xsl:when test="$action='other'"></xsl:when>
+      <xsl:otherwise>-</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:for-each select="./*">
+    <xsl:if test="position()>1"><xsl:value-of select="$joinchar"/></xsl:if>
+    <xsl:apply-templates/>
+  </xsl:for-each>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="menuchoice">
+  <xsl:variable name="shortcut" select="./shortcut"/>
+  <xsl:call-template name="process.menuchoice"/>
+  <xsl:if test="$shortcut">
+    <xsl:text> (</xsl:text>
+    <xsl:apply-templates select="$shortcut"/>
+    <xsl:text>)</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="process.menuchoice">
+  <xsl:param name="nodelist" select="guibutton|guiicon|guilabel|guimenu|guimenuitem|guisubmenu|interface"/><!-- not(shortcut) -->
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($nodelist)"></xsl:when>
+    <xsl:when test="$count=1">
+      <xsl:apply-templates select="$nodelist[$count=position()]"/>
+      <xsl:call-template name="process.menuchoice">
+        <xsl:with-param name="nodelist" select="$nodelist"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="node" select="$nodelist[$count=position()]"/>
+      <xsl:choose>
+        <xsl:when test="name($node)='guimenuitem'
+                        or name($node)='guisubmenu'">
+          <xsl:text>-&gt;</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>+</xsl:otherwise>
+      </xsl:choose>
+      <xsl:apply-templates select="$node"/>
+      <xsl:call-template name="process.menuchoice">
+        <xsl:with-param name="nodelist" select="$nodelist"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="optional">
+  <xsl:value-of select="$arg.choice.opt.open.str"/>
+  <xsl:call-template name="inline.charseq"/>
+  <xsl:value-of select="$arg.choice.opt.close.str"/>
+</xsl:template>
+
+<xsl:template match="citation">
+  <!-- todo: biblio-citation-check -->
+  <xsl:text>[</xsl:text>
+  <xsl:call-template name="inline.charseq"/>
+  <xsl:text>]</xsl:text>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="comment|remark">
+  <xsl:if test="$show.comments != 0">
+    <i><xsl:call-template name="inline.charseq"/></i>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="productname">
+  <xsl:call-template name="inline.charseq"/>
+  <xsl:if test="@class">
+    <xsl:call-template name="dingbat">
+      <xsl:with-param name="dingbat" select="@class"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="productnumber">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="pob|street|city|state|postcode|country|otheraddr">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="phone|fax">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<!-- in Addresses, for example -->
+<xsl:template match="honorific|firstname|surname|lineage|othername">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/html/keywords.xsl b/xsl/html/keywords.xsl
new file mode 100644 (file)
index 0000000..c3b5f70
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="keywordset"></xsl:template>
+<xsl:template match="subjectset"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="keywordset" mode="html.header">
+  <meta name="keywords">
+    <xsl:attribute name="content">
+      <xsl:apply-templates select="keyword" mode="html.header"/>
+    </xsl:attribute>
+  </meta>
+</xsl:template>
+
+<xsl:template match="keyword[position()!=last()]" mode="html.header">
+  <xsl:apply-templates/><xsl:text>, </xsl:text>
+</xsl:template>
+
+<xsl:template match="keyword[position()=last()]" mode="html.header">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/lists.xsl b/xsl/html/lists.xsl
new file mode 100644 (file)
index 0000000..bca4f31
--- /dev/null
@@ -0,0 +1,626 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="itemizedlist">
+  <div class="{name(.)}">
+    <xsl:if test="title">
+      <xsl:apply-templates select="title"/>
+    </xsl:if>
+    <ul>
+      <xsl:if test="@spacing='compact'">
+        <xsl:attribute name="compact">
+          <xsl:value-of select="compact"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="listitem"/>
+    </ul>
+  </div>
+</xsl:template>
+
+<xsl:template match="itemizedlist/title">
+  <p><b><xsl:apply-templates/></b></p>
+</xsl:template>
+
+<xsl:template name="orderedlist-starting-number">
+  <xsl:param name="list" select="."/>
+  <xsl:choose>
+    <xsl:when test="$list/@continuation != 'continues'">1</xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="prevlist"
+                    select="$list/preceding::orderedlist[1]"/>
+      <xsl:choose>
+        <xsl:when test="count($prevlist) = 0">2</xsl:when>
+        <xsl:otherwise>
+          <xsl:variable name="prevlength" select="count($prevlist/listitem)"/>
+          <xsl:variable name="prevstart">
+            <xsl:call-template name="orderedlist-starting-number">
+              <xsl:with-param name="list" select="$prevlist"/>
+            </xsl:call-template>
+          </xsl:variable>
+          <xsl:value-of select="$prevstart + $prevlength"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="orderedlist">
+  <xsl:variable name="start">
+    <xsl:choose>
+      <xsl:when test="@continuation='continues'">
+        <xsl:call-template name="orderedlist-starting-number"/>
+      </xsl:when>
+      <xsl:otherwise>1</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="numeration">
+    <xsl:choose>
+      <xsl:when test="@numeration='arabic'">1</xsl:when>
+      <xsl:when test="@numeration='loweralpha'">a</xsl:when>
+      <xsl:when test="@numeration='lowerroman'">i</xsl:when>
+      <xsl:when test="@numeration='upperalpha'">A</xsl:when>
+      <xsl:when test="@numeration='upperroman'">I</xsl:when>
+      <xsl:otherwise>
+        <!-- alternate the numeration based on depth -->
+        <xsl:variable name="depth" select="count(ancestor::orderedlist)"/>
+        <xsl:variable name="type" select="$depth mod 5"/>
+        <xsl:choose>
+          <xsl:when test="$type = 0">1</xsl:when>
+          <xsl:when test="$type = 1">a</xsl:when>
+          <xsl:when test="$type = 2">i</xsl:when>
+          <xsl:when test="$type = 3">A</xsl:when>
+          <xsl:when test="$type = 4">I</xsl:when>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <div class="{name(.)}">
+    <xsl:if test="title">
+      <xsl:apply-templates select="title"/>
+    </xsl:if>
+    <ol>
+    <xsl:if test="$start != '1'">
+      <xsl:attribute name="start">
+        <xsl:value-of select="$start"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$numeration != ''">
+      <xsl:attribute name="type">
+       <xsl:value-of select="$numeration"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@spacing='compact'">
+      <xsl:attribute name="compact">
+       <xsl:value-of select="compact"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:apply-templates select="listitem"/>
+    </ol>
+  </div>
+</xsl:template>
+
+<xsl:template match="orderedlist/title">
+  <p><b><xsl:apply-templates/></b></p>
+</xsl:template>
+
+<xsl:template match="variablelist">
+  <div class="{name(.)}">
+    <xsl:if test="title">
+      <xsl:apply-templates select="title"/>
+    </xsl:if>
+    <dl>
+    <xsl:apply-templates select="varlistentry"/>
+    </dl>
+  </div>
+</xsl:template>
+
+<xsl:template match="variablelist/title">
+  <p><b><xsl:apply-templates/></b></p>
+</xsl:template>
+
+<xsl:template match="listitem">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:variable name="mark" select="ancestor-or-self::*/@mark"/>
+  <xsl:variable name="override" select="@override"/>
+
+  <xsl:variable name="usemark">
+    <xsl:choose>
+      <xsl:when test="$override != ''">
+       <xsl:value-of select="$override"/>
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:value-of select="$mark"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="cssmark">
+    <xsl:choose>
+      <xsl:when test="$usemark = 'bullet'">disc</xsl:when>
+      <xsl:when test="$usemark = 'box'">square</xsl:when>
+      <xsl:otherwise>
+       <xsl:value-of select="$usemark"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <li>
+    <xsl:if test="$css.decoration = '1' and $cssmark != ''">
+      <xsl:attribute name="style">
+       <xsl:text>list-style-type: </xsl:text>
+       <xsl:value-of select="$cssmark"/>
+      </xsl:attribute>
+    </xsl:if>
+
+    <!-- we can't just drop the anchor in since some browsers (Opera)
+         get confused about line breaks if we do. So if the first child
+         is a para, assume the para will put in the anchor. Otherwise,
+         put the anchor in anyway. -->
+    <xsl:if test="local-name(child::*[1]) != 'para'">
+      <a name="{$id}"/>
+    </xsl:if>
+
+    <xsl:choose>
+      <xsl:when test="$show.revisionflag and @revisionflag">
+       <div class="{@revisionflag}">
+         <xsl:apply-templates/>
+       </div>
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </li>
+</xsl:template>
+
+<xsl:template match="listitem" mode="xref">
+  <xsl:number format="1"/>
+</xsl:template>
+
+<xsl:template match="varlistentry">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <dt><a name="{$id}"/><xsl:apply-templates select="term"/></dt>
+  <dd><xsl:apply-templates select="listitem"/></dd>
+</xsl:template>
+
+<xsl:template match="varlistentry/term">
+  <span class="term"><xsl:apply-templates/>, </span>
+</xsl:template>
+
+<xsl:template match="varlistentry/term[position()=last()]" priority="2">
+  <span class="term"><xsl:apply-templates/></span>
+</xsl:template>
+
+<xsl:template match="varlistentry/listitem">
+  <xsl:choose>
+    <xsl:when test="$show.revisionflag and @revisionflag">
+      <div class="{@revisionflag}">
+       <xsl:apply-templates/>
+      </div>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<!-- ==================================================================== -->
+
+<xsl:template match="simplelist">
+  <!-- with no type specified, the default is 'vert' -->
+  <table class="simplelist" border="0" summary="Simple list">
+    <xsl:call-template name="simplelist.vert">
+      <xsl:with-param name="cols">
+       <xsl:choose>
+         <xsl:when test="@columns">
+           <xsl:value-of select="@columns"/>
+         </xsl:when>
+         <xsl:otherwise>1</xsl:otherwise>
+       </xsl:choose>
+      </xsl:with-param>
+    </xsl:call-template>
+  </table>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='inline']">
+  <span class="{name(.)}"><xsl:apply-templates/></span>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='horiz']">
+  <table class="simplelist" border="0" summary="Simple list">
+    <xsl:call-template name="simplelist.horiz">
+      <xsl:with-param name="cols">
+        <xsl:choose>
+          <xsl:when test="@columns">
+            <xsl:value-of select="@columns"/>
+          </xsl:when>
+          <xsl:otherwise>1</xsl:otherwise>
+        </xsl:choose>
+      </xsl:with-param>
+    </xsl:call-template>
+  </table>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='vert']">
+  <table class="simplelist" border="0" summary="Simple list">
+    <xsl:call-template name="simplelist.vert">
+      <xsl:with-param name="cols">
+        <xsl:choose>
+          <xsl:when test="@columns">
+            <xsl:value-of select="@columns"/>
+          </xsl:when>
+          <xsl:otherwise>1</xsl:otherwise>
+        </xsl:choose>
+      </xsl:with-param>
+    </xsl:call-template>
+  </table>
+</xsl:template>
+
+<xsl:template name="simplelist.horiz">
+  <xsl:param name="cols">1</xsl:param>
+  <xsl:param name="cell">1</xsl:param>
+  <xsl:param name="members" select="./member"/>
+
+  <xsl:if test="$cell &lt;= count($members)">
+    <tr>
+      <xsl:call-template name="simplelist.horiz.row">
+        <xsl:with-param name="cols" select="$cols"/>
+        <xsl:with-param name="cell" select="$cell"/>
+        <xsl:with-param name="members" select="$members"/>
+      </xsl:call-template>
+   </tr>
+    <xsl:call-template name="simplelist.horiz">
+      <xsl:with-param name="cols" select="$cols"/>
+      <xsl:with-param name="cell" select="$cell + $cols"/>
+      <xsl:with-param name="members" select="$members"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="simplelist.horiz.row">
+  <xsl:param name="cols">1</xsl:param>
+  <xsl:param name="cell">1</xsl:param>
+  <xsl:param name="members" select="./member"/>
+  <xsl:param name="curcol">1</xsl:param>
+
+  <xsl:if test="$curcol &lt;= $cols">
+    <td>
+      <xsl:choose>
+        <xsl:when test="$members[position()=$cell]">
+          <xsl:apply-templates select="$members[position()=$cell]"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:choose>
+            <xsl:when test="$using.chunker != 0">
+              <xsl:text>&#160;</xsl:text>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:otherwise>
+      </xsl:choose>
+    </td>
+    <xsl:call-template name="simplelist.horiz.row">
+      <xsl:with-param name="cols" select="$cols"/>
+      <xsl:with-param name="cell" select="$cell+1"/>
+      <xsl:with-param name="members" select="$members"/>
+      <xsl:with-param name="curcol" select="$curcol+1"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="simplelist.vert">
+  <xsl:param name="cols">1</xsl:param>
+  <xsl:param name="cell">1</xsl:param>
+  <xsl:param name="members" select="./member"/>
+  <xsl:param name="rows"
+             select="floor((count($members)+$cols - 1) div $cols)"/>
+
+  <xsl:if test="$cell &lt;= $rows">
+    <tr>
+      <xsl:call-template name="simplelist.vert.row">
+       <xsl:with-param name="cols" select="$cols"/>
+       <xsl:with-param name="rows" select="$rows"/>
+       <xsl:with-param name="cell" select="$cell"/>
+       <xsl:with-param name="members" select="$members"/>
+      </xsl:call-template>
+    </tr>
+    <xsl:call-template name="simplelist.vert">
+      <xsl:with-param name="cols" select="$cols"/>
+      <xsl:with-param name="cell" select="$cell+1"/>
+      <xsl:with-param name="members" select="$members"/>
+      <xsl:with-param name="rows" select="$rows"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="simplelist.vert.row">
+  <xsl:param name="cols">1</xsl:param>
+  <xsl:param name="rows">1</xsl:param>
+  <xsl:param name="cell">1</xsl:param>
+  <xsl:param name="members" select="./member"/>
+  <xsl:param name="curcol">1</xsl:param>
+
+  <xsl:if test="$curcol &lt;= $cols">
+    <td>
+      <xsl:choose>
+        <xsl:when test="$members[position()=$cell]">
+          <xsl:apply-templates select="$members[position()=$cell]"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:choose>
+            <xsl:when test="$using.chunker != 0">
+              <xsl:text>&#160;</xsl:text>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:otherwise>
+      </xsl:choose>
+    </td>
+    <xsl:call-template name="simplelist.vert.row">
+      <xsl:with-param name="cols" select="$cols"/>
+      <xsl:with-param name="rows" select="$rows"/>
+      <xsl:with-param name="cell" select="$cell+$rows"/>
+      <xsl:with-param name="members" select="$members"/>
+      <xsl:with-param name="curcol" select="$curcol+1"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="member">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='inline']/member">
+  <xsl:apply-templates/>
+  <xsl:text>, </xsl:text>
+</xsl:template>
+
+<xsl:template match="simplelist[@type='inline']/member[position()=last()]"
+              priority="2">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="procedure">
+  <div class="{name(.)}">
+    <xsl:if test="title">
+      <xsl:apply-templates select="title" mode="procedure.title.mode"/>
+    </xsl:if>
+    <ol><xsl:apply-templates/></ol>
+  </div>
+</xsl:template>
+
+<xsl:template match="procedure/title">
+</xsl:template>
+
+<xsl:template match="title" mode="procedure.title.mode">
+  <p>
+    <b>
+      <xsl:apply-templates/>
+    </b>
+  </p>
+</xsl:template>
+
+<xsl:template match="substeps">
+  <ol><xsl:apply-templates/></ol>
+</xsl:template>
+
+<xsl:template match="step">
+  <li><xsl:apply-templates/></li>
+</xsl:template>
+
+<xsl:template match="step/title">
+  <xsl:apply-templates select="." mode="procedure.title.mode"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="segmentedlist">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="segmentedlist/title">
+  <p><b><xsl:apply-templates/></b></p>
+</xsl:template>
+
+<xsl:template match="segtitle">
+</xsl:template>
+
+<xsl:template match="segtitle" mode="segtitle-in-seg">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="seglistitem">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="seg">
+  <xsl:variable name="segnum" select="position()"/>
+  <xsl:variable name="seglist" select="ancestor::segmentedlist"/>
+  <xsl:variable name="segtitles" select="$seglist/segtitle"/>
+
+  <!--
+     Note: segtitle is only going to be the right thing in a well formed
+     SegmentedList.  If there are too many Segs or too few SegTitles,
+     you'll get something odd...maybe an error
+  -->
+
+  <p>
+    <b>
+      <xsl:apply-templates select="$segtitles[$segnum=position()]"
+                           mode="segtitle-in-seg"/>
+      <xsl:text>: </xsl:text>
+    </b>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="calloutlist">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <div class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:if test="./title">
+      <p>
+        <b>
+          <xsl:apply-templates select="./title" mode="calloutlist.title.mode"/>
+        </b>
+      </p>
+    </xsl:if>
+    <xsl:choose>
+      <xsl:when test="$callout.list.table != 0">
+        <table border="0" summary="Callout list">
+          <xsl:apply-templates/>
+        </table>
+      </xsl:when>
+      <xsl:otherwise>
+        <dl compact="compact"><xsl:apply-templates/></dl>
+      </xsl:otherwise>
+    </xsl:choose>
+  </div>
+</xsl:template>
+
+<xsl:template match="calloutlist/title">
+</xsl:template>
+
+<xsl:template match="calloutlist/title" mode="calloutlist.title.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="callout">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+  <xsl:choose>
+    <xsl:when test="$callout.list.table != 0">
+      <tr>
+        <td width="5%" valign="top" align="left">
+          <a name="{$id}"/>
+          <xsl:call-template name="callout.arearefs">
+            <xsl:with-param name="arearefs" select="@arearefs"/>
+          </xsl:call-template>
+        </td>
+        <td valign="top" align="left">
+          <xsl:apply-templates/>
+        </td>
+      </tr>
+    </xsl:when>
+    <xsl:otherwise>
+      <dt>
+        <a name="{$id}"/>
+        <xsl:call-template name="callout.arearefs">
+          <xsl:with-param name="arearefs" select="@arearefs"/>
+        </xsl:call-template>
+      </dt>
+      <dd><xsl:apply-templates/></dd>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="callout.arearefs">
+  <xsl:param name="arearefs"></xsl:param>
+  <xsl:if test="$arearefs!=''">
+    <xsl:choose>
+      <xsl:when test="substring-before($arearefs,' ')=''">
+        <xsl:call-template name="callout.arearef">
+          <xsl:with-param name="arearef" select="$arearefs"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="callout.arearef">
+          <xsl:with-param name="arearef"
+                          select="substring-before($arearefs,' ')"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+    <xsl:call-template name="callout.arearefs">
+      <xsl:with-param name="arearefs"
+                      select="substring-after($arearefs,' ')"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="callout.arearef">
+  <xsl:param name="arearef"></xsl:param>
+  <xsl:variable name="targets" select="id($arearef)"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+
+  <xsl:call-template name="check.id.unique">
+    <xsl:with-param name="linkend" select="$arearef"/>
+  </xsl:call-template>
+
+  <xsl:choose>
+    <xsl:when test="count($target)=0">
+      <xsl:text>???</xsl:text>
+    </xsl:when>
+    <xsl:when test="local-name($target)='co'">
+      <a>
+        <xsl:attribute name="href">
+          <xsl:text>#</xsl:text>
+          <xsl:value-of select="$arearef"/>
+        </xsl:attribute>
+        <xsl:apply-templates select="$target" mode="callout-bug"/>
+      </a>
+      <xsl:text> </xsl:text>
+    </xsl:when>
+    <xsl:when test="local-name($target)='areaset'">
+      <xsl:call-template name="callout-bug">
+        <xsl:with-param name="conum">
+          <xsl:apply-templates select="$target" mode="conumber"/>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="local-name($target)='area'">
+      <xsl:choose>
+        <xsl:when test="$target/parent::areaset">
+          <xsl:call-template name="callout-bug">
+            <xsl:with-param name="conum">
+              <xsl:apply-templates select="$target/parent::areaset"
+                                   mode="conumber"/>
+            </xsl:with-param>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="callout-bug">
+            <xsl:with-param name="conum">
+              <xsl:apply-templates select="$target" mode="conumber"/>
+            </xsl:with-param>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>???</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
+
diff --git a/xsl/html/math.xsl b/xsl/html/math.xsl
new file mode 100644 (file)
index 0000000..502a930
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="inlineequation">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="alt">
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/param.xsl b/xsl/html/param.xsl
new file mode 100644 (file)
index 0000000..5f16be9
--- /dev/null
@@ -0,0 +1,1048 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<doc:reference xmlns="">
+<referenceinfo>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<copyright><year>1999</year><year>2000</year>
+<holder>Norman Walsh</holder>
+</copyright>
+</referenceinfo>
+<title>HTML Parameter Reference</title>
+
+<partintro>
+<section><title>Introduction</title>
+
+<para>This is technical reference documentation for the DocBook XSL
+Stylesheets; it documents (some of) the parameters, templates, and
+other elements of the stylesheets.</para>
+
+<para>This reference describes each of the HTML Stylesheet parameters.
+These are the <quote>easily customizable</quote> parts of the stylesheet.
+If you want to specify an alternate value for one or more of these
+parameters, you can do so in a <quote>driver</quote> stylesheet.</para>
+
+<para>For example, if you want to change the <literal>html.stylesheet</literal>
+to <filename>reference.css</filename>, you might create a driver
+stylesheet like this:</para>
+
+<programlisting><![CDATA[<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+  <xsl:import href="/path/to/html/docbook.xsl"/>
+
+  <xsl:param name="html.stylesheet">reference.css</xsl:param>
+
+</xsl:stylesheet>]]></programlisting>
+
+<para>Naturally, you have to change the
+<sgmltag class='attribute'>href</sgmltag> attribute on
+<literal>&lt;xsl:import&gt;</literal>
+to point to <filename>docbook.xsl</filename>
+on your system. (Or <filename>chunk.xsl</filename>, if you're using
+chunking.)</para>
+
+<para>This is not intended to be <quote>user</quote> documentation.
+It is provided for developers writing customization layers for the
+stylesheets, and for anyone who's interested in <quote>how it
+works</quote>.</para>
+
+<para>Although I am trying to be thorough, this documentation is known
+to be incomplete. Don't forget to read the source, too :-)</para>
+</section>
+</partintro>
+</doc:reference>
+
+<!-- ==================================================================== -->
+<xsl:param name="author.othername.in.middle" select="1" doc:type='boolean'/>
+
+<doc:param name="author.othername.in.middle" xmlns="">
+<refpurpose>Is <sgmltag>othername</sgmltag> in <sgmltag>author</sgmltag> a
+middle name?</refpurpose>
+<refdescription>
+<para>If true (non-zero), the <sgmltag>othername</sgmltag> of an <sgmltag>author</sgmltag>
+appears between the <sgmltag>firstname</sgmltag> and
+<sgmltag>surname</sgmltag>.  Otherwise, <sgmltag>othername</sgmltag>
+is suppressed.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="html.stylesheet" select="''" doc:type='string'/>
+
+<doc:param name="html.stylesheet" xmlns="">
+<refpurpose>Name of the stylesheet to use in the generated HTML</refpurpose>
+<refdescription>
+<para>The name of the stylesheet to place in the HTML <sgmltag>LINK</sgmltag>
+tag, or the empty string to suppress the stylesheet <sgmltag>LINK</sgmltag>.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="html.stylesheet.type" doc:type='string'>text/css</xsl:param>
+
+<doc:param name="html.stylesheet.type" xmlns="">
+<refpurpose>The type of the stylesheet used in the generated HTML</refpurpose>
+<refdescription>
+<para>The type of the stylesheet to place in the HTML <sgmltag>link</sgmltag> tag.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="html.base" doc:type='uri'></xsl:param>
+
+<doc:param name="html.base" xmlns="">
+<refpurpose>An HTML base URI</refpurpose>
+<refdescription>
+<para>If html.base is set, it is used for the <sgmltag>BASE</sgmltag>
+element in the <sgmltag>HEAD</sgmltag> of the HTML documents.
+This is useful for dynamically served HTML where the base URI needs
+to be shifted.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="ulink.target" select="'_top'" doc:type='string'/>
+
+<doc:param name="ulink.target" xmlns="">
+<refpurpose>The HTML anchor target for ULinks</refpurpose>
+<refdescription>
+<para>If <parameter>ulink.target</parameter> is set, its value will
+be used for the <sgmltag class='attribute'>target</sgmltag> attribute
+on anchors generated for <sgmltag>ulink</sgmltag>s.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="refentry.xref.manvolnum" select="1" doc:type='boolean'/>
+
+<doc:param name="refentry.xref.manvolnum" xmlns="">
+<refpurpose>Output <sgmltag>manvolnum</sgmltag> as part of 
+<sgmltag>refentry</sgmltag> cross-reference?</refpurpose>
+<refdescription>
+<para>if true (non-zero), the <sgmltag>manvolnum</sgmltag> is used when cross-referencing
+<sgmltag>refentry</sgmltag>s, either with <sgmltag>xref</sgmltag>
+or <sgmltag>citerefentry</sgmltag>.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="show.comments" doc:type='boolean'>1</xsl:param>
+
+<doc:param name="show.comments" xmlns="">
+<refpurpose>Display <sgmltag>comment</sgmltag> elements?</refpurpose>
+<refdescription>
+<para>If true (non-zero), comments will be displayed, otherwise they are suppressed.
+Comments here refers to the <sgmltag>comment</sgmltag> element,
+which will be renamed <sgmltag>remark</sgmltag> in DocBook V4.0,
+not XML comments (&lt;-- like this --&gt;) which are unavailable.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="funcsynopsis.style"
+           doc:type='list'
+           doc:list='ansi kr'>kr</xsl:param>
+
+<doc:param name="funcsynopsis.style" xmlns="">
+<refpurpose>What style of 'FuncSynopsis' should be generated?</refpurpose>
+<refdescription>
+<para>If <varname>funcsynopsis.style</varname> is <literal>ansi</literal>,
+ANSI-style function synopses are generated for a
+<sgmltag>funcsynopsis</sgmltag>, otherwise K&amp;R-style
+function synopses are generated.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="funcsynopsis.decoration" select="1" doc:type='boolean'/>
+
+<doc:param name="funcsynopsis.decoration" xmlns="">
+<refpurpose>Decorate elements of a FuncSynopsis?</refpurpose>
+<refdescription>
+<para>If true (non-zero), elements of the FuncSynopsis will be decorated (e.g. bold or
+italic).  The decoration is controlled by functions that can be redefined
+in a customization layer.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="function.parens" doc:type='boolean'>0</xsl:param>
+
+<doc:param name="function.parens" xmlns="">
+<refpurpose>Generate parens after a function?</refpurpose>
+<refdescription>
+<para>If not 0, the formatting of
+a <sgmltag class="starttag">function</sgmltag> element will include
+generated parenthesis.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="refentry.generate.name" select="1" doc:type='boolean'/>
+
+<doc:param name="refentry.generate.name" xmlns="">
+<refpurpose>Output NAME header before 'RefName'(s)?</refpurpose>
+<refdescription>
+<para>If true (non-zero), a "NAME" section title is output before the list
+of 'RefName's.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="admon.graphics" select="0" doc:type='boolean'/>
+
+<doc:param name="admon.graphics" xmlns="">
+<refpurpose>Use graphics in admonitions?</refpurpose>
+<refdescription>
+<para>If true (non-zero), admonitions are presented in an alternate style that uses
+a graphic.  Default graphics are provided in the distribution.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="admon.graphics.path" doc:type='string'>../images/</xsl:param>
+
+<doc:param name="admon.graphics.path" xmlns="">
+<refpurpose>Path to admonition graphics</refpurpose>
+<refdescription>
+<para>Sets the path, probably relative to the directory where the HTML
+files are created, to the admonition graphics.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="admon.graphics.extension" select="'.png'" doc:type='string'/>
+
+<doc:param name="admon.graphics.extension" xmlns="">
+<refpurpose>Extension for admonition graphics</refpurpose>
+<refdescription>
+<para>Sets the extension to use on admonition graphics.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="admon.style" doc:type='string'>
+  <xsl:text>margin-left: 0.5in; margin-right: 0.5in;</xsl:text>
+</xsl:param>
+
+<doc:param name="admon.style" xmlns="">
+<refpurpose>CSS style attributes for admonitions</refpurpose>
+<refdescription>
+<para>Specifies the value of the <sgmltag class="attribute">STYLE</sgmltag>
+attribute that should be added to admonitions.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="section.autolabel" select="0" doc:type='boolean'/>
+
+<doc:param name="section.autolabel" xmlns="">
+<refpurpose>Are sections enumerated?</refpurpose>
+<refdescription>
+<para>If true (non-zero), unlabeled sections will be enumerated.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="section.label.includes.component.label" select="0"
+           doc:type='boolean'/>
+
+<doc:param name="section.label.includes.component.label" xmlns="">
+<refpurpose>Do section labels include the component label?</refpurpose>
+<refdescription>
+<para>If true (non-zero), section labels are prefixed with the label of the
+component that contains them.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="chapter.autolabel" select="1" doc:type='boolean'/>
+<xsl:param name="appendix.autolabel" select="1" doc:type='boolean'/>
+
+<doc:param name="chapter.autolabel" xmlns="">
+<refpurpose>Are chapters and appendixes enumerated?</refpurpose>
+<refdescription>
+<para>If true (non-zero), unlabeled chapters and appendixes will be enumerated.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="preface.autolabel" select="0" doc:type='boolean'/>
+
+<doc:param name="preface.autolabel" xmlns="">
+<refpurpose>Are prefaces enumerated?</refpurpose>
+<refdescription>
+<para>If true (non-zero), unlabeled prefaces will be enumerated.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="part.autolabel" select="1" doc:type='boolean'/>
+
+<doc:param name="part.autolabel" xmlns="">
+<refpurpose>Are parts and references enumerated?</refpurpose>
+<refdescription>
+<para>If true (non-zero), unlabeled parts and references will be enumerated.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="qandadiv.autolabel" select="1" doc:type='boolean'/>
+
+<doc:param name="qandadiv.autolabel" xmlns="">
+<refpurpose>Are divisions in QAndASets enumerated?</refpurpose>
+<refdescription>
+<para>If true (non-zero), unlabeled qandadivs will be enumerated.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="qanda.inherit.numeration" select="1" doc:type='boolean'/>
+
+<doc:param name="qanda.inherit.numeration" xmlns="">
+<refpurpose>Does enumeration of QandASet components inherit the numeration of parent elements?</refpurpose>
+<refdescription>
+<para>If true (non-zero), numbered QandADiv elements and Questions and Answers inherit
+the numeration of the ancestors of the QandASet.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="qanda.defaultlabel"
+           doc:type='boolean'
+           doc:list='qanda number none'>number</xsl:param>
+
+<doc:param name="qanda.defaultlabel" xmlns="">
+<refpurpose>Sets the default for defaultlabel on QandASet.</refpurpose>
+<refdescription>
+<para>If no defaultlabel attribute is specified on a QandASet, this
+value is used. It must be one of the legal values for the defaultlabel
+attribute.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.qandaset.toc" doc:type='boolean'>1</xsl:param>
+
+<doc:param name="generate.qandaset.toc" xmlns="">
+<refpurpose>Is a Table of Contents created for QandASets?</refpurpose>
+<refdescription>
+<para>If true (non-zero), a ToC is constructed for QandASets.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.qandadiv.toc" doc:type='boolean'>0</xsl:param>
+
+<doc:param name="generate.qandadiv.toc" xmlns="">
+<refpurpose>Is a Table of Contents created for QandADivs?</refpurpose>
+<refdescription>
+<para>If true (non-zero), a ToC is constructed for QandADivs.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="biblioentry.item.separator" doc:type='string'>. </xsl:param>
+
+<doc:param name="biblioentry.item.separator" xmlns="">
+<refpurpose>Text to separate bibliography entries</refpurpose>
+<refdescription>
+<para>Text to separate bibliography entries
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="toc.section.depth"
+           doc:type='integer'
+           doc:min='1'
+           doc:max='10'>2</xsl:param>
+
+<doc:param name="toc.section.depth" xmlns="">
+<refpurpose>How deep should recursive <sgmltag>section</sgmltag>s appear
+in the TOC?</refpurpose>
+<refdescription>
+<para>Specifies the depth to which recursive sections should appear in the
+TOC.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="using.chunker" select="0" doc:type='boolean'/>
+
+<doc:param name="using.chunker" xmlns="">
+<refpurpose>Will the output be chunked?</refpurpose>
+<refdescription>
+<para>In addition to providing chunking, the chunker can cleanup a
+number of XML to HTML issues. If the chunker is not being used, the
+stylesheets try to avoid producing results that will not appear properly
+in browsers.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.component.toc" select="1" doc:type='boolean'/>
+
+<doc:param name="generate.component.toc" xmlns="">
+<refpurpose>Should TOCs be genereated in components (Chapters, Appendixes, etc.)?</refpurpose>
+<refdescription>
+<para>If true (non-zero), they are.
+</para>
+</refdescription>
+</doc:param>
+<!-- ==================================================================== -->
+<xsl:param name="generate.division.toc" select="1" doc:type='boolean'/>
+
+<doc:param name="generate.division.toc" xmlns="">
+<refpurpose>Should TOCs be genereated in divisions (Books, Parts, etc.)?</refpurpose>
+<refdescription>
+<para>If true (non-zero), they are.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="link.mailto.url" doc:type='string'></xsl:param>
+
+<doc:param name="link.mailto.url" xmlns="">
+<refpurpose>Mailto URL for the LINK REL=made HTML HEAD element</refpurpose>
+<refdescription>
+<para>If not the empty string, this address will be used for the
+REL=made <sgmltag>LINK</sgmltag> element in the HTML <sgmltag>HEAD</sgmltag>.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="graphic.default.extension" doc:type='string'></xsl:param>
+
+<doc:param name="graphic.default.extension" xmlns="">
+<refpurpose>Default extension for graphic filenames</refpurpose>
+<refdescription>
+<para>If a <sgmltag>graphic</sgmltag> or <sgmltag>mediaobject</sgmltag>
+includes a reference to a filename that does not include an extension,
+and the <sgmltag class="attribute">format</sgmltag> attribute is
+<emphasis>unspecified</emphasis>, the default extension will be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="toc.list.type"
+           doc:type='list'
+           doc:list='dl ul ol'>dl</xsl:param>
+
+<doc:param name="toc.list.type" xmlns="">
+<refpurpose>Type of HTML list element to use for Tables of Contents</refpurpose>
+<refdescription>
+<para>When an automatically generated Table of Contents (or List of Titles)
+is produced, this HTML element will be used to make the list.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="check.idref" doc:type='boolean'>1</xsl:param>
+
+<doc:param name="check.idref" xmlns="">
+<refpurpose>Test the target of IDREF attributes?</refpurpose>
+<refdescription>
+<para>If 1, the target of IDREF attributes are tested for presence
+(and uniqueness). This can be very expensive in large documents.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="use.id.function" doc:type='boolean' select="'1'"/>
+
+<doc:param name="use.id.function" xmlns="">
+<refpurpose>Use the XPath id() function to find link targets?</refpurpose>
+<refdescription>
+<para>If 1, the stylesheets use the <function>id()</function> function
+to find the targets of cross reference elements. This is more
+efficient, but only works if your XSLT processor implements the
+<function>id()</function> function, naturally.</para>
+<para>THIS PARAMETER IS NOT SUPPORTED. IT IS ALWAYS ASSUMED TO BE 1.
+SEE xref.xsl IF YOU NEED TO TURN IT OFF.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="spacing.paras" doc:type='boolean' select="'1'"/>
+
+<doc:param name="spacing.paras" xmlns="">
+<refpurpose>Insert additional &lt;p&gt; elements for spacing?</refpurpose>
+<refdescription>
+<para>When non-zero, additional, empty paragraphs are inserted in
+several contexts (for example, around informal figures), to create a
+more pleasing visual appearance in many browsers.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:attribute-set name="body.attrs">
+  <xsl:attribute name="bgcolor">white</xsl:attribute>
+  <xsl:attribute name="text">black</xsl:attribute>
+  <xsl:attribute name="link">#0000FF</xsl:attribute>
+  <xsl:attribute name="vlink">#840084</xsl:attribute>
+  <xsl:attribute name="alink">#0000FF</xsl:attribute>
+</xsl:attribute-set>
+
+<doc:attribute-set name="body.attrs" xmlns="">
+<refpurpose>Additional attributes for the HTML body tag</refpurpose>
+<refdescription>
+<para>The attributes defined by this attribute set are added to the
+HTML &lt;body&gt; tag.
+</para>
+</refdescription>
+</doc:attribute-set>
+
+<!-- ==================================================================== -->
+<xsl:param name="css.decoration" doc:type='boolean'>1</xsl:param>
+
+<doc:param name="css.decoration" xmlns="">
+<refpurpose>Enable CSS decoration of elements</refpurpose>
+<refdescription>
+<para>
+If <literal>css.decoration</literal> is turned on, then HTML elements
+produced by the
+stylesheet may be decorated with STYLE attributes.  For example, the
+LI tags produced for list items may include a fragment of CSS in the
+STYLE attribute which sets the CSS property "list-style-type".
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="show.revisionflag" doc:type='boolean'>0</xsl:param>
+
+<doc:param name="show.revisionflag" xmlns="">
+<refpurpose>Enable decoration of elements that have a revisionflag</refpurpose>
+<refdescription>
+<para>
+If <literal>show.revisionflag</literal> is turned on, then the stylesheets
+may produce additional markup designed to allow a CSS stylesheet to
+highlight elements that have specific revisionflag settings.</para>
+
+<para>The markup inserted will be usually be either a &lt;span> or &lt;div>
+with an appropriate <literal>class</literal> attribute. (The value of
+the class attribute will be the same as the value of the revisionflag
+attribute). In some contexts, for example tables, where extra markup
+would be structurally illegal, the class attribute will be added to the
+appropriate container element.</para>
+
+<para>In general, the stylesheets only test for revisionflag in contexts
+where an importing stylesheet would have to redefine whole templates.
+Most of the revisionflag processing is expected to be done by another
+stylesheet, for example <filename>changebars.xsl</filename>.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="suppress.navigation" doc:type='boolean'>0</xsl:param>
+
+<doc:param name="suppress.navigation" xmlns="">
+<refpurpose>Disable header and footer navigation</refpurpose>
+<refdescription>
+<para>
+If <literal>suppress.navigation</literal> is turned on, header and
+footer navigation will be suppressed.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="rootid" select="''" doc:type='string'/>
+
+<doc:param name="rootid" xmlns="">
+<refpurpose>Specify the root element to format</refpurpose>
+<refdescription>
+<para>If <parameter>rootid</parameter> is specified, it must be the
+value of an ID that occurs in the document being formatted. The entire
+document will be loaded and parsed, but formatting will begin at the
+element identified, rather than at the root. For example, this allows
+you to process only chapter 4 of a book.</para>
+<para>Because the entire document is available to the processor, automatic
+numbering, cross references, and other dependencies are correctly
+resolved.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.list.table" select="'1'" doc:type='boolean'/>
+
+<doc:param name="callout.list.table" xmlns="">
+<refpurpose>Present callout lists using a table?</refpurpose>
+<refdescription>
+<para>The default presentation of <sgmltag>CalloutList</sgmltag>s uses
+an HTML <sgmltag>DL</sgmltag>. Some browsers don't align DLs very well
+if <parameter>callout.graphics</parameter> are used. With this option
+turned on, <sgmltag>CalloutList</sgmltag>s are presented in an HTML
+<sgmltag>TABLE</sgmltag>, which usually results in better alignment
+of the callout number with the callout description.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.graphics" select="'1'" doc:type='boolean'/>
+
+<doc:param name="callout.graphics" xmlns="">
+<refpurpose>Use graphics for callouts?</refpurpose>
+<refdescription>
+<para>If non-zero, callouts are presented with graphics (e.g., reverse-video
+circled numbers instead of "(1)", "(2)", etc.).
+Default graphics are provided in the distribution.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.graphics.extension" select="'.png'" doc:type='string'/>
+
+<doc:param name="callout.graphics.extension" xmlns="">
+<refpurpose>Extension for callout graphics</refpurpose>
+<refdescription>
+<para>Sets the extension to use on callout graphics.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.graphics.path" select="'../images/callouts/'" doc:type='string'/>
+
+<doc:param name="callout.graphics.path" xmlns="">
+<refpurpose>Path to callout graphics</refpurpose>
+<refdescription>
+<para>Sets the path, probably relative to the directory where the HTML
+files are created, to the callout graphics.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.graphics.number.limit" select="'10'"
+           doc:type='integer'/>
+
+<doc:param name="callout.graphics.number.limit" xmlns="">
+<refpurpose>Number of the largest callout graphic</refpurpose>
+<refdescription>
+<para>If <parameter>callout.graphics</parameter>
+is non-zero, graphics are used to represent
+callout numbers. The value of
+<parameter>callout.graphics.number.limit</parameter>
+is
+the largest number for which a graphic exists. If the callout number
+exceeds this limit, the default presentation "(nnn)" will always
+be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="use.extensions" select="'0'" doc:type='boolean'/>
+
+<doc:param name="use.extensions" xmlns="">
+<refpurpose>Enable extensions</refpurpose>
+<refdescription>
+<para>If non-zero, extensions may be used. Each extension is
+further controlled by its own parameter. But if
+<parameter>use.extensions</parameter> is zero, no extensions will
+be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="textinsert.extension" select="'1'" doc:type='boolean'/>
+
+<doc:param name="textinsert.extension" xmlns="">
+<refpurpose>Enable the textinsert extension element</refpurpose>
+<refdescription>
+<para>The textinsert extension element inserts the contents of a
+a file into the result tree (as text).
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="saxon.linenumbering" select="'1'" doc:type='boolean'/>
+
+<doc:param name="saxon.linenumbering" xmlns="">
+<refpurpose>Enable the line numbering extension</refpurpose>
+<refdescription>
+<para>If true, verbatim environments (elements that have the
+format='linespecific' notation attribute: address, literallayout,
+programlisting, screen, synopsis) that specify line numbering will
+have, surprise, line numbers.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="linenumbering.extension" select="'1'" doc:type='boolean'/>
+
+<doc:param name="saxon.linenumbering" xmlns="">
+<refpurpose>Enable the line numbering extension</refpurpose>
+<refdescription>
+<para>If true, verbatim environments (elements that have the
+format='linespecific' notation attribute: address, literallayout,
+programlisting, screen, synopsis) that specify line numbering will
+have, surprise, line numbers.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="linenumbering.everyNth" select="'5'" doc:type='integer'/>
+
+<doc:param name="linenumbering.everyNth" xmlns="">
+<refpurpose>Indicate which lines should be numbered</refpurpose>
+<refdescription>
+<para>If line numbering is enabled, everyNth line will be numbered.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="linenumbering.width" select="'3'" doc:type='integer'/>
+
+<doc:param name="linenumbering.width" xmlns="">
+<refpurpose>Indicates the width of line numbers</refpurpose>
+<refdescription>
+<para>If line numbering is enabled, line numbers will appear right
+justified in a field "width" characters wide.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="linenumbering.separator" select="' '" doc:type='string'/>
+
+<doc:param name="linenumbering.separator" xmlns="">
+<refpurpose>Specify a separator between line numbers and lines</refpurpose>
+<refdescription>
+<para>The separator is inserted between line numbers and lines in
+the verbatim environment.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="saxon.callouts" select="'1'" doc:type='boolean'/>
+
+<doc:param name="saxon.callouts" xmlns="">
+<refpurpose>Enable the callout extension</refpurpose>
+<refdescription>
+<para>The callouts extension processes <sgmltag>areaset</sgmltag>
+elements in <sgmltag>ProgramListingCO</sgmltag> and other text-based
+callout elements.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callouts.extension" select="'1'" doc:type='boolean'/>
+
+<doc:param name="callouts.extension" xmlns="">
+<refpurpose>Enable the callout extension</refpurpose>
+<refdescription>
+<para>The callouts extension processes <sgmltag>areaset</sgmltag>
+elements in <sgmltag>ProgramListingCO</sgmltag> and other text-based
+callout elements.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.defaultcolumn" select="'60'" doc:type='integer'/>
+
+<doc:param name="callout.defaultcolumn" xmlns="">
+<refpurpose>Indicates what column callouts appear in by default</refpurpose>
+<refdescription>
+<para>If a callout does not identify a column (for example, if it uses
+the <literal>linerange</literal> <sgmltag class="attribute">unit</sgmltag>),
+it will appear in the default column.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="stylesheet.result.type" select="'html'"
+           doc:type='list'
+           doc:list='html fo'/>
+
+<doc:param name="stylesheet.result.type" xmlns="">
+<refpurpose>Identifies the output format of this stylesheet</refpurpose>
+<refdescription>
+<para>The Saxon extension functions need to know if the output format
+is HTML ('html') or XSL Formatting Objects ('fo'). This variable answers
+that question. Valid settings are 'html' or 'fo'.</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="nominal.table.width" select="'6in'" doc:type='length'/>
+
+<doc:param name="nominal.table.width" xmlns="">
+<refpurpose>The (absolute) nominal width of tables</refpurpose>
+<refdescription>
+<para>In order to convert CALS column widths into HTML column widths, it
+is sometimes necessary to have an absolute table width to use for conversion
+of mixed absolute and relative widths. This value must be an absolute
+length (not a percentag).</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="default.table.width" select="''" doc:type='length'/>
+
+<doc:param name="default.table.width" xmlns="">
+<refpurpose>The default width of tables</refpurpose>
+<refdescription>
+<para>If specified, this value will be used for the WIDTH attribute on
+tables that do not specify an alternate width (with the dbhtml processing
+instruction).</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="saxon.tablecolumns" select="'1'" doc:type='boolean'/>
+
+<doc:param name="saxon.tablecolumns" xmlns="">
+<refpurpose>Enable the table columns extension function</refpurpose>
+<refdescription>
+<para>The table columns extension function adjusts the widths of table
+columns in the HTML result to more accurately reflect the specifications
+in the CALS table.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="tablecolumns.extension" select="'1'" doc:type='boolean'/>
+
+<doc:param name="saxon.tablecolumns" xmlns="">
+<refpurpose>Enable the table columns extension function</refpurpose>
+<refdescription>
+<para>The table columns extension function adjusts the widths of table
+columns in the HTML result to more accurately reflect the specifications
+in the CALS table.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.set.toc" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.book.toc" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.part.toc" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.reference.toc" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.preface.toc" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.chapter.toc" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.appendix.toc" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.article.toc" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.section.toc" select='0' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="generate.index" select='1' doc:type='boolean'/>
+
+<doc:param name="" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.unicode" select="0" doc:type='boolean'/>
+
+<doc:param name="callout.unicode" xmlns="">
+<refpurpose>FIXME:</refpurpose>
+<refdescription>
+<para>FIXME:
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.unicode.start.character" select="10102"
+           doc:type='integer'/>
+
+<doc:param name="callout.graphics.number.limit" xmlns="">
+<refpurpose>Number of the largest callout graphic</refpurpose>
+<refdescription>
+<para>If <parameter>callout.graphics</parameter>
+is non-zero, graphics are used to represent
+callout numbers. The value of
+<parameter>callout.graphics.number.limit</parameter>
+is
+the largest number for which a graphic exists. If the callout number
+exceeds this limit, the default presentation "(nnn)" will always
+be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="callout.unicode.number.limit" select="'10'"
+           doc:type='integer'/>
+
+<doc:param name="callout.graphics.number.limit" xmlns="">
+<refpurpose>Number of the largest callout graphic</refpurpose>
+<refdescription>
+<para>If <parameter>callout.graphics</parameter>
+is non-zero, graphics are used to represent
+callout numbers. The value of
+<parameter>callout.graphics.number.limit</parameter>
+is
+the largest number for which a graphic exists. If the callout number
+exceeds this limit, the default presentation "(nnn)" will always
+be used.
+</para>
+</refdescription>
+</doc:param>
+
+<!-- ==================================================================== -->
+<xsl:param name="use.id.as.filename" select="'0'" doc:type='boolean'/>
+
+<doc:param name="use.id.as.filename" xmlns="">
+<refpurpose>Use ID value of chunk elements as the filename?</refpurpose>
+<refdescription>
+<para>If <parameter>use.id.as.filename</parameter>
+is non-zero, the filename of chunk elements that have IDs will be
+derived from the ID value.
+</para>
+</refdescription>
+</doc:param>
+
+</xsl:stylesheet>
diff --git a/xsl/html/pi.xsl b/xsl/html/pi.xsl
new file mode 100644 (file)
index 0000000..b9220aa
--- /dev/null
@@ -0,0 +1,191 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:template match="processing-instruction()">
+</xsl:template>
+
+<xsl:template match="processing-instruction('dbhtml')">
+  <xsl:if test="$using.chunker">
+    <xsl:processing-instruction name="dbhtml">
+      <xsl:value-of select="."/>
+    </xsl:processing-instruction>
+  </xsl:if>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="dbhtml-attribute">
+  <xsl:param name="pis" select="processing-instruction('dbhtml')"/>
+  <xsl:param name="attribute">filename</xsl:param>
+  <xsl:param name="count">1</xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($pis)">
+      <!-- not found -->
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="pi">
+        <xsl:value-of select="$pis[$count]"/>
+      </xsl:variable>
+      <xsl:choose>
+        <xsl:when test="contains($pi,concat($attribute, '='))">
+          <xsl:variable name="rest" select="substring-after($pi,concat($attribute,'='))"/>
+          <xsl:variable name="quote" select="substring($rest,1,1)"/>
+          <xsl:value-of select="substring-before(substring($rest,2),$quote)"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="dbhtml-attribute">
+            <xsl:with-param name="pis" select="$pis"/>
+            <xsl:with-param name="attribute" select="$attribute"/>
+            <xsl:with-param name="count" select="$count + 1"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="dbhtml-filename">
+  <xsl:param name="pis" select="./processing-instruction('dbhtml')"/>
+  <xsl:call-template name="dbhtml-attribute">
+    <xsl:with-param name="pis" select="$pis"/>
+    <xsl:with-param name="attribute">filename</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="dbhtml-dir">
+  <xsl:param name="pis" select="./processing-instruction('dbhtml')"/>
+  <xsl:call-template name="dbhtml-attribute">
+    <xsl:with-param name="pis" select="$pis"/>
+    <xsl:with-param name="attribute">dir</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process.cmdsynopsis.list">
+  <xsl:param name="cmdsynopses"/><!-- empty node list by default -->
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($cmdsynopses)"></xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="cmdsyn" select="$cmdsynopses[$count]"/>
+
+       <dt>
+       <a>
+         <xsl:attribute name="href">
+           <xsl:call-template name="object.id">
+             <xsl:with-param name="object" select="$cmdsyn"/>
+           </xsl:call-template>
+         </xsl:attribute>
+
+         <xsl:choose>
+           <xsl:when test="$cmdsyn/@xreflabel">
+             <xsl:call-template name="xref.xreflabel">
+               <xsl:with-param name="target" select="$cmdsyn"/>
+             </xsl:call-template>
+           </xsl:when>
+           <xsl:otherwise>
+             <xsl:apply-templates select="$cmdsyn" mode="xref-to">
+               <xsl:with-param name="target" select="$cmdsyn"/>
+             </xsl:apply-templates>
+           </xsl:otherwise>
+         </xsl:choose>
+       </a>
+       </dt>
+
+        <xsl:call-template name="process.cmdsynopsis.list">
+          <xsl:with-param name="cmdsynopses" select="$cmdsynopses"/>
+          <xsl:with-param name="count" select="$count+1"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="processing-instruction('dbcmdlist')">
+  <xsl:variable name="cmdsynopses" select="..//cmdsynopsis"/>
+
+  <xsl:if test="count($cmdsynopses)&lt;1">
+    <xsl:message><xsl:text>No cmdsynopsis elements matched dbcmdlist PI, perhaps it's nested too deep?</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <dl>
+    <xsl:call-template name="process.cmdsynopsis.list">
+      <xsl:with-param name="cmdsynopses" select="$cmdsynopses"/>
+    </xsl:call-template>
+  </dl>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process.funcsynopsis.list">
+  <xsl:param name="funcsynopses"/><!-- empty node list by default -->
+  <xsl:param name="count" select="1"/>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($funcsynopses)"></xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="cmdsyn" select="$funcsynopses[$count]"/>
+
+       <dt>
+       <a>
+         <xsl:attribute name="href">
+           <xsl:call-template name="object.id">
+             <xsl:with-param name="object" select="$cmdsyn"/>
+           </xsl:call-template>
+         </xsl:attribute>
+
+         <xsl:choose>
+           <xsl:when test="$cmdsyn/@xreflabel">
+             <xsl:call-template name="xref.xreflabel">
+               <xsl:with-param name="target" select="$cmdsyn"/>
+             </xsl:call-template>
+           </xsl:when>
+           <xsl:otherwise>
+              <xsl:apply-templates select="$cmdsyn" mode="xref-to">
+                <xsl:with-param name="target" select="$cmdsyn"/>
+              </xsl:apply-templates>
+           </xsl:otherwise>
+         </xsl:choose>
+       </a>
+       </dt>
+
+        <xsl:call-template name="process.funcsynopsis.list">
+          <xsl:with-param name="funcsynopses" select="$funcsynopses"/>
+          <xsl:with-param name="count" select="$count+1"/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="processing-instruction('dbfunclist')">
+  <xsl:variable name="funcsynopses" select="..//funcsynopsis"/>
+
+  <xsl:if test="count($funcsynopses)&lt;1">
+    <xsl:message><xsl:text>No funcsynopsis elements matched dbfunclist PI, perhaps it's nested too deep?</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <dl>
+    <xsl:call-template name="process.funcsynopsis.list">
+      <xsl:with-param name="funcsynopses" select="$funcsynopses"/>
+    </xsl:call-template>
+  </dl>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/qandaset.xsl b/xsl/html/qandaset.xsl
new file mode 100644 (file)
index 0000000..5109dc1
--- /dev/null
@@ -0,0 +1,202 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="qandaset">
+  <xsl:variable name="title" select="title"/>
+  <xsl:variable name="rest" select="*[name(.)!='title']"/>
+
+  <div class="{name(.)}">
+    <xsl:apply-templates select="$title"/>
+    <xsl:if test="$generate.qandaset.toc != '0'">
+      <xsl:call-template name="process.qanda.toc"/>
+    </xsl:if>
+    <xsl:apply-templates select="$rest"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="qandaset/title">
+  <xsl:variable name="qalevel">
+    <xsl:call-template name="qanda.section.level"/>
+  </xsl:variable>
+  <xsl:element name="h{string(number($qalevel)+1)}">
+    <xsl:attribute name="class">
+      <xsl:value-of select="name(.)"/>
+    </xsl:attribute>
+    <xsl:apply-templates/>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="qandadiv">
+  <xsl:variable name="title" select="title"/>
+  <xsl:variable name="rest" select="*[name(.)!='title']"/>
+
+  <div class="{name(.)}">
+    <xsl:apply-templates select="$title"/>
+    <xsl:if test="$generate.qandadiv.toc != '0'">
+      <xsl:call-template name="process.qanda.toc"/>
+    </xsl:if>
+    <xsl:apply-templates select="$rest"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="qandadiv/title">
+  <xsl:variable name="qalevel">
+    <xsl:call-template name="qandadiv.section.level"/>
+  </xsl:variable>
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="parent::*"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:element name="h{string(number($qalevel)+1)}">
+    <xsl:attribute name="class">
+      <xsl:value-of select="name(.)"/>
+    </xsl:attribute>
+    <a name="{$id}">
+      <xsl:apply-templates select="parent::qandadiv" mode="label.markup"/>
+      <xsl:text> </xsl:text>
+      <xsl:apply-templates/>
+    </a>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="qandaentry">
+  <div class="{name(.)}">
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="question">
+  <xsl:variable name="firstch" select="(*[name(.)!='label'])[1]"/>
+  <xsl:variable name="restch" select="(*[name(.)!='label'])[position()!=1]"/>
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="parent::*"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <p>
+      <a name="{$id}">
+        <b>
+          <xsl:apply-templates select="." mode="label.markup"/>
+          <xsl:text> </xsl:text>
+        </b>
+        <xsl:apply-templates select="$firstch" mode="no.wrapper.mode"/>
+      </a>
+    </p>
+    <xsl:apply-templates select="$restch"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="answer">
+  <xsl:variable name="firstch" select="(*[name(.)!='label'])[1]"/>
+  <xsl:variable name="restch" select="(*[name(.)!='label'])[position()!=1]"/>
+
+  <div class="{name(.)}">
+    <p>
+      <b>
+        <xsl:apply-templates select="." mode="label.markup"/>
+        <xsl:text> </xsl:text>
+      </b>
+      <xsl:apply-templates select="$firstch" mode="no.wrapper.mode"/>
+    </p>
+    <xsl:apply-templates select="$restch"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="label">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="process.qanda.toc">
+  <dl>
+    <xsl:apply-templates select="qandadiv" mode="qandatoc.mode"/>
+    <xsl:apply-templates select="qandaentry" mode="qandatoc.mode"/>
+  </dl>
+</xsl:template>
+
+<xsl:template match="qandadiv" mode="qandatoc.mode">
+  <dt><xsl:apply-templates select="title" mode="qandatoc.mode"/></dt>
+  <dd><xsl:call-template name="process.qanda.toc"/></dd>
+</xsl:template>
+
+<xsl:template match="qandadiv/title" mode="qandatoc.mode">
+  <xsl:variable name="qalevel">
+    <xsl:call-template name="qandadiv.section.level"/>
+  </xsl:variable>
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="parent::*"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:apply-templates select="parent::qandadiv" mode="label.markup"/>
+  <xsl:text> </xsl:text>
+  <a>
+    <xsl:attribute name="href">
+      <xsl:call-template name="href.target">
+        <xsl:with-param name="object" select="parent::*"/>
+      </xsl:call-template>
+    </xsl:attribute>
+    <xsl:apply-templates/>
+  </a>
+</xsl:template>
+
+<xsl:template match="qandaentry" mode="qandatoc.mode">
+  <xsl:apply-templates mode="qandatoc.mode"/>
+</xsl:template>
+
+<xsl:template match="question" mode="qandatoc.mode">
+  <xsl:variable name="firstch" select="(*[name(.)!='label'])[1]"/>
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id">
+      <xsl:with-param name="object" select="parent::*"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <dt>
+    <xsl:apply-templates select="." mode="label.markup"/>
+    <xsl:text> </xsl:text>
+    <a>
+      <xsl:attribute name="href">
+        <xsl:call-template name="href.target">
+          <xsl:with-param name="object" select="parent::*"/>
+        </xsl:call-template>
+      </xsl:attribute>
+      <xsl:value-of select="$firstch"/>
+    </a>
+  </dt>
+</xsl:template>
+
+<xsl:template match="answer|revhistory" mode="qandatoc.mode">
+  <!-- nop -->
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="no.wrapper.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/refentry.xsl b/xsl/html/refentry.xsl
new file mode 100644 (file)
index 0000000..8148746
--- /dev/null
@@ -0,0 +1,216 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="reference">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <xsl:if test="@id">
+      <a name="{$id}"/>
+    </xsl:if>
+    <xsl:call-template name="reference.titlepage"/>
+    <xsl:if test="not(partintro) and $generate.reference.toc != '0'">
+      <xsl:call-template name="division.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="reference" mode="division.number">
+  <xsl:number from="book" count="reference" format="I."/>
+</xsl:template>
+
+<xsl:template match="reference/docinfo"></xsl:template>
+<xsl:template match="reference/referenceinfo"></xsl:template>
+<xsl:template match="reference/title"></xsl:template>
+<xsl:template match="reference/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="refentry">
+  <xsl:variable name="refmeta" select=".//refmeta"/>
+  <xsl:variable name="refentrytitle" select="$refmeta//refentrytitle"/>
+  <xsl:variable name="refnamediv" select=".//refnamediv"/>
+  <xsl:variable name="refname" select="$refnamediv//refname"/>
+  <xsl:variable name="title">
+    <xsl:choose>
+      <xsl:when test="$refentrytitle">
+        <xsl:apply-templates select="$refentrytitle[1]" mode="title"/>
+      </xsl:when>
+      <xsl:when test="$refname">
+        <xsl:apply-templates select="$refname[1]" mode="title"/>
+      </xsl:when>
+      <xsl:otherwise></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <h1 class="title">
+      <a>
+        <xsl:attribute name="name">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </a>
+      <xsl:copy-of select="$title"/>
+    </h1>
+    <xsl:apply-templates/>
+    <xsl:call-template name="process.footnotes"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refentry/docinfo|refentry/refentryinfo"></xsl:template>
+
+<xsl:template match="refentrytitle|refname" mode="title">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="refmeta">
+</xsl:template>
+
+<xsl:template match="manvolnum">
+  <xsl:if test="$refentry.xref.manvolnum != 0">
+    <xsl:text>(</xsl:text>
+    <xsl:apply-templates/>
+    <xsl:text>)</xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="refmiscinfo">
+</xsl:template>
+
+<xsl:template match="refentrytitle">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="refnamediv">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="refname">
+  <xsl:apply-templates/>
+  <xsl:if test="following-sibling::refname">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="refname[1]">
+  <xsl:if test="$refentry.generate.name != 0">
+    <h2>
+      <xsl:call-template name="gentext">
+        <xsl:with-param name="key" select="'RefName'"/>
+      </xsl:call-template>
+    </h2>
+  </xsl:if>
+  <xsl:apply-templates/>
+  <xsl:if test="following-sibling::refname">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="refpurpose">
+  <xsl:text> </xsl:text>
+  <xsl:call-template name="dingbat">
+    <xsl:with-param name="dingbat">em-dash</xsl:with-param>
+  </xsl:call-template>
+  <xsl:text> </xsl:text>
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="refdescriptor">
+  <!-- todo: finish this -->
+</xsl:template>
+
+<xsl:template match="refclass">
+  <p>
+    <b>
+      <xsl:if test="@role">
+        <xsl:value-of select="@role"/>
+        <xsl:text>: </xsl:text>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </b>
+  </p>
+</xsl:template>
+
+<xsl:template match="refsynopsisdiv">
+  <div class="{name(.)}">
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id"/>
+      </xsl:attribute>
+    </a>
+    <h2>Synopsis</h2>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="refsynopsisdivinfo"></xsl:template>
+
+<xsl:template match="refsynopsisdiv/title">
+</xsl:template>
+
+<xsl:template match="refsect1|refsect2|refsect3">
+  <xsl:call-template name="block.object"/>
+</xsl:template>
+
+<xsl:template match="refsect1/title">
+  <h2>
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="ancestor::refsect1"/>
+        </xsl:call-template>
+      </xsl:attribute>
+    </a>
+    <xsl:apply-templates/>
+  </h2>
+</xsl:template>
+
+<xsl:template match="refsect2/title">
+  <h3>
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="ancestor::refsect2"/>
+        </xsl:call-template>
+      </xsl:attribute>
+    </a>
+    <xsl:apply-templates/>
+  </h3>
+</xsl:template>
+
+<xsl:template match="refsect3/title">
+  <h4>
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="ancestor::refsect3"/>
+        </xsl:call-template>
+      </xsl:attribute>
+    </a>
+    <xsl:apply-templates/>
+  </h4>
+</xsl:template>
+
+<xsl:template match="refsect1info"></xsl:template>
+<xsl:template match="refsect2info"></xsl:template>
+<xsl:template match="refsect3info"></xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/sections.xsl b/xsl/html/sections.xsl
new file mode 100644 (file)
index 0000000..0f34309
--- /dev/null
@@ -0,0 +1,242 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="section">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:call-template name="section.titlepage"/>
+    <xsl:if test="$generate.section.toc != '0'
+                  or refentry">
+      <xsl:call-template name="section.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="section.titlepage.recto.mode">
+  <xsl:variable name="section" select="(ancestor::section
+                                        |ancestor::simplesect
+                                        |ancestor::sect1
+                                        |ancestor::sect2
+                                        |ancestor::sect3
+                                        |ancestor::sect4
+                                        |ancestor::sect5)[last()]"/>
+
+  <xsl:variable name="level">
+    <xsl:call-template name="section.level">
+      <xsl:with-param name="node" select="$section"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:element name="h{$level}">
+    <xsl:attribute name="class">title</xsl:attribute>
+    <xsl:if test="$css.decoration != '0'">
+      <xsl:if test="$level&lt;3">
+        <xsl:attribute name="style">clear: all</xsl:attribute>
+      </xsl:if>
+    </xsl:if>
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="$section"/>
+        </xsl:call-template>
+      </xsl:attribute>
+    </a>
+    <xsl:apply-templates select="$section" mode="object.title.markup"/>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="sect1">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:call-template name="sect1.titlepage"/>
+    <xsl:if test="$generate.section.toc != '0'
+                  or refentry">
+      <xsl:call-template name="section.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="sect1.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="sect2">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:call-template name="sect2.titlepage"/>
+    <xsl:if test="$generate.section.toc != '0'
+                  or refentry">
+      <xsl:call-template name="section.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="sect2.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="sect3">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:call-template name="sect3.titlepage"/>
+
+    <xsl:if test="$generate.section.toc != '0'
+                  or refentry">
+      <xsl:call-template name="section.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="sect3.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="sect4">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:call-template name="sect4.titlepage"/>
+    <xsl:if test="$generate.section.toc != '0'
+                  or refentry">
+      <xsl:call-template name="section.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="sect4.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="sect5">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:call-template name="sect5.titlepage"/>
+    <xsl:if test="$generate.section.toc != '0'
+                  or refentry">
+      <xsl:call-template name="section.toc"/>
+    </xsl:if>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="sect5.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="simplesect">
+  <xsl:variable name="id">
+    <xsl:call-template name="object.id"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:call-template name="simplesect.titlepage"/>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="title" mode="simplesect.titlepage.recto.mode">
+  <xsl:apply-templates select="." mode="section.titlepage.recto.mode"/>
+</xsl:template>
+
+<xsl:template match="section/title"></xsl:template>
+<xsl:template match="section/subtitle"></xsl:template>
+<xsl:template match="sectioninfo"></xsl:template>
+
+<xsl:template match="sect1/title"></xsl:template>
+<xsl:template match="sect1/subtitle"></xsl:template>
+<xsl:template match="sect1info"></xsl:template>
+
+<xsl:template match="sect2/title"></xsl:template>
+<xsl:template match="sect2/subtitle"></xsl:template>
+<xsl:template match="sect2info"></xsl:template>
+
+<xsl:template match="sect3/title"></xsl:template>
+<xsl:template match="sect3/subtitle"></xsl:template>
+<xsl:template match="sect3info"></xsl:template>
+
+<xsl:template match="sect4/title"></xsl:template>
+<xsl:template match="sect4/subtitle"></xsl:template>
+<xsl:template match="sect4info"></xsl:template>
+
+<xsl:template match="sect5/title"></xsl:template>
+<xsl:template match="sect5/subtitle"></xsl:template>
+<xsl:template match="sect5info"></xsl:template>
+
+<xsl:template match="simplesect/title"></xsl:template>
+<xsl:template match="simplesect/subtitle"></xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="section.heading">
+  <xsl:param name="section" select="."/>
+  <xsl:param name="level" select="'1'"/>
+  <xsl:param name="title"/>
+  <xsl:element name="h{$level}">
+    <xsl:attribute name="class">title</xsl:attribute>
+    <xsl:if test="$css.decoration != '0'">
+      <xsl:if test="$level&lt;3">
+        <xsl:attribute name="style">clear: all</xsl:attribute>
+      </xsl:if>
+    </xsl:if>
+    <a>
+      <xsl:attribute name="name">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="$section"/>
+        </xsl:call-template>
+      </xsl:attribute>
+    </a>
+    <xsl:copy-of select="$title"/>
+  </xsl:element>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="bridgehead">
+  <!-- need to calculate depth! -->
+  <h3><xsl:apply-templates/></h3>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/html/synop.xsl b/xsl/html/synop.xsl
new file mode 100644 (file)
index 0000000..9c0f30d
--- /dev/null
@@ -0,0 +1,939 @@
+<?xml version='1.0'?>
+<!DOCTYPE xsl:stylesheet [
+<!ENTITY RE "&#10;">
+<!ENTITY nbsp "&#160;">
+]>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<!-- synopsis is in verbatim -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="cmdsynopsis">
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <div class="{name(.)}" id="{$id}">
+    <a name="{$id}"/>
+    <xsl:apply-templates/>
+  </div>
+</xsl:template>
+
+<xsl:template match="cmdsynopsis/command">
+  <br/>
+  <xsl:call-template name="inline.monoseq"/>
+  <xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template match="cmdsynopsis/command[1]" priority="2">
+  <xsl:call-template name="inline.monoseq"/>
+  <xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template match="group|arg">
+  <xsl:variable name="choice" select="@choice"/>
+  <xsl:variable name="rep" select="@rep"/>
+  <xsl:variable name="sepchar">
+    <xsl:choose>
+      <xsl:when test="ancestor-or-self::*/@sepchar">
+        <xsl:value-of select="ancestor-or-self::*/@sepchar"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:text> </xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:if test="position()>1"><xsl:value-of select="$sepchar"/></xsl:if>
+  <xsl:choose>
+    <xsl:when test="$choice='plain'">
+      <xsl:value-of select="$arg.choice.plain.open.str"/>
+    </xsl:when>
+    <xsl:when test="$choice='req'">
+      <xsl:value-of select="$arg.choice.req.open.str"/>
+    </xsl:when>
+    <xsl:when test="$choice='opt'">
+      <xsl:value-of select="$arg.choice.opt.open.str"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$arg.choice.def.open.str"/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:apply-templates/>
+  <xsl:choose>
+    <xsl:when test="$rep='repeat'">
+      <xsl:value-of select="$arg.rep.repeat.str"/>
+    </xsl:when>
+    <xsl:when test="$rep='norepeat'">
+      <xsl:value-of select="$arg.rep.norepeat.str"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$arg.rep.def.str"/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:choose>
+    <xsl:when test="$choice='plain'">
+      <xsl:value-of select="$arg.choice.plain.close.str"/>
+    </xsl:when>
+    <xsl:when test="$choice='req'">
+      <xsl:value-of select="$arg.choice.req.close.str"/>
+    </xsl:when>
+    <xsl:when test="$choice='opt'">
+      <xsl:value-of select="$arg.choice.opt.close.str"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$arg.choice.def.close.str"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="group/arg">
+  <xsl:variable name="choice" select="@choice"/>
+  <xsl:variable name="rep" select="@rep"/>
+  <xsl:if test="position()>1"><xsl:value-of select="$arg.or.sep"/></xsl:if>
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="sbr">
+  <br/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="synopfragmentref">
+  <xsl:variable name="target" select="id(@linkend)"/>
+  <xsl:variable name="snum">
+    <xsl:apply-templates select="$target" mode="synopfragment.number"/>
+  </xsl:variable>
+  <i>
+    <a href="{@linkend}">
+      <xsl:text>(</xsl:text>
+      <xsl:value-of select="$snum"/>
+      <xsl:text>)</xsl:text>
+    </a>
+  </i>
+</xsl:template>
+
+<xsl:template match="synopfragment" mode="synopfragment.number">
+  <xsl:number format="1"/>
+</xsl:template>
+
+<xsl:template match="synopfragment">
+  <xsl:variable name="snum">
+    <xsl:apply-templates select="." mode="synopfragment.number"/>
+  </xsl:variable>
+  <p>
+    <a name="#{@id}">
+      <xsl:text>(</xsl:text>
+      <xsl:value-of select="$snum"/>
+      <xsl:text>)</xsl:text>
+    </a>
+    <xsl:text> </xsl:text>
+    <xsl:apply-templates/>
+  </p>
+</xsl:template>   
+
+<xsl:template match="funcsynopsis">
+  <xsl:call-template name="informal.object"/>
+</xsl:template>
+
+<xsl:template match="funcsynopsisinfo">
+  <pre class="{name(.)}"><xsl:apply-templates/></pre>
+</xsl:template>
+
+<xsl:template match="funcprototype">
+  <p>
+    <code>
+      <xsl:apply-templates/>
+      <xsl:if test="$funcsynopsis.style='kr'">
+        <xsl:apply-templates select="./paramdef" mode="kr-funcsynopsis-mode"/>
+      </xsl:if>
+    </code>
+  </p>
+</xsl:template>
+
+<xsl:template match="funcdef">
+  <code class="{name(.)}">
+    <xsl:apply-templates/>
+  </code>
+</xsl:template>
+
+<xsl:template match="funcdef/function">
+  <xsl:choose>
+    <xsl:when test="$funcsynopsis.decoration != 0">
+      <b class="fsfunc"><xsl:apply-templates/></b>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="void">
+  <xsl:choose>
+    <xsl:when test="$funcsynopsis.style='ansi'">
+      <xsl:text>(void);</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>();</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="varargs">
+  <xsl:text>(...);</xsl:text>
+</xsl:template>
+
+<xsl:template match="paramdef">
+  <xsl:variable name="paramnum">
+    <xsl:number count="paramdef" format="1"/>
+  </xsl:variable>
+  <xsl:if test="$paramnum=1">(</xsl:if>
+  <xsl:choose>
+    <xsl:when test="$funcsynopsis.style='ansi'">
+      <xsl:apply-templates/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates select="./parameter"/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:choose>
+    <xsl:when test="following-sibling::paramdef">
+      <xsl:text>, </xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>);</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="paramdef/parameter">
+  <xsl:choose>
+    <xsl:when test="$funcsynopsis.decoration != 0">
+      <var class="pdparam">
+        <xsl:apply-templates/>
+      </var>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:if test="following-sibling::parameter">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="paramdef" mode="kr-funcsynopsis-mode">
+  <br/>
+  <xsl:apply-templates/>
+  <xsl:text>;</xsl:text>
+</xsl:template>
+
+<xsl:template match="funcparams">
+  <xsl:text>(</xsl:text>
+  <xsl:apply-templates/>
+  <xsl:text>)</xsl:text>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:variable name="default-classsynopsis-language">java</xsl:variable>
+
+<xsl:template match="classsynopsis">
+  <xsl:param name="language">
+    <xsl:choose>
+      <xsl:when test="@language">
+       <xsl:value-of select="@language"/>
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:value-of select="$default-classsynopsis-language"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="$language='java'">
+      <xsl:apply-templates select="." mode="java"/>
+    </xsl:when>
+    <xsl:when test="$language='perl'">
+      <xsl:apply-templates select="." mode="perl"/>
+    </xsl:when>
+    <xsl:when test="$language='idl'">
+      <xsl:apply-templates select="." mode="idl"/>
+    </xsl:when>
+    <xsl:when test="$language='cpp'">
+      <xsl:apply-templates select="." mode="cpp"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message>
+       <xsl:text>Unrecognized language on classsynopsis: </xsl:text>
+       <xsl:value-of select="$language"/>
+      </xsl:message>
+      <xsl:apply-templates select=".">
+       <xsl:with-param name="language"
+         select="$default-classsynopsis-language"/>
+      </xsl:apply-templates>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ===== Java ======================================================== -->
+
+<xsl:template match="classsynopsis" mode="java">
+  <pre class="{name(.)}">
+    <xsl:apply-templates select="ooclass[1]" mode="java"/>
+    <xsl:if test="ooclass[position() &gt; 1]">
+      <xsl:text> extends</xsl:text>
+      <xsl:apply-templates select="ooclass[position() &gt; 1]" mode="java"/>
+      <xsl:if test="oointerface|ooexception">
+       <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;</xsl:text>
+      </xsl:if>
+    </xsl:if>
+    <xsl:if test="oointerface">
+      <xsl:text>implements</xsl:text>
+      <xsl:apply-templates select="oointerface" mode="java"/>
+      <xsl:if test="ooexception">
+       <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;</xsl:text>
+      </xsl:if>
+    </xsl:if>
+    <xsl:if test="ooexception">
+      <xsl:text>throws</xsl:text>
+      <xsl:apply-templates select="ooexception" mode="java"/>
+    </xsl:if>
+    <xsl:text>&nbsp;{&RE;&RE;</xsl:text>
+    <xsl:apply-templates select="constructorsynopsis
+                                 |destructorsynopsis
+                                 |fieldsynopsis
+                                 |methodsynopsis
+                                 |classsynopsisinfo" mode="java"/>
+    <xsl:text>}</xsl:text>
+  </pre>
+</xsl:template>
+
+<xsl:template match="classsynopsisinfo" mode="java">
+  <xsl:apply-templates mode="java"/>
+</xsl:template>
+
+<xsl:template match="ooclass|oointerface|ooexception" mode="java">
+  <xsl:choose>
+    <xsl:when test="position() &gt; 1">
+      <xsl:text>, </xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text> </xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="modifier" mode="java">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="classname" mode="java">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'classname'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="interfacename" mode="java">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'interfacename'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="exceptionname" mode="java">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'exceptionname'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="fieldsynopsis" mode="java">
+  <div class="{name(.)}">
+    <xsl:text>&nbsp;&nbsp;</xsl:text>
+    <xsl:apply-templates mode="java"/>
+    <xsl:text>;</xsl:text>
+  </div>
+</xsl:template>
+
+<xsl:template match="type" mode="java">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="varname" mode="java">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="initializer" mode="java">
+  <span class="{name(.)}">
+    <xsl:text>=&nbsp;</xsl:text>
+    <xsl:apply-templates mode="java"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="void" mode="java">
+  <span class="{name(.)}">
+    <xsl:text>void&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="methodname" mode="java">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="methodparam" mode="java">
+  <xsl:param name="indent">0</xsl:param>
+  <xsl:if test="position() &gt; 1">
+    <xsl:text>,&RE;</xsl:text>
+    <xsl:if test="$indent &gt; 0">
+      <xsl:call-template name="copy-string">
+       <xsl:with-param name="string">&nbsp;</xsl:with-param>
+       <xsl:with-param name="count" select="$indent + 1"/>
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="parameter" mode="java">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="java"/>
+  </span>
+</xsl:template>
+
+<xsl:template mode="java"
+  match="constructorsynopsis|destructorsynopsis|methodsynopsis">
+  <xsl:variable name="modifiers" select="modifier"/>
+  <xsl:variable name="notmod" select="*[name(.) != 'modifier']"/>
+  <xsl:variable name="decl">
+    <xsl:text>  </xsl:text>
+    <xsl:apply-templates select="$modifiers" mode="java"/>
+
+    <!-- type -->
+    <xsl:if test="name($notmod[1]) != 'methodname'">
+      <xsl:apply-templates select="$notmod[1]" mode="java"/>
+    </xsl:if>
+
+    <xsl:apply-templates select="methodname" mode="java"/>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <xsl:copy-of select="$decl"/>
+    <xsl:text>(</xsl:text>
+    <xsl:apply-templates select="methodparam" mode="java">
+      <xsl:with-param name="indent" select="string-length($decl)"/>
+    </xsl:apply-templates>
+    <xsl:text>)</xsl:text>
+    <xsl:if test="exceptionname">
+      <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;throws&nbsp;</xsl:text>
+      <xsl:apply-templates select="exceptionname" mode="java"/>
+    </xsl:if>
+    <xsl:text>;</xsl:text>
+  </div>
+</xsl:template>
+
+<!-- ===== C++ ========================================================= -->
+
+<xsl:template match="classsynopsis" mode="cpp">
+  <pre class="{name(.)}">
+    <xsl:apply-templates select="ooclass[1]" mode="cpp"/>
+    <xsl:if test="ooclass[position() &gt; 1]">
+      <xsl:text>: </xsl:text>
+      <xsl:apply-templates select="ooclass[position() &gt; 1]" mode="cpp"/>
+      <xsl:if test="oointerface|ooexception">
+       <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;</xsl:text>
+      </xsl:if>
+    </xsl:if>
+    <xsl:if test="oointerface">
+      <xsl:text> implements</xsl:text>
+      <xsl:apply-templates select="oointerface" mode="cpp"/>
+      <xsl:if test="ooexception">
+       <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;</xsl:text>
+      </xsl:if>
+    </xsl:if>
+    <xsl:if test="ooexception">
+      <xsl:text> throws</xsl:text>
+      <xsl:apply-templates select="ooexception" mode="cpp"/>
+    </xsl:if>
+    <xsl:text>&nbsp;{&RE;&RE;</xsl:text>
+    <xsl:apply-templates select="constructorsynopsis
+                                 |destructorsynopsis
+                                 |fieldsynopsis
+                                 |methodsynopsis
+                                 |classsynopsisinfo" mode="cpp"/>
+    <xsl:text>}</xsl:text>
+  </pre>
+</xsl:template>
+
+<xsl:template match="classsynopsisinfo" mode="cpp">
+  <xsl:apply-templates mode="cpp"/>
+</xsl:template>
+
+<xsl:template match="ooclass|oointerface|ooexception" mode="cpp">
+  <xsl:if test="position() &gt; 1">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="modifier" mode="cpp">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="classname" mode="cpp">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'classname'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="interfacename" mode="cpp">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'interfacename'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="exceptionname" mode="cpp">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'exceptionname'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="fieldsynopsis" mode="cpp">
+  <div class="{name(.)}">
+    <xsl:text>&nbsp;&nbsp;</xsl:text>
+    <xsl:apply-templates mode="cpp"/>
+    <xsl:text>;</xsl:text>
+  </div>
+</xsl:template>
+
+<xsl:template match="type" mode="cpp">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="varname" mode="cpp">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="initializer" mode="cpp">
+  <span class="{name(.)}">
+    <xsl:text>=&nbsp;</xsl:text>
+    <xsl:apply-templates mode="cpp"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="void" mode="cpp">
+  <span class="{name(.)}">
+    <xsl:text>void&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="methodname" mode="cpp">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="methodparam" mode="cpp">
+  <xsl:if test="position() &gt; 1">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="parameter" mode="cpp">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="cpp"/>
+  </span>
+</xsl:template>
+
+<xsl:template mode="cpp"
+  match="constructorsynopsis|destructorsynopsis|methodsynopsis">
+  <xsl:variable name="modifiers" select="modifier"/>
+  <xsl:variable name="notmod" select="*[name(.) != 'modifier']"/>
+  <xsl:variable name="type">
+  </xsl:variable>
+  <div class="{name(.)}">
+    <xsl:text>  </xsl:text>
+    <xsl:apply-templates select="$modifiers" mode="cpp"/>
+
+    <!-- type -->
+    <xsl:if test="name($notmod[1]) != 'methodname'">
+      <xsl:apply-templates select="$notmod[1]" mode="cpp"/>
+    </xsl:if>
+
+    <xsl:apply-templates select="methodname" mode="cpp"/>
+    <xsl:text>(</xsl:text>
+    <xsl:apply-templates select="methodparam" mode="cpp"/>
+    <xsl:text>)</xsl:text>
+    <xsl:if test="exceptionname">
+      <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;throws&nbsp;</xsl:text>
+      <xsl:apply-templates select="exceptionname" mode="cpp"/>
+    </xsl:if>
+    <xsl:text>;</xsl:text>
+  </div>
+</xsl:template>
+
+<!-- ===== IDL ========================================================= -->
+
+<xsl:template match="classsynopsis" mode="idl">
+  <pre class="{name(.)}">
+    <xsl:text>interface </xsl:text>
+    <xsl:apply-templates select="ooclass[1]" mode="idl"/>
+    <xsl:if test="ooclass[position() &gt; 1]">
+      <xsl:text>: </xsl:text>
+      <xsl:apply-templates select="ooclass[position() &gt; 1]" mode="idl"/>
+      <xsl:if test="oointerface|ooexception">
+       <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;</xsl:text>
+      </xsl:if>
+    </xsl:if>
+    <xsl:if test="oointerface">
+      <xsl:text> implements</xsl:text>
+      <xsl:apply-templates select="oointerface" mode="idl"/>
+      <xsl:if test="ooexception">
+       <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;</xsl:text>
+      </xsl:if>
+    </xsl:if>
+    <xsl:if test="ooexception">
+      <xsl:text> throws</xsl:text>
+      <xsl:apply-templates select="ooexception" mode="idl"/>
+    </xsl:if>
+    <xsl:text>&nbsp;{&RE;&RE;</xsl:text>
+    <xsl:apply-templates select="constructorsynopsis
+                                 |destructorsynopsis
+                                 |fieldsynopsis
+                                 |methodsynopsis
+                                 |classsynopsisinfo" mode="idl"/>
+    <xsl:text>}</xsl:text>
+  </pre>
+</xsl:template>
+
+<xsl:template match="classsynopsisinfo" mode="idl">
+  <xsl:apply-templates mode="idl"/>
+</xsl:template>
+
+<xsl:template match="ooclass|oointerface|ooexception" mode="idl">
+  <xsl:if test="position() &gt; 1">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="modifier" mode="idl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="classname" mode="idl">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'classname'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="interfacename" mode="idl">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'interfacename'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="exceptionname" mode="idl">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'exceptionname'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="fieldsynopsis" mode="idl">
+  <div class="{name(.)}">
+    <xsl:text>&nbsp;&nbsp;</xsl:text>
+    <xsl:apply-templates mode="idl"/>
+    <xsl:text>;</xsl:text>
+  </div>
+</xsl:template>
+
+<xsl:template match="type" mode="idl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="varname" mode="idl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="initializer" mode="idl">
+  <span class="{name(.)}">
+    <xsl:text>=&nbsp;</xsl:text>
+    <xsl:apply-templates mode="idl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="void" mode="idl">
+  <span class="{name(.)}">
+    <xsl:text>void&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="methodname" mode="idl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="methodparam" mode="idl">
+  <xsl:if test="position() &gt; 1">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="parameter" mode="idl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="idl"/>
+  </span>
+</xsl:template>
+
+<xsl:template mode="idl"
+  match="constructorsynopsis|destructorsynopsis|methodsynopsis">
+  <xsl:variable name="modifiers" select="modifier"/>
+  <xsl:variable name="notmod" select="*[name(.) != 'modifier']"/>
+  <xsl:variable name="type">
+  </xsl:variable>
+  <div class="{name(.)}">
+    <xsl:text>  </xsl:text>
+    <xsl:apply-templates select="$modifiers" mode="idl"/>
+
+    <!-- type -->
+    <xsl:if test="name($notmod[1]) != 'methodname'">
+      <xsl:apply-templates select="$notmod[1]" mode="idl"/>
+    </xsl:if>
+
+    <xsl:apply-templates select="methodname" mode="idl"/>
+    <xsl:text>(</xsl:text>
+    <xsl:apply-templates select="methodparam" mode="idl"/>
+    <xsl:text>)</xsl:text>
+    <xsl:if test="exceptionname">
+      <xsl:text>&RE;&nbsp;&nbsp;&nbsp;&nbsp;raises(</xsl:text>
+      <xsl:apply-templates select="exceptionname" mode="idl"/>
+      <xsl:text>)</xsl:text>
+    </xsl:if>
+    <xsl:text>;</xsl:text>
+  </div>
+</xsl:template>
+
+<!-- ===== Perl ======================================================== -->
+
+<xsl:template match="classsynopsis" mode="perl">
+  <pre class="{name(.)}">
+    <xsl:text>package </xsl:text>
+    <xsl:apply-templates select="ooclass[1]" mode="perl"/>
+    <xsl:text>;&RE;</xsl:text>
+
+    <xsl:if test="ooclass[position() &gt; 1]">
+      <xsl:text>@ISA = (</xsl:text>
+      <xsl:apply-templates select="ooclass[position() &gt; 1]" mode="perl"/>
+      <xsl:text>);&RE;</xsl:text>
+    </xsl:if>
+
+    <xsl:apply-templates select="constructorsynopsis
+                                 |destructorsynopsis
+                                 |fieldsynopsis
+                                 |methodsynopsis
+                                 |classsynopsisinfo" mode="perl"/>
+  </pre>
+</xsl:template>
+
+<xsl:template match="classsynopsisinfo" mode="perl">
+  <xsl:apply-templates mode="perl"/>
+</xsl:template>
+
+<xsl:template match="ooclass|oointerface|ooexception" mode="perl">
+  <xsl:if test="position() &gt; 1">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="modifier" mode="perl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="classname" mode="perl">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'classname'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="interfacename" mode="perl">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'interfacename'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="exceptionname" mode="perl">
+  <xsl:if test="name(preceding-sibling::*[1]) = 'exceptionname'">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="fieldsynopsis" mode="perl">
+  <div class="{name(.)}">
+    <xsl:text>&nbsp;&nbsp;</xsl:text>
+    <xsl:apply-templates mode="perl"/>
+    <xsl:text>;</xsl:text>
+  </div>
+</xsl:template>
+
+<xsl:template match="type" mode="perl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="varname" mode="perl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+    <xsl:text>&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="initializer" mode="perl">
+  <span class="{name(.)}">
+    <xsl:text>=&nbsp;</xsl:text>
+    <xsl:apply-templates mode="perl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="void" mode="perl">
+  <span class="{name(.)}">
+    <xsl:text>void&nbsp;</xsl:text>
+  </span>
+</xsl:template>
+
+<xsl:template match="methodname" mode="perl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="methodparam" mode="perl">
+  <xsl:if test="position() &gt; 1">
+    <xsl:text>, </xsl:text>
+  </xsl:if>
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+  </span>
+</xsl:template>
+
+<xsl:template match="parameter" mode="perl">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="perl"/>
+  </span>
+</xsl:template>
+
+<xsl:template mode="perl"
+  match="constructorsynopsis|destructorsynopsis|methodsynopsis">
+  <xsl:variable name="modifiers" select="modifier"/>
+  <xsl:variable name="notmod" select="*[name(.) != 'modifier']"/>
+  <xsl:variable name="type">
+  </xsl:variable>
+  <div class="{name(.)}">
+    <xsl:text>sub </xsl:text>
+
+    <xsl:apply-templates select="methodname" mode="perl"/>
+    <xsl:text> { ... };</xsl:text>
+  </div>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/table.xsl b/xsl/html/table.xsl
new file mode 100644 (file)
index 0000000..83869b1
--- /dev/null
@@ -0,0 +1,623 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                xmlns:stbl="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Table"
+                xmlns:xtbl="com.nwalsh.xalan.Table"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="doc stbl xtbl lxslt"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<lxslt:component prefix="xtbl"
+                 functions="adjustColumnWidths"/>
+
+<xsl:template match="tgroup">
+  <table>
+    <xsl:choose>
+      <!-- If there's a <?dbhtml table-summary="foo"?> PI, use it for
+           the HTML table summary attribute -->
+      <xsl:when test="processing-instruction('dbhtml')">
+        <xsl:variable name="summary">
+          <xsl:call-template name="dbhtml-attribute">
+            <xsl:with-param name="pis"
+                            select="processing-instruction('dbhtml')[1]"/>
+            <xsl:with-param name="attribute" select="'table-summary'"/>
+          </xsl:call-template>
+        </xsl:variable>
+        <xsl:if test="$summary != ''">
+          <xsl:attribute name="summary">
+            <xsl:value-of select="$summary"/>
+          </xsl:attribute>
+        </xsl:if>
+      </xsl:when>
+      <!-- Otherwise, if there's a title, use that -->
+      <xsl:when test="../title">
+        <xsl:attribute name="summary">
+          <xsl:value-of select="string(../title)"/>
+        </xsl:attribute>
+      </xsl:when>
+      <!-- Otherwise, forget the whole idea -->
+      <xsl:otherwise><!-- nevermind --></xsl:otherwise>
+    </xsl:choose>
+
+    <xsl:if test="../@pgwide=1">
+      <xsl:attribute name="width">100%</xsl:attribute>
+    </xsl:if>
+
+    <xsl:if test="@align">
+      <xsl:attribute name="align">
+        <xsl:value-of select="@align"/>
+      </xsl:attribute>
+    </xsl:if>
+
+    <xsl:choose>
+      <xsl:when test="../@frame='none'">
+        <xsl:attribute name="border">0</xsl:attribute>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:attribute name="border">1</xsl:attribute>
+      </xsl:otherwise>
+    </xsl:choose>
+
+    <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+    <xsl:variable name="colgroup">
+      <colgroup>
+        <xsl:call-template name="generate.colgroup">
+          <xsl:with-param name="cols" select="@cols"/>
+        </xsl:call-template>
+      </colgroup>
+    </xsl:variable>
+
+    <xsl:variable name="explicit.table.width">
+      <xsl:call-template name="dbhtml-attribute">
+        <xsl:with-param name="pis"
+                        select="../processing-instruction('dbhtml')[1]"/>
+        <xsl:with-param name="attribute" select="'table-width'"/>
+      </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:variable name="table.width">
+      <xsl:choose>
+        <xsl:when test="$explicit.table.width != ''">
+          <xsl:value-of select="$explicit.table.width"/>
+        </xsl:when>
+        <xsl:when test="$default.table.width = ''">
+          <xsl:text>100%</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$default.table.width"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:if test="$default.table.width != ''
+                  or $explicit.table.width != ''">
+      <xsl:attribute name="width">
+        <xsl:choose>
+          <xsl:when test="contains($table.width, '%')">
+            <xsl:value-of select="$table.width"/>
+          </xsl:when>
+          <xsl:when test="$use.extensions != 0
+                          and $tablecolumns.extension != 0">
+            <xsl:choose>
+              <xsl:when test="contains($vendor, 'SAXON 6')">
+                <xsl:value-of select="stbl:convertLength($table.width)"/>
+              </xsl:when>
+              <xsl:when test="contains($vendor, 'SAXON 5')">
+                <!-- the saxon5 extension doesn't support this (yet) -->
+                <xsl:value-of select="$table.width"/>
+              </xsl:when>
+              <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+                <xsl:value-of select="xtbl:convertLength($table.width)"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:message terminate="yes">
+                  <xsl:text>Don't know how to do convert lengths with </xsl:text>
+                  <xsl:value-of select="$vendor"/>
+                </xsl:message>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$table.width"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+    </xsl:if>
+
+    <xsl:choose>
+      <xsl:when test="$use.extensions != 0
+                      and $tablecolumns.extension != 0">
+        <xsl:choose>
+          <xsl:when test="contains($vendor, 'SAXON 6')">
+            <xsl:copy-of select="stbl:adjustColumnWidths($colgroup)"/>
+          </xsl:when>
+          <xsl:when test="contains($vendor, 'SAXON 5')">
+            <!-- the saxon5 extension doesn't support this (yet) -->
+            <xsl:copy-of select="$colgroup"/>
+          </xsl:when>
+          <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+            <xsl:copy-of select="xtbl:adjustColumnWidths($colgroup)"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:message terminate="yes">
+              <xsl:text>Don't know how to do adjust column widths with </xsl:text>
+              <xsl:value-of select="$vendor"/>
+            </xsl:message>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:copy-of select="$colgroup"/>
+      </xsl:otherwise>
+    </xsl:choose>
+
+    <xsl:apply-templates/>
+
+    <xsl:if test=".//footnote">
+      <tr>
+        <td colspan="{@cols}">
+          <xsl:apply-templates select=".//footnote" 
+                               mode="table.footnote.mode"/>
+        </td>
+      </tr>
+    </xsl:if>
+  </table>
+</xsl:template>
+
+<xsl:template match="tgroup/processing-instruction('dbhtml')">
+  <xsl:variable name="summary">
+    <xsl:call-template name="dbhtml-attribute">
+      <xsl:with-param name="pis" select="."/>
+      <xsl:with-param name="attribute" select="'table-summary'"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <!-- Suppress the table-summary PI -->
+  <xsl:if test="$summary = ''">
+    <xsl:processing-instruction name="dbhtml">
+      <xsl:value-of select="."/>
+    </xsl:processing-instruction>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="colspec"></xsl:template>
+
+<xsl:template match="spanspec"></xsl:template>
+
+<xsl:template match="thead|tfoot">
+  <xsl:element name="{name(.)}">
+    <xsl:if test="@align">
+      <xsl:attribute name="align">
+        <xsl:value-of select="@align"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@char">
+      <xsl:attribute name="char">
+        <xsl:value-of select="@char"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@charoff">
+      <xsl:attribute name="charoff">
+        <xsl:value-of select="@charoff"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@valign">
+      <xsl:attribute name="valign">
+        <xsl:value-of select="@valign"/>
+      </xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates/>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="tbody">
+  <tbody>
+    <xsl:if test="@align">
+      <xsl:attribute name="align">
+        <xsl:value-of select="@align"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@char">
+      <xsl:attribute name="char">
+        <xsl:value-of select="@char"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@charoff">
+      <xsl:attribute name="charoff">
+        <xsl:value-of select="@charoff"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@valign">
+      <xsl:attribute name="valign">
+        <xsl:value-of select="@valign"/>
+      </xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates/>
+  </tbody>
+</xsl:template>
+
+<xsl:template match="row">
+  <tr>
+    <xsl:if test="@align">
+      <xsl:attribute name="align">
+        <xsl:value-of select="@align"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@char">
+      <xsl:attribute name="char">
+        <xsl:value-of select="@char"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@charoff">
+      <xsl:attribute name="charoff">
+        <xsl:value-of select="@charoff"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@valign">
+      <xsl:attribute name="valign">
+        <xsl:value-of select="@valign"/>
+      </xsl:attribute>
+    </xsl:if>
+
+    <xsl:apply-templates/>
+  </tr>
+</xsl:template>
+
+<xsl:template match="thead/row/entry">
+  <xsl:call-template name="process.cell">
+    <xsl:with-param name="cellgi">th</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="tbody/row/entry">
+  <xsl:call-template name="process.cell">
+    <xsl:with-param name="cellgi">td</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="tfoot/row/entry">
+  <xsl:call-template name="process.cell">
+    <xsl:with-param name="cellgi">th</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="process.cell">
+  <xsl:param name="cellgi">td</xsl:param>
+  <xsl:variable name="empty.cell" select="count(node()) = 0"/>
+
+  <xsl:variable name="entry.colnum">
+    <xsl:call-template name="entry.colnum"/>
+  </xsl:variable>
+
+  <xsl:if test="$entry.colnum != ''">
+    <xsl:variable name="prev.entry" select="preceding-sibling::*[1]"/>
+    <xsl:variable name="prev.ending.colnum">
+      <xsl:choose>
+        <xsl:when test="$prev.entry">
+          <xsl:call-template name="entry.ending.colnum">
+            <xsl:with-param name="entry" select="$prev.entry"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>0</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <!-- 1.31: removed add-empty-entries; there's no practical way for
+         XSLT to keep track of "overhang" from morerows in previous rows.
+         At least none that I can think of. -->
+  </xsl:if>
+
+  <xsl:element name="{$cellgi}">
+    <xsl:if test="@morerows">
+      <xsl:attribute name="rowspan">
+        <xsl:value-of select="@morerows+1"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@namest">
+      <xsl:attribute name="colspan">
+        <xsl:call-template name="calculate.colspan"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@align">
+      <xsl:attribute name="align">
+        <xsl:value-of select="@align"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@char">
+      <xsl:attribute name="char">
+        <xsl:value-of select="@char"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@charoff">
+      <xsl:attribute name="charoff">
+        <xsl:value-of select="@charoff"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:if test="@valign">
+      <xsl:attribute name="valign">
+        <xsl:value-of select="@valign"/>
+      </xsl:attribute>
+    </xsl:if>
+
+    <xsl:if test="not(preceding-sibling::*)
+                  and ancestor::row/@id">
+      <a name="{ancestor::row/@id}"/>
+    </xsl:if>
+
+    <xsl:if test="@id">
+      <a name="{@id}"/>
+    </xsl:if>
+
+    <xsl:choose>
+      <xsl:when test="$empty.cell">
+        <xsl:text>&#160;</xsl:text>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template name="entry.colnum">
+  <xsl:param name="entry" select="."/>
+
+  <xsl:choose>
+    <xsl:when test="$entry/@colname">
+      <xsl:variable name="colname" select="$entry/@colname"/>
+      <xsl:variable name="colspec"
+                    select="$entry/ancestor::tgroup/colspec[@colname=$colname]"/>
+      <xsl:call-template name="colspec.colnum">
+        <xsl:with-param name="colspec" select="$colspec"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$entry/@namest">
+      <xsl:variable name="namest" select="$entry/@namest"/>
+      <xsl:variable name="colspec"
+                    select="$entry/ancestor::tgroup/colspec[@colname=$namest]"/>
+      <xsl:call-template name="colspec.colnum">
+        <xsl:with-param name="colspec" select="$colspec"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="count($entry/preceding-sibling::*) = 0">1</xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="pcol">
+        <xsl:call-template name="entry.ending.colnum">
+          <xsl:with-param name="entry"
+                          select="$entry/preceding-sibling::*[1]"/>
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:value-of select="$pcol + 1"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<doc:template name="entry.colnum" xmlns="">
+<refpurpose>Determine the column number in which a given entry occurs</refpurpose>
+<refdescription>
+<para>If an <sgmltag>entry</sgmltag> has a
+<sgmltag class="attribute">colname</sgmltag> or
+<sgmltag class="attribute">namest</sgmltag> attribute, this template
+will determine the number of the column in which the entry should occur.
+For other <sgmltag>entry</sgmltag>s, nothing is returned.</para>
+</refdescription>
+<refparameter>
+<variablelist>
+<varlistentry><term>entry</term>
+<listitem>
+<para>The <sgmltag>entry</sgmltag>-element which is to be tested.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</refparameter>
+
+<refreturn>
+<para>This template returns the column number if it can be determined,
+or nothing (the empty string)</para>
+</refreturn>
+</doc:template>
+
+<xsl:template name="entry.ending.colnum">
+  <xsl:param name="entry" select="."/>
+
+  <xsl:choose>
+    <xsl:when test="$entry/@colname">
+      <xsl:variable name="colname" select="$entry/@colname"/>
+      <xsl:variable name="colspec"
+                    select="$entry/ancestor::tgroup/colspec[@colname=$colname]"/>
+      <xsl:call-template name="colspec.colnum">
+        <xsl:with-param name="colspec" select="$colspec"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$entry/@nameend">
+      <xsl:variable name="nameend" select="$entry/@nameend"/>
+      <xsl:variable name="colspec"
+                    select="$entry/ancestor::tgroup/colspec[@colname=$nameend]"/>
+      <xsl:call-template name="colspec.colnum">
+        <xsl:with-param name="colspec" select="$colspec"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="count($entry/preceding-sibling::*) = 0">1</xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="pcol">
+        <xsl:call-template name="entry.ending.colnum">
+          <xsl:with-param name="entry"
+                          select="$entry/preceding-sibling::*[1]"/>
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:value-of select="$pcol + 1"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="colspec.colnum">
+  <xsl:param name="colspec" select="."/>
+  <xsl:choose>
+    <xsl:when test="$colspec/@colnum">
+      <xsl:value-of select="$colspec/@colnum"/>
+    </xsl:when>
+    <xsl:when test="$colspec/preceding-sibling::colspec">
+      <xsl:variable name="prec.colspec.colnum">
+        <xsl:call-template name="colspec.colnum">
+          <xsl:with-param name="colspec"
+                          select="$colspec/preceding-sibling::colspec[1]"/>
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:value-of select="$prec.colspec.colnum + 1"/>
+    </xsl:when>
+    <xsl:otherwise>1</xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="generate.colgroup">
+  <xsl:param name="cols" select="1"/>
+  <xsl:param name="count" select="1"/>
+  <xsl:choose>
+    <xsl:when test="$count>$cols"></xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="generate.col">
+        <xsl:with-param name="countcol" select="$count"/>
+      </xsl:call-template>
+      <xsl:call-template name="generate.colgroup">
+        <xsl:with-param name="cols" select="$cols"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="generate.col">
+  <xsl:param name="countcol">1</xsl:param>
+  <xsl:param name="colspecs" select="./colspec"/>
+  <xsl:param name="count">1</xsl:param>
+  <xsl:param name="colnum">1</xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="$count>count($colspecs)">
+      <col/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
+      <xsl:variable name="colspec.colnum">
+        <xsl:choose>
+          <xsl:when test="$colspec/@colnum">
+            <xsl:value-of select="$colspec/@colnum"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$colnum"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:choose>
+        <xsl:when test="$colspec.colnum=$countcol">
+          <col>
+            <xsl:if test="$colspec/@colwidth
+                          and $use.extensions != 0
+                          and $tablecolumns.extension != 0">
+              <xsl:attribute name="width">
+                <xsl:value-of select="$colspec/@colwidth"/>
+              </xsl:attribute>
+            </xsl:if>
+            <xsl:if test="$colspec/@align">
+              <xsl:attribute name="align">
+                <xsl:value-of select="$colspec/@align"/>
+              </xsl:attribute>
+            </xsl:if>
+            <xsl:if test="$colspec/@char">
+              <xsl:attribute name="char">
+                <xsl:value-of select="$colspec/@char"/>
+              </xsl:attribute>
+            </xsl:if>
+            <xsl:if test="$colspec/@charoff">
+              <xsl:attribute name="charoff">
+                <xsl:value-of select="$colspec/@charoff"/>
+              </xsl:attribute>
+            </xsl:if>
+          </col>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="generate.col">
+            <xsl:with-param name="countcol" select="$countcol"/>
+            <xsl:with-param name="colspecs" select="$colspecs"/>
+            <xsl:with-param name="count" select="$count+1"/>
+            <xsl:with-param name="colnum">
+              <xsl:choose>
+                <xsl:when test="$colspec/@colnum">
+                  <xsl:value-of select="$colspec/@colnum + 1"/>
+                </xsl:when>
+                <xsl:otherwise>
+                  <xsl:value-of select="$colnum + 1"/>
+                </xsl:otherwise>
+              </xsl:choose>
+            </xsl:with-param>
+           </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+
+</xsl:template>
+
+<xsl:template name="colspec.colwidth">
+  <!-- when this macro is called, the current context must be an entry -->
+  <xsl:param name="colname"></xsl:param>
+  <!-- .. = row, ../.. = thead|tbody, ../../.. = tgroup -->
+  <xsl:param name="colspecs" select="../../../../tgroup/colspec"/>
+  <xsl:param name="count">1</xsl:param>
+  <xsl:choose>
+    <xsl:when test="$count>count($colspecs)"></xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
+      <xsl:choose>
+        <xsl:when test="$colspec/@colname=$colname">
+          <xsl:value-of select="$colspec/@colwidth"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="colspec.colwidth">
+            <xsl:with-param name="colname" select="$colname"/>
+            <xsl:with-param name="colspecs" select="$colspecs"/>
+            <xsl:with-param name="count" select="$count+1"/>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="calculate.colspan">
+  <xsl:param name="entry" select="."/>
+  <xsl:variable name="namest" select="$entry/@namest"/>
+  <xsl:variable name="nameend" select="$entry/@nameend"/>
+
+  <xsl:variable name="scol">
+    <xsl:call-template name="colspec.colnum">
+      <xsl:with-param name="colspec"
+                      select="$entry/ancestor::tgroup/colspec[@colname=$namest]"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="ecol">
+    <xsl:call-template name="colspec.colnum">
+      <xsl:with-param name="colspec"
+                      select="$entry/ancestor::tgroup/colspec[@colname=$nameend]"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:value-of select="$ecol - $scol + 1"/>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/xsl/html/titlepage.templates.xml b/xsl/html/titlepage.templates.xml
new file mode 100644 (file)
index 0000000..30a0b6f
--- /dev/null
@@ -0,0 +1,593 @@
+<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
+            xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param"
+             xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="article" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <hr/>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="set" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <hr/>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="book" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <hr/>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="part" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="partintro" wrapper="div">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="reference" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <hr/>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+  <t:titlepage element="dedication" wrapper="div" class="titlepage">
+    <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          force="1"
+          named-template="component.title"
+          param:node="ancestor-or-self::dedication[1]"/>
+    <subtitle predicate="[1]"/>
+    </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="preface" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="chapter" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="appendix" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="section" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <xsl:if test="count(parent::*)='0'"><hr/></xsl:if>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect1" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <xsl:if test="count(parent::*)='0'"><hr/></xsl:if>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect2" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <xsl:if test="count(parent::*)='0'"><hr/></xsl:if>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect3" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <xsl:if test="count(parent::*)='0'"><hr/></xsl:if>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect4" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <xsl:if test="count(parent::*)='0'"><hr/></xsl:if>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="sect5" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <xsl:if test="count(parent::*)='0'"><hr/></xsl:if>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<t:titlepage element="simplesect" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+    <corpauthor/>
+    <authorgroup/>
+    <author/>
+    <releaseinfo/>
+    <copyright/>
+    <legalnotice/>
+    <pubdate/>
+    <revision/>
+    <revhistory/>
+    <abstract/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+    <xsl:if test="count(parent::*)='0'"><hr/></xsl:if>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="bibliography" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          force="1"
+          named-template="component.title"
+          param:node="ancestor-or-self::bibliography[1]"/>
+    <subtitle predicate="[1]"/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="glossary" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"/>
+    <subtitle predicate="[1]"/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+<t:titlepage element="index" wrapper="div" class="titlepage">
+  <t:titlepage-content side="recto">
+    <title predicate="[1]"
+          force="1"
+          named-template="component.title"
+          param:node="ancestor-or-self::index[1]"/>
+    <subtitle predicate="[1]"/>
+  </t:titlepage-content>
+
+  <t:titlepage-content side="verso">
+  </t:titlepage-content>
+
+  <t:titlepage-separator>
+  </t:titlepage-separator>
+
+  <t:titlepage-before side="recto">
+  </t:titlepage-before>
+
+  <t:titlepage-before side="verso">
+  </t:titlepage-before>
+</t:titlepage>
+
+<!-- ==================================================================== -->
+
+</t:templates>
diff --git a/xsl/html/titlepage.xsl b/xsl/html/titlepage.xsl
new file mode 100644 (file)
index 0000000..8395dda
--- /dev/null
@@ -0,0 +1,632 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:attribute-set name="book.titlepage.recto.style"/>
+<xsl:attribute-set name="book.titlepage.verso.style"/>
+
+<xsl:attribute-set name="article.titlepage.recto.style"/>
+<xsl:attribute-set name="article.titlepage.verso.style"/>
+
+<xsl:attribute-set name="set.titlepage.recto.style"/>
+<xsl:attribute-set name="set.titlepage.verso.style"/>
+
+<xsl:attribute-set name="part.titlepage.recto.style"/>
+<xsl:attribute-set name="part.titlepage.verso.style"/>
+
+<xsl:attribute-set name="partintro.titlepage.recto.style"/>
+<xsl:attribute-set name="partintro.titlepage.verso.style"/>
+
+<xsl:attribute-set name="reference.titlepage.recto.style"/>
+<xsl:attribute-set name="reference.titlepage.verso.style"/>
+
+<xsl:attribute-set name="dedication.titlepage.recto.style"/>
+<xsl:attribute-set name="dedication.titlepage.verso.style"/>
+
+<xsl:attribute-set name="preface.titlepage.recto.style"/>
+<xsl:attribute-set name="preface.titlepage.verso.style"/>
+
+<xsl:attribute-set name="chapter.titlepage.recto.style"/>
+<xsl:attribute-set name="chapter.titlepage.verso.style"/>
+
+<xsl:attribute-set name="appendix.titlepage.recto.style"/>
+<xsl:attribute-set name="appendix.titlepage.verso.style"/>
+
+<xsl:attribute-set name="bibliography.titlepage.recto.style"/>
+<xsl:attribute-set name="bibliography.titlepage.verso.style"/>
+
+<xsl:attribute-set name="glossary.titlepage.recto.style"/>
+<xsl:attribute-set name="glossary.titlepage.verso.style"/>
+
+<xsl:attribute-set name="index.titlepage.recto.style"/>
+<xsl:attribute-set name="index.titlepage.verso.style"/>
+
+<xsl:attribute-set name="section.titlepage.recto.style"/>
+<xsl:attribute-set name="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect1.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect1.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect2.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect2.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect3.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect3.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect4.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect4.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="sect5.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="sect5.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="simplesect.titlepage.recto.style"
+                   use-attribute-sets="section.titlepage.recto.style"/>
+<xsl:attribute-set name="simplesect.titlepage.verso.style"
+                   use-attribute-sets="section.titlepage.verso.style"/>
+
+<xsl:attribute-set name="table.of.contents.titlepage.recto.style"/>
+<xsl:attribute-set name="table.of.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.tables.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.tables.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.figures.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.figures.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.equations.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.equations.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.examples.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.examples.contents.titlepage.verso.style"/>
+
+<xsl:attribute-set name="list.of.unknowns.titlepage.recto.style"/>
+<xsl:attribute-set name="list.of.unknowns.contents.titlepage.verso.style"/>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="titlepage.mode">
+  <!-- if an element isn't found in this mode, try the default mode -->
+  <xsl:apply-templates select="."/>
+</xsl:template>
+
+<xsl:template match="abbrev" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="abstract" mode="titlepage.mode">
+  <div class="{name(.)}">
+    <xsl:call-template name="formal.object.heading">
+      <xsl:with-param name="title">
+        <xsl:apply-templates select="." mode="title.markup"/>
+      </xsl:with-param>
+    </xsl:call-template>
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="abstract/title" mode="titlepage.mode">
+</xsl:template>
+
+<xsl:template match="address" mode="titlepage.mode">
+  <xsl:apply-templates select="."/>
+</xsl:template>
+
+<xsl:template match="affiliation" mode="titlepage.mode">
+  <div class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="artpagenums" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="author" mode="titlepage.mode">
+  <h3 class="{name(.)}"><xsl:call-template name="person.name"/></h3>
+  <xsl:apply-templates mode="titlepage.mode" select="./affiliation"/>
+</xsl:template>
+
+<xsl:template match="authorblurb" mode="titlepage.mode">
+  <div class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="authorgroup" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="authorinitials" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="bibliomisc" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="bibliomset" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="collab" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="confgroup" mode="titlepage.mode">
+  <div class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="confdates" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="conftitle" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="confnum" mode="titlepage.mode">
+  <!-- suppress -->
+</xsl:template>
+
+<xsl:template match="contractnum" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="contractsponsor" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="contrib" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="copyright" mode="titlepage.mode">
+  <xsl:variable name="years" select="year"/>
+  <xsl:variable name="holders" select="holder"/>
+
+  <p class="{name(.)}">
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'Copyright'"/>
+    </xsl:call-template>
+    <xsl:call-template name="gentext.space"/>
+    <xsl:call-template name="dingbat">
+      <xsl:with-param name="dingbat">copyright</xsl:with-param>
+    </xsl:call-template>
+    <xsl:call-template name="gentext.space"/>
+    <xsl:apply-templates select="$years" mode="titlepage.mode"/>
+    <xsl:call-template name="gentext.space"/>
+<!--
+    <xsl:call-template name="gentext.by"/>
+    <xsl:call-template name="gentext.space"/>
+-->
+    <xsl:apply-templates select="$holders" mode="titlepage.mode"/>
+  </p>
+</xsl:template>
+
+<xsl:template match="year" mode="titlepage.mode">
+  <xsl:apply-templates/><xsl:text>, </xsl:text>
+</xsl:template>
+
+<xsl:template match="year[position()=last()]" mode="titlepage.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="holder" mode="titlepage.mode">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="corpauthor" mode="titlepage.mode">
+  <h3 class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </h3>
+</xsl:template>
+
+<xsl:template match="corpname" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="date" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="edition" mode="titlepage.mode">
+  <p class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <xsl:call-template name="gentext.space"/>
+    <xsl:call-template name="gentext">
+      <xsl:with-param name="key" select="'Edition'"/>
+    </xsl:call-template>
+  </p>
+</xsl:template>
+
+<xsl:template match="editor" mode="titlepage.mode">
+  <h3 class="{name(.)}"><xsl:call-template name="person.name"/></h3>
+</xsl:template>
+
+<xsl:template match="editor[position()=1]" mode="titlepage.mode">
+  <h4 class="editedby"><xsl:call-template name="gentext.edited.by"/></h4>
+  <h3 class="{name(.)}"><xsl:call-template name="person.name"/></h3>
+</xsl:template>
+
+<xsl:template match="firstname" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="graphic" mode="titlepage.mode">
+  <!-- use the normal graphic handling code -->
+  <xsl:apply-templates select="."/>
+</xsl:template>
+
+<xsl:template match="honorific" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="isbn" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="issn" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="itermset" mode="titlepage.mode">
+</xsl:template>
+
+<xsl:template match="invpartnumber" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="issuenum" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="jobtitle" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="keywordset" mode="titlepage.mode">
+</xsl:template>
+
+<xsl:template match="legalnotice " mode="titlepage.mode">
+  <div class="{local-name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="legalnotice/title" mode="titlepage.mode">
+  <p class="legalnotice-title"><b><xsl:apply-templates/></b></p>
+</xsl:template>
+
+<xsl:template match="lineage" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="modespec" mode="titlepage.mode">
+</xsl:template>
+
+<xsl:template match="orgdiv" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="orgname" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="othercredit" mode="titlepage.mode">
+  <h3 class="{name(.)}"><xsl:call-template name="person.name"/></h3>
+  <xsl:apply-templates mode="titlepage.mode"
+   select="./affiliation"/>
+</xsl:template>
+
+<xsl:template match="othername" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pagenums" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="printhistory" mode="titlepage.mode">
+  <div class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </div>
+</xsl:template>
+
+<xsl:template match="productname" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="productnumber" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pubdate" mode="titlepage.mode">
+  <p class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </p>
+</xsl:template>
+
+<xsl:template match="publishername" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="pubsnumber" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="releaseinfo" mode="titlepage.mode">
+  <p class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </p>
+</xsl:template>
+
+<xsl:template match="revhistory" mode="titlepage.mode">
+  <xsl:variable name="numcols">
+    <xsl:choose>
+      <xsl:when test="//authorinitials">3</xsl:when>
+      <xsl:otherwise>2</xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <div class="{name(.)}">
+    <table border="1" width="100%" summary="Revision history">
+      <tr>
+        <th align="left" valign="top" colspan="{$numcols}">
+          <b>
+            <xsl:call-template name="gentext">
+              <xsl:with-param name="key" select="'RevHistory'"/>
+            </xsl:call-template>
+          </b>
+        </th>
+      </tr>
+      <xsl:apply-templates mode="titlepage.mode">
+        <xsl:with-param name="numcols" select="$numcols"/>
+      </xsl:apply-templates>
+    </table>
+  </div>
+</xsl:template>
+
+<xsl:template match="revhistory/revision" mode="titlepage.mode">
+  <xsl:param name="numcols" select="'3'"/>
+  <xsl:variable name="revnumber" select=".//revnumber"/>
+  <xsl:variable name="revdate"   select=".//date"/>
+  <xsl:variable name="revauthor" select=".//authorinitials"/>
+  <xsl:variable name="revremark" select=".//revremark|.//revdescription"/>
+  <tr>
+    <td align="left">
+      <xsl:if test="$revnumber">
+        <xsl:call-template name="gentext">
+          <xsl:with-param name="key" select="'Revision'"/>
+        </xsl:call-template>
+        <xsl:call-template name="gentext.space"/>
+        <xsl:apply-templates select="$revnumber[1]" mode="titlepage.mode"/>
+      </xsl:if>
+    </td>
+    <td align="left">
+      <xsl:apply-templates select="$revdate[1]" mode="titlepage.mode"/>
+    </td>
+    <xsl:choose>
+      <xsl:when test="$revauthor">
+        <td align="left">
+          <xsl:apply-templates select="$revauthor[1]" mode="titlepage.mode"/>
+        </td>
+      </xsl:when>
+      <xsl:when test="$numcols &gt; 2">
+        <td>&#160;</td>
+      </xsl:when>
+      <xsl:otherwise></xsl:otherwise>
+    </xsl:choose>
+  </tr>
+  <xsl:if test="$revremark">
+    <tr>
+      <td align="left" colspan="{$numcols}">
+        <xsl:apply-templates select="$revremark[1]" mode="titlepage.mode"/>
+      </td>
+    </tr>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="revision/revnumber" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="revision/date" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="revision/authorinitials" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="revision/revremark" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="revision/revdescription" mode="titlepage.mode">
+  <xsl:apply-templates mode="titlepage.mode"/>
+</xsl:template>
+
+<xsl:template match="seriesvolnums" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="shortaffil" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="subjectset" mode="titlepage.mode">
+</xsl:template>
+
+<xsl:template match="subtitle" mode="titlepage.mode">
+  <h2 class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+  </h2>
+</xsl:template>
+
+<xsl:template match="surname" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<xsl:template match="title" mode="titlepage.mode">
+  <xsl:variable name="id">
+    <xsl:choose>
+      <!-- if title is in an *info wrapper, get the grandparent -->
+      <xsl:when test="contains(local-name(..), 'info')">
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select="../.."/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="object.id">
+          <xsl:with-param name="object" select=".."/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <h1 class="{name(.)}">
+    <a name="{$id}"/>
+    <xsl:choose>
+      <xsl:when test="$show.revisionflag and @revisionflag">
+       <span class="{@revisionflag}">
+         <xsl:apply-templates mode="titlepage.mode"/>
+       </span>
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:apply-templates mode="titlepage.mode"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </h1>
+</xsl:template>
+
+<xsl:template match="titleabbrev" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+  
+<xsl:template match="volumenum" mode="titlepage.mode">
+  <span class="{name(.)}">
+    <xsl:apply-templates mode="titlepage.mode"/>
+    <br/>
+  </span>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
diff --git a/xsl/html/toc.xsl b/xsl/html/toc.xsl
new file mode 100644 (file)
index 0000000..55d4716
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="toc">
+</xsl:template>
+
+<xsl:template match="tocpart|tocchap|tocfront|tocback|tocentry">
+</xsl:template>
+
+<xsl:template match="toclevel1|toclevel2|toclevel3|toclevel4|toclevel5">
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="lot|lotentry">
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/verbatim.xsl b/xsl/html/verbatim.xsl
new file mode 100644 (file)
index 0000000..d958d91
--- /dev/null
@@ -0,0 +1,298 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:sverb="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Verbatim"
+                xmlns:xverb="com.nwalsh.xalan.Verbatim"
+                xmlns:lxslt="http://xml.apache.org/xslt"
+                exclude-result-prefixes="sverb xverb lxslt"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<lxslt:component prefix="xverb"
+                 functions="numberLines"/>
+
+<xsl:template match="programlisting|screen|synopsis">
+  <xsl:param name="suppress-numbers" select="'0'"/>
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+  <xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
+
+  <!-- Obey the <?dbhtml linenumbering.everyNth="x"?> PI -->
+  <xsl:variable name="pi.linenumbering.everyNth">
+    <xsl:call-template name="dbhtml-attribute">
+      <xsl:with-param name="attribute" select="'everyNth'"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:variable name="everyNth">
+    <xsl:choose>
+      <xsl:when test="$pi.linenumbering.everyNth != ''">
+        <xsl:value-of select="$pi.linenumbering.everyNth"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$linenumbering.everyNth"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!-- Obey the <?dbhtml linenumbering.separator="x"?> PI -->
+  <xsl:variable name="pi.linenumbering.separator">
+    <xsl:call-template name="dbhtml-attribute">
+      <xsl:with-param name="attribute" select="'linenumbering.separator'"/>
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:variable name="separator">
+    <xsl:choose>
+      <xsl:when test="$pi.linenumbering.separator != ''">
+        <xsl:value-of select="$pi.linenumbering.separator"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$linenumbering.separator"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:if test="@id">
+    <a href="{$id}"/>
+  </xsl:if>
+
+  <xsl:choose>
+    <xsl:when test="$suppress-numbers = '0'
+                    and @linenumbering = 'numbered'
+                    and $use.extensions != '0'
+                    and $linenumbering.extension != '0'">
+      <xsl:variable name="rtf">
+        <xsl:apply-templates/>
+      </xsl:variable>
+      <pre class="{name(.)}">
+        <xsl:call-template name="number.rtf.lines">
+          <xsl:with-param name="rtf" select="$rtf"/>
+          <xsl:with-param name="linenumbering.everyNth"
+                          select="$everyNth"/>
+          <xsl:with-param name="linenumbering.width"
+                          select="$linenumbering.width"/>
+          <xsl:with-param name="linenumbering.separator"
+                          select="$separator"/>
+        </xsl:call-template>
+      </pre>
+    </xsl:when>
+
+    <xsl:otherwise>
+      <pre class="{name(.)}">
+        <xsl:apply-templates/>
+      </pre>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="literallayout">
+  <xsl:param name="suppress-numbers" select="'0'"/>
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:variable name="rtf">
+    <xsl:apply-templates/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$suppress-numbers = '0'
+                    and @linenumbering = 'numbered'
+                    and $use.extensions != '0'
+                    and $linenumbering.extension != '0'">
+      <xsl:choose>
+        <xsl:when test="@class='monospaced'">
+          <pre class="{name(.)}">
+            <xsl:call-template name="number.rtf.lines">
+              <xsl:with-param name="rtf" select="$rtf"/>
+              <xsl:with-param name="linenumbering.everyNth"
+                              select="$linenumbering.everyNth"/>
+              <xsl:with-param name="linenumbering.width"
+                              select="$linenumbering.width"/>
+              <xsl:with-param name="linenumbering.separator"
+                              select="$linenumbering.separator"/>
+            </xsl:call-template>
+          </pre>
+        </xsl:when>
+        <xsl:otherwise>
+          <div class="{name(.)}">
+            <xsl:call-template name="number.rtf.lines">
+              <xsl:with-param name="rtf" select="$rtf"/>
+              <xsl:with-param name="linenumbering.everyNth"
+                              select="$linenumbering.everyNth"/>
+              <xsl:with-param name="linenumbering.width"
+                              select="$linenumbering.width"/>
+              <xsl:with-param name="linenumbering.separator"
+                              select="$linenumbering.separator"/>
+            </xsl:call-template>
+          </div>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+
+    <xsl:otherwise>
+      <xsl:choose>
+        <xsl:when test="@class='monospaced'">
+          <pre class="{name(.)}">
+            <xsl:copy-of select="$rtf"/>
+          </pre>
+        </xsl:when>
+        <xsl:otherwise>
+          <div class="{name(.)}">
+            <xsl:copy-of select="$rtf"/>
+          </div>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="literallayout[not(@class)
+                                   or @class != 'monospaced']//text()">
+  <xsl:call-template name="make-verbatim">
+    <xsl:with-param name="text" select="."/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="address">
+  <xsl:param name="suppress-numbers" select="'0'"/>
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:variable name="rtf">
+    <xsl:apply-templates/>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$suppress-numbers = '0'
+                    and @linenumbering = 'numbered'
+                    and $use.extensions != '0'
+                    and $linenumbering.extension != '0'">
+      <div class="{name(.)}">
+        <xsl:call-template name="number.rtf.lines">
+          <xsl:with-param name="rtf" select="$rtf"/>
+          <xsl:with-param name="linenumbering.everyNth"
+                          select="$linenumbering.everyNth"/>
+          <xsl:with-param name="linenumbering.width"
+                          select="$linenumbering.width"/>
+          <xsl:with-param name="linenumbering.separator"
+                          select="$linenumbering.separator"/>
+        </xsl:call-template>
+      </div>
+    </xsl:when>
+
+    <xsl:otherwise>
+      <div class="{name(.)}">
+        <xsl:apply-templates/>
+      </div>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="number.rtf.lines">
+  <xsl:param name="rtf" select="''"/>
+  <!-- the following parameters must have these names ... -->
+  <xsl:param name="linenumbering.everyNth" select="1"/>
+  <xsl:param name="linenumbering.width" select="3"/>
+  <xsl:param name="linenumbering.separator" select="' |'"/>
+
+  <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
+
+  <xsl:choose>
+    <xsl:when test="contains($vendor, 'SAXON ')">
+      <xsl:copy-of select="sverb:numberLines($rtf)"/>
+    </xsl:when>
+    <xsl:when test="contains($vendor, 'Apache Software Foundation')">
+      <xsl:copy-of select="xverb:numberLines($rtf)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message terminate="yes">
+        <xsl:text>Don't know how to do line numbering with </xsl:text>
+        <xsl:value-of select="$vendor"/>
+      </xsl:message>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="address//text()">
+  <xsl:call-template name="make-verbatim">
+    <xsl:with-param name="text" select="."/>
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="make-verbatim">
+  <xsl:param name="text" select="''"/>
+
+  <xsl:variable name="starts-with-space"
+                select="substring($text, 1, 1) = ' '"/>
+
+  <xsl:variable name="starts-with-nl"
+                select="substring($text, 1, 1) = '&#xA;'"/>
+
+  <xsl:variable name="before-space">
+    <xsl:if test="contains($text, ' ')">
+      <xsl:value-of select="substring-before($text, ' ')"/>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:variable name="before-nl">
+    <xsl:if test="contains($text, '&#xA;')">
+      <xsl:value-of select="substring-before($text, '&#xA;')"/>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:choose>
+    <xsl:when test="$starts-with-space">
+      <xsl:text>&#160;</xsl:text>
+      <xsl:call-template name="make-verbatim">
+        <xsl:with-param name="text" select="substring($text,2)"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <xsl:when test="$starts-with-nl">
+      <br/><xsl:text>&#xA;</xsl:text>
+      <xsl:call-template name="make-verbatim">
+        <xsl:with-param name="text" select="substring($text,2)"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- if the string before a space is shorter than the string before
+         a newline, fix the space...-->
+    <xsl:when test="$before-space != ''
+                    and ((string-length($before-space)
+                          &lt; string-length($before-nl))
+                          or $before-nl = '')">
+      <xsl:value-of select="$before-space"/>
+      <xsl:text>&#160;</xsl:text>
+      <xsl:call-template name="make-verbatim">
+        <xsl:with-param name="text" select="substring-after($text, ' ')"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- if the string before a newline is shorter than the string before
+         a space, fix the newline...-->
+    <xsl:when test="$before-nl != ''
+                    and ((string-length($before-nl)
+                          &lt; string-length($before-space))
+                          or $before-space = '')">
+      <xsl:value-of select="$before-nl"/>
+      <br/><xsl:text>&#xA;</xsl:text>
+      <xsl:call-template name="make-verbatim">
+        <xsl:with-param name="text" select="substring-after($text, '&#xA;')"/>
+      </xsl:call-template>
+    </xsl:when>
+
+    <!-- the string before the newline and the string before the
+         space are the same; which means they must both be empty -->
+    <xsl:otherwise>
+      <xsl:value-of select="$text"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/xref.xsl b/xsl/html/xref.xsl
new file mode 100644 (file)
index 0000000..2de5dca
--- /dev/null
@@ -0,0 +1,328 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<!-- ==================================================================== -->
+
+<xsl:template match="anchor">
+  <a>
+    <xsl:attribute name="name">
+      <xsl:call-template name="object.id"/>
+    </xsl:attribute>
+  </a>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="xref">
+  <xsl:variable name="targets" select="id(@linkend)"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+  <xsl:variable name="refelem" select="local-name($target)"/>
+
+  <xsl:call-template name="check.id.unique">
+    <xsl:with-param name="linkend" select="@linkend"/>
+  </xsl:call-template>
+
+  <xsl:if test="@id">
+    <a name="{@id}"/>
+  </xsl:if>
+
+  <xsl:choose>
+    <xsl:when test="$refelem=''">
+      <xsl:message>
+       <xsl:text>XRef to nonexistent id: </xsl:text>
+       <xsl:value-of select="@linkend"/>
+      </xsl:message>
+      <xsl:text>???</xsl:text>
+    </xsl:when>
+
+    <xsl:when test="$target/@xreflabel">
+      <a>
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="$target"/>
+          </xsl:call-template>
+        </xsl:attribute>
+        <xsl:call-template name="xref.xreflabel">
+          <xsl:with-param name="target" select="$target"/>
+        </xsl:call-template>
+      </a>
+    </xsl:when>
+
+    <xsl:otherwise>
+      <a>
+        <xsl:attribute name="href">
+          <xsl:call-template name="href.target">
+            <xsl:with-param name="object" select="$target"/>
+          </xsl:call-template>
+        </xsl:attribute>
+
+        <xsl:choose>
+         <xsl:when test="@endterm">
+           <xsl:variable name="etargets" select="id(@endterm)"/>
+           <xsl:variable name="etarget" select="$etargets[1]"/>
+           <xsl:choose>
+             <xsl:when test="count($etarget) = 0">
+               <xsl:message>
+                 <xsl:value-of select="count($etargets)"/>
+                 <xsl:text>Endterm points to nonexistent ID: </xsl:text>
+                 <xsl:value-of select="@endterm"/>
+               </xsl:message>
+               <xsl:text>???</xsl:text>
+             </xsl:when>
+             <xsl:otherwise>
+               <xsl:apply-templates select="$etarget" mode="xref.text"/>
+             </xsl:otherwise>
+           </xsl:choose>
+         </xsl:when>
+
+          <xsl:otherwise>
+            <xsl:apply-templates select="$target" mode="xref-to"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </a>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="*" mode="xref-to">
+  <xsl:param name="target" select="."/>
+  <xsl:param name="refelem" select="local-name($target)"/>
+
+  <xsl:message>
+    <xsl:text>Don't know what gentext to create for xref to: "</xsl:text>
+    <xsl:value-of select="$refelem"/>
+    <xsl:text>"</xsl:text>
+  </xsl:message>
+  <xsl:text>???</xsl:text>
+</xsl:template>
+
+<xsl:template match="author" mode="xref-to">
+  <xsl:param name="target" select="."/>
+  <xsl:param name="refelem" select="local-name($target)"/>
+
+  <xsl:call-template name="person.name"/>
+</xsl:template>
+
+<xsl:template match="figure" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="example" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="table" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="equation" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="cmdsynopsis" mode="xref-to">
+  <xsl:apply-templates select="(.//command)[1]" mode="xref"/>
+</xsl:template>
+
+<xsl:template match="funcsynopsis" mode="xref-to">
+  <xsl:apply-templates select="(.//function)[1]" mode="xref"/>
+</xsl:template>
+
+<xsl:template match="dedication" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="preface" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="chapter" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="appendix" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="bibliography" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="biblioentry|bibliomixed" mode="xref-to">
+  <!-- handles both biblioentry and bibliomixed -->
+  <xsl:text>[</xsl:text>
+  <xsl:choose>
+    <xsl:when test="local-name(*[1]) = 'abbrev'">
+      <xsl:apply-templates select="*[1]"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="@id"/>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:text>]</xsl:text>
+</xsl:template>
+
+<xsl:template match="glossary" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="index" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="section|simplesect
+                     |sect1|sect2|sect3|sect4|sect5
+                     |refsect1|refsect2|refsect3" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+  <!-- What about "in Chapter X"? -->
+</xsl:template>
+
+<xsl:template match="question" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="answer" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="part" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="reference" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<xsl:template match="co" mode="xref-to">
+  <xsl:apply-templates select="." mode="callout-bug"/>
+</xsl:template>
+
+<xsl:template match="book" mode="xref-to">
+  <xsl:apply-templates select="." mode="object.xref.markup"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="link">
+  <xsl:variable name="targets" select="id(@linkend)"/>
+  <xsl:variable name="target" select="$targets[1]"/>
+
+  <xsl:call-template name="check.id.unique">
+    <xsl:with-param name="linkend" select="@linkend"/>
+  </xsl:call-template>
+
+  <a>
+    <xsl:if test="@id">
+      <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
+    </xsl:if>
+
+    <xsl:attribute name="href">
+      <xsl:call-template name="href.target">
+        <xsl:with-param name="object" select="$target"/>
+      </xsl:call-template>
+    </xsl:attribute>
+
+    <xsl:apply-templates/>
+  </a>
+</xsl:template>
+
+<xsl:template match="ulink">
+  <a>
+    <xsl:if test="@id">
+      <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
+    </xsl:if>
+    <xsl:attribute name="href"><xsl:value-of select="@url"/></xsl:attribute>
+    <xsl:if test="$ulink.target != ''">
+      <xsl:attribute name="target">
+        <xsl:value-of select="$ulink.target"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:choose>
+      <xsl:when test="count(child::node())=0">
+       <xsl:value-of select="@url"/>
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </a>
+</xsl:template>
+
+<xsl:template match="olink">
+  <xsl:if test="@id">
+    <a name="{@id}"/>
+  </xsl:if>
+  <xsl:apply-templates/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="title.xref">
+  <xsl:param name="target" select="."/>
+  <xsl:choose>
+    <xsl:when test="local-name($target) = 'figure'
+                    or local-name($target) = 'example'
+                    or local-name($target) = 'equation'
+                    or local-name($target) = 'table'
+                    or local-name($target) = 'dedication'
+                    or local-name($target) = 'preface'
+                    or local-name($target) = 'bibliography'
+                    or local-name($target) = 'glossary'
+                    or local-name($target) = 'index'
+                    or local-name($target) = 'setindex'
+                    or local-name($target) = 'colophon'">
+      <xsl:call-template name="gentext.startquote"/>
+      <xsl:apply-templates select="$target" mode="title.markup"/>
+      <xsl:call-template name="gentext.endquote"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <i>
+        <xsl:apply-templates select="$target" mode="title.markup"/>
+      </i>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="number.xref">
+  <xsl:apply-templates select="." mode="label.markup"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="xref.xreflabel">
+  <!-- called to process an xreflabel...you might use this to make  -->
+  <!-- xreflabels come out in the right font for different targets, -->
+  <!-- for example. -->
+  <xsl:param name="target" select="."/>
+  <xsl:value-of select="$target/@xreflabel"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template match="title" mode="xref">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="command" mode="xref">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+<xsl:template match="function" mode="xref">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/html/xtchunk.xsl b/xsl/html/xtchunk.xsl
new file mode 100644 (file)
index 0000000..b1db4d2
--- /dev/null
@@ -0,0 +1,9 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xt="http://www.jclark.com/xt"
+                extension-element-prefixes="xt"
+               version="1.0">
+
+<xsl:include href="chunk-common.xsl"/>
+<xsl:include href="xtchunker.xsl"/>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/xsl/html/xtchunker.xsl b/xsl/html/xtchunker.xsl
new file mode 100644 (file)
index 0000000..202e285
--- /dev/null
@@ -0,0 +1,39 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xt="http://www.jclark.com/xt"
+                extension-element-prefixes="xt"
+               version="1.0">
+
+<!-- This stylesheet works with XT; for others use chunker.xsl -->
+
+<!-- ==================================================================== -->
+
+<xsl:template name="make-relative-filename">
+  <xsl:param name="base.dir" select="'./'"/>
+  <xsl:param name="base.name" select="''"/>
+
+  <!-- XT makes chunks relative -->
+  <xsl:choose>
+    <xsl:when test="count(parent::*) = 0">
+      <xsl:value-of select="concat($base.dir,$base.name)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$base.name"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template name="write.chunk">
+  <xsl:param name="filename" select="''"/>
+  <xsl:param name="method" select="'html'"/>
+  <xsl:param name="encoding" select="'ISO-8859-1'"/>
+  <xsl:param name="content" select="''"/>
+
+  <!-- apparently XT doesn't support AVTs for method and encoding -->
+  <xt:document href="{$filename}"
+               method="html"
+               encoding="ISO-8859-1">
+    <xsl:copy-of select="$content"/>
+  </xt:document>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/images/callouts/1.png b/xsl/images/callouts/1.png
new file mode 100644 (file)
index 0000000..7d47343
Binary files /dev/null and b/xsl/images/callouts/1.png differ
diff --git a/xsl/images/callouts/10.png b/xsl/images/callouts/10.png
new file mode 100644 (file)
index 0000000..997bbc8
Binary files /dev/null and b/xsl/images/callouts/10.png differ
diff --git a/xsl/images/callouts/2.png b/xsl/images/callouts/2.png
new file mode 100644 (file)
index 0000000..5d09341
Binary files /dev/null and b/xsl/images/callouts/2.png differ
diff --git a/xsl/images/callouts/3.png b/xsl/images/callouts/3.png
new file mode 100644 (file)
index 0000000..ef7b700
Binary files /dev/null and b/xsl/images/callouts/3.png differ
diff --git a/xsl/images/callouts/4.png b/xsl/images/callouts/4.png
new file mode 100644 (file)
index 0000000..adb8364
Binary files /dev/null and b/xsl/images/callouts/4.png differ
diff --git a/xsl/images/callouts/5.png b/xsl/images/callouts/5.png
new file mode 100644 (file)
index 0000000..4d7eb46
Binary files /dev/null and b/xsl/images/callouts/5.png differ
diff --git a/xsl/images/callouts/6.png b/xsl/images/callouts/6.png
new file mode 100644 (file)
index 0000000..0ba694a
Binary files /dev/null and b/xsl/images/callouts/6.png differ
diff --git a/xsl/images/callouts/7.png b/xsl/images/callouts/7.png
new file mode 100644 (file)
index 0000000..472e96f
Binary files /dev/null and b/xsl/images/callouts/7.png differ
diff --git a/xsl/images/callouts/8.png b/xsl/images/callouts/8.png
new file mode 100644 (file)
index 0000000..5e60973
Binary files /dev/null and b/xsl/images/callouts/8.png differ
diff --git a/xsl/images/callouts/9.png b/xsl/images/callouts/9.png
new file mode 100644 (file)
index 0000000..a0676d2
Binary files /dev/null and b/xsl/images/callouts/9.png differ
diff --git a/xsl/images/caution.gif b/xsl/images/caution.gif
new file mode 100644 (file)
index 0000000..d9f5e5b
Binary files /dev/null and b/xsl/images/caution.gif differ
diff --git a/xsl/images/caution.png b/xsl/images/caution.png
new file mode 100644 (file)
index 0000000..5b7809c
Binary files /dev/null and b/xsl/images/caution.png differ
diff --git a/xsl/images/caution.tif b/xsl/images/caution.tif
new file mode 100644 (file)
index 0000000..4a28294
Binary files /dev/null and b/xsl/images/caution.tif differ
diff --git a/xsl/images/home.png b/xsl/images/home.png
new file mode 100644 (file)
index 0000000..cbb711d
Binary files /dev/null and b/xsl/images/home.png differ
diff --git a/xsl/images/important.gif b/xsl/images/important.gif
new file mode 100644 (file)
index 0000000..6795d9a
Binary files /dev/null and b/xsl/images/important.gif differ
diff --git a/xsl/images/important.png b/xsl/images/important.png
new file mode 100644 (file)
index 0000000..12c90f6
Binary files /dev/null and b/xsl/images/important.png differ
diff --git a/xsl/images/important.tif b/xsl/images/important.tif
new file mode 100644 (file)
index 0000000..184de63
Binary files /dev/null and b/xsl/images/important.tif differ
diff --git a/xsl/images/next.png b/xsl/images/next.png
new file mode 100644 (file)
index 0000000..45835bf
Binary files /dev/null and b/xsl/images/next.png differ
diff --git a/xsl/images/note.gif b/xsl/images/note.gif
new file mode 100644 (file)
index 0000000..f329d35
Binary files /dev/null and b/xsl/images/note.gif differ
diff --git a/xsl/images/note.png b/xsl/images/note.png
new file mode 100644 (file)
index 0000000..d0c3c64
Binary files /dev/null and b/xsl/images/note.png differ
diff --git a/xsl/images/note.tif b/xsl/images/note.tif
new file mode 100644 (file)
index 0000000..08644d6
Binary files /dev/null and b/xsl/images/note.tif differ
diff --git a/xsl/images/prev.png b/xsl/images/prev.png
new file mode 100644 (file)
index 0000000..cf24654
Binary files /dev/null and b/xsl/images/prev.png differ
diff --git a/xsl/images/tip.gif b/xsl/images/tip.gif
new file mode 100644 (file)
index 0000000..823f2b4
Binary files /dev/null and b/xsl/images/tip.gif differ
diff --git a/xsl/images/tip.png b/xsl/images/tip.png
new file mode 100644 (file)
index 0000000..5c4aab3
Binary files /dev/null and b/xsl/images/tip.png differ
diff --git a/xsl/images/tip.tif b/xsl/images/tip.tif
new file mode 100644 (file)
index 0000000..4a3d8c7
Binary files /dev/null and b/xsl/images/tip.tif differ
diff --git a/xsl/images/toc-blank.png b/xsl/images/toc-blank.png
new file mode 100644 (file)
index 0000000..6ffad17
Binary files /dev/null and b/xsl/images/toc-blank.png differ
diff --git a/xsl/images/toc-minus.png b/xsl/images/toc-minus.png
new file mode 100644 (file)
index 0000000..abbb020
Binary files /dev/null and b/xsl/images/toc-minus.png differ
diff --git a/xsl/images/toc-plus.png b/xsl/images/toc-plus.png
new file mode 100644 (file)
index 0000000..941312c
Binary files /dev/null and b/xsl/images/toc-plus.png differ
diff --git a/xsl/images/up.png b/xsl/images/up.png
new file mode 100644 (file)
index 0000000..07634de
Binary files /dev/null and b/xsl/images/up.png differ
diff --git a/xsl/images/warning.gif b/xsl/images/warning.gif
new file mode 100644 (file)
index 0000000..3adf191
Binary files /dev/null and b/xsl/images/warning.gif differ
diff --git a/xsl/images/warning.png b/xsl/images/warning.png
new file mode 100644 (file)
index 0000000..1c33db8
Binary files /dev/null and b/xsl/images/warning.png differ
diff --git a/xsl/images/warning.tif b/xsl/images/warning.tif
new file mode 100644 (file)
index 0000000..7b6611e
Binary files /dev/null and b/xsl/images/warning.tif differ
diff --git a/xsl/lib/lib.xsl b/xsl/lib/lib.xsl
new file mode 100644 (file)
index 0000000..7aa690b
--- /dev/null
@@ -0,0 +1,242 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+                exclude-result-prefixes="doc"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     This module implements DTD-independent functions
+
+     ******************************************************************** -->
+
+<doc:reference xmlns="">
+<referenceinfo>
+<releaseinfo role="meta">
+$Id$
+</releaseinfo>
+<author><surname>Walsh</surname>
+<firstname>Norman</firstname></author>
+<copyright><year>1999</year><year>2000</year>
+<holder>Norman Walsh</holder>
+</copyright>
+</referenceinfo>
+<title>Library Template Reference</title>
+
+<partintro>
+<section><title>Introduction</title>
+
+<para>This is technical reference documentation for the DocBook XSL
+Stylesheets; it documents (some of) the parameters, templates, and
+other elements of the stylesheets.</para>
+
+<para>This is not intended to be <quote>user</quote> documentation.
+It is provided for developers writing customization layers for the
+stylesheets, and for anyone who's interested in <quote>how it
+works</quote>.</para>
+
+<para>Although I am trying to be thorough, this documentation is known
+to be incomplete. Don't forget to read the source, too :-)</para>
+</section>
+</partintro>
+</doc:reference>
+
+<xsl:template name="dot.count">
+  <!-- Returns the number of "." characters in a string -->
+  <xsl:param name="string"></xsl:param>
+  <xsl:param name="count" select="0"/>
+  <xsl:choose>
+    <xsl:when test="contains($string, '.')">
+      <xsl:call-template name="dot.count">
+        <xsl:with-param name="string" select="substring-after($string, '.')"/>
+        <xsl:with-param name="count" select="$count+1"/>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$count"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ================================================================== -->
+
+<xsl:template name="copy-string">
+  <!-- returns 'count' copies of 'string' -->
+  <xsl:param name="string"></xsl:param>
+  <xsl:param name="count" select="0"/>
+  <xsl:param name="result"></xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="$count>0">
+      <xsl:call-template name="copy-string">
+        <xsl:with-param name="string" select="$string"/>
+        <xsl:with-param name="count" select="$count - 1"/>
+        <xsl:with-param name="result">
+          <xsl:value-of select="$result"/>
+          <xsl:value-of select="$string"/>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$result"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<doc:template name="string.subst" xmlns="">
+<refpurpose>Substitute one text string for another in a string</refpurpose>
+<refdescription>
+<para>The <function>string.subst</function> template replaces all
+occurances of <param>target</param> in <param>string</param>
+with <param>replacement</param> and returns the result.
+</para>
+</refdescription>
+</doc:template>
+
+<xsl:template name="string.subst">
+  <xsl:param name="string"></xsl:param>
+  <xsl:param name="target"></xsl:param>
+  <xsl:param name="replacement"></xsl:param>
+
+  <xsl:choose>
+    <xsl:when test="contains($string, $target)">
+      <xsl:variable name="rest">
+        <xsl:call-template name="string.subst">
+          <xsl:with-param name="string"
+                          select="substring-after($string, $target)"/>
+          <xsl:with-param name="target" select="$target"/>
+          <xsl:with-param name="replacement" select="$replacement"/>
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:value-of select="concat(substring-before($string, $target),
+                                   $replacement,
+                                   $rest)"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$string"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ================================================================== -->
+
+<doc:template name="xpointer.idref" xmlns="">
+<refpurpose>Extract IDREF from an XPointer</refpurpose>
+<refdescription>
+<para>The <function>xpointer.idref</function> template returns the
+ID portion of an XPointer which is a pointer to an ID within the current
+document, or the empty string if it is not.</para>
+<para>In other words, <function>xpointer.idref</function> returns
+<quote>foo</quote> when passed either <literal>#foo</literal>
+or <literal>#xpointer(id('foo'))</literal>, otherwise it returns
+the empty string.</para>
+</refdescription>
+</doc:template>
+
+<xsl:template name="xpointer.idref">
+  <xsl:param name="xpointer">http://...</xsl:param>
+  <xsl:choose>
+    <xsl:when test="starts-with($xpointer, '#xpointer(id(')">
+      <xsl:variable name="rest" select="substring-after($xpointer, '#xpointer(id(')"/>
+      <xsl:variable name="quote" select="substring($rest, 1, 1)"/>
+      <xsl:value-of select="substring-before(substring-after($xpointer, $quote), $quote)"/>
+    </xsl:when>
+    <xsl:when test="starts-with($xpointer, '#')">
+      <xsl:value-of select="substring-after($xpointer, '#')"/>
+    </xsl:when>
+    <!-- otherwise it's a pointer to some other document -->
+  </xsl:choose>
+</xsl:template>
+
+<!-- ================================================================== -->
+
+<doc:template name="length-magnitude" xmlns="">
+<refpurpose>Return the unqualified dimension from a length specification</refpurpose>
+<refdescription>
+<para>The <function>length-magnitude</function> template returns the
+unqualified length ("20" for "20pt") from a dimension.
+</para>
+</refdescription>
+</doc:template>
+
+<xsl:template name="length-magnitude">
+  <xsl:param name="length" select="'0pt'"/>
+
+  <xsl:choose>
+    <xsl:when test="string-length($length) = 0"/>
+    <xsl:when test="substring($length,1,1) = '0'
+                    or substring($length,1,1) = '1'
+                    or substring($length,1,1) = '2'
+                    or substring($length,1,1) = '3'
+                    or substring($length,1,1) = '4'
+                    or substring($length,1,1) = '5'
+                    or substring($length,1,1) = '6'
+                    or substring($length,1,1) = '7'
+                    or substring($length,1,1) = '8'
+                    or substring($length,1,1) = '9'
+                    or substring($length,1,1) = '.'">
+      <xsl:value-of select="substring($length,1,1)"/>
+      <xsl:call-template name="length-magnitude">
+        <xsl:with-param name="length" select="substring($length,2)"/>
+      </xsl:call-template>
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- ================================================================== -->
+
+<doc:template name="length-spec" xmlns="">
+<refpurpose>Return a fully qualified length specification</refpurpose>
+<refdescription>
+<para>The <function>length-spec</function> template returns the
+qualified length from a dimension. If an unqualified length is given,
+the <param>default.units</param> will be added to it.
+</para>
+</refdescription>
+</doc:template>
+
+<xsl:template name="length-spec">
+  <xsl:param name="length" select="'0pt'"/>
+  <xsl:param name="default.units" select="'pt'"/>
+  <xsl:variable name="magnitude">
+    <xsl:call-template name="length-magnitude">
+      <xsl:with-param name="length" select="$length"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="units">
+    <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
+  </xsl:variable>
+
+  <xsl:value-of select="$magnitude"/>
+  <xsl:choose>
+    <xsl:when test="$units='cm'
+                    or $units='mm'
+                    or $units='in'
+                    or $units='pt'
+                    or $units='pc'
+                    or $units='px'
+                    or $units='em'">
+      <xsl:value-of select="$units"/>
+    </xsl:when>
+    <xsl:when test="$units = ''">
+      <xsl:value-of select="$default.units"/>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message>
+        <xsl:text>Unrecognized unit of measure: </xsl:text>
+        <xsl:value-of select="$units"/>
+        <xsl:text>.</xsl:text>
+      </xsl:message>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xsl/xhtml/docbook.xsl b/xsl/xhtml/docbook.xsl
new file mode 100644 (file)
index 0000000..31a5562
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'>
+
+<!-- ********************************************************************
+     $Id$
+     ********************************************************************
+
+     This file is part of the XSL DocBook Stylesheet distribution.
+     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
+     and other information.
+
+     ******************************************************************** -->
+
+<xsl:include href="../html/docbook.xsl"/>
+
+ <!-- this has to be last because of document order nonsense -->
+<xsl:output method="xml"/>
+
+</xsl:stylesheet>
diff --git a/xsl/xhtml/xtchunk.xsl b/xsl/xhtml/xtchunk.xsl
new file mode 100644 (file)
index 0000000..f1ca18d
--- /dev/null
@@ -0,0 +1,135 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xt="http://www.jclark.com/xt"
+               version="1.0"
+                extension-element-prefixes="xt">
+
+<!-- NB: because xt:document doesn't seem to accept an AVT in its -->
+<!-- method attribute, some code has to be duplicated here. Check -->
+<!-- to make sure this code is in sync with ../html/xtchunk.xsl   -->
+<!-- if you're having difficulties :-(                            -->
+
+<xsl:include href="../html/xtchunk.xsl"/>
+
+<xsl:variable name="html.ext">.xhtm</xsl:variable>
+
+<xsl:output method="xml"/>
+
+<xsl:template match="set|book|part|preface|chapter|appendix
+                     |article
+                     |reference|refentry
+                     |sect1[position()>1]
+                     |section[position()>1 and name(parent::*) != 'section']
+                     |setindex
+                     |book/glossary|article/glossary
+                     |book/bibliography|article/bibliography
+                     |book/index|article/index
+                     |colophon">
+  <xsl:variable name="prev"
+    select="(preceding::book[1]
+             |preceding::preface[1]
+             |preceding::chapter[1]
+             |preceding::appendix[1]
+             |preceding::part[1]
+             |preceding::reference[1]
+             |preceding::refentry[1]
+             |preceding::colophon[1]
+             |preceding::sect1[position()=1
+                               and name(preceding-sibling::*[1]) = 'sect1']
+             |preceding::section[position()=1
+                                 and name(preceding-sibling::*[1]) = 'section'
+                                 and name(parent::*) != 'section']
+             |preceding::article[1]
+             |preceding::bibliography[1]
+             |preceding::glossary[1]
+             |preceding::index[1]
+             |preceding::setindex[1]
+             |ancestor::set
+             |ancestor::book[1]
+             |ancestor::preface[1]
+             |ancestor::chapter[1]
+             |ancestor::appendix[1]
+             |ancestor::part[1]
+             |ancestor::reference[1]
+             |ancestor::article[1])[last()]"/>
+
+  <xsl:variable name="next"
+    select="(following::book[1]
+             |following::preface[1]
+             |following::chapter[1]
+             |following::appendix[1]
+             |following::part[1]
+             |following::reference[1]
+             |following::refentry[1]
+             |following::colophon[1]
+             |following::sect1[1]
+             |following::section[name(parent::*) != 'section']
+             |following::bibliography[1]
+             |following::glossary[1]
+             |following::index[1]
+             |following::article[1]
+             |following::setindex[1]
+             |descendant::book[1]
+             |descendant::preface[1]
+             |descendant::chapter[1]
+             |descendant::appendix[1]
+             |descendant::article[1]
+             |descendant::bibliography[1]
+             |descendant::glossary[1]
+             |descendant::index[1]
+             |descendant::colophon[1]
+             |descendant::setindex[1]
+             |descendant::part[1]
+             |descendant::reference[1]
+             |descendant::refentry[1]
+             |descendant::sect1[2]
+             |descendant::section[position()=2
+                                  and name(parent::*) != 'section'])[1]"/>
+
+  <xsl:variable name="ischunk"><xsl:call-template name="chunk"/></xsl:variable>
+  <xsl:variable name="chunkfn">
+    <xsl:if test="$ischunk='1'">
+      <xsl:apply-templates mode="chunk-filename" select="."/>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:if test="$ischunk='0'">
+    <xsl:message>
+      <xsl:text>Error </xsl:text>
+      <xsl:value-of select="name(.)"/>
+      <xsl:text> is not a chunk!</xsl:text>
+    </xsl:message>
+  </xsl:if>
+
+  <xsl:message>
+    <xsl:text>Writing </xsl:text>
+    <xsl:value-of select="$chunkfn"/>
+    <xsl:text> for </xsl:text>
+    <xsl:value-of select="name(.)"/>
+  </xsl:message>
+
+  <xt:document method="html" href="{$chunkfn}">
+    <html>
+      <xsl:call-template name="html.head">
+        <xsl:with-param name="prev" select="$prev"/>
+        <xsl:with-param name="next" select="$next"/>
+      </xsl:call-template>
+
+      <body>
+        <xsl:call-template name="header.navigation">
+          <xsl:with-param name="prev" select="$prev"/>
+          <xsl:with-param name="next" select="$next"/>
+        </xsl:call-template>
+
+
+        <xsl:apply-imports/>
+
+        <xsl:call-template name="footer.navigation">
+          <xsl:with-param name="prev" select="$prev"/>
+          <xsl:with-param name="next" select="$next"/>
+        </xsl:call-template>
+      </body>
+    </html>
+  </xt:document>
+</xsl:template>
+
+</xsl:stylesheet>