aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Wielicki <j.wielicki@sotecware.net>2017-09-28 19:51:07 +0200
committerJonas Wielicki <j.wielicki@sotecware.net>2017-09-28 19:51:07 +0200
commitb9a410551eb6e33c829ab7435d258c7e0ed58954 (patch)
treee63e7f4737ceadf81d36c313cb9d89c6e50d1eee
parentfba129b50845dffe32d069bbd9d5276e03613e78 (diff)
Import the texml-related XSL files into this repository
This helps against build failures due to sourceforge being unavailable.
-rw-r--r--Dockerfile1
-rw-r--r--texml-xsl/cmp.xsl318
-rw-r--r--texml-xsl/date-time.xsl1447
-rw-r--r--texml-xsl/example.xsl90
-rw-r--r--texml-xsl/markup.xsl789
-rw-r--r--texml-xsl/math.xsl618
-rw-r--r--texml-xsl/node.xsl229
-rw-r--r--texml-xsl/stdlib.xsl340
-rw-r--r--texml-xsl/string.xsl1233
-rw-r--r--texml-xsl/svg.xsl1
-rw-r--r--texml-xsl/uri.xsl580
-rw-r--r--xep2texml.xsl2
12 files changed, 5647 insertions, 1 deletions
diff --git a/Dockerfile b/Dockerfile
index f0c22cf..f97e318 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -10,6 +10,7 @@ COPY *.xml xep.* *.css *.xsl *.js *.xsl Makefile /src/
COPY resources/*.pdf /src/resources/
COPY tools/*.py /src/tools/
COPY inbox/*.xml inbox/*.ent inbox/*.dtd /src/inbox/
+COPY texml-xsl/*.xsl /src/texml-xsl/
WORKDIR /src
RUN OUTDIR=/var/www/html/extensions/ make -j$NCORES $TARGETS
diff --git a/texml-xsl/cmp.xsl b/texml-xsl/cmp.xsl
new file mode 100644
index 0000000..59ec8a5
--- /dev/null
+++ b/texml-xsl/cmp.xsl
@@ -0,0 +1,318 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet
+ version="1.0"
+ extension-element-prefixes="doc"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
+ xmlns:str="http://xsltsl.org/string"
+ xmlns:cmp="http://xsltsl.org/cmp"
+ exclude-result-prefixes="cmp str doc"
+>
+
+ <doc:reference xmlns="">
+ <referenceinfo>
+ <releaseinfo role="meta">
+ $Id$
+ </releaseinfo>
+ <author>
+ <surname>Hummel</surname>
+ <firstname>Mark</firstname>
+ </author>
+ <copyright>
+ <year>2003</year>
+ <holder>Mark Hummel</holder>
+ </copyright>
+ </referenceinfo>
+
+ <title>XML Compare</title>
+
+ <partintro>
+ <section>
+ <title>Introduction</title>
+
+ <para>This module provides a template for comparing two xml documents. </para>
+
+ </section>
+ </partintro>
+
+ </doc:reference>
+
+
+ <doc:template name="cmp:diff">
+ <refpurpose>Compare</refpurpose>
+
+ <refdescription>
+ <para>Compare two xml documents and display differences. Two xml documents are defined to be the same if: They have the matching elements and attributes, and that the data in the elements also match. The comparison is order sensitive. </para>
+
+ <para>The element names from the documents at the current depth are compared, followed by their values, then any attribute names and values are compared. The process is applied then to the subtrees of the documents.</para>
+
+ <para>Notes: If there are leaf nodes in one nodeset which don't exist in the other, the value of those 'extra' elements won't appear as a difference.
+ </para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>ns1</term>
+ <term>ns2</term>
+ <listitem>
+ <para>The two nodesets which are to be compared. </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the difference between the documents. </para>
+
+ <para>The format of the output is an xml document. A node is added to the result tree for every difference. The node contains the type of difference (e.g element name difference, attribute value difference, etc), the value in the first nodeset and the value in the second nodeset, and the parent node. The indentation level is the depth at which the difference was found relative to the first document. </para>
+
+ </refreturn>
+ </doc:template>
+
+ <!-- pass in a nodeset and compare. Is order sensitive. Output attribute, element and textual differences. -->
+
+ <xsl:template name="cmp:diff">
+ <xsl:param name="ns1"/>
+ <xsl:param name="ns2"/>
+
+ <!-- attribute compare -->
+ <!-- Optimisation attempt
+
+ Can probaby change this into one loop ie -
+ <xsl:for-each
+ i = position
+ if node1[i] = node2[i]...
+
+ -->
+
+ <!-- Need to check if there are two sets of attributes -->
+ <xsl:choose>
+ <xsl:when test='count($ns1/attribute::*) = count($ns2/attribute::*)'>
+ <xsl:for-each select="$ns1/attribute::*">
+ <xsl:variable name="name1" select="name()"/>
+ <xsl:variable name="value1" select="."/>
+ <xsl:variable name="i" select="position()"/>
+
+ <xsl:for-each select="$ns2/attribute::*">
+
+ <xsl:variable name="j" select="position()"/>
+ <xsl:variable name="name2" select="name()"/>
+ <xsl:variable name="value2" select="."/>
+
+ <xsl:if test="$i = $j">
+ <xsl:if test="$name1 != $name2">
+ <attributeNameDifference>
+ <parentElement><xsl:value-of select="name(..)"/></parentElement>
+ <before><xsl:value-of select="$name1"/></before>
+ <after><xsl:value-of select="$name2"/></after>
+ </attributeNameDifference>
+ </xsl:if>
+
+ <xsl:if test="$name1 = $name2 and $value1 != $value2">
+ <attributeValueDifference>
+ <parentElement><xsl:value-of select="name(..)"/></parentElement>
+ <before><xsl:value-of select="$value1"/></before>
+ <after><xsl:value-of select="$value2"/></after>
+ </attributeValueDifference>
+ </xsl:if>
+
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <attributeNameDifference>
+ <parentElement>
+ <xsl:value-of select="name(..)"/>
+ </parentElement>
+ <before><xsl:value-of select='$ns1/attribute::*'/></before>
+ <after><xsl:value-of select='$ns2/attribute::*'/></after>
+ </attributeNameDifference>
+ </xsl:otherwise>
+ </xsl:choose>
+
+
+ <!-- Find element differences by comparing the element names from the same position in both documents. Iterate over all the nodes in the nodeset with the largest number of elements, so the extra elements will appear as differences. -->
+
+ <xsl:choose>
+ <!-- Define loop direction based on which tree has more nodes
+ FIXME: Replacing this with one for-each and a test for the case
+ of the second tree having more nodes would be more elegant
+
+ Solution: Add variable for direction and assign the 'larger' nodeset to that
+ variable. Then do one for-each.
+
+ FIXME: The solution is a bit too iterative. Make it more functional
+
+ -->
+ <xsl:when test="count($ns1) &gt; count($ns2)">
+ <xsl:for-each select="$ns1">
+ <xsl:variable name="i" select="position()"/>
+
+ <xsl:message>node[<xsl:value-of select='$i'/>]:
+ <xsl:value-of select='$ns1[$i]'/>
+ </xsl:message>
+
+ <!-- Element name compare -->
+ <xsl:if test="name($ns1[$i]) != name($ns2[$i])">
+ <elementNameDifference>
+ <parentElement><xsl:value-of select="name(..)"/></parentElement>
+ <before><xsl:value-of select="name($ns1[$i])"/></before>
+ <after><xsl:value-of select="name($ns2[$i])"/></after>
+ </elementNameDifference>
+ </xsl:if>
+
+ <!-- Element Value compare -->
+
+ <xsl:if test="count($ns1/*) = 0">
+ <xsl:if test="$ns1[$i] != $ns2[$i]">
+ <elementValueDifference>
+ <parentElement><xsl:value-of select="name(..)"/></parentElement>
+ <before><xsl:value-of select="$ns1[$i]"/></before>
+ <after><xsl:value-of select="$ns2[$i]"/></after>
+ </elementValueDifference>
+ </xsl:if>
+ </xsl:if>
+
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="$ns2">
+ <xsl:variable name="i" select="position()"/>
+
+ <!-- Element Name compare -->
+
+ <xsl:if test="name($ns1[$i]) != name($ns2[$i])">
+ <elementNameDifference>
+ <parentElement><xsl:value-of select="name(..)"/></parentElement>
+ <before><xsl:value-of select="name($ns1[$i])"/></before>
+ <after><xsl:value-of select="name($ns2[$i])"/></after>
+ </elementNameDifference>
+
+ </xsl:if>
+
+ <!-- value compare -->
+
+ <xsl:if test="count($ns2/*) = 0">
+ <xsl:if test="$ns2[$i] != $ns1[$i]">
+ <elementValueDifference>
+ <parentElement><xsl:value-of select="name(..)"/></parentElement>
+ <after><xsl:value-of select="$ns2[$i]"/></after>
+ <before><xsl:value-of select="$ns1[$i]"/></before>
+ </elementValueDifference>
+ </xsl:if>
+ </xsl:if>
+
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <!-- stop processing when leaf node is reached. -->
+
+ <xsl:if test="count($ns1/*) &gt; 0 and count($ns2/*) &gt; 0">
+ <xsl:call-template name="cmp:diff">
+ <xsl:with-param name="ns1" select="$ns1/*"/>
+ <xsl:with-param name="ns2" select="$ns2/*"/>
+ </xsl:call-template>
+ </xsl:if>
+
+ </xsl:template>
+
+ <!-- Return false if the two nodesets are not identical
+ -->
+
+ <xsl:template name="cmp:cmp">
+ <xsl:param name="ns1"/>
+ <xsl:param name="ns2"/>
+ <xsl:param name="depth"/>
+
+ <xsl:choose>
+ <xsl:when test='count($ns1) != count($ns2)'>
+ <xsl:value-of select='"countDiff"'/>
+ </xsl:when>
+ <xsl:when test='count($ns1/attribute::*) != count($ns2/attribute::*)'>
+ <xsl:value-of select='"countDiff"'/>
+ </xsl:when>
+ <xsl:when test='$ns1 and $ns2'>
+
+ <xsl:variable name='result'>
+ <xsl:call-template name='cmp:cmp'>
+ <xsl:with-param name='ns1' select='$ns1/*'/>
+ <xsl:with-param name='ns2' select='$ns2/*'/>
+ <xsl:with-param name='depth' select='$depth+1'/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test='$result = "countDiff"'>
+ <xsl:value-of select='$result'/>
+ </xsl:when>
+ <xsl:when test='$result = "textDiff"'>
+ <xsl:value-of select='$result'/>
+ </xsl:when>
+ <xsl:when test='$result = ""'>
+
+ <xsl:variable name='keyText1' select='name($ns1)'/>
+ <xsl:variable name='keyText2' select='name($ns2)'/>
+
+ <xsl:choose>
+ <!-- Check if the text of the nodesets are the same and the attributes-->
+ <xsl:when test='$ns1 = $ns2 and $keyText1 = $keyText2'>
+
+ <!-- Check the attribute names are the same -->
+ <!-- Number of attributes being different is caught higher up -->
+ <xsl:if test='count($ns1/attribute::*)'>
+ <xsl:for-each select='$ns1/attribute::*'>
+ <xsl:variable name='i' select='position()'/>
+ <xsl:variable name='name1' select='name(.)'/>
+ <xsl:variable name='value1' select='.'/>
+
+ <xsl:for-each select='$ns2/attribute::*'>
+ <xsl:variable name='j' select='position()'/>
+ <xsl:variable name='name2' select='name(.)'/>
+ <xsl:variable name='value2' select='.'/>
+
+ <xsl:if test='$i = $j and ($name1 != $name2 or
+ $value1 != $value2)'>
+ <xsl:value-of select='"textDiff"'/>
+ </xsl:if>
+
+ </xsl:for-each>
+ </xsl:for-each>
+ </xsl:if>
+ <!--
+ <xsl:variable name='diffResult'>
+ <xsl:call-template name='cmp:diff'>
+ <xsl:with-param name='ns1' select='$ns1'/>
+ <xsl:with-param name='ns2' select='$ns2'/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:if test='not($diffResult = "")'>
+ <xsl:value-of select='"textDiff"'/>
+ </xsl:if>
+ -->
+
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select='"textDiff"'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+
+ </xsl:when>
+ <xsl:when test='$ns1 and not($ns2)'>
+ <xsl:value-of select='"structDiff"'/>
+ </xsl:when>
+ <xsl:when test='$ns2 and not($ns1)'>
+ <xsl:value-of select='"structDiff"'/>
+ </xsl:when>
+ </xsl:choose>
+
+ </xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/texml-xsl/date-time.xsl b/texml-xsl/date-time.xsl
new file mode 100644
index 0000000..f2c96cf
--- /dev/null
+++ b/texml-xsl/date-time.xsl
@@ -0,0 +1,1447 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
+ xmlns:dt="http://xsltsl.org/date-time"
+ xmlns:str="http://xsltsl.org/string"
+ extension-element-prefixes="doc str">
+
+ <doc:reference xmlns="">
+ <referenceinfo>
+ <releaseinfo role="meta">
+ $Id$
+ </releaseinfo>
+ <author>
+ <surname>Diamond</surname>
+ <firstname>Jason</firstname>
+ </author>
+ <copyright>
+ <year>2004</year>
+ <holder>Steve Ball</holder>
+ </copyright>
+ <copyright>
+ <year>2001</year>
+ <holder>Jason Diamond</holder>
+ </copyright>
+ </referenceinfo>
+
+ <title>Date/Time Processing</title>
+
+ <partintro>
+ <section>
+ <title>Introduction</title>
+
+ <para>This module provides templates for formatting and parsing date/time strings.</para>
+
+ <para>See <ulink url="http://www.tondering.dk/claus/calendar.html">http://www.tondering.dk/claus/calendar.html</ulink> for more information on calendars and the calculations this library performs.</para>
+
+ </section>
+ </partintro>
+
+ </doc:reference>
+
+ <doc:template name="dt:format-date-time" xmlns="">
+ <refpurpose>Returns a string with a formatted date/time.</refpurpose>
+
+ <refdescription>
+ <para>The formatted date/time is determined by the format parameter. The default format is %Y-%m-%dT%H:%M:%S%z, the W3C format.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+
+ <varlistentry>
+ <term>xsd-date-time</term>
+ <listitem>
+ <para>The date-time value in XML Schemas (WXS) format.</para>
+ <para>If this value is specified, it takes priority over other parameters.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>year</term>
+ <listitem>
+ <para>Year</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>month</term>
+ <listitem>
+ <para>Month (1 - 12; January = 1)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>day</term>
+ <listitem>
+ <para>Day of month (1 - 31)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>hour</term>
+ <listitem>
+ <para>Hours since midnight (0 - 23)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>minute</term>
+ <listitem>
+ <para>Minutes after hour (0 - 59)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>second</term>
+ <listitem>
+ <para>Seconds after minute (0 - 59)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>time-zone</term>
+ <listitem>
+ <para>Time zone string (e.g., 'Z' or '-08:00')</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>format</term>
+ <listitem>
+ <para>The format specification.</para>
+ <variablelist>
+
+ <varlistentry>
+ <term>%a</term>
+ <listitem>
+ <para>Abbreviated weekday name</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%A</term>
+ <listitem>
+ <para>Full weekday name</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%b</term>
+ <listitem>
+ <para>Abbreviated month name</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%B</term>
+ <listitem>
+ <para>Full month name</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%c</term>
+ <listitem>
+ <para>Date and time representation appropriate for locale</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%d</term>
+ <listitem>
+ <para>Day of month as decimal number (01 - 31)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%e</term>
+ <listitem>
+ <para>Day of month as decimal number (1 - 31)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%H</term>
+ <listitem>
+ <para>Hour in 24-hour format (00 - 23)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%I</term>
+ <listitem>
+ <para>Hour in 12-hour format (01 - 12)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%i</term>
+ <listitem>
+ <para>Hour in 12-hour format (1 - 12)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%j</term>
+ <listitem>
+ <para>Day of year as decimal number (001 - 366)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%m</term>
+ <listitem>
+ <para>Month as decimal number (01 - 12)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%n</term>
+ <listitem>
+ <para>Month as decimal number (1 - 12)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%M</term>
+ <listitem>
+ <para>Minute as decimal number (00 - 59)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%P</term>
+ <listitem>
+ <para>Current locale's A.M./P.M. indicator for 12-hour clock, uppercase</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%Q</term>
+ <listitem>
+ <para>Current locale's A.M./P.M. indicator for 12-hour clock, uppercase with periods</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%p</term>
+ <listitem>
+ <para>Current locale's A.M./P.M. indicator for 12-hour clock, lowercase</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%q</term>
+ <listitem>
+ <para>Current locale's A.M./P.M. indicator for 12-hour clock, lowercase with periods</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%S</term>
+ <listitem>
+ <para>Second as decimal number (00 - 59)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%U</term>
+ <listitem>
+ <para>Week of year as decimal number, with Sunday as first day of week (00 - 53)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%w</term>
+ <listitem>
+ <para>Weekday as decimal number (0 - 6; Sunday is 0)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%W</term>
+ <listitem>
+ <para>Week of year as decimal number, with Monday as first day of week (00 - 53)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%x</term>
+ <listitem>
+ <para>Date representation for current locale </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%X</term>
+ <listitem>
+ <para>Time representation for current locale</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%y</term>
+ <listitem>
+ <para>Year without century, as decimal number (00 - 99)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%Y</term>
+ <listitem>
+ <para>Year with century, as decimal number</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%z</term>
+ <listitem>
+ <para>Time-zone name or abbreviation; no characters if time zone is unknown</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>%%</term>
+ <listitem>
+ <para>Percent sign</para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a formatted date/time string.</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:format-date-time">
+ <xsl:param name='xsd-date-time'/>
+ <xsl:param name="year"/>
+ <xsl:param name="month"/>
+ <xsl:param name="day"/>
+ <xsl:param name="hour"/>
+ <xsl:param name="minute"/>
+ <xsl:param name="second"/>
+ <xsl:param name="time-zone"/>
+ <xsl:param name="format" select="'%Y-%m-%dT%H:%M:%S%z'"/>
+
+ <xsl:value-of select="substring-before($format, '%')"/>
+
+ <xsl:variable name="code" select="substring(substring-after($format, '%'), 1, 1)"/>
+
+ <xsl:choose>
+
+ <xsl:when test='$xsd-date-time'>
+ <xsl:call-template name='dt:format-date-time'>
+ <xsl:with-param name='year'>
+ <xsl:call-template name='dt:get-xsd-datetime-year'>
+ <xsl:with-param name='xsd-date-time' select='$xsd-date-time'/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name='month'>
+ <xsl:call-template name='dt:get-xsd-datetime-month'>
+ <xsl:with-param name='xsd-date-time' select='$xsd-date-time'/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name='day'>
+ <xsl:call-template name='dt:get-xsd-datetime-day'>
+ <xsl:with-param name='xsd-date-time' select='$xsd-date-time'/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name='hour'>
+ <xsl:call-template name='dt:get-xsd-datetime-hour'>
+ <xsl:with-param name='xsd-date-time' select='$xsd-date-time'/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name='minute'>
+ <xsl:call-template name='dt:get-xsd-datetime-minute'>
+ <xsl:with-param name='xsd-date-time' select='$xsd-date-time'/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name='second'>
+ <xsl:call-template name='dt:get-xsd-datetime-second'>
+ <xsl:with-param name='xsd-date-time' select='$xsd-date-time'/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name='time-zone'>
+ <xsl:call-template name='dt:get-xsd-datetime-timezone'>
+ <xsl:with-param name='xsd-date-time' select='$xsd-date-time'/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name='format'>
+ <xsl:choose>
+ <xsl:when test='contains($format, "%")'>
+ <xsl:text>%</xsl:text>
+ <xsl:value-of select='substring-after($format, "%")'/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select='$format'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Abbreviated weekday name -->
+ <xsl:when test="$code='a'">
+ <xsl:variable name="day-of-the-week">
+ <xsl:call-template name="dt:calculate-day-of-the-week">
+ <xsl:with-param name="year" select="$year"/>
+ <xsl:with-param name="month" select="$month"/>
+ <xsl:with-param name="day" select="$day"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:call-template name="dt:get-day-of-the-week-abbreviation">
+ <xsl:with-param name="day-of-the-week" select="$day-of-the-week"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Full weekday name -->
+ <xsl:when test="$code='A'">
+ <xsl:variable name="day-of-the-week">
+ <xsl:call-template name="dt:calculate-day-of-the-week">
+ <xsl:with-param name="year" select="$year"/>
+ <xsl:with-param name="month" select="$month"/>
+ <xsl:with-param name="day" select="$day"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:call-template name="dt:get-day-of-the-week-name">
+ <xsl:with-param name="day-of-the-week" select="$day-of-the-week"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Abbreviated month name -->
+ <xsl:when test="$code='b'">
+ <xsl:call-template name="dt:get-month-abbreviation">
+ <xsl:with-param name="month" select="$month"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Full month name -->
+ <xsl:when test="$code='B'">
+ <xsl:call-template name="dt:get-month-name">
+ <xsl:with-param name="month" select="$month"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Date and time representation appropriate for locale -->
+ <xsl:when test="$code='c'">
+ <xsl:text>[not implemented]</xsl:text>
+ </xsl:when>
+
+ <!-- Day of month as decimal number (01 - 31) -->
+ <xsl:when test="$code='d'">
+ <xsl:if test="$day &lt; 10">0</xsl:if>
+ <xsl:value-of select="number($day)"/>
+ </xsl:when>
+ <!-- Day of month as decimal number (1 - 31) -->
+ <xsl:when test="$code='e'">
+ <xsl:value-of select="number($day)"/>
+ </xsl:when>
+
+ <!-- Hour in 24-hour format (00 - 23) -->
+ <xsl:when test="$code='H'">
+ <xsl:if test="$hour &lt; 10">0</xsl:if>
+ <xsl:value-of select="number($hour)"/>
+ </xsl:when>
+
+ <!-- Hour in 12-hour format (01 - 12) -->
+ <xsl:when test="$code='I'">
+ <xsl:choose>
+ <xsl:when test="$hour = 0">12</xsl:when>
+ <xsl:when test="$hour &lt; 10">0<xsl:value-of select="$hour - 0"/></xsl:when>
+ <xsl:when test="$hour &lt; 13"><xsl:value-of select="$hour - 0"/></xsl:when>
+ <xsl:when test="$hour &lt; 22">0<xsl:value-of select="$hour - 12"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$hour - 12"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <!-- Hour in 12-hour format (1 - 12) -->
+ <xsl:when test="$code='i'">
+ <xsl:choose>
+ <xsl:when test="$hour = 0">12</xsl:when>
+ <xsl:when test="$hour &lt; 10"><xsl:value-of select="$hour - 0"/></xsl:when>
+ <xsl:when test="$hour &lt; 13"><xsl:value-of select="$hour - 0"/></xsl:when>
+ <xsl:when test="$hour &lt; 22"><xsl:value-of select="$hour - 12"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$hour - 12"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <!-- Day of year as decimal number (001 - 366) -->
+ <xsl:when test="$code='j'">
+ <xsl:text>[not implemented]</xsl:text>
+ </xsl:when>
+
+ <!-- Month as decimal number (01 - 12) -->
+ <xsl:when test="$code='m'">
+ <xsl:if test="$month &lt; 10">0</xsl:if>
+ <xsl:value-of select="number($month)"/>
+ </xsl:when>
+ <!-- Month as decimal number (1 - 12) -->
+ <xsl:when test="$code='n'">
+ <xsl:value-of select="number($month)"/>
+ </xsl:when>
+
+ <!-- Minute as decimal number (00 - 59) -->
+ <xsl:when test="$code='M'">
+ <xsl:if test="$minute &lt; 10">0</xsl:if>
+ <xsl:value-of select="number($minute)"/>
+ </xsl:when>
+
+ <!-- Current locale's A.M./P.M. indicator for 12-hour clock -->
+ <xsl:when test="$code='p'">
+ <xsl:choose>
+ <xsl:when test="$hour &lt; 12">am</xsl:when>
+ <xsl:otherwise>pm</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <!-- Current locale's A.M./P.M. indicator for 12-hour clock with periods -->
+ <xsl:when test="$code='q'">
+ <xsl:choose>
+ <xsl:when test="$hour &lt; 12">am</xsl:when>
+ <xsl:otherwise>p.m.</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <!-- Current locale's A.M./P.M. indicator for 12-hour clock -->
+ <xsl:when test="$code='P'">
+ <xsl:choose>
+ <xsl:when test="$hour &lt; 12">AM</xsl:when>
+ <xsl:otherwise>PM</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <!-- Current locale's A.M./P.M. indicator for 12-hour clock with periods -->
+ <xsl:when test="$code='Q'">
+ <xsl:choose>
+ <xsl:when test="$hour &lt; 12">AM</xsl:when>
+ <xsl:otherwise>P.M.</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <!-- Second as decimal number (00 - 59) -->
+ <xsl:when test="$code='S'">
+ <xsl:if test="$second &lt; 10">0</xsl:if>
+ <xsl:value-of select="number($second)"/>
+ </xsl:when>
+
+ <!-- Week of year as decimal number, with Sunday as first day of week (00 - 53) -->
+ <xsl:when test="$code='U'">
+ <!-- add 1 to day -->
+ <xsl:call-template name="dt:calculate-week-number">
+ <xsl:with-param name="year" select="$year"/>
+ <xsl:with-param name="month" select="$month"/>
+ <xsl:with-param name="day" select="$day + 1"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Weekday as decimal number (0 - 6; Sunday is 0) -->
+ <xsl:when test="$code='w'">
+ <xsl:call-template name="dt:calculate-day-of-the-week">
+ <xsl:with-param name="year" select="$year"/>
+ <xsl:with-param name="month" select="$month"/>
+ <xsl:with-param name="day" select="$day"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Week of year as decimal number, with Monday as first day of week (00 - 53) -->
+ <xsl:when test="$code='W'">
+ <xsl:call-template name="dt:calculate-week-number">
+ <xsl:with-param name="year" select="$year"/>
+ <xsl:with-param name="month" select="$month"/>
+ <xsl:with-param name="day" select="$day"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Date representation for current locale -->
+ <xsl:when test="$code='x'">
+ <xsl:text>[not implemented]</xsl:text>
+ </xsl:when>
+
+ <!-- Time representation for current locale -->
+ <xsl:when test="$code='X'">
+ <xsl:text>[not implemented]</xsl:text>
+ </xsl:when>
+
+ <!-- Year without century, as decimal number (00 - 99) -->
+ <xsl:when test="$code='y'">
+ <xsl:text>[not implemented]</xsl:text>
+ </xsl:when>
+
+ <!-- Year with century, as decimal number -->
+ <xsl:when test="$code='Y'">
+ <xsl:value-of select="concat(substring('000', string-length(number($year))), $year)"/>
+ </xsl:when>
+
+ <!-- Time-zone name or abbreviation; no characters if time zone is unknown -->
+ <xsl:when test="$code='z'">
+ <xsl:value-of select="$time-zone"/>
+ </xsl:when>
+
+ <!-- Percent sign -->
+ <xsl:when test="$code='%'">
+ <xsl:text>%</xsl:text>
+ </xsl:when>
+
+ </xsl:choose>
+
+ <xsl:variable name="remainder" select="substring(substring-after($format, '%'), 2)"/>
+
+ <xsl:if test="not($xsd-date-time) and $remainder">
+ <xsl:call-template name="dt:format-date-time">
+ <xsl:with-param name="year" select="$year"/>
+ <xsl:with-param name="month" select="$month"/>
+ <xsl:with-param name="day" select="$day"/>
+ <xsl:with-param name="hour" select="$hour"/>
+ <xsl:with-param name="minute" select="$minute"/>
+ <xsl:with-param name="second" select="$second"/>
+ <xsl:with-param name="time-zone" select="$time-zone"/>
+ <xsl:with-param name="format" select="$remainder"/>
+ </xsl:call-template>
+ </xsl:if>
+
+ </xsl:template>
+
+ <doc:template name="dt:calculate-day-of-the-week" xmlns="">
+ <refpurpose>Calculates the day of the week.</refpurpose>
+
+ <refdescription>
+ <para>Given any Gregorian date, this calculates the day of the week.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>year</term>
+ <listitem>
+ <para>Year</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>month</term>
+ <listitem>
+ <para>Month (1 - 12; January = 1)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>day</term>
+ <listitem>
+ <para>Day of month (1 - 31)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the day of the week (0 - 6; Sunday = 0).</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:calculate-day-of-the-week">
+ <xsl:param name="year"/>
+ <xsl:param name="month"/>
+ <xsl:param name="day"/>
+
+ <xsl:variable name="a" select="floor((14 - $month) div 12)"/>
+ <xsl:variable name="y" select="$year - $a"/>
+ <xsl:variable name="m" select="$month + 12 * $a - 2"/>
+
+ <xsl:value-of select="($day + $y + floor($y div 4) - floor($y div 100) + floor($y div 400) + floor((31 * $m) div 12)) mod 7"/>
+
+ </xsl:template>
+
+ <doc:template name="dt:calculate-last-day-of-month" xmlns="">
+ <refpurpose>Calculates the number of days for a specified month.</refpurpose>
+
+ <refdescription>
+ <para>Given any Gregorian month, this calculates the last day of the month.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>year</term>
+ <listitem>
+ <para>Year</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>month</term>
+ <listitem>
+ <para>Month (1 - 12; January = 1)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the number of days in given month as a decimal number.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="dt:calculate-last-day-of-month">
+ <xsl:param name="year"/>
+ <xsl:param name="month"/>
+
+ <xsl:choose>
+ <xsl:when test="$month = 2">
+ <xsl:choose>
+ <xsl:when test="($year mod 4) = 0 and (($year mod 400) = 0
+ or ($year mod 100) != 0)">29</xsl:when>
+ <xsl:otherwise>28</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="$month &lt; 8">
+ <xsl:choose>
+ <xsl:when test="$month mod 2 = 0">30</xsl:when>
+ <xsl:otherwise>31</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$month mod 2 = 1">30</xsl:when>
+ <xsl:otherwise>31</xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="dt:get-day-of-the-week-name" xmlns="">
+ <refpurpose>Gets the day of the week's full name.</refpurpose>
+
+ <refdescription>
+ <para>Converts a numeric day of the week value into a string representing the day's full name.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>day-of-the-week</term>
+ <listitem>
+ <para>Day of the week (0 - 6; Sunday = 0)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a string.</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:get-day-of-the-week-name">
+ <xsl:param name="day-of-the-week"/>
+
+ <xsl:choose>
+ <xsl:when test="$day-of-the-week = 0">Sunday</xsl:when>
+ <xsl:when test="$day-of-the-week = 1">Monday</xsl:when>
+ <xsl:when test="$day-of-the-week = 2">Tuesday</xsl:when>
+ <xsl:when test="$day-of-the-week = 3">Wednesday</xsl:when>
+ <xsl:when test="$day-of-the-week = 4">Thursday</xsl:when>
+ <xsl:when test="$day-of-the-week = 5">Friday</xsl:when>
+ <xsl:when test="$day-of-the-week = 6">Saturday</xsl:when>
+ <xsl:otherwise>error: <xsl:value-of select="$day-of-the-week"/></xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="dt:get-day-of-the-week-abbreviation" xmlns="">
+ <refpurpose>Gets the day of the week's abbreviation.</refpurpose>
+
+ <refdescription>
+ <para>Converts a numeric day of the week value into a string representing the day's abbreviation.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>day-of-the-week</term>
+ <listitem>
+ <para>Day of the week (0 - 6; Sunday = 0)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a string.</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:get-day-of-the-week-abbreviation">
+ <xsl:param name="day-of-the-week"/>
+
+ <xsl:choose>
+ <xsl:when test="$day-of-the-week = 0">Sun</xsl:when>
+ <xsl:when test="$day-of-the-week = 1">Mon</xsl:when>
+ <xsl:when test="$day-of-the-week = 2">Tue</xsl:when>
+ <xsl:when test="$day-of-the-week = 3">Wed</xsl:when>
+ <xsl:when test="$day-of-the-week = 4">Thu</xsl:when>
+ <xsl:when test="$day-of-the-week = 5">Fri</xsl:when>
+ <xsl:when test="$day-of-the-week = 6">Sat</xsl:when>
+ <xsl:otherwise>error: <xsl:value-of select="$day-of-the-week"/></xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="dt:get-month-name" xmlns="">
+ <refpurpose>Gets the month's full name.</refpurpose>
+
+ <refdescription>
+ <para>Converts a numeric month value into a string representing the month's full name.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>month</term>
+ <listitem>
+ <para>Month (1 - 12; Januaray = 1)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a string.</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:get-month-name">
+ <xsl:param name="month"/>
+
+ <xsl:choose>
+ <xsl:when test="$month = 1">January</xsl:when>
+ <xsl:when test="$month = 2">February</xsl:when>
+ <xsl:when test="$month = 3">March</xsl:when>
+ <xsl:when test="$month = 4">April</xsl:when>
+ <xsl:when test="$month = 5">May</xsl:when>
+ <xsl:when test="$month = 6">June</xsl:when>
+ <xsl:when test="$month = 7">July</xsl:when>
+ <xsl:when test="$month = 8">August</xsl:when>
+ <xsl:when test="$month = 9">September</xsl:when>
+ <xsl:when test="$month = 10">October</xsl:when>
+ <xsl:when test="$month = 11">November</xsl:when>
+ <xsl:when test="$month = 12">December</xsl:when>
+ <xsl:otherwise>error: <xsl:value-of select="$month"/></xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="dt:get-month-abbreviation" xmlns="">
+ <refpurpose>Gets the month's abbreviation.</refpurpose>
+
+ <refdescription>
+ <para>Converts a numeric month value into a string representing the month's abbreviation.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>month</term>
+ <listitem>
+ <para>Month (1 - 12; Januaray = 1)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a string.</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:get-month-abbreviation">
+ <xsl:param name="month"/>
+
+ <xsl:choose>
+ <xsl:when test="$month = 1">Jan</xsl:when>
+ <xsl:when test="$month = 2">Feb</xsl:when>
+ <xsl:when test="$month = 3">Mar</xsl:when>
+ <xsl:when test="$month = 4">Apr</xsl:when>
+ <xsl:when test="$month = 5">May</xsl:when>
+ <xsl:when test="$month = 6">Jun</xsl:when>
+ <xsl:when test="$month = 7">Jul</xsl:when>
+ <xsl:when test="$month = 8">Aug</xsl:when>
+ <xsl:when test="$month = 9">Sep</xsl:when>
+ <xsl:when test="$month = 10">Oct</xsl:when>
+ <xsl:when test="$month = 11">Nov</xsl:when>
+ <xsl:when test="$month = 12">Dec</xsl:when>
+ <xsl:otherwise>error: <xsl:value-of select="$month"/></xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="dt:calculate-julian-day" xmlns="">
+ <refpurpose>Calculates the Julian Day for a specified date.</refpurpose>
+
+ <refdescription>
+ <para>Given any Gregorian date, this calculates the Julian Day.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>year</term>
+ <listitem>
+ <para>Year</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>month</term>
+ <listitem>
+ <para>Month (1 - 12; January = 1)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>day</term>
+ <listitem>
+ <para>Day of month (1 - 31)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the Julian Day as a decimal number.</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:calculate-julian-day">
+ <xsl:param name="year"/>
+ <xsl:param name="month"/>
+ <xsl:param name="day"/>
+
+ <xsl:variable name="a" select="floor((14 - $month) div 12)"/>
+ <xsl:variable name="y" select="$year + 4800 - $a"/>
+ <xsl:variable name="m" select="$month + 12 * $a - 3"/>
+
+ <xsl:value-of select="$day + floor((153 * $m + 2) div 5) + $y * 365 + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045"/>
+
+ </xsl:template>
+
+ <doc:template name="dt:format-julian-day" xmlns="">
+ <refpurpose>Returns a string with a formatted date for a specified Julian Day.</refpurpose>
+
+ <refdescription>
+ <para>Given any Julian Day, this returns a string according to the format specification.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>julian-day</term>
+ <listitem>
+ <para>A Julian Day</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>format</term>
+ <listitem>
+ <para>The format specification. See dt:format-date-time for more details.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>A string.</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:format-julian-day">
+ <xsl:param name="julian-day"/>
+ <xsl:param name="format" select="'%Y-%m-%d'"/>
+
+ <xsl:variable name="a" select="$julian-day + 32044"/>
+ <xsl:variable name="b" select="floor((4 * $a + 3) div 146097)"/>
+ <xsl:variable name="c" select="$a - floor(($b * 146097) div 4)"/>
+
+ <xsl:variable name="d" select="floor((4 * $c + 3) div 1461)"/>
+ <xsl:variable name="e" select="$c - floor((1461 * $d) div 4)"/>
+ <xsl:variable name="m" select="floor((5 * $e + 2) div 153)"/>
+
+ <xsl:variable name="day" select="$e - floor((153 * $m + 2) div 5) + 1"/>
+ <xsl:variable name="month" select="$m + 3 - 12 * floor($m div 10)"/>
+ <xsl:variable name="year" select="$b * 100 + $d - 4800 + floor($m div 10)"/>
+
+ <xsl:call-template name="dt:format-date-time">
+ <xsl:with-param name="year" select="$year"/>
+ <xsl:with-param name="month" select="$month"/>
+ <xsl:with-param name="day" select="$day"/>
+ <xsl:with-param name="format" select="$format"/>
+ </xsl:call-template>
+
+ </xsl:template>
+
+ <doc:template name="dt:calculate-week-number" xmlns="">
+ <refpurpose>Calculates the week number for a specified date.</refpurpose>
+
+ <refdescription>
+ <para>Assumes Monday is the first day of the week.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>year</term>
+ <listitem>
+ <para>Year</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>month</term>
+ <listitem>
+ <para>Month (1 - 12; January = 1)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>day</term>
+ <listitem>
+ <para>Day of month (1 - 31)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the week number as a decimal number.</para>
+ </refreturn>
+
+ </doc:template>
+
+ <xsl:template name="dt:calculate-week-number">
+ <xsl:param name="year"/>
+ <xsl:param name="month"/>
+ <xsl:param name="day"/>
+
+ <xsl:variable name="J">
+ <xsl:call-template name="dt:calculate-julian-day">
+ <xsl:with-param name="year" select="$year"/>
+ <xsl:with-param name="month" select="$month"/>
+ <xsl:with-param name="day" select="$day"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="d4" select="($J + 31741 - ($J mod 7)) mod 146097 mod 36524 mod 1461"/>
+ <xsl:variable name="L" select="floor($d4 div 1460)"/>
+ <xsl:variable name="d1" select="(($d4 - $L) mod 365) + $L"/>
+
+ <xsl:value-of select="floor($d1 div 7) + 1"/>
+
+ </xsl:template>
+
+ <doc:template name="dt:get-month-number" xmlns="">
+ <refpurpose>Take a month by name and return a number which can be used as input to the templates. </refpurpose>
+
+ <refdescription>
+ <para>Input</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>month</term>
+ <listitem>
+ <para>Month as described either by full name or abbreviation.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Return a month as a decimal number. (Jan = 1)</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='dt:get-month-number'>
+ <xsl:param name='month'/>
+
+ <xsl:variable name='monToUpper'>
+ <xsl:call-template name='str:to-upper'>
+ <xsl:with-param name='text' select='$month'/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test='starts-with($monToUpper,"JAN")'>
+ <xsl:value-of select='"1"'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"FEB")'>
+ <xsl:value-of select='2'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"MAR")'>
+ <xsl:value-of select='3'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"APR")'>
+ <xsl:value-of select='4'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"MAY")'>
+ <xsl:value-of select='5'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"JUN")'>
+ <xsl:value-of select='6'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"JUL")'>
+ <xsl:value-of select='7'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"AUG")'>
+ <xsl:value-of select='8'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"SEP")'>
+ <xsl:value-of select='9'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"OCT")'>
+ <xsl:value-of select='10'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"NOV")'>
+ <xsl:value-of select='11'/>
+ </xsl:when>
+ <xsl:when test='starts-with($monToUpper,"DEC")'>
+ <xsl:value-of select='"12"'/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="dt:get-xsd-datetime-year" xmlns="">
+ <refpurpose>Return year component of XSD DateTime value.</refpurpose>
+
+ <refdescription>
+ <para>Extract component of XML Schemas DateTime value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>xsd-date-time</term>
+ <listitem>
+ <para>A value in XSD DateTime format.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns year component.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='dt:get-xsd-datetime-year'>
+ <xsl:param name='xsd-date-time'/>
+
+ <xsl:choose>
+ <xsl:when test='contains($xsd-date-time, "T")'>
+ <xsl:call-template name='dt:get-xsd-datetime-year'>
+ <xsl:with-param name='xsd-date-time' select='substring-before($xsd-date-time, "T")'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Check for time -->
+ <xsl:when test='substring($xsd-date-time, 3, 1) = ":"'/>
+
+ <xsl:otherwise>
+ <!-- This is a date -->
+ <xsl:value-of select='substring-before($xsd-date-time, "-")'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="dt:get-xsd-datetime-month" xmlns="">
+ <refpurpose>Return month component of XSD DateTime value.</refpurpose>
+
+ <refdescription>
+ <para>Extract component of XML Schemas DateTime value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>xsd-date-time</term>
+ <listitem>
+ <para>A value in XSD DateTime format.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns month component.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='dt:get-xsd-datetime-month'>
+ <xsl:param name='xsd-date-time'/>
+
+ <xsl:choose>
+ <xsl:when test='contains($xsd-date-time, "T")'>
+ <xsl:call-template name='dt:get-xsd-datetime-month'>
+ <xsl:with-param name='xsd-date-time' select='substring-before($xsd-date-time, "T")'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Check for time -->
+ <xsl:when test='substring($xsd-date-time, 3, 1) = ":"'/>
+
+ <xsl:otherwise>
+ <!-- This is a date -->
+ <xsl:value-of select='substring(substring-after($xsd-date-time, "-"), 1, 2)'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="dt:get-xsd-datetime-day" xmlns="">
+ <refpurpose>Return day component of XSD DateTime value.</refpurpose>
+
+ <refdescription>
+ <para>Extract component of XML Schemas DateTime value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>xsd-date-time</term>
+ <listitem>
+ <para>A value in XSD DateTime format.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns day component.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='dt:get-xsd-datetime-day'>
+ <xsl:param name='xsd-date-time'/>
+
+ <xsl:choose>
+ <xsl:when test='contains($xsd-date-time, "T")'>
+ <xsl:call-template name='dt:get-xsd-datetime-day'>
+ <xsl:with-param name='xsd-date-time' select='substring-before($xsd-date-time, "T")'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Check for time -->
+ <xsl:when test='substring($xsd-date-time, 3, 1) = ":"'/>
+
+ <xsl:otherwise>
+ <!-- This is a date -->
+ <xsl:value-of select='substring(substring-after($xsd-date-time, "-"), 4, 2)'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="dt:get-xsd-datetime-hour" xmlns="">
+ <refpurpose>Return hour component of XSD DateTime value.</refpurpose>
+
+ <refdescription>
+ <para>Extract component of XML Schemas DateTime value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>xsd-date-time</term>
+ <listitem>
+ <para>A value in XSD DateTime format.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns hour component.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='dt:get-xsd-datetime-hour'>
+ <xsl:param name='xsd-date-time'/>
+
+ <xsl:choose>
+ <xsl:when test='contains($xsd-date-time, "T")'>
+ <xsl:call-template name='dt:get-xsd-datetime-hour'>
+ <xsl:with-param name='xsd-date-time' select='substring-after($xsd-date-time, "T")'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Check for time -->
+ <xsl:when test='substring($xsd-date-time, 3, 1) = ":"'>
+ <xsl:value-of select='substring($xsd-date-time, 1, 2)'/>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- This is a date -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="dt:get-xsd-datetime-minute" xmlns="">
+ <refpurpose>Return minute component of XSD DateTime value.</refpurpose>
+
+ <refdescription>
+ <para>Extract component of XML Schemas DateTime value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>xsd-date-time</term>
+ <listitem>
+ <para>A value in XSD DateTime format.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns minute component.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='dt:get-xsd-datetime-minute'>
+ <xsl:param name='xsd-date-time'/>
+
+ <xsl:choose>
+ <xsl:when test='contains($xsd-date-time, "T")'>
+ <xsl:call-template name='dt:get-xsd-datetime-minute'>
+ <xsl:with-param name='xsd-date-time' select='substring-after($xsd-date-time, "T")'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Check for time -->
+ <xsl:when test='substring($xsd-date-time, 3, 1) = ":"'>
+ <xsl:value-of select='substring($xsd-date-time, 4, 2)'/>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- This is a date -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="dt:get-xsd-datetime-second" xmlns="">
+ <refpurpose>Return second component of XSD DateTime value.</refpurpose>
+
+ <refdescription>
+ <para>Extract component of XML Schemas DateTime value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>xsd-date-time</term>
+ <listitem>
+ <para>A value in XSD DateTime format.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns second component.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='dt:get-xsd-datetime-second'>
+ <xsl:param name='xsd-date-time'/>
+
+ <xsl:choose>
+ <xsl:when test='contains($xsd-date-time, "T")'>
+ <xsl:call-template name='dt:get-xsd-datetime-second'>
+ <xsl:with-param name='xsd-date-time' select='substring-after($xsd-date-time, "T")'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- Check for time -->
+ <xsl:when test='substring($xsd-date-time, 3, 1) = ":"'>
+ <xsl:variable name='part' select='substring($xsd-date-time, 7)'/>
+ <xsl:choose>
+ <xsl:when test='contains($part, "Z")'>
+ <xsl:value-of select='substring-before($part, "Z")'/>
+ </xsl:when>
+ <xsl:when test='contains($part, "+")'>
+ <xsl:value-of select='substring-before($part, "+")'/>
+ </xsl:when>
+ <xsl:when test='contains($part, "-")'>
+ <xsl:value-of select='substring-before($part, "-")'/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select='$part'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- This is a date -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="dt:get-xsd-datetime-timezone" xmlns="">
+ <refpurpose>Return timezone component of XSD DateTime value.</refpurpose>
+
+ <refdescription>
+ <para>Extract component of XML Schemas DateTime value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>xsd-date-time</term>
+ <listitem>
+ <para>A value in XSD DateTime format.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns timezone component.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='dt:get-xsd-datetime-timezone'>
+ <xsl:param name='xsd-date-time'/>
+
+ <xsl:choose>
+ <xsl:when test='contains($xsd-date-time, "Z")'>Z</xsl:when>
+ <xsl:when test='contains($xsd-date-time, "T")'>
+ <xsl:call-template name='dt:get-xsd-datetime-timezone'>
+ <xsl:with-param name='xsd-date-time' select='substring-after($xsd-date-time, "T")'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test='substring($xsd-date-time, 3, 1) = ":"'>
+ <!-- This is a time -->
+ <xsl:choose>
+ <xsl:when test='contains($xsd-date-time, "+")'>
+ <xsl:text>+</xsl:text>
+ <xsl:value-of select='substring-after($xsd-date-time, "+")'/>
+ </xsl:when>
+ <xsl:when test='contains($xsd-date-time, "-")'>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select='substring-after($xsd-date-time, "-")'/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- This is a date -->
+ <xsl:value-of select='substring(substring-after($xsd-date-time, "-"), 6)'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/texml-xsl/example.xsl b/texml-xsl/example.xsl
new file mode 100644
index 0000000..790c6cb
--- /dev/null
+++ b/texml-xsl/example.xsl
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet
+ version="1.0"
+ extension-element-prefixes="doc"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
+ xmlns:eg="http://xsltsl.org/example"
+>
+
+ <doc:reference xmlns="">
+ <referenceinfo>
+ <releaseinfo role="meta">
+ $Id$
+ </releaseinfo>
+ <author>
+ <surname>Ball</surname>
+ <firstname>Steve</firstname>
+ </author>
+ <copyright>
+ <year>2001</year>
+ <holder>Steve Ball</holder>
+ </copyright>
+ </referenceinfo>
+
+ <title>Example Stylesheet</title>
+
+ <partintro>
+ <section>
+ <title>Introduction</title>
+
+ <para>This module provides a template for adding stylesheet modules to the XSLT Standard Library.</para>
+ <para>To add a new module to the library, follow these easy steps:</para>
+ <orderedlist>
+ <listitem>
+ <para>Copy this file and replace its contents with the new module templates and documentation.</para>
+ </listitem>
+ <listitem>
+ <para>Copy the corresponding test file in the <filename>test</filename> directory. Replace its contents with tests for the new module.</para>
+ </listitem>
+ <listitem>
+ <para>Add an include element in the <filename>stdlib.xsl</filename> stylesheet.</para>
+ </listitem>
+ <listitem>
+ <para>Add an entry in the <filename>test/test.xml</filename> file.</para>
+ </listitem>
+ <listitem>
+ <para>Add entries in the <filename>test/test.xsl</filename> stylesheet.</para>
+ </listitem>
+ <listitem>
+ <para>Add an entry in the <filename>doc/build.xml</filename> file.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>The <filename>example.xsl</filename> stylesheet provides a more extensive example.</para>
+
+ </section>
+ </partintro>
+
+ </doc:reference>
+
+ <doc:template name="eg:example" xmlns="">
+ <refpurpose>Template Example</refpurpose>
+
+ <refdescription>
+ <para>Provides a template for writing templates. Replace this paragraph with a description of your template</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The example string</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns nothing.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="eg:example">
+ <xsl:param name="text"/>
+ </xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/texml-xsl/markup.xsl b/texml-xsl/markup.xsl
new file mode 100644
index 0000000..dc78c4b
--- /dev/null
+++ b/texml-xsl/markup.xsl
@@ -0,0 +1,789 @@
+<xsl:stylesheet version='1.0'
+ xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
+ xmlns:doc='http://xsltsl.org/xsl/documentation/1.0'
+ xmlns:markup='http://xsltsl.org/markup'
+ xmlns:str='http://xsltsl.org/string'
+ extension-element-prefixes='doc markup str'>
+
+ <doc:reference xmlns=''>
+ <referenceinfo>
+ <releaseinfo role="meta">
+ $Id$
+ </releaseinfo>
+ <author>
+ <surname>Ball</surname>
+ <firstname>Steve</firstname>
+ </author>
+ <copyright>
+ <year>2003</year>
+ <year>2001</year>
+ <holder>Steve Ball</holder>
+ </copyright>
+ </referenceinfo>
+
+ <title>XML Markup Templates</title>
+
+ <partintro>
+ <section>
+ <title>Introduction</title>
+
+ <para>This stylesheet module provides functions for generating literal XML markup.</para>
+
+ </section>
+ </partintro>
+
+ </doc:reference>
+
+ <doc:template name="markup:xml-declaration" xmlns="">
+ <refpurpose>Create an XML Declaration</refpurpose>
+
+ <refdescription>
+ <para>This template returns an XML Declaration. Although the XSLT standard provides control over the generation of the XML Declaration, this template may be useful in circumstances where the values must be computed at runtime.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>version</term>
+ <listitem>
+ <para>Version number.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>standalone</term>
+ <listitem>
+ <para>Standalone indication. Must be value "yes" or "no".</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>encoding</term>
+ <listitem>
+ <para>Character encoding.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns an XML Declaration as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:xml-declaration'>
+ <xsl:param name='version' select="'1.0'"/>
+ <xsl:param name='standalone'/>
+ <xsl:param name='encoding'/>
+
+ <xsl:text disable-output-escaping='yes'>&lt;?xml version="</xsl:text>
+ <xsl:copy-of select="$version"/>
+ <xsl:text>"</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="string-length($standalone) = 0"/>
+ <xsl:when test='$standalone = "yes" or $standalone = "no"'>
+ <xsl:text> standalone="</xsl:text>
+ <xsl:copy-of select="$standalone"/>
+ <xsl:text>"</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message terminate="yes">invalid value "<xsl:value-of select="$standalone"/>" for standalone attribute</xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:if test='string-length($encoding) &gt; 0'>
+ <xsl:text> encoding="</xsl:text>
+ <xsl:copy-of select='$encoding'/>
+ <xsl:text>"</xsl:text>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>?&gt;
+</xsl:text>
+ </xsl:template>
+
+ <doc:template name="markup:doctype-declaration" xmlns="">
+ <refpurpose>Create a Document Type Declaration</refpurpose>
+
+ <refdescription>
+ <para>This template returns a Document Type Declaration. Although the XSLT standard provides control over the generation of a Document Type Declaration, this template may be useful in circumstances where the values for the identifiers or the internal subset must be computed at runtime.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>docel</term>
+ <listitem>
+ <para>The name of the document element.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>publicid</term>
+ <listitem>
+ <para>The public identifier for the external DTD subset.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>systemid</term>
+ <listitem>
+ <para>The system identifier for the external DTD subset.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>internaldtd</term>
+ <listitem>
+ <para>The internal DTD subset.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a Document Type Declaration as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:doctype-declaration'>
+ <xsl:param name='docel'/>
+ <xsl:param name='publicid'/>
+ <xsl:param name='systemid'/>
+ <xsl:param name='internaldtd'/>
+
+ <xsl:if test='string-length($docel) = 0'>
+ <xsl:message terminate='yes'>No document element specified</xsl:message>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE </xsl:text>
+ <xsl:copy-of select="$docel"/>
+
+ <xsl:call-template name='markup:external-identifier'>
+ <xsl:with-param name='publicid' select='$publicid'/>
+ <xsl:with-param name='systemid' select='$systemid'/>
+ <xsl:with-param name='leading-space' select='true()'/>
+ </xsl:call-template>
+
+ <xsl:if test='string-length($internaldtd) &gt; 0'>
+ <xsl:text> [</xsl:text>
+ <xsl:copy-of select='$internaldtd'/>
+ <xsl:text>]</xsl:text>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>&gt;
+</xsl:text>
+ </xsl:template>
+
+ <doc:template name="markup:element-declaration" xmlns="">
+ <refpurpose>Create an Element Declaration</refpurpose>
+
+ <refdescription>
+ <para>This template returns an element declaration..</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>type</term>
+ <listitem>
+ <para>The element type.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>content-spec</term>
+ <listitem>
+ <para>The content specification.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns an element declaration as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:element-declaration'>
+ <xsl:param name='type'/>
+ <xsl:param name='content-spec' select="'ANY'"/>
+
+ <xsl:if test='string-length($type) = 0'>
+ <xsl:message terminate='yes'>element type must be specified</xsl:message>
+ </xsl:if>
+ <xsl:if test='string-length($content-spec) = 0'>
+ <xsl:message terminate='yes'>content specification must be specified</xsl:message>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>&lt;!ELEMENT </xsl:text>
+ <xsl:copy-of select='$type'/>
+ <xsl:text> </xsl:text>
+ <xsl:copy-of select='$content-spec'/>
+ <xsl:text disable-output-escaping='yes'>&gt;</xsl:text>
+ </xsl:template>
+
+ <doc:template name="markup:attlist-declaration" xmlns="">
+ <refpurpose>Create an Attribute List Declaration</refpurpose>
+
+ <refdescription>
+ <para>This template returns an attribute list declaration.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>type</term>
+ <listitem>
+ <para>The element type.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>attr-defns</term>
+ <listitem>
+ <para>Attribute definitions.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns an attribute list declaration as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:attlist-declaration'>
+ <xsl:param name='type'/>
+ <xsl:param name='attr-defns'/>
+
+ <xsl:if test='string-length($type) = 0'>
+ <xsl:message terminate='yes'>element type must be specified</xsl:message>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>&lt;!ATTLIST </xsl:text>
+ <xsl:copy-of select='$type'/>
+ <xsl:text> </xsl:text>
+ <xsl:copy-of select='$attr-defns'/>
+ <xsl:text disable-output-escaping='yes'>&gt;</xsl:text>
+ </xsl:template>
+
+ <doc:template name="markup:attribute-definition" xmlns="">
+ <refpurpose>Create an Attribute Definition</refpurpose>
+
+ <refdescription>
+ <para>This template returns an attribute definition.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>The attribute name.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>type</term>
+ <listitem>
+ <para>The attribute type.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>default</term>
+ <listitem>
+ <para>The attribute default.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns an attribute definition as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:attribute-definition'>
+ <xsl:param name='name'/>
+ <xsl:param name='type'/>
+ <xsl:param name='default'/>
+
+ <xsl:if test='string-length($name) = 0'>
+ <xsl:message terminate='yes'>attribute name must be specified</xsl:message>
+ </xsl:if>
+ <xsl:if test='string-length($type) = 0'>
+ <xsl:message terminate='yes'>attribute type must be specified</xsl:message>
+ </xsl:if>
+ <xsl:if test='string-length($default) = 0'>
+ <xsl:message terminate='yes'>attribute default must be specified</xsl:message>
+ </xsl:if>
+
+ <xsl:text> </xsl:text>
+ <xsl:copy-of select='$name'/>
+ <xsl:text> </xsl:text>
+ <xsl:copy-of select='$type'/>
+ <xsl:text> </xsl:text>
+ <xsl:copy-of select='$default'/>
+ </xsl:template>
+
+ <doc:template name="markup:entity-declaration" xmlns="">
+ <refpurpose>Create an Entity Declaration</refpurpose>
+
+ <refdescription>
+ <para>This template returns an entity declaration.</para>
+ <para>If the 'text' parameter is given a value, then an internal entity is created. If either the 'publicid' or 'systemid' parameters are given a value then an external entity is created. It is an error for the 'text' parameter to have value as well as the 'publicid', 'systemid' or 'notation' parameters.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>The entity name.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>parameter</term>
+ <listitem>
+ <para>Boolean value to determine whether a parameter entity is created. Default is 'false()'.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The replacement text. Must be a string.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>nodes</term>
+ <listitem>
+ <para>The replacement text as a nodeset. The nodeset is formatted as XML using the as-xml template. If both text and nodes are specified then nodes takes precedence.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>publicid</term>
+ <listitem>
+ <para>The public identifier for an external entity.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>systemid</term>
+ <listitem>
+ <para>The system identifier for an external entity.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>notation</term>
+ <listitem>
+ <para>The notation for an external entity.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns an entity declaration as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:entity-declaration'>
+ <xsl:param name='name'/>
+ <xsl:param name='parameter' select='false()'/>
+ <xsl:param name='text'/>
+ <xsl:param name='nodes'/>
+ <xsl:param name='publicid'/>
+ <xsl:param name='systemid'/>
+ <xsl:param name='notation'/>
+
+ <xsl:if test='string-length($name) = 0'>
+ <xsl:message terminate='yes'>entity name must be specified</xsl:message>
+ </xsl:if>
+ <xsl:if test='string-length($text) &gt; 0 and
+ (string-length($publicid) &gt; 0 or
+ string-length($systemid) &gt; 0 or
+ string-length($notation) &gt; 0)'>
+ <xsl:message terminate='yes'>both replacement text and external identifier specified</xsl:message>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>&lt;!ENTITY </xsl:text>
+ <xsl:copy-of select='$name'/>
+ <xsl:text> </xsl:text>
+ <xsl:if test="$parameter">
+ <xsl:text>% </xsl:text>
+ </xsl:if>
+
+ <xsl:choose>
+ <xsl:when test="$nodes">
+ <xsl:call-template name='markup:quote-value'>
+ <xsl:with-param name='value'>
+ <xsl:call-template name="markup:as-xml">
+ <xsl:with-param name="nodes" select="$nodes"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test='$text'>
+ <xsl:call-template name='markup:quote-value'>
+ <xsl:with-param name='value' select='$text'/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name='markup:external-identifier'>
+ <xsl:with-param name='publicid' select='$publicid'/>
+ <xsl:with-param name='systemid' select='$systemid'/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:if test='$notation'>
+ <xsl:text> NDATA "</xsl:text>
+ <xsl:copy-of select='$notation'/>
+ <xsl:text>"</xsl:text>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>&gt;</xsl:text>
+ </xsl:template>
+
+ <doc:template name="markup:quote-value" xmlns="">
+ <refpurpose>Quote an Attribute Value</refpurpose>
+
+ <refdescription>
+ <para>This template returns a quoted value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>value</term>
+ <listitem>
+ <para>The value to quote.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a quote value as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:quote-value'>
+ <xsl:param name='value'/>
+
+ <xsl:variable name="quoted">
+ <xsl:call-template name='markup:quote-value-aux'>
+ <xsl:with-param name='value' select='$value'/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="contains($value, '&lt;')">
+ <xsl:call-template name='str:subst'>
+ <xsl:with-param name='text' select='$quoted'/>
+ <xsl:with-param name='replace'>&lt;</xsl:with-param>
+ <xsl:with-param name='with'>
+ <xsl:text disable-output-escaping='yes'>&amp;lt;</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select='$quoted'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name='markup:quote-value-aux'>
+ <xsl:param name='value'/>
+
+ <!-- Quoting hell! -->
+ <xsl:variable name="quot">&quot;</xsl:variable>
+ <xsl:variable name="apos">&apos;</xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test='contains($value, $quot) and contains($value, $apos)'>
+ <xsl:text>"</xsl:text>
+ <xsl:call-template name='str:subst'>
+ <xsl:with-param name='text' select='$value'/>
+ <xsl:with-param name='replace'>"</xsl:with-param>
+ <xsl:with-param name='with'>
+ <xsl:text disable-output-escaping='yes'>&amp;quot;</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:text>"</xsl:text>
+ </xsl:when>
+ <xsl:when test='contains($value, $quot)'>
+ <xsl:text>'</xsl:text>
+ <xsl:value-of select='$value'/>
+ <xsl:text>'</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>"</xsl:text>
+ <xsl:value-of select='$value'/>
+ <xsl:text>"</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="markup:external-identifier" xmlns="">
+ <refpurpose>Create an External Identifier</refpurpose>
+
+ <refdescription>
+ <para>This template returns an external identifier.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>publicid</term>
+ <listitem>
+ <para>The public identifier.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>systemid</term>
+ <listitem>
+ <para>The system identifier.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns an external identifier as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:external-identifier'>
+ <xsl:param name='publicid'/>
+ <xsl:param name='systemid'/>
+ <xsl:param name='leading-space' select='false()'/>
+
+ <xsl:choose>
+ <xsl:when test='string-length($publicid) &gt; 0'>
+ <xsl:if test='$leading-space'>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ <xsl:text disable-output-escaping='yes'>PUBLIC "</xsl:text>
+ <xsl:value-of select='$publicid' disable-output-escaping='yes'/>
+ <xsl:text disable-output-escaping='yes'>"</xsl:text>
+ <xsl:if test='string-length($systemid) &gt; 0'>
+ <xsl:text disable-output-escaping='yes'> "</xsl:text>
+ <xsl:value-of select='$systemid' disable-output-escaping='yes'/>
+ <xsl:text disable-output-escaping='yes'>"</xsl:text>
+ </xsl:if>
+ </xsl:when>
+ <xsl:when test="string-length($systemid) &gt; 0">
+ <xsl:if test='$leading-space'>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ <xsl:text disable-output-escaping='yes'>SYSTEM "</xsl:text>
+ <xsl:value-of select='$systemid' disable-output-escaping='yes'/>
+ <xsl:text disable-output-escaping='yes'>"</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="markup:entity-reference" xmlns="">
+ <refpurpose>Create an Entity Reference</refpurpose>
+
+ <refdescription>
+ <para>This template returns an entity reference.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>The name of the entity.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns an entity reference as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:entity-reference'>
+ <xsl:param name='name'/>
+
+ <xsl:text disable-output-escaping='yes'>&amp;</xsl:text>
+ <xsl:value-of select='$name'/>
+ <xsl:text>;</xsl:text>
+
+ </xsl:template>
+
+ <doc:template name="markup:notation-declaration" xmlns="">
+ <refpurpose>Create a Notation Declaration</refpurpose>
+
+ <refdescription>
+ <para>This template returns a notation declaration.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>The notation name.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>publicid</term>
+ <listitem>
+ <para>The public identifier for the notation.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>systemid</term>
+ <listitem>
+ <para>The system identifier for the notation.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a notation declaration as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:notation-declaration'>
+ <xsl:param name='name'/>
+ <xsl:param name='publicid'/>
+ <xsl:param name='systemid'/>
+
+ <xsl:if test='string-length($name) = 0'>
+ <xsl:message terminate='yes'>notation name must be specified</xsl:message>
+ </xsl:if>
+ <xsl:if test='string-length($publicid) = 0 and string-length($systemid) = 0'>
+ <xsl:message terminate='yes'>external identifier must be specified</xsl:message>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>&lt;!NOTATION </xsl:text>
+ <xsl:copy-of select='$name'/>
+
+ <xsl:call-template name='markup:external-identifier'>
+ <xsl:with-param name='publicid' select='$publicid'/>
+ <xsl:with-param name='systemid' select='$systemid'/>
+ <xsl:with-param name='leading-space' select='true()'/>
+ </xsl:call-template>
+
+ <xsl:text disable-output-escaping='yes'>&gt;</xsl:text>
+ </xsl:template>
+
+ <doc:template name="markup:cdata-section" xmlns="">
+ <refpurpose>Create a CDATA Section</refpurpose>
+
+ <refdescription>
+ <para>This template returns a CDATA Section. The XSLT specification provides a mechanism for instructing the XSL processor to output character data in a CDATA section for certain elements, but this template may be useful in those circumstances where not all instances of an element are to have their content placed in a CDATA section.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The content of the CDATA section.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a CDATA section as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:cdata-section'>
+ <xsl:param name='text'/>
+
+ <xsl:if test="contains($text, ']]&gt;')">
+ <xsl:message terminate="yes">CDATA section contains "]]&gt;"</xsl:message>
+ </xsl:if>
+
+ <xsl:text disable-output-escaping='yes'>&lt;![CDATA[</xsl:text>
+ <xsl:copy-of select='$text'/>
+ <xsl:text disable-output-escaping='yes'>]]&gt;</xsl:text>
+ </xsl:template>
+
+ <doc:template name="markup:as-xml" xmlns="">
+ <refpurpose>Format Nodeset As XML Markup</refpurpose>
+
+ <refdescription>
+ <para>This template returns XML markup. Each node in the given nodeset is converted to its equivalent XML markup.</para>
+
+ <para>BUG: This version may not adequately handle XML Namespaces.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>nodes</term>
+ <listitem>
+ <para>Nodeset to format as XML.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns XML markup.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='markup:as-xml'>
+ <xsl:param name='nodes'/>
+
+ <xsl:if test="$nodes">
+ <xsl:choose>
+ <xsl:when test="$nodes[1]/self::*">
+ <xsl:text disable-output-escaping='yes'>&lt;</xsl:text>
+ <xsl:value-of select="name($nodes[1])"/>
+ <xsl:for-each select="$nodes[1]/@*">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="name()"/>
+ <xsl:text>=</xsl:text>
+ <xsl:call-template name='markup:quote-value'>
+ <xsl:with-param name='value' select='.'/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:choose>
+ <xsl:when test='$nodes[1]/node()'>
+ <xsl:text disable-output-escaping='yes'>&gt;</xsl:text>
+ <xsl:call-template name='markup:as-xml'>
+ <xsl:with-param name='nodes' select='$nodes[1]/node()'/>
+ </xsl:call-template>
+ <xsl:text disable-output-escaping='yes'>&lt;/</xsl:text>
+ <xsl:value-of select="name($nodes[1])"/>
+ <xsl:text disable-output-escaping='yes'>&gt;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text disable-output-escaping='yes'>/&gt;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="$nodes[1]/self::text()">
+ <xsl:value-of select="$nodes[1]"/>
+ </xsl:when>
+ <xsl:when test="$nodes[1]/self::comment()">
+ <xsl:text disable-output-escaping='yes'>&lt;!--</xsl:text>
+ <xsl:value-of select="$nodes[1]"/>
+ <xsl:text disable-output-escaping='yes'>--&gt;</xsl:text>
+ </xsl:when>
+ <xsl:when test="$nodes[1]/self::processing-instruction()">
+ <xsl:text disable-output-escaping='yes'>&lt;?</xsl:text>
+ <xsl:value-of select="name($nodes[1])"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$nodes[1]"/>
+ <xsl:text disable-output-escaping='yes'>?&gt;</xsl:text>
+ </xsl:when>
+
+ <xsl:when test="not($nodes[1]/parent::*)"/> <!-- root node -->
+ <xsl:when test="count($nodes[1] | $nodes[1]/../namespace::*) = count($nodes[1]/../namespace::*)"/> <!-- namespace node -->
+ <xsl:when test="count($nodes[1] | $nodes[1]/../@*) = count($nodes[1]/../@*)"/> <!-- attribute node -->
+ </xsl:choose>
+
+ <xsl:call-template name="markup:as-xml">
+ <xsl:with-param name="nodes" select="$nodes[position() &gt; 1]"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/texml-xsl/math.xsl b/texml-xsl/math.xsl
new file mode 100644
index 0000000..d1a2b6a
--- /dev/null
+++ b/texml-xsl/math.xsl
@@ -0,0 +1,618 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
+ xmlns:math="http://xsltsl.org/math"
+ exclude-result-prefixes="doc math">
+
+ <doc:reference xmlns="">
+ <referenceinfo>
+ <releaseinfo role="meta">
+ $Id$
+ </releaseinfo>
+ <author>
+ <surname>Ball</surname>
+ <firstname>Steve</firstname>
+ </author>
+ <copyright>
+ <year>2004</year>
+ <year>2002</year>
+ <holder>Steve Ball</holder>
+ </copyright>
+ </referenceinfo>
+
+ <title>Math Module</title>
+
+ <partintro>
+ <section>
+ <title>Introduction</title>
+
+ <para>This module provides mathematical functions.</para>
+ </section>
+ </partintro>
+
+ </doc:reference>
+
+ <doc:template name="math:power" xmlns="">
+ <refpurpose>Power</refpurpose>
+
+ <refdescription>
+ <para>Raises a number to a power.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>base</term>
+ <listitem>
+ <para>The base number. Must be a number.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>power</term>
+ <listitem>
+ <para>The power to raise the number to. Must be an integer.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns base multiplied by itself power times. If the base or power are not numbers or if the power is fractional then an empty string is returned.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="math:power">
+ <xsl:param name="base"/>
+ <xsl:param name="power"/>
+
+ <xsl:choose>
+ <xsl:when test='$power = "0" and $base = "0"'>
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test='$power = "0" and number($base)'>
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test='$power = "0" and not(number($base))'/>
+ <xsl:when test='$base = "0" and number($power)'>
+ <xsl:text>0</xsl:text>
+ </xsl:when>
+
+ <xsl:when test='not(number($base)) or not(number($power))'/>
+
+ <xsl:when test='floor(number($power)) != number($power)'/>
+
+ <xsl:when test='number($power) &lt; 0'>
+ <xsl:variable name='x'>
+ <xsl:call-template name='math:power'>
+ <xsl:with-param name='base' select='$base'/>
+ <xsl:with-param name='power' select='-1 * $power'/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select='1 div $x'/>
+ </xsl:when>
+
+ <xsl:when test='number($power) = 1'>
+ <xsl:value-of select='$base'/>
+ </xsl:when>
+
+ <xsl:when test='number($power) &gt; 0'>
+ <xsl:variable name='x'>
+ <xsl:call-template name='math:power'>
+ <xsl:with-param name='base' select='$base'/>
+ <xsl:with-param name='power' select='$power - 1'/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select='$base * $x'/>
+ </xsl:when>
+ <xsl:otherwise/>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="math:cvt-hex-decimal" xmlns="">
+ <refpurpose>Conversion</refpurpose>
+
+ <refdescription>
+ <para>Converts a hexidecimal value to a decimal value.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>value</term>
+ <listitem>
+ <para>The hexidecimal number. Must be a number in hexidecimal format.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the value as a decimal string. If the value is not a number then a NaN value is returned.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="math:cvt-hex-decimal">
+ <xsl:param name="value"/>
+
+ <xsl:choose>
+ <xsl:when test='$value = ""'/>
+
+ <xsl:when test='string-length($value) = 1'>
+ <xsl:call-template name='math:cvt-hex-decimal-digit'>
+ <xsl:with-param name='digit' select='$value'/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name='first-digit'>
+ <xsl:call-template name='math:cvt-hex-decimal-digit'>
+ <xsl:with-param name='digit' select='substring($value, 1, 1)'/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name='remainder'>
+ <xsl:call-template name='math:cvt-hex-decimal'>
+ <xsl:with-param name='value' select='substring($value, 2)'/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select='$first-digit * 16 + $remainder'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name='math:cvt-hex-decimal-digit'>
+ <xsl:param name='digit' select='0'/>
+ <xsl:choose>
+ <xsl:when test='$digit &lt;= 9'>
+ <xsl:value-of select='$digit'/>
+ </xsl:when>
+ <xsl:when test='$digit = "a" or $digit = "A"'>10</xsl:when>
+ <xsl:when test='$digit = "b" or $digit = "B"'>11</xsl:when>
+ <xsl:when test='$digit = "c" or $digit = "C"'>12</xsl:when>
+ <xsl:when test='$digit = "d" or $digit = "D"'>13</xsl:when>
+ <xsl:when test='$digit = "e" or $digit = "E"'>14</xsl:when>
+ <xsl:when test='$digit = "f" or $digit = "F"'>15</xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="math:ordinal" xmlns="">
+ <refpurpose>Ordinal number</refpurpose>
+
+ <refdescription>
+ <para>Gives the ordinal number of a given counting number. For example, 1 becomes "1st".</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>number</term>
+ <listitem>
+ <para>An integer number.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the number with an ordinal suffix.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="math:ordinal">
+ <xsl:param name="number"/>
+
+ <xsl:choose>
+ <xsl:when test='$number &lt; 0'/>
+ <xsl:otherwise>
+ <xsl:value-of select='$number'/>
+ <xsl:choose>
+ <xsl:when test='$number = 11 or $number = 12 or $number = 13'>th</xsl:when>
+ <xsl:when test='$number mod 10 = 1'>st</xsl:when>
+ <xsl:when test='$number mod 10 = 2'>nd</xsl:when>
+ <xsl:when test='$number mod 10 = 3'>rd</xsl:when>
+ <xsl:otherwise>th</xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+
+ <doc:template name="math:ordinal-as-word" xmlns="">
+ <refpurpose>Returns an ordinal number</refpurpose>
+
+ <refdescription>
+ <para>This template returns the ordinal number for a given counting number as a word. For example "first" for 1.</para>
+ <para>Only handles numbers less than 10000000 (ten million).</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>number</term>
+ <listitem>
+ <para>The counting number.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>conjunctive</term>
+ <listitem>
+ <para>Whether to add the word "and" to the result, for example "one hundred and first" rather than "one hundred first". Default is "yes".</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the ordinal number as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="math:ordinal-as-word">
+ <xsl:param name="number" select="0"/>
+ <xsl:param name='conjunctive' select='"yes"'/>
+ <xsl:param name='preceding' select='0'/>
+
+ <xsl:choose>
+ <xsl:when test='$preceding = 1 and $number = 0'/>
+ <xsl:when test='$number = 0'>zeroth</xsl:when>
+
+ <xsl:when test="$number &lt; 1 or $number != floor($number)"/>
+
+ <xsl:when test='$number = 1'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>first</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 2'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>second</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 3'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>third</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 4'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>fourth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 5'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>fifth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 6'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>sixth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 7'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>seventh</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 8'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>eighth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 9'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>ninth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 10'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>tenth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 11'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>eleventh</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 12'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>twelveth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 13'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>thirteenth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 14'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>fourteenth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 15'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>fifteenth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 16'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>sixteenth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 17'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>seventeenth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 18'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>eighteenth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 19'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>nineteenth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 20'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>twentieth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 30'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>thirtieth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 40'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>fortieth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 50'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>fiftieth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 60'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>sixtieth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 70'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>seventieth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 80'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>eightieth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number = 90'>
+ <xsl:if test='$preceding = 1'> and </xsl:if>
+ <xsl:text>ninetieth</xsl:text>
+ </xsl:when>
+
+ <xsl:when test='$number mod 1000000 = 0'>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 1000000)'/>
+ </xsl:call-template>
+ <xsl:text> millionth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number &lt; 1000000 and $number mod 1000 = 0'>
+ <xsl:if test='$preceding = 1 and $conjunctive'> and </xsl:if>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 1000)'/>
+ </xsl:call-template>
+ <xsl:text> thousandth</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number &lt; 1000 and $number mod 100 = 0'>
+ <xsl:if test='$preceding = 1 and $conjunctive'> and </xsl:if>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 100)'/>
+ </xsl:call-template>
+ <xsl:text> hundredth</xsl:text>
+ </xsl:when>
+
+ <xsl:when test='$number &gt; 1000000'>
+ <xsl:if test='$preceding = 1'>
+ <xsl:text> </xsl:text>
+ <xsl:if test='$conjunctive'>and </xsl:if>
+ </xsl:if>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 1000000) * 1000000'/>
+ </xsl:call-template>
+ <xsl:choose>
+ <xsl:when
+ test='(floor(floor(($number mod 1000000) + 0.1) div 100000) > 0 and $number mod 100000 > 0) or
+ (floor(floor(($number mod 100000) + 0.1) div 10000) > 0 and $number mod 10000 > 0) or
+ (floor(floor(($number mod 10000) + 0.1) div 1000) > 0 and $number mod 1000 > 0) or
+ (floor(floor(($number mod 1000) + 0.1) div 100) > 0 and $number mod 100 > 0) or
+ (floor(floor(($number mod 100) + 0.1) div 10) > 0 and $number mod 10 > 0 and $number mod 100 > 20)'>
+ <xsl:text> </xsl:text>
+ <xsl:call-template name='math:ordinal-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 1000000) + 0.1)'/>
+ <xsl:with-param name='conjunctive' select='$conjunctive'/>
+ <xsl:with-param name='preceding' select='0'/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name='math:ordinal-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 1000000) + 0.1)'/>
+ <xsl:with-param name='conjunctive' select='$conjunctive'/>
+ <xsl:with-param name='preceding' select='1'/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test='$number &gt; 1000'>
+ <xsl:if test='$preceding = 1'>
+ <xsl:text> </xsl:text>
+ <xsl:if test='$conjunctive'>and </xsl:if>
+ </xsl:if>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 1000) * 1000'/>
+ <xsl:with-param name='conjunctive' select='$conjunctive'/>
+ </xsl:call-template>
+ <xsl:choose>
+ <xsl:when test='floor(floor(($number mod 1000) + 0.1) div 100) > 0'>
+ <xsl:text> </xsl:text>
+ <xsl:call-template name='math:ordinal-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 1000) + 0.1)'/>
+ <xsl:with-param name='conjunctive' select='$conjunctive'/>
+ <xsl:with-param name='preceding' select='0'/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name='math:ordinal-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 1000) + 0.1)'/>
+ <xsl:with-param name='conjunctive' select='$conjunctive'/>
+ <xsl:with-param name='preceding' select='1'/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test='$number &gt; 100'>
+ <xsl:if test='$preceding = 1'>
+ <xsl:text> </xsl:text>
+ <xsl:if test='$conjunctive'>and </xsl:if>
+ </xsl:if>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 100) * 100'/>
+ </xsl:call-template>
+ <xsl:call-template name='math:ordinal-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 100) + 0.1)'/>
+ <xsl:with-param name='conjunctive' select='$conjunctive'/>
+ <xsl:with-param name='preceding' select='1'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test='$number &gt; 20'>
+ <xsl:if test='$preceding = 1'>
+ <xsl:text> </xsl:text>
+ <xsl:if test='$conjunctive'>and </xsl:if>
+ </xsl:if>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 10) * 10'/>
+ </xsl:call-template>
+ <xsl:text> </xsl:text>
+ <xsl:call-template name='math:ordinal-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 10) + 0.1)'/>
+ <xsl:with-param name='conjunctive' select='$conjunctive'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise/>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="math:number-as-word" xmlns="">
+ <refpurpose>Returns a number as a word</refpurpose>
+
+ <refdescription>
+ <para>This template returns the word for a given integer number, for example "one" for 1.</para>
+ <para>Only handles numbers less than 10000000 (ten million).</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>number</term>
+ <listitem>
+ <para>The counting number.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>conjunctive</term>
+ <listitem>
+ <para>Adds the word "and" where appropriate, for example.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the number as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="math:number-as-word">
+ <xsl:param name="number" select="0"/>
+ <xsl:param name='conjunctive' select='true()'/>
+
+ <xsl:choose>
+
+ <xsl:when test='$number = 0'>zero</xsl:when>
+
+ <xsl:when test='$number &lt; 0'>
+ <xsl:text>minus </xsl:text>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='-1 * $number'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="$number != floor($number)"/>
+
+ <xsl:when test='$number mod 1000000 = 0'>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 1000000)'/>
+ </xsl:call-template>
+ <xsl:text> million</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number &gt;= 1000000'>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 1000000)'/>
+ </xsl:call-template>
+ <xsl:text> million </xsl:text>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 1000000) + 0.1)'/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test='$number mod 1000 = 0'>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 1000)'/>
+ </xsl:call-template>
+ <xsl:text> thousand</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number &gt;= 1000'>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 1000)'/>
+ </xsl:call-template>
+ <xsl:text> thousand </xsl:text>
+ <xsl:if test='$conjunctive and floor(floor(($number mod 1000) + 0.1) div 100) = 0'>and </xsl:if>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 1000) + 0.1)'/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test='$number mod 100 = 0'>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 100)'/>
+ </xsl:call-template>
+ <xsl:text> hundred</xsl:text>
+ </xsl:when>
+ <xsl:when test='$number &gt;= 100'>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 100)'/>
+ </xsl:call-template>
+ <xsl:text> hundred </xsl:text>
+ <xsl:if test='$conjunctive'>and </xsl:if>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 100) + 0.1)'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test='$number = 1'>one</xsl:when>
+ <xsl:when test='$number = 2'>two</xsl:when>
+ <xsl:when test='$number = 3'>three</xsl:when>
+ <xsl:when test='$number = 4'>four</xsl:when>
+ <xsl:when test='$number = 5'>five</xsl:when>
+ <xsl:when test='$number = 6'>six</xsl:when>
+ <xsl:when test='$number = 7'>seven</xsl:when>
+ <xsl:when test='$number = 8'>eight</xsl:when>
+ <xsl:when test='$number = 9'>nine</xsl:when>
+ <xsl:when test='$number = 10'>ten</xsl:when>
+ <xsl:when test='$number = 11'>eleven</xsl:when>
+ <xsl:when test='$number = 12'>twelve</xsl:when>
+ <xsl:when test='$number = 13'>thirteen</xsl:when>
+ <xsl:when test='$number = 14'>fourteen</xsl:when>
+ <xsl:when test='$number = 15'>fifteen</xsl:when>
+ <xsl:when test='$number = 16'>sixteen</xsl:when>
+ <xsl:when test='$number = 17'>seventeen</xsl:when>
+ <xsl:when test='$number = 18'>eighteen</xsl:when>
+ <xsl:when test='$number = 19'>nineteen</xsl:when>
+ <xsl:when test='$number = 20'>twenty</xsl:when>
+ <xsl:when test='$number = 30'>thirty</xsl:when>
+ <xsl:when test='$number = 40'>forty</xsl:when>
+ <xsl:when test='$number = 50'>fifty</xsl:when>
+ <xsl:when test='$number = 60'>sixty</xsl:when>
+ <xsl:when test='$number = 70'>seventy</xsl:when>
+ <xsl:when test='$number = 80'>eighty</xsl:when>
+ <xsl:when test='$number = 90'>ninety</xsl:when>
+
+ <xsl:when test='$number &lt; 100'>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor($number div 10) * 10'/>
+ </xsl:call-template>
+ <xsl:text> </xsl:text>
+ <xsl:call-template name='math:number-as-word'>
+ <xsl:with-param name='number' select='floor(($number mod 10) + 0.1)'/>
+ </xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/texml-xsl/node.xsl b/texml-xsl/node.xsl
new file mode 100644
index 0000000..c8d20b4
--- /dev/null
+++ b/texml-xsl/node.xsl
@@ -0,0 +1,229 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
+ xmlns:node="http://xsltsl.org/node"
+ extension-element-prefixes="doc node">
+
+ <doc:reference xmlns="">
+ <referenceinfo>
+ <releaseinfo role="meta">
+ $Id$
+ </releaseinfo>
+ <author>
+ <surname>Ball</surname>
+ <firstname>Steve</firstname>
+ </author>
+ <copyright>
+ <year>2001</year>
+ <holder>Steve Ball</holder>
+ </copyright>
+ </referenceinfo>
+
+ <title>Node Templates</title>
+
+ <partintro>
+ <section>
+ <title>Introduction</title>
+
+ <para>This stylesheet module provides functions for reporting on or manipulating nodes and nodesets.</para>
+
+ </section>
+ </partintro>
+
+ </doc:reference>
+
+ <doc:template name="node:xpath" xmlns="">
+ <refpurpose>Returns an XPath location path</refpurpose>
+
+ <refdescription>
+ <para>This template returns an XPath location path that uniquely identifies the given node within the document.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>node</term>
+ <listitem>
+ <para>The node to create an XPath for. If this parameter is given as a nodeset, then the first node in the nodeset is used.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns an XPath location path as a string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="node:xpath">
+ <xsl:param name="node" select="."/>
+
+ <xsl:choose>
+
+ <xsl:when test="$node">
+
+ <xsl:for-each select="$node[1]/ancestor-or-self::*">
+ <xsl:text/>/<xsl:value-of select="name()"/>
+ <xsl:text/>[<xsl:value-of select="count(preceding-sibling::*[name() = name(current())]) + 1"/>]<xsl:text/>
+ </xsl:for-each>
+
+ <xsl:choose>
+
+ <xsl:when test="$node[1]/self::comment()">
+ <xsl:text>/comment()</xsl:text>
+ <xsl:text/>[<xsl:value-of select="count($node[1]/preceding-sibling::comment()) + 1" />]<xsl:text/>
+ </xsl:when>
+
+ <xsl:when test="$node[1]/self::processing-instruction()">
+ <xsl:text>/processing-instruction()</xsl:text>
+ <xsl:text/>[<xsl:value-of select="count($node[1]/preceding-sibling::processing-instruction()) + 1" />]<xsl:text/>
+ </xsl:when>
+
+ <xsl:when test="$node[1]/self::text()">
+ <xsl:text>/text()</xsl:text>
+ <xsl:text/>[<xsl:value-of select="count($node[1]/preceding-sibling::text()) + 1" />]<xsl:text/>
+ </xsl:when>
+
+ <xsl:when test="not($node[1]/..)">
+ <xsl:text>/</xsl:text>
+ </xsl:when>
+
+ <xsl:when test="count($node[1]/../namespace::* | $node[1]) = count($node[1]/../namespace::*)">
+ <xsl:text/>/namespace::<xsl:value-of select="name($node[1])" />
+ </xsl:when>
+
+ <xsl:when test="count($node[1]/../@* | $node[1]) = count($node[1]/../@*)">
+ <xsl:text/>/@<xsl:value-of select="name($node[1])" />
+ </xsl:when>
+
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:text>/..</xsl:text>
+ </xsl:otherwise>
+
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="node:type" xmlns="">
+ <refpurpose>Return node type</refpurpose>
+
+ <refdescription>
+ <para>Returns the type of a node as a string.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>node</term>
+ <listitem>
+ <para>The node to get the type for. If this parameter is given as a nodeset, then the first node in the nodeset is used.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns node type as a string. Values returned are:</para>
+ <variablelist>
+ <varlistentry>
+ <term>Element</term>
+ <listitem>
+ <para><literal>element</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Text Node</term>
+ <listitem>
+ <para><literal>text</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Comment</term>
+ <listitem>
+ <para><literal>comment</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Processing Instruction</term>
+ <listitem>
+ <para><literal>processing instruction</literal></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="node:type">
+ <xsl:param name="node" select="."/>
+
+ <xsl:choose>
+ <xsl:when test="not($node)"/>
+ <xsl:when test="$node[1]/self::*">
+ <xsl:text>element</xsl:text>
+ </xsl:when>
+ <xsl:when test="$node[1]/self::text()">
+ <xsl:text>text</xsl:text>
+ </xsl:when>
+ <xsl:when test="$node[1]/self::comment()">
+ <xsl:text>comment</xsl:text>
+ </xsl:when>
+ <xsl:when test="$node[1]/self::processing-instruction()">
+ <xsl:text>processing instruction</xsl:text>
+ </xsl:when>
+ <xsl:when test="not($node[1]/parent::*)">
+ <xsl:text>root</xsl:text>
+ </xsl:when>
+ <xsl:when test="count($node[1] | $node[1]/../namespace::*) = count($node[1]/../namespace::*)">
+ <xsl:text>namespace</xsl:text>
+ </xsl:when>
+ <xsl:when test="count($node[1] | $node[1]/../@*) = count($node[1]/../@*)">
+ <xsl:text>attribute</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="node:copy" xmlns="">
+ <refpurpose>Copy Nodes</refpurpose>
+
+ <refdescription>
+ <para>Makes a copy of the given nodes, including attributes and descendants.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>nodes</term>
+ <listitem>
+ <para>The nodes to copy.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the copied nodes as a result tree fragment.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='node:copy'>
+ <xsl:param name='nodes' select='.'/>
+
+ <xsl:for-each select='$nodes'>
+ <xsl:copy>
+ <xsl:for-each select='@*'>
+ <xsl:copy/>
+ </xsl:for-each>
+
+ <xsl:for-each select='node()'>
+ <xsl:call-template name='node:copy'/>
+ </xsl:for-each>
+ </xsl:copy>
+ </xsl:for-each>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/texml-xsl/stdlib.xsl b/texml-xsl/stdlib.xsl
new file mode 100644
index 0000000..22c35ca
--- /dev/null
+++ b/texml-xsl/stdlib.xsl
@@ -0,0 +1,340 @@
+<?xml version="1.0"?>
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY version "1.2.1">
+]>
+
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
+ exclude-result-prefixes="doc"
+ version="1.0">
+
+ <xsl:import href="string.xsl"/>
+ <xsl:import href="date-time.xsl"/>
+ <xsl:import href="node.xsl"/>
+ <xsl:import href="uri.xsl"/>
+ <xsl:import href="markup.xsl"/>
+ <xsl:import href="math.xsl"/>
+ <xsl:import href="cmp.xsl"/>
+
+ <xsl:import href="svg.xsl"/>
+<!--
+ <xsl:import href="html/html.xsl"/>
+ <xsl:import href="fo/fo.xsl"/>
+-->
+
+ <!-- For a new module, add an import element here -->
+ <xsl:import href="example.xsl"/>
+
+ <doc:book xmlns="">
+ <bookinfo>
+ <title>XSLT Standard Library</title>
+ <subtitle>Version &version;</subtitle>
+ <!-- $Id$ -->
+
+ <author>
+ <surname>Ball</surname>
+ <firstname>Steve</firstname>
+ </author>
+ <copyright>
+ <year>2004</year>
+ <year>2002</year>
+ <holder>Steve Ball</holder>
+ </copyright>
+ </bookinfo>
+
+ <preface>
+ <para>The <ulink url="http://www.w3.org/Style/XSL">XSLT</ulink> Standard Library, <acronym>xsltsl</acronym>, provides the XSLT developer with a set of XSLT templates for commonly used functions. These are implemented purely in XSLT, that is they do not use any extensions.</para>
+ <para><acronym>xsltsl</acronym> is a <ulink url="http://sourceforge.net/projects/xsltsl/">SourceForge project</ulink>.</para>
+ <para><ulink url="http://sourceforge.net/"><inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="sflogo.gif" width="88" height="31"/>
+ </imageobject>
+ <textobject>
+ <phrase>SourceForge Logo</phrase>
+ </textobject>
+ </inlinemediaobject></ulink></para>
+ <para>Goals of the <acronym>xsltsl</acronym> project include:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Provision of a high-quality library of XSLT templates, suitable for inclusion by vendors in XSLT processor software products.</para>
+ </listitem>
+ <listitem>
+ <para>Demonstration of best practice in XSLT stylesheet development and documentation.</para>
+ </listitem>
+ <listitem>
+ <para>Provide examples of various techniques used to develop XSLT stylesheets (ie. a working FAQ).</para>
+ </listitem>
+ </itemizedlist>
+ </preface>
+
+ <chapter>
+ <title>Using The Library</title>
+
+ <para>There are two ways of using the library:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Use a local copy of the library.</para>
+ <orderedlist>
+ <listitem>
+ <para>Download the distribution (see below).</para>
+ </listitem>
+ <listitem>
+ <para>Unpack the distribution, using either gunzip/tar or unzip.</para>
+ </listitem>
+ <listitem>
+ <para>In your stylesheet import or include either the main stylesheet, <filename>stdlib.xsl</filename>, or the stylesheet module you wish to use, such as <filename>string.xsl</filename>. This example assumes that the distribution has been extracted into the same directory as your own stylesheet:</para>
+ <informalexample>
+ <programlisting><![CDATA[
+<xsl:import href="stdlib.xsl"/>
+]]></programlisting>
+ </informalexample>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ <listitem>
+ <para>Import or include either the main stylesheet, or the stylesheet module you wish to use, directly from the library website; http://xsltsl.sourceforge.net/modules/. The <filename>modules</filename> directory always contains the latest stable release. For example:</para>
+ <informalexample>
+ <programlisting><![CDATA[
+<xsl:import href="http://xsltsl.sourceforge.net/modules/stdlib.xsl"/>
+]]></programlisting>
+ </informalexample>
+ <para>Older versions of the library are available in subdirectories. For example, to access version 1.1 of the library use:</para>
+ <informalexample>
+ <programlisting><![CDATA[
+<xsl:import href="http://xsltsl.sourceforge.net/modules/1.1/stdlib.xsl"/>
+]]></programlisting>
+ </informalexample>
+ </listitem>
+ </itemizedlist>
+ <para>Next, add XML Namespace declarations for the modules you wish to use. For example, to use templates from the string module, your stylesheet should have the following declaration:</para>
+ <informalexample>
+ <programlisting><![CDATA[
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:str="http://xsltsl.org/string">
+
+<xsl:import href="http://xsltsl.sourceforge.net/modules/stdlib.xsl"/>
+]]></programlisting>
+ </informalexample>
+ <para>Finally, use a template with the <sgmltag>call-template</sgmltag> element. Most templates require parameters, which are passed using the <sgmltag>with-param</sgmltag> element. For example:</para>
+ <informalexample>
+ <programlisting><![CDATA[
+<xsl:template match="foo">
+ <xsl:call-template name="str:subst">
+ <xsl:with-param name="text" select="."/>
+ <xsl:with-param name="replace">a word</xsl:with-param>
+ <xsl:with-param name="with">another word</xsl:with-param>
+ </xsl:call-template>
+</xsl:template>
+]]></programlisting>
+ </informalexample>
+ </chapter>
+
+ <chapter>
+ <title>Obtaining The Library</title>
+
+ <para>The XSLT Standard Library is available for download as either:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Gzip'd tarball: <ulink url="http://prdownloads.sourceforge.net/xsltsl/xsltsl-&version;.tar.gz">http://prdownloads.sourceforge.net/xsltsl/xsltsl-&version;.tar.gz</ulink></para>
+ </listitem>
+ <listitem>
+ <para>Zip file: <ulink url="http://prdownloads.sourceforge.net/xsltsl/xsltsl-&version;.zip">http://prdownloads.sourceforge.net/xsltsl/xsltsl-&version;.zip</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </chapter>
+
+ <chapter>
+ <title>Getting Involved</title>
+
+ <para>Contributions to the project are most welcome, and may be in the form of stylesheet modules, patches, bug reports or sample code. Any contributed code must use the LGPL license to be accepted into the library.</para>
+
+ <para>See the SourceForge Project Page <ulink url="http://sourceforge.net/projects/xsltsl/">http://sourceforge.net/projects/xsltsl/</ulink> for information on the development of the project. Bug reports may be submitted here.</para>
+
+ <para>See the project Web Page <ulink url="http://xsltsl.sourceforge.net/">http://xsltsl.sourceforge.net/</ulink> for documentation.</para>
+
+ <para>There are three mailing lists for the project:</para>
+ <variablelist>
+ <varlistentry>
+ <term><email>xsltsl-users@lists.sourceforge.net</email></term>
+ <listitem>
+ <para>Discussion of the use of <acronym>xsltsl</acronym>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><email>xsltsl-devel@lists.sourceforge.net</email></term>
+ <listitem>
+ <para>Discussion of the development of <acronym>xsltsl</acronym>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><email>xsltsl-announce@lists.sourceforge.net</email></term>
+ <listitem>
+ <para>Project announcements.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </chapter>
+
+ <chapter>
+ <title>XML Namespaces</title>
+
+ <para>Apart from the XSLT XML Namespace (http://www.w3.org/1999/XSL/Transform), <acronym>xsltsl</acronym> employs a number of XML Namespaces to allow inclusion of the library in developer stylesheets. In addition, documentation is defined in a separate namespace.</para>
+ <para>Each module is allocated a namespace URI by appending the module name to the URI for the project, http://xsltsl.org/. For example, the string module has the namespace URI http://xsltsl.org/string.</para>
+ <para>All documentation is written using an <ulink url="docbook-extensions.html">extension</ulink> of <ulink url="http://www.docbook.org/">DocBook</ulink> designed for <ulink url="docbook-extensions.html">embedding DocBook into XSLT stylesheets</ulink>. The namespace URI for DocBook embedded in stylesheets is http://xsltsl.org/xsl/documentation/1.0</para>
+ </chapter>
+
+ <chapter>
+ <title>Engineering Standards</title>
+
+ <para>In order to maintain a high engineering standard, all modules and contributions to the <acronym>xsltsl</acronym> project must adhere to the following coding and documentation standards. Submissions which do not meet (or exceed) this standard will not be accepted.</para>
+ <itemizedlist>
+ <listitem>
+ <para>All stylesheets must be indented, with each level indented by two spaces. NB. a simple stylesheet could be used to enforce/fix this.</para>
+ </listitem>
+ <listitem>
+ <para>Templates are named using a qualified name (QName). The namespace URI for the template's containing stylesheet is assigned as above.</para>
+ </listitem>
+ <listitem>
+ <para>Parameters for templates should use sensible names. Where possible (or if in doubt), follow these conventions:</para>
+ <itemizedlist>
+ <listitem>
+ <para>A parameter containing a single node is named <parametername>node</parametername>. Where more than one parameter contains a single node, the suffix <parametername>Node</parametername> is appended to the parameter name, eg. <parametername>referenceNode</parametername></para>
+ </listitem>
+ <listitem>
+ <para>A parameter which potentially contains multiple nodes is named <parametername>nodes</parametername>. Where more than one parameter potentially contains multiple nodes, the suffix <parametername>Nodes</parametername> is appended to the parameter name, eg. <parametername>copyNodes</parametername></para>
+ </listitem>
+ <listitem>
+ <para>A parameter which contains a string value is named <parametername>text</parametername>.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>All templates in each stylesheet must be documented. A template is documented as a <ulink url="http://www.docbook.org/">DocBook</ulink> RefEntry.</para>
+ </listitem>
+ <listitem>
+ <para>Every stylesheet must include a test suite. The test system is in the <filename>test</filename> subdirectory. See <ulink url="test/test.html">test/test.html</ulink> for further details.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>An <ulink url="example.xsl">example stylesheet</ulink> has been provided, which acts as a template for new stylesheet modules.</para>
+
+ </chapter>
+
+ <chapter>
+ <title>Related Work</title>
+
+ <para>The <ulink url="http://www.exslt.org/">EXSLT</ulink> project is creating a library to standardise extension functions. The XSLT Standard Library is complementary to the EXSLT project.</para>
+
+ </chapter>
+
+ <chapter>
+ <title>Reference Documentation</title>
+
+ <para>Reference documentation is available for each module.</para>
+
+ <section>
+ <title>String Processing</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="string.html">string.xsl</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Nodes</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="node.html">node.xsl</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Date/Time Processing</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="date-time.html">date-time.xsl</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Mathematics</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="math.html">math.xsl</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>URI (Uniform Resource Identifier) Processing</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="uri.html">uri.xsl</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Comparing Nodesets</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="cmp.html">cmp.xsl</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Generating XML Markup</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="markup.html">markup.xsl</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Presentation Media Support</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Scalable Vector Graphics: <ulink url="svg.html">svg.xsl</ulink></para>
+ </listitem>
+<!--
+ <listitem>
+ <para><ulink url="html/html.html">html/html.xsl</ulink></para>
+ </listitem>
+ <listitem>
+ <para><ulink url="fo/fo.html">fo/fo.xsl</ulink></para>
+ </listitem>
+-->
+ </itemizedlist>
+ </section>
+
+ <section>
+ <title>Example</title>
+
+ <!-- Add a new module in a similar fashion -->
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="example.html">example.xsl</ulink></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </chapter>
+
+ </doc:book>
+
+</xsl:stylesheet>
diff --git a/texml-xsl/string.xsl b/texml-xsl/string.xsl
new file mode 100644
index 0000000..1c7bf74
--- /dev/null
+++ b/texml-xsl/string.xsl
@@ -0,0 +1,1233 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
+ xmlns:str="http://xsltsl.org/string"
+ extension-element-prefixes="doc str">
+
+ <doc:reference xmlns="">
+ <referenceinfo>
+ <releaseinfo role="meta">
+ $Id$
+ </releaseinfo>
+ <author>
+ <surname>Ball</surname>
+ <firstname>Steve</firstname>
+ </author>
+ <copyright>
+ <year>2002</year>
+ <year>2001</year>
+ <holder>Steve Ball</holder>
+ </copyright>
+ </referenceinfo>
+
+ <title>String Processing</title>
+
+ <partintro>
+ <section>
+ <title>Introduction</title>
+
+ <para>This module provides templates for manipulating strings.</para>
+
+ </section>
+ </partintro>
+
+ </doc:reference>
+
+ <!-- Common string constants and datasets as XSL variables -->
+
+ <!-- str:lower and str:upper contain pairs of lower and upper case
+ characters. Below insanely long strings should contain the
+ official lower/uppercase pairs, making this stylesheet working
+ for every language on earth. Hopefully. -->
+ <!-- These values are not enough, however. There are some
+ exceptions, dealt with below. -->
+ <xsl:variable name="xsltsl-str-lower" select="'&#x0061;&#x0062;&#x0063;&#x0064;&#x0065;&#x0066;&#x0067;&#x0068;&#x0069;&#x006A;&#x006B;&#x006C;&#x006D;&#x006E;&#x006F;&#x0070;&#x0071;&#x0072;&#x0073;&#x0074;&#x0075;&#x0076;&#x0077;&#x0078;&#x0079;&#x007A;&#x00B5;&#x00E0;&#x00E1;&#x00E2;&#x00E3;&#x00E4;&#x00E5;&#x00E6;&#x00E7;&#x00E8;&#x00E9;&#x00EA;&#x00EB;&#x00EC;&#x00ED;&#x00EE;&#x00EF;&#x00F0;&#x00F1;&#x00F2;&#x00F3;&#x00F4;&#x00F5;&#x00F6;&#x00F8;&#x00F9;&#x00FA;&#x00FB;&#x00FC;&#x00FD;&#x00FE;&#x00FF;&#x0101;&#x0103;&#x0105;&#x0107;&#x0109;&#x010B;&#x010D;&#x010F;&#x0111;&#x0113;&#x0115;&#x0117;&#x0119;&#x011B;&#x011D;&#x011F;&#x0121;&#x0123;&#x0125;&#x0127;&#x0129;&#x012B;&#x012D;&#x012F;&#x0131;&#x0133;&#x0135;&#x0137;&#x013A;&#x013C;&#x013E;&#x0140;&#x0142;&#x0144;&#x0146;&#x0148;&#x014B;&#x014D;&#x014F;&#x0151;&#x0153;&#x0155;&#x0157;&#x0159;&#x015B;&#x015D;&#x015F;&#x0161;&#x0163;&#x0165;&#x0167;&#x0169;&#x016B;&#x016D;&#x016F;&#x0171;&#x0173;&#x0175;&#x0177;&#x017A;&#x017C;&#x017E;&#x017F;&#x0183;&#x0185;&#x0188;&#x018C;&#x0192;&#x0195;&#x0199;&#x01A1;&#x01A3;&#x01A5;&#x01A8;&#x01AD;&#x01B0;&#x01B4;&#x01B6;&#x01B9;&#x01BD;&#x01BF;&#x01C5;&#x01C6;&#x01C8;&#x01C9;&#x01CB;&#x01CC;&#x01CE;&#x01D0;&#x01D2;&#x01D4;&#x01D6;&#x01D8;&#x01DA;&#x01DC;&#x01DD;&#x01DF;&#x01E1;&#x01E3;&#x01E5;&#x01E7;&#x01E9;&#x01EB;&#x01ED;&#x01EF;&#x01F2;&#x01F3;&#x01F5;&#x01F9;&#x01FB;&#x01FD;&#x01FF;&#x0201;&#x0203;&#x0205;&#x0207;&#x0209;&#x020B;&#x020D;&#x020F;&#x0211;&#x0213;&#x0215;&#x0217;&#x0219;&#x021B;&#x021D;&#x021F;&#x0223;&#x0225;&#x0227;&#x0229;&#x022B;&#x022D;&#x022F;&#x0231;&#x0233;&#x0253;&#x0254;&#x0256;&#x0257;&#x0259;&#x025B;&#x0260;&#x0263;&#x0268;&#x0269;&#x026F;&#x0272;&#x0275;&#x0280;&#x0283;&#x0288;&#x028A;&#x028B;&#x0292;&#x0345;&#x03AC;&#x03AD;&#x03AE;&#x03AF;&#x03B1;&#x03B2;&#x03B3;&#x03B4;&#x03B5;&#x03B6;&#x03B7;&#x03B8;&#x03B9;&#x03BA;&#x03BB;&#x03BC;&#x03BD;&#x03BE;&#x03BF;&#x03C0;&#x03C1;&#x03C2;&#x03C3;&#x03C4;&#x03C5;&#x03C6;&#x03C7;&#x03C8;&#x03C9;&#x03CA;&#x03CB;&#x03CC;&#x03CD;&#x03CE;&#x03D0;&#x03D1;&#x03D5;&#x03D6;&#x03DB;&#x03DD;&#x03DF;&#x03E1;&#x03E3;&#x03E5;&#x03E7;&#x03E9;&#x03EB;&#x03ED;&#x03EF;&#x03F0;&#x03F1;&#x03F2;&#x03F5;&#x0430;&#x0431;&#x0432;&#x0433;&#x0434;&#x0435;&#x0436;&#x0437;&#x0438;&#x0439;&#x043A;&#x043B;&#x043C;&#x043D;&#x043E;&#x043F;&#x0440;&#x0441;&#x0442;&#x0443;&#x0444;&#x0445;&#x0446;&#x0447;&#x0448;&#x0449;&#x044A;&#x044B;&#x044C;&#x044D;&#x044E;&#x044F;&#x0450;&#x0451;&#x0452;&#x0453;&#x0454;&#x0455;&#x0456;&#x0457;&#x0458;&#x0459;&#x045A;&#x045B;&#x045C;&#x045D;&#x045E;&#x045F;&#x0461;&#x0463;&#x0465;&#x0467;&#x0469;&#x046B;&#x046D;&#x046F;&#x0471;&#x0473;&#x0475;&#x0477;&#x0479;&#x047B;&#x047D;&#x047F;&#x0481;&#x048D;&#x048F;&#x0491;&#x0493;&#x0495;&#x0497;&#x0499;&#x049B;&#x049D;&#x049F;&#x04A1;&#x04A3;&#x04A5;&#x04A7;&#x04A9;&#x04AB;&#x04AD;&#x04AF;&#x04B1;&#x04B3;&#x04B5;&#x04B7;&#x04B9;&#x04BB;&#x04BD;&#x04BF;&#x04C2;&#x04C4;&#x04C8;&#x04CC;&#x04D1;&#x04D3;&#x04D5;&#x04D7;&#x04D9;&#x04DB;&#x04DD;&#x04DF;&#x04E1;&#x04E3;&#x04E5;&#x04E7;&#x04E9;&#x04EB;&#x04ED;&#x04EF;&#x04F1;&#x04F3;&#x04F5;&#x04F9;&#x0561;&#x0562;&#x0563;&#x0564;&#x0565;&#x0566;&#x0567;&#x0568;&#x0569;&#x056A;&#x056B;&#x056C;&#x056D;&#x056E;&#x056F;&#x0570;&#x0571;&#x0572;&#x0573;&#x0574;&#x0575;&#x0576;&#x0577;&#x0578;&#x0579;&#x057A;&#x057B;&#x057C;&#x057D;&#x057E;&#x057F;&#x0580;&#x0581;&#x0582;&#x0583;&#x0584;&#x0585;&#x0586;&#x1E01;&#x1E03;&#x1E05;&#x1E07;&#x1E09;&#x1E0B;&#x1E0D;&#x1E0F;&#x1E11;&#x1E13;&#x1E15;&#x1E17;&#x1E19;&#x1E1B;&#x1E1D;&#x1E1F;&#x1E21;&#x1E23;&#x1E25;&#x1E27;&#x1E29;&#x1E2B;&#x1E2D;&#x1E2F;&#x1E31;&#x1E33;&#x1E35;&#x1E37;&#x1E39;&#x1E3B;&#x1E3D;&#x1E3F;&#x1E41;&#x1E43;&#x1E45;&#x1E47;&#x1E49;&#x1E4B;&#x1E4D;&#x1E4F;&#x1E51;&#x1E53;&#x1E55;&#x1E57;&#x1E59;&#x1E5B;&#x1E5D;&#x1E5F;&#x1E61;&#x1E63;&#x1E65;&#x1E67;&#x1E69;&#x1E6B;&#x1E6D;&#x1E6F;&#x1E71;&#x1E73;&#x1E75;&#x1E77;&#x1E79;&#x1E7B;&#x1E7D;&#x1E7F;&#x1E81;&#x1E83;&#x1E85;&#x1E87;&#x1E89;&#x1E8B;&#x1E8D;&#x1E8F;&#x1E91;&#x1E93;&#x1E95;&#x1E9B;&#x1EA1;&#x1EA3;&#x1EA5;&#x1EA7;&#x1EA9;&#x1EAB;&#x1EAD;&#x1EAF;&#x1EB1;&#x1EB3;&#x1EB5;&#x1EB7;&#x1EB9;&#x1EBB;&#x1EBD;&#x1EBF;&#x1EC1;&#x1EC3;&#x1EC5;&#x1EC7;&#x1EC9;&#x1ECB;&#x1ECD;&#x1ECF;&#x1ED1;&#x1ED3;&#x1ED5;&#x1ED7;&#x1ED9;&#x1EDB;&#x1EDD;&#x1EDF;&#x1EE1;&#x1EE3;&#x1EE5;&#x1EE7;&#x1EE9;&#x1EEB;&#x1EED;&#x1EEF;&#x1EF1;&#x1EF3;&#x1EF5;&#x1EF7;&#x1EF9;&#x1F00;&#x1F01;&#x1F02;&#x1F03;&#x1F04;&#x1F05;&#x1F06;&#x1F07;&#x1F10;&#x1F11;&#x1F12;&#x1F13;&#x1F14;&#x1F15;&#x1F20;&#x1F21;&#x1F22;&#x1F23;&#x1F24;&#x1F25;&#x1F26;&#x1F27;&#x1F30;&#x1F31;&#x1F32;&#x1F33;&#x1F34;&#x1F35;&#x1F36;&#x1F37;&#x1F40;&#x1F41;&#x1F42;&#x1F43;&#x1F44;&#x1F45;&#x1F51;&#x1F53;&#x1F55;&#x1F57;&#x1F60;&#x1F61;&#x1F62;&#x1F63;&#x1F64;&#x1F65;&#x1F66;&#x1F67;&#x1F70;&#x1F71;&#x1F72;&#x1F73;&#x1F74;&#x1F75;&#x1F76;&#x1F77;&#x1F78;&#x1F79;&#x1F7A;&#x1F7B;&#x1F7C;&#x1F7D;&#x1F80;&#x1F81;&#x1F82;&#x1F83;&#x1F84;&#x1F85;&#x1F86;&#x1F87;&#x1F90;&#x1F91;&#x1F92;&#x1F93;&#x1F94;&#x1F95;&#x1F96;&#x1F97;&#x1FA0;&#x1FA1;&#x1FA2;&#x1FA3;&#x1FA4;&#x1FA5;&#x1FA6;&#x1FA7;&#x1FB0;&#x1FB1;&#x1FB3;&#x1FBE;&#x1FC3;&#x1FD0;&#x1FD1;&#x1FE0;&#x1FE1;&#x1FE5;&#x1FF3;&#x2170;&#x2171;&#x2172;&#x2173;&#x2174;&#x2175;&#x2176;&#x2177;&#x2178;&#x2179;&#x217A;&#x217B;&#x217C;&#x217D;&#x217E;&#x217F;&#x24D0;&#x24D1;&#x24D2;&#x24D3;&#x24D4;&#x24D5;&#x24D6;&#x24D7;&#x24D8;&#x24D9;&#x24DA;&#x24DB;&#x24DC;&#x24DD;&#x24DE;&#x24DF;&#x24E0;&#x24E1;&#x24E2;&#x24E3;&#x24E4;&#x24E5;&#x24E6;&#x24E7;&#x24E8;&#x24E9;&#xFF41;&#xFF42;&#xFF43;&#xFF44;&#xFF45;&#xFF46;&#xFF47;&#xFF48;&#xFF49;&#xFF4A;&#xFF4B;&#xFF4C;&#xFF4D;&#xFF4E;&#xFF4F;&#xFF50;&#xFF51;&#xFF52;&#xFF53;&#xFF54;&#xFF55;&#xFF56;&#xFF57;&#xFF58;&#xFF59;&#xFF5A;&#x10428;&#x10429;&#x1042A;&#x1042B;&#x1042C;&#x1042D;&#x1042E;&#x1042F;&#x10430;&#x10431;&#x10432;&#x10433;&#x10434;&#x10435;&#x10436;&#x10437;&#x10438;&#x10439;&#x1043A;&#x1043B;&#x1043C;&#x1043D;&#x1043E;&#x1043F;&#x10440;&#x10441;&#x10442;&#x10443;&#x10444;&#x10445;&#x10446;&#x10447;&#x10448;&#x10449;&#x1044A;&#x1044B;&#x1044C;&#x1044D;'"/>
+ <xsl:variable name="xsltsl-str-upper" select="'&#x0041;&#x0042;&#x0043;&#x0044;&#x0045;&#x0046;&#x0047;&#x0048;&#x0049;&#x004A;&#x004B;&#x004C;&#x004D;&#x004E;&#x004F;&#x0050;&#x0051;&#x0052;&#x0053;&#x0054;&#x0055;&#x0056;&#x0057;&#x0058;&#x0059;&#x005A;&#x039C;&#x00C0;&#x00C1;&#x00C2;&#x00C3;&#x00C4;&#x00C5;&#x00C6;&#x00C7;&#x00C8;&#x00C9;&#x00CA;&#x00CB;&#x00CC;&#x00CD;&#x00CE;&#x00CF;&#x00D0;&#x00D1;&#x00D2;&#x00D3;&#x00D4;&#x00D5;&#x00D6;&#x00D8;&#x00D9;&#x00DA;&#x00DB;&#x00DC;&#x00DD;&#x00DE;&#x0178;&#x0100;&#x0102;&#x0104;&#x0106;&#x0108;&#x010A;&#x010C;&#x010E;&#x0110;&#x0112;&#x0114;&#x0116;&#x0118;&#x011A;&#x011C;&#x011E;&#x0120;&#x0122;&#x0124;&#x0126;&#x0128;&#x012A;&#x012C;&#x012E;&#x0049;&#x0132;&#x0134;&#x0136;&#x0139;&#x013B;&#x013D;&#x013F;&#x0141;&#x0143;&#x0145;&#x0147;&#x014A;&#x014C;&#x014E;&#x0150;&#x0152;&#x0154;&#x0156;&#x0158;&#x015A;&#x015C;&#x015E;&#x0160;&#x0162;&#x0164;&#x0166;&#x0168;&#x016A;&#x016C;&#x016E;&#x0170;&#x0172;&#x0174;&#x0176;&#x0179;&#x017B;&#x017D;&#x0053;&#x0182;&#x0184;&#x0187;&#x018B;&#x0191;&#x01F6;&#x0198;&#x01A0;&#x01A2;&#x01A4;&#x01A7;&#x01AC;&#x01AF;&#x01B3;&#x01B5;&#x01B8;&#x01BC;&#x01F7;&#x01C4;&#x01C4;&#x01C7;&#x01C7;&#x01CA;&#x01CA;&#x01CD;&#x01CF;&#x01D1;&#x01D3;&#x01D5;&#x01D7;&#x01D9;&#x01DB;&#x018E;&#x01DE;&#x01E0;&#x01E2;&#x01E4;&#x01E6;&#x01E8;&#x01EA;&#x01EC;&#x01EE;&#x01F1;&#x01F1;&#x01F4;&#x01F8;&#x01FA;&#x01FC;&#x01FE;&#x0200;&#x0202;&#x0204;&#x0206;&#x0208;&#x020A;&#x020C;&#x020E;&#x0210;&#x0212;&#x0214;&#x0216;&#x0218;&#x021A;&#x021C;&#x021E;&#x0222;&#x0224;&#x0226;&#x0228;&#x022A;&#x022C;&#x022E;&#x0230;&#x0232;&#x0181;&#x0186;&#x0189;&#x018A;&#x018F;&#x0190;&#x0193;&#x0194;&#x0197;&#x0196;&#x019C;&#x019D;&#x019F;&#x01A6;&#x01A9;&#x01AE;&#x01B1;&#x01B2;&#x01B7;&#x0399;&#x0386;&#x0388;&#x0389;&#x038A;&#x0391;&#x0392;&#x0393;&#x0394;&#x0395;&#x0396;&#x0397;&#x0398;&#x0399;&#x039A;&#x039B;&#x039C;&#x039D;&#x039E;&#x039F;&#x03A0;&#x03A1;&#x03A3;&#x03A3;&#x03A4;&#x03A5;&#x03A6;&#x03A7;&#x03A8;&#x03A9;&#x03AA;&#x03AB;&#x038C;&#x038E;&#x038F;&#x0392;&#x0398;&#x03A6;&#x03A0;&#x03DA;&#x03DC;&#x03DE;&#x03E0;&#x03E2;&#x03E4;&#x03E6;&#x03E8;&#x03EA;&#x03EC;&#x03EE;&#x039A;&#x03A1;&#x03A3;&#x0395;&#x0410;&#x0411;&#x0412;&#x0413;&#x0414;&#x0415;&#x0416;&#x0417;&#x0418;&#x0419;&#x041A;&#x041B;&#x041C;&#x041D;&#x041E;&#x041F;&#x0420;&#x0421;&#x0422;&#x0423;&#x0424;&#x0425;&#x0426;&#x0427;&#x0428;&#x0429;&#x042A;&#x042B;&#x042C;&#x042D;&#x042E;&#x042F;&#x0400;&#x0401;&#x0402;&#x0403;&#x0404;&#x0405;&#x0406;&#x0407;&#x0408;&#x0409;&#x040A;&#x040B;&#x040C;&#x040D;&#x040E;&#x040F;&#x0460;&#x0462;&#x0464;&#x0466;&#x0468;&#x046A;&#x046C;&#x046E;&#x0470;&#x0472;&#x0474;&#x0476;&#x0478;&#x047A;&#x047C;&#x047E;&#x0480;&#x048C;&#x048E;&#x0490;&#x0492;&#x0494;&#x0496;&#x0498;&#x049A;&#x049C;&#x049E;&#x04A0;&#x04A2;&#x04A4;&#x04A6;&#x04A8;&#x04AA;&#x04AC;&#x04AE;&#x04B0;&#x04B2;&#x04B4;&#x04B6;&#x04B8;&#x04BA;&#x04BC;&#x04BE;&#x04C1;&#x04C3;&#x04C7;&#x04CB;&#x04D0;&#x04D2;&#x04D4;&#x04D6;&#x04D8;&#x04DA;&#x04DC;&#x04DE;&#x04E0;&#x04E2;&#x04E4;&#x04E6;&#x04E8;&#x04EA;&#x04EC;&#x04EE;&#x04F0;&#x04F2;&#x04F4;&#x04F8;&#x0531;&#x0532;&#x0533;&#x0534;&#x0535;&#x0536;&#x0537;&#x0538;&#x0539;&#x053A;&#x053B;&#x053C;&#x053D;&#x053E;&#x053F;&#x0540;&#x0541;&#x0542;&#x0543;&#x0544;&#x0545;&#x0546;&#x0547;&#x0548;&#x0549;&#x054A;&#x054B;&#x054C;&#x054D;&#x054E;&#x054F;&#x0550;&#x0551;&#x0552;&#x0553;&#x0554;&#x0555;&#x0556;&#x1E00;&#x1E02;&#x1E04;&#x1E06;&#x1E08;&#x1E0A;&#x1E0C;&#x1E0E;&#x1E10;&#x1E12;&#x1E14;&#x1E16;&#x1E18;&#x1E1A;&#x1E1C;&#x1E1E;&#x1E20;&#x1E22;&#x1E24;&#x1E26;&#x1E28;&#x1E2A;&#x1E2C;&#x1E2E;&#x1E30;&#x1E32;&#x1E34;&#x1E36;&#x1E38;&#x1E3A;&#x1E3C;&#x1E3E;&#x1E40;&#x1E42;&#x1E44;&#x1E46;&#x1E48;&#x1E4A;&#x1E4C;&#x1E4E;&#x1E50;&#x1E52;&#x1E54;&#x1E56;&#x1E58;&#x1E5A;&#x1E5C;&#x1E5E;&#x1E60;&#x1E62;&#x1E64;&#x1E66;&#x1E68;&#x1E6A;&#x1E6C;&#x1E6E;&#x1E70;&#x1E72;&#x1E74;&#x1E76;&#x1E78;&#x1E7A;&#x1E7C;&#x1E7E;&#x1E80;&#x1E82;&#x1E84;&#x1E86;&#x1E88;&#x1E8A;&#x1E8C;&#x1E8E;&#x1E90;&#x1E92;&#x1E94;&#x1E60;&#x1EA0;&#x1EA2;&#x1EA4;&#x1EA6;&#x1EA8;&#x1EAA;&#x1EAC;&#x1EAE;&#x1EB0;&#x1EB2;&#x1EB4;&#x1EB6;&#x1EB8;&#x1EBA;&#x1EBC;&#x1EBE;&#x1EC0;&#x1EC2;&#x1EC4;&#x1EC6;&#x1EC8;&#x1ECA;&#x1ECC;&#x1ECE;&#x1ED0;&#x1ED2;&#x1ED4;&#x1ED6;&#x1ED8;&#x1EDA;&#x1EDC;&#x1EDE;&#x1EE0;&#x1EE2;&#x1EE4;&#x1EE6;&#x1EE8;&#x1EEA;&#x1EEC;&#x1EEE;&#x1EF0;&#x1EF2;&#x1EF4;&#x1EF6;&#x1EF8;&#x1F08;&#x1F09;&#x1F0A;&#x1F0B;&#x1F0C;&#x1F0D;&#x1F0E;&#x1F0F;&#x1F18;&#x1F19;&#x1F1A;&#x1F1B;&#x1F1C;&#x1F1D;&#x1F28;&#x1F29;&#x1F2A;&#x1F2B;&#x1F2C;&#x1F2D;&#x1F2E;&#x1F2F;&#x1F38;&#x1F39;&#x1F3A;&#x1F3B;&#x1F3C;&#x1F3D;&#x1F3E;&#x1F3F;&#x1F48;&#x1F49;&#x1F4A;&#x1F4B;&#x1F4C;&#x1F4D;&#x1F59;&#x1F5B;&#x1F5D;&#x1F5F;&#x1F68;&#x1F69;&#x1F6A;&#x1F6B;&#x1F6C;&#x1F6D;&#x1F6E;&#x1F6F;&#x1FBA;&#x1FBB;&#x1FC8;&#x1FC9;&#x1FCA;&#x1FCB;&#x1FDA;&#x1FDB;&#x1FF8;&#x1FF9;&#x1FEA;&#x1FEB;&#x1FFA;&#x1FFB;&#x1F88;&#x1F89;&#x1F8A;&#x1F8B;&#x1F8C;&#x1F8D;&#x1F8E;&#x1F8F;&#x1F98;&#x1F99;&#x1F9A;&#x1F9B;&#x1F9C;&#x1F9D;&#x1F9E;&#x1F9F;&#x1FA8;&#x1FA9;&#x1FAA;&#x1FAB;&#x1FAC;&#x1FAD;&#x1FAE;&#x1FAF;&#x1FB8;&#x1FB9;&#x1FBC;&#x0399;&#x1FCC;&#x1FD8;&#x1FD9;&#x1FE8;&#x1FE9;&#x1FEC;&#x1FFC;&#x2160;&#x2161;&#x2162;&#x2163;&#x2164;&#x2165;&#x2166;&#x2167;&#x2168;&#x2169;&#x216A;&#x216B;&#x216C;&#x216D;&#x216E;&#x216F;&#x24B6;&#x24B7;&#x24B8;&#x24B9;&#x24BA;&#x24BB;&#x24BC;&#x24BD;&#x24BE;&#x24BF;&#x24C0;&#x24C1;&#x24C2;&#x24C3;&#x24C4;&#x24C5;&#x24C6;&#x24C7;&#x24C8;&#x24C9;&#x24CA;&#x24CB;&#x24CC;&#x24CD;&#x24CE;&#x24CF;&#xFF21;&#xFF22;&#xFF23;&#xFF24;&#xFF25;&#xFF26;&#xFF27;&#xFF28;&#xFF29;&#xFF2A;&#xFF2B;&#xFF2C;&#xFF2D;&#xFF2E;&#xFF2F;&#xFF30;&#xFF31;&#xFF32;&#xFF33;&#xFF34;&#xFF35;&#xFF36;&#xFF37;&#xFF38;&#xFF39;&#xFF3A;&#x10400;&#x10401;&#x10402;&#x10403;&#x10404;&#x10405;&#x10406;&#x10407;&#x10408;&#x10409;&#x1040A;&#x1040B;&#x1040C;&#x1040D;&#x1040E;&#x1040F;&#x10410;&#x10411;&#x10412;&#x10413;&#x10414;&#x10415;&#x10416;&#x10417;&#x10418;&#x10419;&#x1041A;&#x1041B;&#x1041C;&#x1041D;&#x1041E;&#x1041F;&#x10420;&#x10421;&#x10422;&#x10423;&#x10424;&#x10425;'"/>
+ <xsl:variable name="xsltsl-str-digits" select="'0123456789'"/>
+ <!-- space (#x20) characters, carriage returns, line feeds, or tabs. -->
+ <xsl:variable name="xsltsl-str-ws" select="'&#x20;&#x9;&#xD;&#xA;'"/>
+
+ <doc:template name="str:to-upper" xmlns="">
+ <refpurpose>Make string uppercase</refpurpose>
+
+ <refdescription>
+ <para>Converts all lowercase letters to uppercase.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string to be converted</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string with all uppercase letters.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:to-upper">
+ <xsl:param name="text"/>
+
+ <!-- Below exception is extracted from unicode's SpecialCasing.txt
+ file. It's the german lowercase "eszett" (the thing looking
+ like a greek beta) that's to become "SS" in uppercase (note:
+ that are *two* characters, that's why it doesn't fit in the
+ list of upper/lowercase characters). There are more
+ characters in that file (103, excluding the locale-specific
+ ones), but they seemed to be much less used to me and they
+ add up to a hellish long stylesheet.... - Reinout -->
+ <xsl:param name="modified-text">
+ <xsl:call-template name="str:subst">
+ <xsl:with-param name="text">
+ <xsl:value-of select="$text"/>
+ </xsl:with-param>
+ <xsl:with-param name="replace">
+ <xsl:text>&#x00DF;</xsl:text>
+ </xsl:with-param>
+ <xsl:with-param name="with">
+ <xsl:text>&#x0053;</xsl:text>
+ <xsl:text>&#x0053;</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:param>
+
+ <xsl:value-of select="translate($modified-text, $xsltsl-str-lower, $xsltsl-str-upper)"/>
+ </xsl:template>
+
+ <doc:template name="str:to-lower" xmlns="">
+ <refpurpose>Make string lowercase</refpurpose>
+
+ <refdescription>
+ <para>Converts all uppercase letters to lowercase.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string to be converted</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string with all lowercase letters.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:to-lower">
+ <xsl:param name="text"/>
+
+ <xsl:value-of select="translate($text, $xsltsl-str-upper, $xsltsl-str-lower)"/>
+ </xsl:template>
+
+ <doc:template name="str:capitalise" xmlns="">
+ <refpurpose>Capitalise string</refpurpose>
+
+ <refdescription>
+ <para>Converts first character of string to an uppercase letter. All remaining characters are converted to lowercase.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string to be capitalised</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>all</term>
+ <listitem>
+ <para>Boolean controlling whether all words in the string are capitalised.</para>
+ <para>Default is true.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string with first character uppcase and all remaining characters lowercase.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:capitalise">
+ <xsl:param name="text"/>
+ <xsl:param name="all" select="true()"/>
+
+ <xsl:choose>
+ <xsl:when test="$all and (contains($text, ' ') or contains($text, ' ') or contains($text, '&#10;'))">
+ <xsl:variable name="firstword">
+ <xsl:call-template name="str:substring-before-first">
+ <xsl:with-param name="text" select="$text"/>
+ <xsl:with-param name="chars" select="$xsltsl-str-ws"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:call-template name="str:capitalise">
+ <xsl:with-param name="text">
+ <xsl:value-of select="$firstword"/>
+ </xsl:with-param>
+ <xsl:with-param name="all" select="false()"/>
+ </xsl:call-template>
+ <xsl:value-of select="substring($text, string-length($firstword) + 1, 1)"/>
+ <xsl:call-template name="str:capitalise">
+ <xsl:with-param name="text">
+ <xsl:value-of select="substring($text, string-length($firstword) + 2)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:call-template name="str:to-upper">
+ <xsl:with-param name="text" select="substring($text, 1, 1)"/>
+ </xsl:call-template>
+ <xsl:call-template name="str:to-lower">
+ <xsl:with-param name="text" select="substring($text, 2)"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:to-camelcase" xmlns="">
+ <refpurpose>Convert a string to one camelcase word</refpurpose>
+
+ <refdescription>
+ <para>Converts a string to one lowerCamelCase or UpperCamelCase
+ word, depending on the setting of the "upper"
+ parameter. UpperCamelCase is also called MixedCase while
+ lowerCamelCase is also called just camelCase. The template
+ removes any spaces, tabs and slashes, but doesn't deal with
+ other punctuation. It's purpose is to convert strings like
+ "hollow timber flush door" to a term suitable as identifier or
+ XML tag like "HollowTimberFlushDoor".
+ </para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string to be capitalised</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>upper</term>
+ <listitem>
+ <para>Boolean controlling whether the string becomes an
+ UpperCamelCase word or a lowerCamelCase word.</para>
+ <para>Default is true.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string with first character uppcase and all remaining characters lowercase.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:to-camelcase">
+ <xsl:param name="text"/>
+ <xsl:param name="upper" select="true()"/>
+ <!-- First change all 'strange' characters to spaces -->
+ <xsl:param name="string-with-only-spaces">
+ <xsl:value-of select="translate($text,concat($xsltsl-str-ws,'/'),' ')"/>
+ </xsl:param>
+ <!-- Then process them -->
+ <xsl:param name="before-space-removal">
+ <xsl:variable name="firstword">
+ <xsl:call-template name="str:substring-before-first">
+ <xsl:with-param name="text" select="$string-with-only-spaces"/>
+ <xsl:with-param name="chars" select="$xsltsl-str-ws"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$upper">
+ <xsl:call-template name="str:to-upper">
+ <xsl:with-param name="text" select="substring($firstword, 1, 1)"/>
+ </xsl:call-template>
+ <xsl:call-template name="str:to-lower">
+ <xsl:with-param name="text" select="substring($firstword, 2)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str:to-lower">
+ <xsl:with-param name="text" select="$firstword"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:call-template name="str:capitalise">
+ <xsl:with-param name="text">
+ <xsl:value-of select="substring($string-with-only-spaces, string-length($firstword) + 2)"/>
+ </xsl:with-param>
+ <xsl:with-param name="all" select="true()"/>
+ </xsl:call-template>
+ </xsl:param>
+ <xsl:value-of select="translate($before-space-removal,' ','')"/>
+ </xsl:template>
+
+ <doc:template name="str:substring-before-first" xmlns="">
+ <refpurpose>String extraction</refpurpose>
+
+ <refdescription>
+ <para>Extracts the portion of string 'text' which occurs before any of the characters in string 'chars'.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string from which to extract a substring.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>chars</term>
+ <listitem>
+ <para>The string containing characters to find.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:substring-before-first">
+ <xsl:param name="text"/>
+ <xsl:param name="chars"/>
+
+ <xsl:choose>
+
+ <xsl:when test="string-length($text) = 0"/>
+
+ <xsl:when test="string-length($chars) = 0">
+ <xsl:value-of select="$text"/>
+ </xsl:when>
+
+ <xsl:when test="contains($text, substring($chars, 1, 1))">
+ <xsl:variable name="this" select="substring-before($text, substring($chars, 1, 1))"/>
+ <xsl:variable name="rest">
+ <xsl:call-template name="str:substring-before-first">
+ <xsl:with-param name="text" select="$text"/>
+ <xsl:with-param name="chars" select="substring($chars, 2)"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="string-length($this) &lt; string-length($rest)">
+ <xsl:value-of select="$this"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$rest"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:call-template name="str:substring-before-first">
+ <xsl:with-param name="text" select="$text"/>
+ <xsl:with-param name="chars" select="substring($chars, 2)"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:substring-after-last" xmlns="">
+ <refpurpose>String extraction</refpurpose>
+
+ <refdescription>
+ <para>Extracts the portion of string 'text' which occurs after the last of the character in string 'chars'.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string from which to extract a substring.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>chars</term>
+ <listitem>
+ <para>The string containing characters to find.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:substring-after-last">
+ <xsl:param name="text"/>
+ <xsl:param name="chars"/>
+
+ <xsl:choose>
+
+ <xsl:when test="contains($text, $chars)">
+ <xsl:variable name="last" select="substring-after($text, $chars)"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($last, $chars)">
+ <xsl:call-template name="str:substring-after-last">
+ <xsl:with-param name="text" select="$last"/>
+ <xsl:with-param name="chars" select="$chars"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$last"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:substring-before-last" xmlns="">
+ <refpurpose>String extraction</refpurpose>
+
+ <refdescription>
+ <para>Extracts the portion of string 'text' which occurs before the first character of the last occurance of string 'chars'.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string from which to extract a substring.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>chars</term>
+ <listitem>
+ <para>The string containing characters to find.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:substring-before-last">
+ <xsl:param name="text"/>
+ <xsl:param name="chars"/>
+
+ <xsl:choose>
+
+ <xsl:when test="string-length($text) = 0"/>
+
+ <xsl:when test="string-length($chars) = 0">
+ <xsl:value-of select="$text"/>
+ </xsl:when>
+
+ <xsl:when test="contains($text, $chars)">
+ <xsl:call-template name="str:substring-before-last-aux">
+ <xsl:with-param name="text" select="$text"/>
+ <xsl:with-param name="chars" select="$chars"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="str:substring-before-last-aux">
+ <xsl:param name="text"/>
+ <xsl:param name="chars"/>
+
+ <xsl:choose>
+ <xsl:when test="string-length($text) = 0"/>
+
+ <xsl:when test="contains($text, $chars)">
+ <xsl:variable name="after">
+ <xsl:call-template name="str:substring-before-last-aux">
+ <xsl:with-param name="text" select="substring-after($text, $chars)"/>
+ <xsl:with-param name="chars" select="$chars"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="substring-before($text, $chars)"/>
+ <xsl:if test="string-length($after) &gt; 0">
+ <xsl:value-of select="$chars"/>
+ <xsl:copy-of select="$after"/>
+ </xsl:if>
+ </xsl:when>
+
+ <xsl:otherwise/>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:subst" xmlns="">
+ <refpurpose>String substitution</refpurpose>
+
+ <refdescription>
+ <para>Substitute 'replace' for 'with' in string 'text'.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string upon which to perform substitution.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>replace</term>
+ <listitem>
+ <para>The string to substitute.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>with</term>
+ <listitem>
+ <para>The string to be substituted.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>disable-output-escaping</term>
+ <listitem>
+ <para>A value of <literal>yes</literal> indicates that the result should have output escaping disabled. Any other value allows normal escaping of text values. The default is to enable output escaping.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:subst">
+ <xsl:param name="text"/>
+ <xsl:param name="replace"/>
+ <xsl:param name="with"/>
+ <xsl:param name='disable-output-escaping'>no</xsl:param>
+
+ <xsl:choose>
+ <xsl:when test="string-length($replace) = 0 and $disable-output-escaping = 'yes'">
+ <xsl:value-of select="$text" disable-output-escaping='yes'/>
+ </xsl:when>
+ <xsl:when test="string-length($replace) = 0">
+ <xsl:value-of select="$text"/>
+ </xsl:when>
+ <xsl:when test="contains($text, $replace)">
+
+ <xsl:variable name="before" select="substring-before($text, $replace)"/>
+ <xsl:variable name="after" select="substring-after($text, $replace)"/>
+
+ <xsl:choose>
+ <xsl:when test='$disable-output-escaping = "yes"'>
+ <xsl:value-of select="$before" disable-output-escaping="yes"/>
+ <xsl:value-of select="$with" disable-output-escaping="yes"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$before"/>
+ <xsl:value-of select="$with"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:call-template name="str:subst">
+ <xsl:with-param name="text" select="$after"/>
+ <xsl:with-param name="replace" select="$replace"/>
+ <xsl:with-param name="with" select="$with"/>
+ <xsl:with-param name="disable-output-escaping" select="$disable-output-escaping"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test='$disable-output-escaping = "yes"'>
+ <xsl:value-of select="$text" disable-output-escaping="yes"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:count-substring" xmlns="">
+ <refpurpose>Count Substrings</refpurpose>
+
+ <refdescription>
+ <para>Counts the number of times a substring occurs in a string. This can also counts the number of times a character occurs in a string, since a character is simply a string of length 1.</para>
+ </refdescription>
+
+ <example>
+ <title>Counting Lines</title>
+ <programlisting><![CDATA[
+<xsl:call-template name="str:count-substring">
+ <xsl:with-param name="text" select="$mytext"/>
+ <xsl:with-param name="chars" select="'&#x0a;'"/>
+</xsl:call-template>
+]]></programlisting>
+ </example>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The source string.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>chars</term>
+ <listitem>
+ <para>The substring to count.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns a non-negative integer value.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:count-substring">
+ <xsl:param name="text"/>
+ <xsl:param name="chars"/>
+
+ <xsl:choose>
+ <xsl:when test="string-length($text) = 0 or string-length($chars) = 0">
+ <xsl:text>0</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($text, $chars)">
+ <xsl:variable name="remaining">
+ <xsl:call-template name="str:count-substring">
+ <xsl:with-param name="text" select="substring-after($text, $chars)"/>
+ <xsl:with-param name="chars" select="$chars"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="$remaining + 1"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>0</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:substring-after-at" xmlns="">
+ <refpurpose>String extraction</refpurpose>
+ <refdescription>
+ <para>Extracts the portion of a 'char' delimited 'text' string "array" at a given 'position'.</para>
+ </refdescription>
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string from which to extract a substring.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>chars</term>
+ <listitem>
+ <para>delimiters</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>position</term>
+ <listitem>
+ <para>position of the elements</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>all</term>
+ <listitem>
+ <para>If true all of the remaining string is returned, otherwise only the element at the given position is returned. Default: false().</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+ <refreturn>
+ <para>Returns string.</para>
+ </refreturn>
+ </doc:template>
+
+
+ <xsl:template name="str:substring-after-at">
+ <xsl:param name="text"/>
+ <xsl:param name="chars"/>
+ <xsl:param name="position"/>
+ <xsl:param name="all" select='false()'/>
+
+ <xsl:choose>
+ <xsl:when test='number($position) = 0 and $all'>
+ <xsl:value-of select='$text'/>
+ </xsl:when>
+ <xsl:when test='number($position) = 0 and not($chars)'>
+ <xsl:value-of select='$text'/>
+ </xsl:when>
+ <xsl:when test='number($position) = 0 and not(contains($text, $chars))'>
+ <xsl:value-of select='$text'/>
+ </xsl:when>
+ <xsl:when test='not(contains($text, $chars))'>
+ </xsl:when>
+ <xsl:when test="number($position) = 0">
+ <xsl:value-of select="substring-before($text, $chars)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str:substring-after-at">
+ <xsl:with-param name="text" select="substring-after($text, $chars)"/>
+ <xsl:with-param name="chars" select="$chars"/>
+ <xsl:with-param name="all" select="$all"/>
+ <xsl:with-param name="position" select="$position - 1"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:substring-before-at" xmlns="">
+ <refpurpose>String extraction</refpurpose>
+ <refdescription>
+ <para>Extracts the portion of a 'char' delimited 'text' string "array" at a given 'position' </para>
+ </refdescription>
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string from which to extract a substring.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>chars</term>
+ <listitem>
+ <para>delimiters</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>position</term>
+ <listitem>
+ <para>position of the elements</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+ <refreturn>
+ <para>Returns string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:substring-before-at">
+ <xsl:param name="text"/>
+ <xsl:param name="chars"/>
+ <xsl:param name="position"/>
+
+ <xsl:choose>
+ <xsl:when test="$position &lt;= 0"/>
+ <xsl:when test="not(contains($text, $chars))"/>
+ <xsl:otherwise>
+ <xsl:value-of select='substring-before($text, $chars)'/>
+ <xsl:value-of select='$chars'/>
+
+ <xsl:call-template name="str:substring-before-at">
+ <xsl:with-param name="text" select="substring-after($text, $chars)"/>
+ <xsl:with-param name="position" select="$position - 1"/>
+ <xsl:with-param name="chars" select="$chars"/>
+ </xsl:call-template>
+
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:insert-at" xmlns="">
+ <refpurpose>String insertion</refpurpose>
+ <refdescription>
+ <para>Insert 'chars' into "text' at any given "position'</para>
+ </refdescription>
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string upon which to perform insertion</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>position</term>
+ <listitem>
+ <para>the position where insertion will be performed</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>with</term>
+ <listitem>
+ <para>The string to be inserted</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+ <refreturn>
+ <para>Returns string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:insert-at">
+ <xsl:param name="text"/>
+ <xsl:param name="position"/>
+ <xsl:param name="chars"/>
+
+ <xsl:variable name="firstpart" select="substring($text, 0, $position)"/>
+ <xsl:variable name="secondpart" select="substring($text, $position, string-length($text))"/>
+
+ <xsl:value-of select="concat($firstpart, $chars, $secondpart)"/>
+ </xsl:template>
+
+
+ <doc:template name="str:backward" xmlns="">
+ <refpurpose>String reversal</refpurpose>
+
+ <refdescription>
+ <para>Reverse the content of a given string</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string to be reversed</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns string.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:backward">
+ <xsl:param name="text"/>
+ <xsl:variable name="mirror">
+ <xsl:call-template name="str:build-mirror">
+ <xsl:with-param name="text" select="$text"/>
+ <xsl:with-param name="position" select="string-length($text)"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="substring($mirror, string-length($text) + 1, string-length($text))"/>
+ </xsl:template>
+
+ <xsl:template name="str:build-mirror">
+ <xsl:param name="text"/>
+ <xsl:param name="position"/>
+
+ <xsl:choose>
+ <xsl:when test="$position &gt; 0">
+ <xsl:call-template name="str:build-mirror">
+ <xsl:with-param name="text" select="concat($text, substring($text, $position, 1))"/>
+ <xsl:with-param name="position" select="$position - 1"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:justify" xmlns="">
+ <refpurpose>Format a string</refpurpose>
+
+ <refdescription>
+ <para>Inserts newlines and spaces into a string to format it as a block of text.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>String to be formatted.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>max</term>
+ <listitem>
+ <para>Maximum line length.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>indent</term>
+ <listitem>
+ <para>Number of spaces to insert at the beginning of each line.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>justify</term>
+ <listitem>
+ <para>Justify left, right or both. Not currently implemented (fixed at "left").</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Formatted block of text.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name='str:justify'>
+ <xsl:param name='text'/>
+ <xsl:param name='max' select='"80"'/>
+ <xsl:param name='indent' select='"0"'/>
+ <xsl:param name='justify' select='"left"'/>
+
+ <xsl:choose>
+ <xsl:when test='string-length($text) = 0 or $max &lt;= 0'/>
+
+ <xsl:when test='string-length($text) > $max and contains($text, " ") and string-length(substring-before($text, " ")) > $max'>
+ <xsl:call-template name='str:generate-string'>
+ <xsl:with-param name='text' select='" "'/>
+ <xsl:with-param name='count' select='$indent'/>
+ </xsl:call-template>
+ <xsl:value-of select='substring-before($text, " ")'/>
+ <xsl:text>
+</xsl:text>
+ <xsl:call-template name='str:justify'>
+ <xsl:with-param name='text' select='substring-after($text, " ")'/>
+ <xsl:with-param name='max' select='$max'/>
+ <xsl:with-param name='indent' select='$indent'/>
+ <xsl:with-param name='justify' select='$justify'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test='string-length($text) > $max and contains($text, " ")'>
+ <xsl:variable name='first'>
+ <xsl:call-template name='str:substring-before-last'>
+ <xsl:with-param name='text' select='substring($text, 1, $max)'/>
+ <xsl:with-param name='chars' select='" "'/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:call-template name='str:generate-string'>
+ <xsl:with-param name='text' select='" "'/>
+ <xsl:with-param name='count' select='$indent'/>
+ </xsl:call-template>
+ <xsl:value-of select='$first'/>
+ <xsl:text>
+</xsl:text>
+ <xsl:call-template name='str:justify'>
+ <xsl:with-param name='text' select='substring($text, string-length($first) + 2)'/>
+ <xsl:with-param name='max' select='$max'/>
+ <xsl:with-param name='indent' select='$indent'/>
+ <xsl:with-param name='justify' select='$justify'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:call-template name='str:generate-string'>
+ <xsl:with-param name='text' select='" "'/>
+ <xsl:with-param name='count' select='$indent'/>
+ </xsl:call-template>
+ <xsl:value-of select='$text'/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:character-first" xmlns="">
+ <refpurpose>Find first occurring character in a string</refpurpose>
+
+ <refdescription>
+ <para>Finds which of the given characters occurs first in a string.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The source string.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>chars</term>
+ <listitem>
+ <para>The characters to search for.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+ </doc:template>
+
+ <xsl:template name="str:character-first">
+ <xsl:param name="text"/>
+ <xsl:param name="chars"/>
+
+ <xsl:choose>
+ <xsl:when test="string-length($text) = 0 or string-length($chars) = 0"/>
+
+ <xsl:when test="contains($text, substring($chars, 1, 1))">
+ <xsl:variable name="next-character">
+ <xsl:call-template name="str:character-first">
+ <xsl:with-param name="text" select="$text"/>
+ <xsl:with-param name="chars" select="substring($chars, 2)"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="string-length($next-character)">
+ <xsl:variable name="first-character-position" select="string-length(substring-before($text, substring($chars, 1, 1)))"/>
+ <xsl:variable name="next-character-position" select="string-length(substring-before($text, $next-character))"/>
+
+ <xsl:choose>
+ <xsl:when test="$first-character-position &lt; $next-character-position">
+ <xsl:value-of select="substring($chars, 1, 1)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$next-character"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring($chars, 1, 1)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str:character-first">
+ <xsl:with-param name="text" select="$text"/>
+ <xsl:with-param name="chars" select="substring($chars, 2)"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <doc:template name="str:string-match" xmlns="">
+ <refpurpose>Match A String To A Pattern</refpurpose>
+
+ <refdescription>
+ <para>Performs globbing-style pattern matching on a string.</para>
+ </refdescription>
+
+ <example>
+ <title>Match Pattern</title>
+ <programlisting><![CDATA[
+<xsl:call-template name="str:string-match">
+ <xsl:with-param name="text" select="$mytext"/>
+ <xsl:with-param name="pattern" select="'abc*def?g'"/>
+</xsl:call-template>
+]]></programlisting>
+ </example>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The source string.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pattern</term>
+ <listitem>
+ <para>The pattern to match against. Certain characters have special meaning:</para>
+ <variablelist>
+ <varlistentry>
+ <term>*</term>
+ <listitem>
+ <para>Matches zero or more characters.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>?</term>
+ <listitem>
+ <para>Matches a single character.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>\</term>
+ <listitem>
+ <para>Character escape. The next character is taken as a literal character.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns "1" if the string matches the pattern, "0" otherwise.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="str:string-match">
+ <xsl:param name="text"/>
+ <xsl:param name="pattern"/>
+
+ <xsl:choose>
+ <xsl:when test="$pattern = '*'">
+ <!-- Special case: always matches -->
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test="string-length($text) = 0 and string-length($pattern) = 0">
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test="string-length($text) = 0 or string-length($pattern) = 0">
+ <xsl:text>0</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name='before-special'>
+ <xsl:call-template name='str:substring-before-first'>
+ <xsl:with-param name='text' select='$pattern'/>
+ <xsl:with-param name='chars' select='"*?\"'/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name='special'>
+ <xsl:call-template name='str:character-first'>
+ <xsl:with-param name='text' select='$pattern'/>
+ <xsl:with-param name='chars' select='"*?\"'/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name='new-text' select='substring($text, string-length($before-special) + 1)'/>
+ <xsl:variable name='new-pattern' select='substring($pattern, string-length($before-special) + 1)'/>
+
+ <xsl:choose>
+ <xsl:when test="not(starts-with($text, $before-special))">
+ <!-- Verbatim characters don't match -->
+ <xsl:text>0</xsl:text>
+ </xsl:when>
+
+ <xsl:when test="$special = '*' and string-length($new-pattern) = 1">
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test="$special = '*'">
+ <xsl:call-template name='str:match-postfix'>
+ <xsl:with-param name='text' select='$new-text'/>
+ <xsl:with-param name='pattern' select='substring($new-pattern, 2)'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="$special = '?'">
+ <xsl:call-template name="str:string-match">
+ <xsl:with-param name='text' select='substring($new-text, 2)'/>
+ <xsl:with-param name='pattern' select='substring($new-pattern, 2)'/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="$special = '\' and substring($new-text, 1, 1) = substring($new-pattern, 2, 1)">
+ <xsl:call-template name="str:string-match">
+ <xsl:with-param name='text' select='substring($new-text, 2)'/>
+ <xsl:with-param name='pattern' select='substring($new-pattern, 3)'/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$special = '\' and substring($new-text, 1, 1) != substring($new-pattern, 2, 1)">
+ <xsl:text>0</xsl:text>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- There were no special characters in the pattern -->
+ <xsl:choose>
+ <xsl:when test='$text = $pattern'>
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>0</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="str:match-postfix">
+ <xsl:param name="text"/>
+ <xsl:param name="pattern"/>
+
+ <xsl:variable name='result'>
+ <xsl:call-template name='str:string-match'>
+ <xsl:with-param name='text' select='$text'/>
+ <xsl:with-param name='pattern' select='$pattern'/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test='$result = "1"'>
+ <xsl:value-of select='$result'/>
+ </xsl:when>
+ <xsl:when test='string-length($text) = 0'>
+ <xsl:text>0</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name='str:match-postfix'>
+ <xsl:with-param name='text' select='substring($text, 2)'/>
+ <xsl:with-param name='pattern' select='$pattern'/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="str:generate-string" xmlns="">
+ <refpurpose>Create A Repeating Sequence of Characters</refpurpose>
+
+ <refdescription>
+ <para>Repeats a string a given number of times.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>text</term>
+ <listitem>
+ <para>The string to repeat.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>count</term>
+ <listitem>
+ <para>The number of times to repeat the string.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+ </doc:template>
+
+ <xsl:template name="str:generate-string">
+ <xsl:param name="text"/>
+ <xsl:param name="count"/>
+
+ <xsl:choose>
+ <xsl:when test="string-length($text) = 0 or $count &lt;= 0"/>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ <xsl:call-template name="str:generate-string">
+ <xsl:with-param name="text" select="$text"/>
+ <xsl:with-param name="count" select="$count - 1"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/texml-xsl/svg.xsl b/texml-xsl/svg.xsl
new file mode 100644
index 0000000..5eed1f0
--- /dev/null
+++ b/texml-xsl/svg.xsl
@@ -0,0 +1 @@
+<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:svg='http://xsltsl.org/svg' xmlns:doc="http://xsltsl.org/xsl/documentation/1.0" exclude-result-prefixes="doc"> <xsl:variable name='svg-public-id' select='"-//W3C//DTD SVG 20010904//EN"'/> <xsl:variable name='svg-system-id' select='"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"'/> <doc:reference xmlns=""> <referenceinfo> <releaseinfo role="meta"> $Id$ </releaseinfo> <author> <surname>Ball</surname> <firstname>Steve</firstname> </author> <copyright> <year>2002</year> <holder>Steve Ball</holder> </copyright> </referenceinfo> <title>SVG Stylesheet</title> <partintro> <section> <title>Introduction</title> <para>This module provides templates for creating SVG images.</para> </section> </partintro> </doc:reference> <doc:template name="svg:aqua-button-defs" xmlns=""> <refpurpose>Aqua-style Button</refpurpose> <refdescription> <para>Part of the mechanism to create an Aqua-style button. Include a call to this template in your SVG document's <sgmltag>defs</sgmltag> element. This template only needs to be included once. Use this in conjunction with <sgmltag>svg:aqua-button</sgmltag>.</para> <para>The default values for color1, color2 and color3 result in a grey button.</para> </refdescription> <refparameter> <variablelist> <varlistentry> <term>prefix</term> <listitem> <para>A prefix to append to the identifiers used, so that they don't clash with other identifiers. Default: "aqua-".</para> </listitem> </varlistentry> <varlistentry> <term>color1</term> <listitem> <para>The base colour of the button. Default: "#d9d9d9".</para> </listitem> </varlistentry> <varlistentry> <term>color2</term> <listitem> <para>A "background" colour for the button. Should be a darker colour than color1. Default: "#a9a9a9".</para> </listitem> </varlistentry> <varlistentry> <term>color3</term> <listitem> <para>A highlight colour for the button. Should be a lighter colour than color1. Default: "#f9f9f9".</para> </listitem> </varlistentry> </variablelist> </refparameter> <refreturn> <para>Returns SVG result-tree-fragment.</para> </refreturn> </doc:template> <xsl:template name="svg:aqua-button-defs"> <xsl:param name="prefix" select='"aqua-"'/> <xsl:param name="color1" select='"#d9d9d9"'/> <xsl:param name="color2" select='"#a9a9a9"'/> <xsl:param name="color3" select='"#f9f9f9"'/> <linearGradient id='{$prefix}gradient' x1='0%' y1='0%' x2='0%' y2='100%'> <stop offset='0%' stop-color='{$color2}'/> <stop offset='100%' stop-color='{$color1}'/> </linearGradient> <linearGradient id='{$prefix}highlight-gradient' x1='0%' y1='0%' x2='0%' y2='100%'> <stop offset='0%' stop-color='#ffffff'/> <stop offset='75%' stop-color='{$color3}' stop-opacity='0'/> <stop offset='100%' stop-color='{$color3}' stop-opacity='0'/> </linearGradient> <linearGradient id='{$prefix}revhighlight-gradient' x1='0%' y1='100%' x2='0%' y2='0%'> <stop offset='0%' stop-color='#ffffff'/> <stop offset='50%' stop-color='{$color3}' stop-opacity='0'/> <stop offset='100%' stop-color='{$color3}' stop-opacity='0'/> </linearGradient> <linearGradient id='{$prefix}corner-left-gradient' x1='0%' y1='0%' x2='100%' y2='100%'> <stop offset='0%' stop-color='#000000'/> <stop offset='100%' stop-color='{$color3}' stop-opacity='0'/> </linearGradient> <linearGradient id='{$prefix}corner-right-gradient' x1='100%' y1='0%' x2='0%' y2='100%'> <stop offset='0%' stop-color='#000000'/> <stop offset='100%' stop-color='{$color3}' stop-opacity='0'/> </linearGradient> <filter id='{$prefix}filter-blur' filterUnits='userSpaceOnUse' x='0' y='0' width='200' height='100'> <feGaussianBlur in='SourceGraphic' stdDeviation='2'/> </filter> <filter id='{$prefix}drop-shadow' y='-5' height='100'> <feColorMatrix type='matrix' in='SourceAlpha' result='inglow' values='.5 .5 .5 1 0 .5 .5 .5 1 0 .5 .5 .5 1 0 0 0 0 1 0'/> <feBlend mode='multiply' in2='SourceGraphic' in='inglow' result='innerglow'/> <feGaussianBlur stdDeviation='4' in='SourceAlpha' result='shadow'/> <feColorMatrix type='matrix' in='shadow' result='lightshadow' values='.33 .33 .33 1 0 .33 .33 .33 1 0 .33 .33 .33 1 0 0 0 0 1 0'/> <feOffset in='lightshadow' dx='0' dy='3' result='dropshadow'/> <feMerge> <feMergeNode in='dropshadow'/> <feMergeNode in='innerglow'/> </feMerge> </filter> </xsl:template> <doc:template name="svg:aqua-button" xmlns=""> <refpurpose>Aqua-style Button</refpurpose> <refdescription> <para>Part of the mechanism to create an Aqua-style button. Include a call to this template in your SVG document where you want a button to appear. This template can be used many times in a single SVG document. Use this in conjunction with <sgmltag>svg:aqua-button-defs</sgmltag>.</para> </refdescription> <refparameter> <variablelist> <varlistentry> <term>prefix</term> <listitem> <para>A prefix to append to the identifiers used, so that they don't clash with other identifiers. Default: "aqua-".</para> </listitem> </varlistentry> </variablelist> </refparameter> <refreturn> <para>Returns SVG result-tree-fragment.</para> </refreturn> </doc:template> <xsl:template name='svg:aqua-button'> <xsl:param name="prefix" select='"aqua-"'/> <g filter='url(#{$prefix}drop-shadow)'> <clipPath id='{$prefix}main-shape'> <path clip-rule='evenodd' d="M50,90 C0,90 0,30 50,30 L150,30 C200,30 200,90 150,90 z" /> </clipPath> <path fill="url(#{$prefix}gradient)" stroke="none" d="M50,90 C0,90 0,30 50,30 L150,30 C200,30 200,90 150,90 z" /> <path clip-path='url(#{$prefix}main-shape)' fill='url(#{$prefix}corner-left-gradient)' stroke='none' filter='url(#{$prefix}filter-blur)' d="M50,57 L13,57 A35,35 -90 0,1 50,30 z" /> <path clip-path='url(#{$prefix}main-shape)' fill='url(#{$prefix}corner-right-gradient)' stroke='none' filter='url(#{$prefix}filter-blur)' d="M150,30 A35,35 90 0,1 190,57 L150,57 z" /> <path fill="url(#{$prefix}highlight-gradient)" stroke="none" stroke-width='1' d="M50,65 C20,65 20,35 50,35 L150,35 C180,35 180,65 150,65 z" /> <path filter='url(#{$prefix}filter-blur)' fill="url(#{$prefix}revhighlight-gradient)" stroke="none" d="M50,85 C10,85 10,35 50,35 L150,35 C190,35 190,85 150,85 z" /> </g> </xsl:template> </xsl:stylesheet> \ No newline at end of file
diff --git a/texml-xsl/uri.xsl b/texml-xsl/uri.xsl
new file mode 100644
index 0000000..7beed10
--- /dev/null
+++ b/texml-xsl/uri.xsl
@@ -0,0 +1,580 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet
+ version="1.0"
+ extension-element-prefixes="doc"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
+ xmlns:uri="http://xsltsl.org/uri"
+>
+
+ <doc:reference xmlns="">
+ <referenceinfo>
+ <releaseinfo role="meta">
+ $Id$
+ </releaseinfo>
+ <author>
+ <surname>Diamond</surname>
+ <firstname>Jason</firstname>
+ </author>
+ <copyright>
+ <year>2001</year>
+ <holder>Jason Diamond</holder>
+ </copyright>
+ </referenceinfo>
+
+ <title>URI (Uniform Resource Identifier) Processing</title>
+
+ <partintro>
+ <section>
+ <title>Introduction</title>
+ <para>This module provides templates for processing URIs (Uniform Resource Identifers).</para>
+ </section>
+ </partintro>
+
+ </doc:reference>
+
+ <doc:template name="uri:is-absolute-uri" xmlns="">
+ <refpurpose>Determines if a URI is absolute or relative.</refpurpose>
+
+ <refdescription>
+ <para>Absolute URIs start with a scheme (like "http:" or "mailto:").</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>uri</term>
+ <listitem>
+ <para>An absolute or relative URI.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns 'true' if the URI is absolute or '' if it's not.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="uri:is-absolute-uri">
+ <xsl:param name="uri"/>
+
+ <xsl:if test="contains($uri, ':')">
+ <xsl:value-of select="true()"/>
+ </xsl:if>
+
+ </xsl:template>
+
+ <doc:template name="uri:get-uri-scheme" xmlns="">
+ <refpurpose>Gets the scheme part of a URI.</refpurpose>
+
+ <refdescription>
+ <para>The ':' is not part of the scheme.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>uri</term>
+ <listitem>
+ <para>An absolute or relative URI.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the scheme (without the ':') or '' if the URI is relative.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="uri:get-uri-scheme">
+ <xsl:param name="uri"/>
+ <xsl:if test="contains($uri, ':')">
+ <xsl:value-of select="substring-before($uri, ':')"/>
+ </xsl:if>
+ </xsl:template>
+
+ <doc:template name="uri:get-uri-authority" xmlns="">
+ <refpurpose>Gets the authority part of a URI.</refpurpose>
+
+ <refdescription>
+ <para>The authority usually specifies the host machine for a resource. It always follows '//' in a typical URI.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>uri</term>
+ <listitem>
+ <para>An absolute or relative URI.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the authority (without the '//') or '' if the URI has no authority.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="uri:get-uri-authority">
+ <xsl:param name="uri"/>
+
+ <xsl:variable name="a">
+ <xsl:choose>
+ <xsl:when test="contains($uri, ':')">
+ <xsl:if test="substring(substring-after($uri, ':'), 1, 2) = '//'">
+ <xsl:value-of select="substring(substring-after($uri, ':'), 3)"/>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="substring($uri, 1, 2) = '//'">
+ <xsl:value-of select="substring($uri, 3)"/>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="contains($a, '/')">
+ <xsl:value-of select="substring-before($a, '/')" />
+ </xsl:when>
+ <xsl:when test="contains($a, '?')">
+ <xsl:value-of select="substring-before($a, '?')" />
+ </xsl:when>
+ <xsl:when test="contains($a, '#')">
+ <xsl:value-of select="substring-before($a, '#')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$a" />
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="uri:get-uri-path" xmlns="">
+ <refpurpose>Gets the path part of a URI.</refpurpose>
+
+ <refdescription>
+ <para>The path usually comes after the '/' in a URI.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>uri</term>
+ <listitem>
+ <para>An absolute or relative URI.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the path (with any leading '/') or '' if the URI has no path.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="uri:get-uri-path">
+ <xsl:param name="uri"/>
+
+ <xsl:variable name="p">
+ <xsl:choose>
+ <xsl:when test="contains($uri, '//')">
+ <xsl:if test="contains(substring-after($uri, '//'), '/')">
+ <xsl:value-of select="concat('/', substring-after(substring-after($uri, '//'), '/'))"/>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="contains($uri, ':')">
+ <xsl:value-of select="substring-after($uri, ':')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$uri"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="contains($p, '?')">
+ <xsl:value-of select="substring-before($p, '?')" />
+ </xsl:when>
+ <xsl:when test="contains($p, '#')">
+ <xsl:value-of select="substring-before($p, '#')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$p" />
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="uri:get-uri-query" xmlns="">
+ <refpurpose>Gets the query part of a URI.</refpurpose>
+
+ <refdescription>
+ <para>The query comes after the '?' in a URI.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>uri</term>
+ <listitem>
+ <para>An absolute or relative URI.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the query (without the '?') or '' if the URI has no query.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="uri:get-uri-query">
+ <xsl:param name="uri"/>
+
+ <xsl:variable name="q" select="substring-after($uri, '?')"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($q, '#')">
+ <xsl:value-of select="substring-before($q, '#')"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$q"/></xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <doc:template name="uri:get-uri-fragment" xmlns="">
+ <refpurpose>Gets the fragment part of a URI.</refpurpose>
+
+ <refdescription>
+ <para>The fragment comes after the '#' in a URI.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>uri</term>
+ <listitem>
+ <para>An absolute or relative URI.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>Returns the fragment (without the '#') or '' if the URI has no fragment.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="uri:get-uri-fragment">
+ <xsl:param name="uri"/>
+
+ <xsl:value-of select="substring-after($uri, '#')"/>
+
+ </xsl:template>
+
+ <doc:template name="uri:resolve-uri" xmlns="">
+ <refpurpose>Resolves a URI reference against a base URI.</refpurpose>
+
+ <refdescription>
+ <para>This template follows the guidelines specified by <ulink url="ftp://ftp.isi.edu/in-notes/rfc2396.txt">RFC 2396</ulink>.</para>
+ </refdescription>
+
+ <refparameter>
+ <variablelist>
+ <varlistentry>
+ <term>reference</term>
+ <listitem>
+ <para>A (potentially relative) URI reference.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>base</term>
+ <listitem>
+ <para>The base URI.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>document</term>
+ <listitem>
+ <para>The URI of the current document. This defaults to the value of the base URI if not specified.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refparameter>
+
+ <refreturn>
+ <para>The "combined" URI.</para>
+ </refreturn>
+ </doc:template>
+
+ <xsl:template name="uri:resolve-uri">
+ <xsl:param name="reference"/>
+ <xsl:param name="base"/>
+ <xsl:param name="document" select="$base"/>
+
+ <xsl:variable name="reference-scheme">
+ <xsl:call-template name="uri:get-uri-scheme">
+ <xsl:with-param name="uri" select="$reference"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="reference-authority">
+ <xsl:call-template name="uri:get-uri-authority">
+ <xsl:with-param name="uri" select="$reference"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="reference-path">
+ <xsl:call-template name="uri:get-uri-path">
+ <xsl:with-param name="uri" select="$reference"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="reference-query">
+ <xsl:call-template name="uri:get-uri-query">
+ <xsl:with-param name="uri" select="$reference"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="reference-fragment">
+ <xsl:call-template name="uri:get-uri-fragment">
+ <xsl:with-param name="uri" select="$reference"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+
+ <xsl:when test="
+ not(string-length($reference-scheme)) and
+ not(string-length($reference-authority)) and
+ not(string-length($reference-path)) and
+ not(string-length($reference-query))"
+ >
+
+ <xsl:choose>
+ <xsl:when test="contains($document, '?')">
+ <xsl:value-of select="substring-before($document, '?')"/>
+ </xsl:when>
+ <xsl:when test="contains($document, '#')">
+ <xsl:value-of select="substring-before($document, '#')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$document"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:if test="string-length($reference-fragment)">
+ <xsl:value-of select="concat('#', $reference-fragment)"/>
+ </xsl:if>
+
+ </xsl:when>
+
+ <xsl:when test="string-length($reference-scheme)">
+
+ <xsl:value-of select="$reference"/>
+
+ </xsl:when>
+
+ <xsl:otherwise>
+
+ <xsl:variable name="base-scheme">
+ <xsl:call-template name="uri:get-uri-scheme">
+ <xsl:with-param name="uri" select="$base"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="base-authority">
+ <xsl:call-template name="uri:get-uri-authority">
+ <xsl:with-param name="uri" select="$base"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="base-path">
+ <xsl:call-template name="uri:get-uri-path">
+ <xsl:with-param name="uri" select="$base"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="base-query">
+ <xsl:call-template name="uri:get-uri-query">
+ <xsl:with-param name="uri" select="$base"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="base-fragment">
+ <xsl:call-template name="uri:get-uri-fragment">
+ <xsl:with-param name="uri" select="$base"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="result-authority">
+ <xsl:choose>
+ <xsl:when test="string-length($reference-authority)">
+ <xsl:value-of select="$reference-authority"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$base-authority"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="result-path">
+ <xsl:choose>
+ <!-- don't normalize absolute paths -->
+ <xsl:when test="starts-with($reference-path, '/')">
+ <xsl:value-of select="$reference-path" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="uri:normalize-path">
+ <xsl:with-param name="path">
+ <xsl:if test="string-length($reference-authority) = 0 and substring($reference-path, 1, 1) != '/'">
+ <xsl:call-template name="uri:get-path-without-file">
+ <xsl:with-param name="path-with-file" select="$base-path"/>
+ </xsl:call-template>
+ <xsl:value-of select="'/'"/>
+ </xsl:if>
+ <xsl:value-of select="$reference-path"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:value-of select="concat($base-scheme, '://', $result-authority, $result-path)"/>
+
+ <xsl:if test="string-length($reference-query)">
+ <xsl:value-of select="concat('?', $reference-query)"/>
+ </xsl:if>
+
+ <xsl:if test="string-length($reference-fragment)">
+ <xsl:value-of select="concat('#', $reference-fragment)"/>
+ </xsl:if>
+
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <xsl:template name="uri:get-path-without-file">
+ <xsl:param name="path-with-file" />
+ <xsl:param name="path-without-file" />
+
+ <xsl:choose>
+ <xsl:when test="contains($path-with-file, '/')">
+ <xsl:call-template name="uri:get-path-without-file">
+ <xsl:with-param name="path-with-file" select="substring-after($path-with-file, '/')" />
+ <xsl:with-param name="path-without-file">
+ <xsl:choose>
+ <xsl:when test="$path-without-file">
+ <xsl:value-of select="concat($path-without-file, '/', substring-before($path-with-file, '/'))" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring-before($path-with-file, '/')" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$path-without-file" />
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <xsl:template name="uri:normalize-path">
+ <xsl:param name="path"/>
+ <xsl:param name="result" select="''"/>
+
+ <xsl:choose>
+ <xsl:when test="string-length($path)">
+ <xsl:choose>
+ <xsl:when test="$path = '/'">
+ <xsl:value-of select="concat($result, '/')"/>
+ </xsl:when>
+ <xsl:when test="$path = '.'">
+ <xsl:value-of select="concat($result, '/')"/>
+ </xsl:when>
+ <xsl:when test="$path = '..'">
+ <xsl:call-template name="uri:get-path-without-file">
+ <xsl:with-param name="path-with-file" select="$result"/>
+ </xsl:call-template>
+ <xsl:value-of select="'/'"/>
+ </xsl:when>
+ <xsl:when test="contains($path, '/')">
+ <!-- the current segment -->
+ <xsl:variable name="s" select="substring-before($path, '/')"/>
+ <!-- the remaining path -->
+ <xsl:variable name="p">
+ <xsl:choose>
+ <xsl:when test="substring-after($path, '/') = ''">
+ <xsl:value-of select="'/'"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring-after($path, '/')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$s = ''">
+ <xsl:call-template name="uri:normalize-path">
+ <xsl:with-param name="path" select="$p"/>
+ <xsl:with-param name="result" select="$result"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$s = '.'">
+ <xsl:call-template name="uri:normalize-path">
+ <xsl:with-param name="path" select="$p"/>
+ <xsl:with-param name="result" select="$result"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$s = '..'">
+ <xsl:choose>
+ <xsl:when test="string-length($result) and (substring($result, string-length($result) - 2) != '/..')">
+ <xsl:call-template name="uri:normalize-path">
+ <xsl:with-param name="path" select="$p"/>
+ <xsl:with-param name="result">
+ <xsl:call-template name="uri:get-path-without-file">
+ <xsl:with-param name="path-with-file" select="$result"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="uri:normalize-path">
+ <xsl:with-param name="path" select="$p"/>
+ <xsl:with-param name="result" select="concat($result, '/..')"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="uri:normalize-path">
+ <xsl:with-param name="path" select="$p"/>
+ <xsl:with-param name="result" select="concat($result, '/', $s)"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat($result, '/', $path)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$result"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/xep2texml.xsl b/xep2texml.xsl
index 8e2af75..348ce3a 100644
--- a/xep2texml.xsl
+++ b/xep2texml.xsl
@@ -29,7 +29,7 @@
-->
<!--<xsl:include href="xsltsl/string.xsl"/>-->
-<xsl:import href="http://xsltsl.sourceforge.net/modules/stdlib.xsl"/>
+<xsl:import href="texml-xsl/stdlib.xsl"/>
<!-- Create a variable named $maxXEPVersiom containing the MAX version -->
<xsl:variable name="maxXEPVersion">