summaryrefslogtreecommitdiffstats
path: root/kdoctools/docbook/xsl/lib
diff options
context:
space:
mode:
Diffstat (limited to 'kdoctools/docbook/xsl/lib')
-rw-r--r--kdoctools/docbook/xsl/lib/ChangeLog74
-rw-r--r--kdoctools/docbook/xsl/lib/lib.xml750
-rw-r--r--kdoctools/docbook/xsl/lib/lib.xsl355
-rw-r--r--kdoctools/docbook/xsl/lib/lib.xweb772
4 files changed, 1951 insertions, 0 deletions
diff --git a/kdoctools/docbook/xsl/lib/ChangeLog b/kdoctools/docbook/xsl/lib/ChangeLog
new file mode 100644
index 000000000..ccd788403
--- /dev/null
+++ b/kdoctools/docbook/xsl/lib/ChangeLog
@@ -0,0 +1,74 @@
+2004-09-24 Robert Stayton <bobstayton@users.sourceforge.net>
+
+ * lib.xweb: Fixed param prototype to remove Saxon8 warning.
+
+2004-08-11 Robert Stayton <bobstayton@users.sourceforge.net>
+
+ * lib.xweb: Fixed problem of PI name suffix being matched instead of whole name.
+
+2003-04-05 Adam Di Carlo <adicarlo@users.sourceforge.net>
+
+ * lib.xweb: a pica is 12 points, rather than a sixth of an inch
+
+2003-03-26 Michael Smith <xmldoc@users.sourceforge.net>
+
+ * Makefile: wdocbook.xsl obsoleted by w2docbook.xsl, updated globally
+
+2003-03-25 Michael Smith <xmldoc@users.sourceforge.net>
+
+ * Makefile: reverting wdocbook.xsl -> w2docbook.xsl changes
+
+2003-03-05 Michael Smith <xmldoc@users.sourceforge.net>
+
+ * Makefile:
+
+ Wrong filename was breaking build, fixed.
+
+ Had ../../litprog/wdocbook.xsl but needed ../../litprog/w2docbook.xsl
+
+2002-09-15 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xweb: Fix bug where PIs match the suffix of a name instead of the whole name
+
+2002-06-09 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xweb: Fix bug #496453: make sure comments don't contain illegal chars
+
+2002-05-12 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xweb: Changed default units to px; added length-in-points template
+
+2002-03-25 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * .cvsignore: Ignore lib.xsl too
+
+ * .cvsignore, Makefile, lib.xsl, lib.xweb: Use Literate XML to generate lib.xsl
+
+ * Makefile: Update documentation build to reflect use of lib.xweb
+
+2002-03-18 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xsl: Replace generate.*.toc and generate.*.lot with single generate.toc parameter.
+
+2002-03-14 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xsl: Whitespace only: change CR/LF back to LF. Norm was a total moron.
+
+ * lib.xsl: Whitespace changes only: use PC-style CR/LF because Unix clients choke on this far less often than PC clients choke on the reverse. Grrr.
+
+2002-01-09 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xsl: Added length-units template to extract units from lengths
+
+2001-11-28 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xsl: Added pi-attribute template
+
+2001-04-03 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xsl: Documentation fixes
+
+2001-04-02 Norman Walsh <nwalsh@users.sourceforge.net>
+
+ * lib.xsl: New file.
+
diff --git a/kdoctools/docbook/xsl/lib/lib.xml b/kdoctools/docbook/xsl/lib/lib.xml
new file mode 100644
index 000000000..117438daf
--- /dev/null
+++ b/kdoctools/docbook/xsl/lib/lib.xml
@@ -0,0 +1,750 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book
+ PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<book>
+<bookinfo>
+<title>XSL Library Template Reference</title>
+<releaseinfo role="cvs">$Id$
+</releaseinfo>
+<corpauthor>DocBook Open Repository Team</corpauthor>
+<copyright>
+ <year>1999</year>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <holder>Norman Walsh</holder>
+</copyright>
+</bookinfo>
+
+<preface><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>
+
+</preface>
+
+<reference>
+<title>General Library Templates</title>
+
+<refentry id="dot.count">
+<refnamediv>
+<refname>dot.count</refname>
+<refpurpose>Returns the number of <quote>.</quote> characters in a string</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<programlisting format="linespecific"><programlisting id="dot.count.frag">
+&lt;xsl:template name="dot.count"&gt;
+ &lt;!-- Returns the number of "." characters in a string --&gt;
+ &lt;xsl:param name="string"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="count" select="0"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="contains($string, '.')"&gt;
+ &lt;xsl:call-template name="dot.count"&gt;
+ &lt;xsl:with-param name="string" select="substring-after($string, '.')"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="count" select="$count+1"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:value-of select="$count"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="copy-string">
+<refnamediv>
+<refname>copy-string</refname>
+<refpurpose>Returns <quote>count</quote> copies of a string</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<programlisting format="linespecific"><programlisting id="copy-string.frag">
+&lt;xsl:template name="copy-string"&gt;
+ &lt;!-- returns 'count' copies of 'string' --&gt;
+ &lt;xsl:param name="string"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="count" select="0"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="result"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="$count&gt;0"&gt;
+ &lt;xsl:call-template name="copy-string"&gt;
+ &lt;xsl:with-param name="string" select="$string"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="count" select="$count - 1"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="result"&gt;
+ &lt;xsl:value-of select="$result"&gt;&lt;/xsl:value-of&gt;
+ &lt;xsl:value-of select="$string"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:value-of select="$result"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="string.subst">
+<refnamediv>
+<refname>string.subst</refname>
+<refpurpose>Substitute one text string for another in a string</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">string.subst</function> template replaces all
+occurances of <parameter moreinfo="none">target</parameter> in <parameter moreinfo="none">string</parameter>
+with <parameter moreinfo="none">replacement</parameter> and returns the result.
+</para>
+
+<programlisting format="linespecific"><programlisting id="string.subst.frag">
+&lt;xsl:template name="string.subst"&gt;
+ &lt;xsl:param name="string"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="target"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="replacement"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="contains($string, $target)"&gt;
+ &lt;xsl:variable name="rest"&gt;
+ &lt;xsl:call-template name="string.subst"&gt;
+ &lt;xsl:with-param name="string" select="substring-after($string, $target)"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="target" select="$target"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="replacement" select="$replacement"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:variable&gt;
+ &lt;xsl:value-of select="concat(substring-before($string, $target), $replacement, $rest)"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:value-of select="$string"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="xpointer.idref">
+<refnamediv>
+<refname>xpointer.idref</refname>
+<refpurpose>Extract IDREF from an XPointer</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">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 moreinfo="none">xpointer.idref</function> returns
+<quote>foo</quote> when passed either <literal moreinfo="none">#foo</literal>
+or <literal moreinfo="none">#xpointer(id('foo'))</literal>, otherwise it returns
+the empty string.</para>
+
+<programlisting format="linespecific"><programlisting id="xpointer.idref.frag">
+&lt;xsl:template name="xpointer.idref"&gt;
+ &lt;xsl:param name="xpointer"&gt;http://...&lt;/xsl:param&gt;
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="starts-with($xpointer, '#xpointer(id(')"&gt;
+ &lt;xsl:variable name="rest" select="substring-after($xpointer, '#xpointer(id(')"&gt;&lt;/xsl:variable&gt;
+ &lt;xsl:variable name="quote" select="substring($rest, 1, 1)"&gt;&lt;/xsl:variable&gt;
+ &lt;xsl:value-of select="substring-before(substring-after($xpointer, $quote), $quote)"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:when test="starts-with($xpointer, '#')"&gt;
+ &lt;xsl:value-of select="substring-after($xpointer, '#')"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;!-- otherwise it's a pointer to some other document --&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+
+<refentry id="length-magnitude">
+<refnamediv>
+<refname>length-magnitude</refname>
+<refpurpose>Return the unqualified dimension from a length specification</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">length-magnitude</function> template returns the
+unqualified length ("20" for "20pt") from a dimension.
+</para>
+
+<programlisting format="linespecific"><programlisting id="length-magnitude.frag">
+&lt;xsl:template name="length-magnitude"&gt;
+ &lt;xsl:param name="length" select="'0pt'"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="string-length($length) = 0"&gt;&lt;/xsl:when&gt;
+ &lt;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) = '.'"&gt;
+ &lt;xsl:value-of select="substring($length,1,1)"&gt;&lt;/xsl:value-of&gt;
+ &lt;xsl:call-template name="length-magnitude"&gt;
+ &lt;xsl:with-param name="length" select="substring($length,2)"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:when&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="length-units">
+<refnamediv>
+<refname>length-units</refname>
+<refpurpose>Return the units from a length specification</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">length-units</function> template returns the
+units ("pt" for "20pt") from a length. If no units are supplied on the
+length, the <parameter moreinfo="none">defauilt.units</parameter> are returned.</para>
+
+<programlisting format="linespecific"><programlisting id="length-units.frag">
+&lt;xsl:template name="length-units"&gt;
+ &lt;xsl:param name="length" select="'0pt'"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="default.units" select="'px'"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:variable name="magnitude"&gt;
+ &lt;xsl:call-template name="length-magnitude"&gt;
+ &lt;xsl:with-param name="length" select="$length"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:variable&gt;
+
+ &lt;xsl:variable name="units"&gt;
+ &lt;xsl:value-of select="substring($length, string-length($magnitude)+1)"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:variable&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="$units = ''"&gt;
+ &lt;xsl:value-of select="$default.units"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:value-of select="$units"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="length-spec">
+<refnamediv>
+<refname>length-spec</refname>
+<refpurpose>Return a fully qualified length specification</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">length-spec</function> template returns the
+qualified length from a dimension. If an unqualified length is given,
+the <parameter moreinfo="none">default.units</parameter> will be added to it.
+</para>
+
+<programlisting format="linespecific"><programlisting id="length-spec.frag">
+&lt;xsl:template name="length-spec"&gt;
+ &lt;xsl:param name="length" select="'0pt'"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="default.units" select="'px'"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:variable name="magnitude"&gt;
+ &lt;xsl:call-template name="length-magnitude"&gt;
+ &lt;xsl:with-param name="length" select="$length"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:variable&gt;
+
+ &lt;xsl:variable name="units"&gt;
+ &lt;xsl:value-of select="substring($length, string-length($magnitude)+1)"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:variable&gt;
+
+ &lt;xsl:value-of select="$magnitude"&gt;&lt;/xsl:value-of&gt;
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="$units='cm' or $units='mm' or $units='in' or $units='pt' or $units='pc' or $units='px' or $units='em'"&gt;
+ &lt;xsl:value-of select="$units"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:when test="$units = ''"&gt;
+ &lt;xsl:value-of select="$default.units"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:message&gt;
+ &lt;xsl:text&gt;Unrecognized unit of measure: &lt;/xsl:text&gt;
+ &lt;xsl:value-of select="$units"&gt;&lt;/xsl:value-of&gt;
+ &lt;xsl:text&gt;.&lt;/xsl:text&gt;
+ &lt;/xsl:message&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="length-in-points">
+<refnamediv>
+<refname>length-in-points</refname>
+<refpurpose>Returns the size, in points, of a specified length</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">length-in-points</function> template converts a length
+specification to points and returns that value as an unqualified
+number.
+</para>
+
+<caution>
+<para>There is no way for the template to infer the size of an
+<literal moreinfo="none">em</literal>. It relies on the default <parameter moreinfo="none">em.size</parameter>
+which is initially <literal moreinfo="none">10</literal> (for 10pt).</para>
+
+<para>Similarly, converting pixesl to points relies on the
+<parameter moreinfo="none">pixels.per.inch</parameter> parameter which is initially
+<literal moreinfo="none">90</literal>.
+</para>
+</caution>
+
+<programlisting format="linespecific"><programlisting id="length-in-points.frag">
+&lt;xsl:template name="length-in-points"&gt;
+ &lt;xsl:param name="length" select="'0pt'"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="em.size" select="10"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="pixels.per.inch" select="90"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:variable name="magnitude"&gt;
+ &lt;xsl:call-template name="length-magnitude"&gt;
+ &lt;xsl:with-param name="length" select="$length"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:variable&gt;
+
+ &lt;xsl:variable name="units"&gt;
+ &lt;xsl:value-of select="substring($length, string-length($magnitude)+1)"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:variable&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="$units = 'pt'"&gt;
+ &lt;xsl:value-of select="$magnitude"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:when test="$units = 'cm'"&gt;
+ &lt;xsl:value-of select="$magnitude div 2.54 * 72.0"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:when test="$units = 'mm'"&gt;
+ &lt;xsl:value-of select="$magnitude div 25.4 * 72.0"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:when test="$units = 'in'"&gt;
+ &lt;xsl:value-of select="$magnitude * 72.0"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:when test="$units = 'pc'"&gt;
+ &lt;xsl:value-of select="$magnitude * 12.0"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:when test="$units = 'px'"&gt;
+ &lt;xsl:value-of select="$magnitude div $pixels.per.inch * 72.0"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:when test="$units = 'em'"&gt;
+ &lt;xsl:value-of select="$magnitude * $em.size"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:message&gt;
+ &lt;xsl:text&gt;Unrecognized unit of measure: &lt;/xsl:text&gt;
+ &lt;xsl:value-of select="$units"&gt;&lt;/xsl:value-of&gt;
+ &lt;xsl:text&gt;.&lt;/xsl:text&gt;
+ &lt;/xsl:message&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="pi-attribute">
+<refnamediv>
+<refname>pi-attribute</refname>
+<refpurpose>Extract a pseudo-attribute from a PI</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">pi-attribute</function> template extracts a pseudo-attribute
+from a processing instruction. For example, given the PI
+<quote><literal moreinfo="none">&lt;?foo bar="1" baz='red'?&gt;</literal></quote>,</para>
+<programlisting format="linespecific">&lt;xsl:call-template name="pi-attribute"&gt;
+ &lt;xsl:with-param name="pis" select="processing-instruction('foo')"/&gt;
+ &lt;xsl:with-param name="attribute" select="'baz'"/&gt;
+&lt;/xsl:call-template&gt;</programlisting>
+<para>will return <quote>red</quote>. This template returns the first matching
+attribute that it finds. Presented with processing instructions that
+contain badly formed pseudo-attributes (missing or unbalanced quotes,
+for example), the template may silently return erroneous results.</para>
+
+<programlisting format="linespecific"><programlisting id="pi-attribute.frag">
+&lt;xsl:template name="pi-attribute"&gt;
+ &lt;xsl:param name="pis" select="processing-instruction('BOGUS_PI')"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="attribute"&gt;filename&lt;/xsl:param&gt;
+ &lt;xsl:param name="count"&gt;1&lt;/xsl:param&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="$count&gt;count($pis)"&gt;
+ &lt;!-- not found --&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:variable name="pi"&gt;
+ &lt;xsl:value-of select="$pis[$count]"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:variable&gt;
+ &lt;xsl:variable name="pivalue"&gt;
+ &lt;xsl:value-of select="concat(' ', normalize-space($pi))"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:variable&gt;
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="contains($pivalue,concat(' ', $attribute, '='))"&gt;
+ &lt;xsl:variable name="rest" select="substring-after($pivalue,concat(' ', $attribute,'='))"&gt;&lt;/xsl:variable&gt;
+ &lt;xsl:variable name="quote" select="substring($rest,1,1)"&gt;&lt;/xsl:variable&gt;
+ &lt;xsl:value-of select="substring-before(substring($rest,2),$quote)"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:call-template name="pi-attribute"&gt;
+ &lt;xsl:with-param name="pis" select="$pis"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="attribute" select="$attribute"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="count" select="$count + 1"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="lookup.key">
+<refnamediv>
+<refname>lookup.key</refname>
+<refpurpose>Retrieve the value associated with a particular key in a table</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>Given a table of space-delimited key/value pairs,
+the <function moreinfo="none">lookup.key</function> template extracts the value associated
+with a particular key.</para>
+
+<programlisting format="linespecific"><programlisting id="lookup.key.frag">
+&lt;xsl:template name="lookup.key"&gt;
+ &lt;xsl:param name="key" select="''"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="table" select="''"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:if test="contains($table, ' ')"&gt;
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="substring-before($table, ' ') = $key"&gt;
+ &lt;xsl:variable name="rest" select="substring-after($table, ' ')"&gt;&lt;/xsl:variable&gt;
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="contains($rest, ' ')"&gt;
+ &lt;xsl:value-of select="substring-before($rest, ' ')"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:value-of select="$rest"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:call-template name="lookup.key"&gt;
+ &lt;xsl:with-param name="key" select="$key"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="table" select="substring-after(substring-after($table,' '), ' ')"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+ &lt;/xsl:if&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="xpath.location">
+<refnamediv>
+<refname>xpath.location</refname>
+<refpurpose>Calculate the XPath child-sequence to the current node</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">xpath.location</function> template calculates the
+absolute path from the root of the tree to the current element node.
+</para>
+
+<programlisting format="linespecific"><programlisting id="xpath.location.frag">
+&lt;xsl:template name="xpath.location"&gt;
+ &lt;xsl:param name="node" select="."&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="path" select="''"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:variable name="next.path"&gt;
+ &lt;xsl:value-of select="local-name($node)"&gt;&lt;/xsl:value-of&gt;
+ &lt;xsl:if test="$path != ''"&gt;/&lt;/xsl:if&gt;
+ &lt;xsl:value-of select="$path"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:variable&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="$node/parent::*"&gt;
+ &lt;xsl:call-template name="xpath.location"&gt;
+ &lt;xsl:with-param name="node" select="$node/parent::*"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="path" select="$next.path"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:text&gt;/&lt;/xsl:text&gt;
+ &lt;xsl:value-of select="$next.path"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+
+
+<refentry id="comment-escape-string">
+<refnamediv>
+<refname>comment-escape-string</refname>
+<refpurpose>Prepare a string for inclusion in an XML comment</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">comment-escape-string</function> template returns a string
+that has been transformed so that it can safely be output as an XML comment.
+Internal occurrences of "--" will be replaced with "- -" and a leading and/or
+trailing space will be added to the string, if necessary.</para>
+
+<programlisting format="linespecific"><programlisting id="comment-escape-string">
+&lt;xsl:template name="comment-escape-string"&gt;
+ &lt;xsl:param name="string" select="''"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:if test="starts-with($string, '-')"&gt;
+ &lt;xsl:text&gt; &lt;/xsl:text&gt;
+ &lt;/xsl:if&gt;
+
+ &lt;xsl:call-template name="comment-escape-string.recursive"&gt;
+ &lt;xsl:with-param name="string" select="$string"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+
+ &lt;xsl:if test="substring($string, string-length($string), 1) = '-'"&gt;
+ &lt;xsl:text&gt; &lt;/xsl:text&gt;
+ &lt;/xsl:if&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+<refentry id="comment-escape-string.recursive">
+<refnamediv>
+<refname>comment-escape-string.recursive</refname>
+<refpurpose>Internal function used by comment-escape-string</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function moreinfo="none">comment-escape-string.recursive</function> template is used
+by <function moreinfo="none">comment-escape-string</function>.</para>
+
+<programlisting format="linespecific"><programlisting id="comment-escape-string.recursive">
+&lt;xsl:template name="comment-escape-string.recursive"&gt;
+ &lt;xsl:param name="string" select="''"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="contains($string, '--')"&gt;
+ &lt;xsl:value-of select="substring-before($string, '--')"&gt;&lt;/xsl:value-of&gt;
+ &lt;xsl:value-of select="'- -'"&gt;&lt;/xsl:value-of&gt;
+ &lt;xsl:call-template name="comment-escape-string.recursive"&gt;
+ &lt;xsl:with-param name="string" select="substring-after($string, '--')"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:value-of select="$string"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+</refsect1>
+</refentry>
+
+</reference>
+
+<reference>
+<title>Relative URI Functions</title>
+
+<partintro><title>Introduction</title>
+
+<para>These functions manipulate relative URI references.</para>
+
+<para>The following assumptions must hold true:</para>
+
+<orderedlist inheritnum="ignore" continuation="restarts">
+<listitem>
+<para>All URIs are relative.</para>
+</listitem>
+<listitem>
+<para>No URI contains the <quote><literal moreinfo="none">../</literal></quote> sequence
+which would effectively move <quote>up</quote> the hierarchy.</para>
+</listitem>
+</orderedlist>
+
+<para>If these assumptions do not hold, the results are unpredictable.</para>
+
+</partintro>
+
+<refentry id="count.uri.path.depth">
+<refnamediv>
+<refname>count.uri.path.depth</refname>
+<refpurpose>Count the number of path components in a relative URI</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>This function counts the number of path components in a relative URI.</para>
+
+<programlisting format="linespecific"><programlisting id="count.uri.path.depth.frag">
+&lt;xsl:template name="count.uri.path.depth"&gt;
+ &lt;xsl:param name="filename" select="''"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="count" select="0"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="contains($filename, '/')"&gt;
+ &lt;xsl:call-template name="count.uri.path.depth"&gt;
+ &lt;xsl:with-param name="filename" select="substring-after($filename, '/')"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="count" select="$count + 1"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:value-of select="$count"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+<refentry id="trim.common.uri.paths">
+<refnamediv>
+<refname>trim.common.uri.paths</refname>
+<refpurpose>Trim common leading path components from a relative URI</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>This function trims common leading path components from a relative URI.</para>
+
+<programlisting format="linespecific"><programlisting id="trim.common.uri.paths.frag">
+&lt;xsl:template name="trim.common.uri.paths"&gt;
+ &lt;xsl:param name="uriA" select="''"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="uriB" select="''"&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name="return" select="'A'"&gt;&lt;/xsl:param&gt;
+
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="contains($uriA, '/') and contains($uriB, '/') and substring-before($uriA, '/') = substring-before($uriB, '/')"&gt;
+ &lt;xsl:call-template name="trim.common.uri.paths"&gt;
+ &lt;xsl:with-param name="uriA" select="substring-after($uriA, '/')"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="uriB" select="substring-after($uriB, '/')"&gt;&lt;/xsl:with-param&gt;
+ &lt;xsl:with-param name="return" select="$return"&gt;&lt;/xsl:with-param&gt;
+ &lt;/xsl:call-template&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:choose&gt;
+ &lt;xsl:when test="$return = 'A'"&gt;
+ &lt;xsl:value-of select="$uriA"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:when&gt;
+ &lt;xsl:otherwise&gt;
+ &lt;xsl:value-of select="$uriB"&gt;&lt;/xsl:value-of&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+ &lt;/xsl:otherwise&gt;
+ &lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+</programlisting></programlisting>
+
+</refsect1>
+</refentry>
+
+</reference>
+
+<appendix><title>The Stylesheet</title>
+
+<para>The <filename moreinfo="none">lib.xsl</filename> stylesheet is just a wrapper
+around these functions.</para>
+
+<programlisting id="top">
+
+&lt;!-- ********************************************************************
+ $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
+
+ ******************************************************************** --&gt;
+
+&lt;xsl:stylesheet exclude-result-prefixes="src" version="1.0"&gt;
+
+&lt;src:fragref linkend="dot.count.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="copy-string.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="string.subst.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="xpointer.idref.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="length-magnitude.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="length-units.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="length-spec.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="length-in-points.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="pi-attribute.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="lookup.key.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="xpath.location.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="comment-escape-string"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="comment-escape-string.recursive"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="count.uri.path.depth.frag"&gt;&lt;/src:fragref&gt;
+&lt;src:fragref linkend="trim.common.uri.paths.frag"&gt;&lt;/src:fragref&gt;
+
+&lt;/xsl:stylesheet&gt;
+</programlisting>
+
+</appendix>
+</book> \ No newline at end of file
diff --git a/kdoctools/docbook/xsl/lib/lib.xsl b/kdoctools/docbook/xsl/lib/lib.xsl
new file mode 100644
index 000000000..f9f2bb4d4
--- /dev/null
+++ b/kdoctools/docbook/xsl/lib/lib.xsl
@@ -0,0 +1,355 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- ********************************************************************
+ $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
+
+ ******************************************************************** -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:src="http://nwalsh.com/xmlns/litprog/fragment" exclude-result-prefixes="src" version="1.0">
+
+<xsl:template name="dot.count">
+ <!-- Returns the number of "." characters in a string -->
+ <xsl:param name="string"/>
+ <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 name="count" select="0"/>
+ <xsl:param name="result"/>
+
+ <xsl:choose>
+ <xsl:when test="$count&gt;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>
+<xsl:template name="string.subst">
+ <xsl:param name="string"/>
+ <xsl:param name="target"/>
+ <xsl:param name="replacement"/>
+
+ <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>
+<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>
+<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>
+<xsl:template name="length-units">
+ <xsl:param name="length" select="'0pt'"/>
+ <xsl:param name="default.units" select="'px'"/>
+ <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:choose>
+ <xsl:when test="$units = ''">
+ <xsl:value-of select="$default.units"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$units"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+<xsl:template name="length-spec">
+ <xsl:param name="length" select="'0pt'"/>
+ <xsl:param name="default.units" select="'px'"/>
+
+ <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:template name="length-in-points">
+ <xsl:param name="length" select="'0pt'"/>
+ <xsl:param name="em.size" select="10"/>
+ <xsl:param name="pixels.per.inch" select="90"/>
+
+ <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:choose>
+ <xsl:when test="$units = 'pt'">
+ <xsl:value-of select="$magnitude"/>
+ </xsl:when>
+ <xsl:when test="$units = 'cm'">
+ <xsl:value-of select="$magnitude div 2.54 * 72.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'mm'">
+ <xsl:value-of select="$magnitude div 25.4 * 72.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'in'">
+ <xsl:value-of select="$magnitude * 72.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'pc'">
+ <xsl:value-of select="$magnitude * 12.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'px'">
+ <xsl:value-of select="$magnitude div $pixels.per.inch * 72.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'em'">
+ <xsl:value-of select="$magnitude * $em.size"/>
+ </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:template name="pi-attribute">
+ <xsl:param name="pis" select="processing-instruction('BOGUS_PI')"/>
+ <xsl:param name="attribute">filename</xsl:param>
+ <xsl:param name="count">1</xsl:param>
+
+ <xsl:choose>
+ <xsl:when test="$count&gt;count($pis)">
+ <!-- not found -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="pi">
+ <xsl:value-of select="$pis[$count]"/>
+ </xsl:variable>
+ <xsl:variable name="pivalue">
+ <xsl:value-of select="concat(' ', normalize-space($pi))"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="contains($pivalue,concat(' ', $attribute, '='))">
+ <xsl:variable name="rest" select="substring-after($pivalue,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="pi-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="lookup.key">
+ <xsl:param name="key" select="''"/>
+ <xsl:param name="table" select="''"/>
+
+ <xsl:if test="contains($table, ' ')">
+ <xsl:choose>
+ <xsl:when test="substring-before($table, ' ') = $key">
+ <xsl:variable name="rest" select="substring-after($table, ' ')"/>
+ <xsl:choose>
+ <xsl:when test="contains($rest, ' ')">
+ <xsl:value-of select="substring-before($rest, ' ')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$rest"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="lookup.key">
+ <xsl:with-param name="key" select="$key"/>
+ <xsl:with-param name="table" select="substring-after(substring-after($table,' '), ' ')"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+</xsl:template>
+<xsl:template name="xpath.location">
+ <xsl:param name="node" select="."/>
+ <xsl:param name="path" select="''"/>
+
+ <xsl:variable name="next.path">
+ <xsl:value-of select="local-name($node)"/>
+ <xsl:if test="$path != ''">/</xsl:if>
+ <xsl:value-of select="$path"/>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$node/parent::*">
+ <xsl:call-template name="xpath.location">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ <xsl:with-param name="path" select="$next.path"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>/</xsl:text>
+ <xsl:value-of select="$next.path"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+<xsl:template name="comment-escape-string">
+ <xsl:param name="string" select="''"/>
+
+ <xsl:if test="starts-with($string, '-')">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+
+ <xsl:call-template name="comment-escape-string.recursive">
+ <xsl:with-param name="string" select="$string"/>
+ </xsl:call-template>
+
+ <xsl:if test="substring($string, string-length($string), 1) = '-'">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+</xsl:template>
+<xsl:template name="comment-escape-string.recursive">
+ <xsl:param name="string" select="''"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, '--')">
+ <xsl:value-of select="substring-before($string, '--')"/>
+ <xsl:value-of select="'- -'"/>
+ <xsl:call-template name="comment-escape-string.recursive">
+ <xsl:with-param name="string" select="substring-after($string, '--')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$string"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+<xsl:template name="count.uri.path.depth">
+ <xsl:param name="filename" select="''"/>
+ <xsl:param name="count" select="0"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($filename, '/')">
+ <xsl:call-template name="count.uri.path.depth">
+ <xsl:with-param name="filename" select="substring-after($filename, '/')"/>
+ <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="trim.common.uri.paths">
+ <xsl:param name="uriA" select="''"/>
+ <xsl:param name="uriB" select="''"/>
+ <xsl:param name="return" select="'A'"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($uriA, '/') and contains($uriB, '/') and substring-before($uriA, '/') = substring-before($uriB, '/')">
+ <xsl:call-template name="trim.common.uri.paths">
+ <xsl:with-param name="uriA" select="substring-after($uriA, '/')"/>
+ <xsl:with-param name="uriB" select="substring-after($uriB, '/')"/>
+ <xsl:with-param name="return" select="$return"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$return = 'A'">
+ <xsl:value-of select="$uriA"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$uriB"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet> \ No newline at end of file
diff --git a/kdoctools/docbook/xsl/lib/lib.xweb b/kdoctools/docbook/xsl/lib/lib.xweb
new file mode 100644
index 000000000..e8ee75c0c
--- /dev/null
+++ b/kdoctools/docbook/xsl/lib/lib.xweb
@@ -0,0 +1,772 @@
+<book xmlns:src="http://nwalsh.com/xmlns/litprog/fragment"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<bookinfo>
+<title>XSL Library Template Reference</title>
+<releaseinfo role="cvs">$Id$
+</releaseinfo>
+<corpauthor>DocBook Open Repository Team</corpauthor>
+<copyright>
+ <year>1999</year>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <holder>Norman Walsh</holder>
+</copyright>
+</bookinfo>
+
+<preface><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>
+
+</preface>
+
+<reference>
+<title>General Library Templates</title>
+
+<refentry id="dot.count">
+<refnamediv>
+<refname>dot.count</refname>
+<refpurpose>Returns the number of <quote>.</quote> characters in a string</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<programlisting><src:fragment id='dot.count.frag'>
+<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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="copy-string">
+<refnamediv>
+<refname>copy-string</refname>
+<refpurpose>Returns <quote>count</quote> copies of a string</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<programlisting><src:fragment id='copy-string.frag'>
+<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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+
+<refentry id="string.subst">
+<refnamediv>
+<refname>string.subst</refname>
+<refpurpose>Substitute one text string for another in a string</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>string.subst</function> template replaces all
+occurances of <parameter>target</parameter> in <parameter>string</parameter>
+with <parameter>replacement</parameter> and returns the result.
+</para>
+
+<programlisting><src:fragment id='string.subst.frag'>
+<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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="xpointer.idref">
+<refnamediv>
+<refname>xpointer.idref</refname>
+<refpurpose>Extract IDREF from an XPointer</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<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>
+
+<programlisting><src:fragment id='xpointer.idref.frag'>
+<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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+
+<!-- ================================================================== -->
+
+<refentry id="length-magnitude">
+<refnamediv>
+<refname>length-magnitude</refname>
+<refpurpose>Return the unqualified dimension from a length specification</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>length-magnitude</function> template returns the
+unqualified length ("20" for "20pt") from a dimension.
+</para>
+
+<programlisting><src:fragment id='length-magnitude.frag'>
+<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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="length-units">
+<refnamediv>
+<refname>length-units</refname>
+<refpurpose>Return the units from a length specification</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>length-units</function> template returns the
+units ("pt" for "20pt") from a length. If no units are supplied on the
+length, the <parameter>defauilt.units</parameter> are returned.</para>
+
+<programlisting><src:fragment id='length-units.frag'>
+<xsl:template name="length-units">
+ <xsl:param name="length" select="'0pt'"/>
+ <xsl:param name="default.units" select="'px'"/>
+ <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:choose>
+ <xsl:when test="$units = ''">
+ <xsl:value-of select="$default.units"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$units"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="length-spec">
+<refnamediv>
+<refname>length-spec</refname>
+<refpurpose>Return a fully qualified length specification</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>length-spec</function> template returns the
+qualified length from a dimension. If an unqualified length is given,
+the <parameter>default.units</parameter> will be added to it.
+</para>
+
+<programlisting><src:fragment id='length-spec.frag'>
+<xsl:template name="length-spec">
+ <xsl:param name="length" select="'0pt'"/>
+ <xsl:param name="default.units" select="'px'"/>
+
+ <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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="length-in-points">
+<refnamediv>
+<refname>length-in-points</refname>
+<refpurpose>Returns the size, in points, of a specified length</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>length-in-points</function> template converts a length
+specification to points and returns that value as an unqualified
+number.
+</para>
+
+<caution>
+<para>There is no way for the template to infer the size of an
+<literal>em</literal>. It relies on the default <parameter>em.size</parameter>
+which is initially <literal>10</literal> (for 10pt).</para>
+
+<para>Similarly, converting pixesl to points relies on the
+<parameter>pixels.per.inch</parameter> parameter which is initially
+<literal>90</literal>.
+</para>
+</caution>
+
+<programlisting><src:fragment id='length-in-points.frag'>
+<xsl:template name="length-in-points">
+ <xsl:param name="length" select="'0pt'"/>
+ <xsl:param name="em.size" select="10"/>
+ <xsl:param name="pixels.per.inch" select="90"/>
+
+ <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:choose>
+ <xsl:when test="$units = 'pt'">
+ <xsl:value-of select="$magnitude"/>
+ </xsl:when>
+ <xsl:when test="$units = 'cm'">
+ <xsl:value-of select="$magnitude div 2.54 * 72.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'mm'">
+ <xsl:value-of select="$magnitude div 25.4 * 72.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'in'">
+ <xsl:value-of select="$magnitude * 72.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'pc'">
+ <xsl:value-of select="$magnitude * 12.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'px'">
+ <xsl:value-of select="$magnitude div $pixels.per.inch * 72.0"/>
+ </xsl:when>
+ <xsl:when test="$units = 'em'">
+ <xsl:value-of select="$magnitude * $em.size"/>
+ </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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="pi-attribute">
+<refnamediv>
+<refname>pi-attribute</refname>
+<refpurpose>Extract a pseudo-attribute from a PI</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>pi-attribute</function> template extracts a pseudo-attribute
+from a processing instruction. For example, given the PI
+<quote><literal>&lt;?foo bar="1" baz='red'?&gt;</literal></quote>,</para>
+<programlisting><![CDATA[<xsl:call-template name="pi-attribute">
+ <xsl:with-param name="pis" select="processing-instruction('foo')"/>
+ <xsl:with-param name="attribute" select="'baz'"/>
+</xsl:call-template>]]></programlisting>
+<para>will return <quote>red</quote>. This template returns the first matching
+attribute that it finds. Presented with processing instructions that
+contain badly formed pseudo-attributes (missing or unbalanced quotes,
+for example), the template may silently return erroneous results.</para>
+
+<programlisting><src:fragment id='pi-attribute.frag'>
+<xsl:template name="pi-attribute">
+ <xsl:param name="pis" select="processing-instruction('BOGUS_PI')"/>
+ <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:variable name="pivalue">
+ <xsl:value-of select="concat(' ', normalize-space($pi))"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="contains($pivalue,concat(' ', $attribute, '='))">
+ <xsl:variable name="rest" select="substring-after($pivalue,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="pi-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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="lookup.key">
+<refnamediv>
+<refname>lookup.key</refname>
+<refpurpose>Retrieve the value associated with a particular key in a table</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>Given a table of space-delimited key/value pairs,
+the <function>lookup.key</function> template extracts the value associated
+with a particular key.</para>
+
+<programlisting><src:fragment id='lookup.key.frag'>
+<xsl:template name="lookup.key">
+ <xsl:param name="key" select="''"/>
+ <xsl:param name="table" select="''"/>
+
+ <xsl:if test="contains($table, ' ')">
+ <xsl:choose>
+ <xsl:when test="substring-before($table, ' ') = $key">
+ <xsl:variable name="rest" select="substring-after($table, ' ')"/>
+ <xsl:choose>
+ <xsl:when test="contains($rest, ' ')">
+ <xsl:value-of select="substring-before($rest, ' ')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$rest"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="lookup.key">
+ <xsl:with-param name="key" select="$key"/>
+ <xsl:with-param name="table"
+ select="substring-after(substring-after($table,' '), ' ')"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+</xsl:template>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="xpath.location">
+<refnamediv>
+<refname>xpath.location</refname>
+<refpurpose>Calculate the XPath child-sequence to the current node</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>xpath.location</function> template calculates the
+absolute path from the root of the tree to the current element node.
+</para>
+
+<programlisting><src:fragment id='xpath.location.frag'>
+<xsl:template name="xpath.location">
+ <xsl:param name="node" select="."/>
+ <xsl:param name="path" select="''"/>
+
+ <xsl:variable name="next.path">
+ <xsl:value-of select="local-name($node)"/>
+ <xsl:if test="$path != ''">/</xsl:if>
+ <xsl:value-of select="$path"/>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$node/parent::*">
+ <xsl:call-template name="xpath.location">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ <xsl:with-param name="path" select="$next.path"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>/</xsl:text>
+ <xsl:value-of select="$next.path"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<!-- ================================================================== -->
+
+<refentry id="comment-escape-string">
+<refnamediv>
+<refname>comment-escape-string</refname>
+<refpurpose>Prepare a string for inclusion in an XML comment</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>comment-escape-string</function> template returns a string
+that has been transformed so that it can safely be output as an XML comment.
+Internal occurrences of "--" will be replaced with "- -" and a leading and/or
+trailing space will be added to the string, if necessary.</para>
+
+<programlisting><src:fragment id='comment-escape-string'>
+<xsl:template name="comment-escape-string">
+ <xsl:param name="string" select="''"/>
+
+ <xsl:if test="starts-with($string, '-')">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+
+ <xsl:call-template name="comment-escape-string.recursive">
+ <xsl:with-param name="string" select="$string"/>
+ </xsl:call-template>
+
+ <xsl:if test="substring($string, string-length($string), 1) = '-'">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+</xsl:template>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<refentry id="comment-escape-string.recursive">
+<refnamediv>
+<refname>comment-escape-string.recursive</refname>
+<refpurpose>Internal function used by comment-escape-string</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>The <function>comment-escape-string.recursive</function> template is used
+by <function>comment-escape-string</function>.</para>
+
+<programlisting><src:fragment id="comment-escape-string.recursive">
+<xsl:template name="comment-escape-string.recursive">
+ <xsl:param name="string" select="''"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, '--')">
+ <xsl:value-of select="substring-before($string, '--')"/>
+ <xsl:value-of select="'- -'"/>
+ <xsl:call-template name="comment-escape-string.recursive">
+ <xsl:with-param name="string" select="substring-after($string, '--')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$string"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+</src:fragment></programlisting>
+</refsect1>
+</refentry>
+
+</reference>
+
+<reference>
+<title>Relative URI Functions</title>
+
+<partintro><title>Introduction</title>
+
+<para>These functions manipulate relative URI references.</para>
+
+<para>The following assumptions must hold true:</para>
+
+<orderedlist>
+<listitem>
+<para>All URIs are relative.</para>
+</listitem>
+<listitem>
+<para>No URI contains the <quote><literal>../</literal></quote> sequence
+which would effectively move <quote>up</quote> the hierarchy.</para>
+</listitem>
+</orderedlist>
+
+<para>If these assumptions do not hold, the results are unpredictable.</para>
+
+</partintro>
+
+<refentry id="count.uri.path.depth">
+<refnamediv>
+<refname>count.uri.path.depth</refname>
+<refpurpose>Count the number of path components in a relative URI</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>This function counts the number of path components in a relative URI.</para>
+
+<programlisting><src:fragment id='count.uri.path.depth.frag'>
+<xsl:template name="count.uri.path.depth">
+ <xsl:param name="filename" select="''"/>
+ <xsl:param name="count" select="0"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($filename, '/')">
+ <xsl:call-template name="count.uri.path.depth">
+ <xsl:with-param name="filename" select="substring-after($filename, '/')"/>
+ <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>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+<refentry id="trim.common.uri.paths">
+<refnamediv>
+<refname>trim.common.uri.paths</refname>
+<refpurpose>Trim common leading path components from a relative URI</refpurpose>
+</refnamediv>
+
+<refsect1><title>Description</title>
+
+<para>This function trims common leading path components from a relative URI.</para>
+
+<programlisting><src:fragment id='trim.common.uri.paths.frag'>
+<xsl:template name="trim.common.uri.paths">
+ <xsl:param name="uriA" select="''"/>
+ <xsl:param name="uriB" select="''"/>
+ <xsl:param name="return" select="'A'"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($uriA, '/') and contains($uriB, '/')
+ and substring-before($uriA, '/') = substring-before($uriB, '/')">
+ <xsl:call-template name="trim.common.uri.paths">
+ <xsl:with-param name="uriA" select="substring-after($uriA, '/')"/>
+ <xsl:with-param name="uriB" select="substring-after($uriB, '/')"/>
+ <xsl:with-param name="return" select="$return"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$return = 'A'">
+ <xsl:value-of select="$uriA"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$uriB"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+</src:fragment></programlisting>
+
+</refsect1>
+</refentry>
+
+</reference>
+
+<appendix><title>The Stylesheet</title>
+
+<para>The <filename>lib.xsl</filename> stylesheet is just a wrapper
+around these functions.</para>
+
+<src:fragment id="top" mundane-result-prefixes="xsl">
+
+<!-- ********************************************************************
+ $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
+
+ ******************************************************************** -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:src="http://nwalsh.com/xmlns/litprog/fragment"
+ exclude-result-prefixes="src"
+ version='1.0'>
+
+<src:fragref linkend="dot.count.frag"/>
+<src:fragref linkend="copy-string.frag"/>
+<src:fragref linkend="string.subst.frag"/>
+<src:fragref linkend="xpointer.idref.frag"/>
+<src:fragref linkend="length-magnitude.frag"/>
+<src:fragref linkend="length-units.frag"/>
+<src:fragref linkend="length-spec.frag"/>
+<src:fragref linkend="length-in-points.frag"/>
+<src:fragref linkend="pi-attribute.frag"/>
+<src:fragref linkend="lookup.key.frag"/>
+<src:fragref linkend="xpath.location.frag"/>
+<src:fragref linkend="comment-escape-string"/>
+<src:fragref linkend="comment-escape-string.recursive"/>
+<src:fragref linkend="count.uri.path.depth.frag"/>
+<src:fragref linkend="trim.common.uri.paths.frag"/>
+
+</xsl:stylesheet>
+</src:fragment>
+
+</appendix>
+</book>