[Gnucash-changes] r13566 - gnucash/trunk - Optional XSL stylesheets and support - prototypes

Neil Williams codehelp at cvs.gnucash.org
Thu Mar 9 11:54:46 EST 2006


Author: codehelp
Date: 2006-03-09 11:54:44 -0500 (Thu, 09 Mar 2006)
New Revision: 13566
Trac: http://svn.gnucash.org/trac/changeset/13566

Added:
   gnucash/trunk/src/optional/xsl/
   gnucash/trunk/src/optional/xsl/Makefile.am
   gnucash/trunk/src/optional/xsl/README
   gnucash/trunk/src/optional/xsl/date-time.xsl
   gnucash/trunk/src/optional/xsl/gnucash-gnccustomer-vcard2.xsl
   gnucash/trunk/src/optional/xsl/gnucash-std.xsl
   gnucash/trunk/src/optional/xsl/string.xsl
   gnucash/trunk/src/optional/xsl/vcard-gnccustomer.pl
Modified:
   gnucash/trunk/ChangeLog
   gnucash/trunk/configure.in
   gnucash/trunk/src/optional/Makefile.am
Log:
Optional XSL stylesheets and support - prototypes

Modified: gnucash/trunk/ChangeLog
===================================================================
--- gnucash/trunk/ChangeLog	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/ChangeLog	2006-03-09 16:54:44 UTC (rev 13566)
@@ -1,5 +1,22 @@
 2006-03-09  Neil Williams <linux at codehelp.co.uk>
+	* src/optional/xsl : New directory for optional XSL
+	* src/optional/xsl/vcard-gnccustomer.pl : Perl script
+	to create QSF from VCards
+	* src/optional/xsl/gnucash-gnccustomer-vcard2.xsl :
+	XSL to generate vcards from QSF (gncCustomer)
+	* src/optional/xsl/gnucash-std.xsl : Common routines
+	for gnucash XSL stylesheets
+	* src/optional/xsl/Makefile.am : Don't build, just install.
+	* src/optional/xsl/string.xsl : xsltsl standard library XSL
+	in place until available as a package.
+	* src/optional/xsl/README : Notes on using XSL and examples.
+	* src/optional/xsl/date-time.xsl : xsltsl standard library.
+	* src/optional/Makefile.am : install only.
+	* configure.in : Add instruction to build a Makefile in
+	src/optional/xsl
 
+2006-03-09  Neil Williams <linux at codehelp.co.uk>
+
 	* src/business/business-core/gncInvoice.c : Enable
 	QOF_TYPE_COLLECT to allow recursive copying of gncEntry
 	within a gncInvoice for QSF export.

Modified: gnucash/trunk/configure.in
===================================================================
--- gnucash/trunk/configure.in	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/configure.in	2006-03-09 16:54:44 UTC (rev 13566)
@@ -2228,6 +2228,7 @@
           src/optional/Makefile
           src/optional/swig/Makefile
           src/optional/swig/examples/Makefile
+          src/optional/xsl/Makefile
           src/pixmaps/Makefile
           src/quotes/Makefile
           src/register/Makefile

Modified: gnucash/trunk/src/optional/Makefile.am
===================================================================
--- gnucash/trunk/src/optional/Makefile.am	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/src/optional/Makefile.am	2006-03-09 16:54:44 UTC (rev 13566)
@@ -6,4 +6,4 @@
 # get this to work (automake 1.4p5).
 
 SUBDIRS = 
-DIST_SUBDIRS = swig
+DIST_SUBDIRS = swig xsl


Property changes on: gnucash/trunk/src/optional/xsl
___________________________________________________________________
Name: svn:ignore
   + Makefile.in
Makefile



Added: gnucash/trunk/src/optional/xsl/Makefile.am
===================================================================
--- gnucash/trunk/src/optional/xsl/Makefile.am	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/src/optional/xsl/Makefile.am	2006-03-09 16:54:44 UTC (rev 13566)
@@ -0,0 +1,13 @@
+xsldir = ${datadir}/xml/gnucash/xsl
+
+xsl_DATA = \
+ README \
+ date-time.xsl \
+ gnucash-std.xsl \
+ string.xsl \
+ gnucash-gnccustomer-vcard2.xsl \
+ vcard-gnccustomer.pl
+
+EXTRA_DIST = \
+ ${xsl_DATA}
+

Added: gnucash/trunk/src/optional/xsl/README
===================================================================
--- gnucash/trunk/src/optional/xsl/README	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/src/optional/xsl/README	2006-03-09 16:54:44 UTC (rev 13566)
@@ -0,0 +1,98 @@
+GnuCash, XSL and QSF.
+====================
+
+       If you need to convert gnucash QSF data into other formats, take a look at the example
+       stylesheets  installed  with  gnucash.  You  are  welcome to contribute new or amended
+       stylesheets - just post them on the QOF-devel mailing list.
+
+       http://lists.sourceforge.net/lists/listinfo/qof-devel
+
+       Depending on your package manager, the XSL stylesheets should be installed in
+       /usr/share/xml/gnucash/xsl/, or on Fink /sw/share/xml/gnucash/xsl/.
+
+       Current stylesheets are works in progress, but include:
+
+       · gnucash-gnccustomer-vcard2.xsl 
+
+          This  stylesheet  converts  QSF  export  gnucash  customer  data into a brief Vcard, 
+          suitable  for  upload  to  Kaddressbook. Each  VCard is written into a separate .vcf 
+          file,  named  after  the  contact described in the pilot_address records. Spaces are
+          replaced with underscores.  Specify  the  '-o dir/' option to xsltproc to output all
+          vcards into a directory.
+
+       ·  Others
+
+          Stylesheets for ICS, vcal and possibly LDAP are planned. Any plain text, XML or HTML
+          format can be generated, theoretically. If you  have a request for an XSL stylesheet
+          or if you have a stylesheet you would like to make available to others,  mention  it
+          on the QOF-devel mailing list.
+
+       Also included is a perl script: 
+
+       ·  vcard-gnccustomer.pl
+
+          The  script  uses  the Text::vCard::Addressbook  CPAN  module  to parse VCard files, 
+          including those from other applications,  into QSF XML that  could  be imported into 
+          gnucash and merged into your gnucash customer list. With a  few  tweaks,  this could
+          also be configured to create QSF XML suitable for gnucash vendor or employee records.
+
+       You  are  free to copy and modify these stylesheets to your own requirements, including
+       translations and customised  formats.  Depending on your package manager, this is often
+       best done by copying the installed file  to  a  local  directory  before  modifying  it.
+       GnuCash  does  not reference these  stylesheets directly. If your modifications could be
+       useful to others, please contribute them to  gnucash via the QOF-devel mailing  list  or
+       gnucash-devel mailing list. Submitted stylesheets should be licenced under the GNU GPL.
+
+
+LOCALISATION (l10N) OF STYLESHEET OUTPUT.
+========================================
+
+       Later HTML  stylesheets  will  support providing  translatable strings and user-specific
+       encodings via external parameters. This can make the command line very long so  is  best
+       performed using  a script. Each descriptive word in the output is configured as a string
+       parameter for the stylesheet and can be replaced with a translated version.  HTML output
+       supports  setting the HTML language (as would be specified in the <html> lang attribute)
+       and the encoding (as would be specified in the  <meta>  charset  value  in  the  content
+       attribute).  If  you use  these stylesheets via a scripting language - like bash, PHP or
+       Perl - you could automate the translation by passing values obtained from a normal  get-
+       text PO  file.  Copy  the translatable strings into your script file as normal variables
+       then mark up those variables for translation by gettext. When the script is called, get-
+       text  will assign the translated values to the variables and your script can simply echo
+       those values to the calls to the XSL parser routines.
+
+       It  is  important  that  the  HTML  language  and  the encoding match each other AND the 
+       expected content of the HTML output generated from the gnucash QSF data.
+
+       When  providing translated strings, the same constraints apply as if you were using get-
+       text and a normal PO file: the context and format of the translation  should  match  the
+       intention expressed in the default value of the parameter. If the default is plural, the
+       translation should be plural. If the default is capitalised, the translation  should  be
+       capitalised  -  subject  to grammatical  rules for that language - even if the parameter 
+       name itself is not capitalised.
+
+       Each stylesheet specifies the translatable strings in a block near the top of the  file,
+       marked  as  for  the attention  of  translators. Common settings, like the HTML language
+       parameter and  the encoding support, are  in  the  gnucash-std.xsl  stylesheet  and  are
+       available in all HTML stylesheets by using the string parameters html_lang and encoding.
+
+       For more information, please ask on the gnucash-devel mailing list, the QOF-devel mailing
+       list or see the pilot-qof source: http://pilot-qof.sourceforge.net/
+
+EXAMPLES
+========
+
+       Convert a QSF XML file containing gncCustomer records,  into  individual VCard .vcf files
+       in  the vcards/ directory - which must already exist. Files are named according to either
+       the company or name of the gncAddress record.
+
+        $ xsltproc -o vcards/ gnucash-gnccustomer-vcard2.xsl addresses.xml
+
+       This example is based on an "in-progress" QSF invoice stylesheet for gnucash that is based
+       on the existing pilot-qof HTML invoice stylesheet. It overrides the  default  mileage-rate 
+       (0.30 currency units per unit distance) and the default hourly-rate (20 currency units per
+       hour) provided by the stylesheet with user specific values.  The  example  is here just to
+       indicate how --stringparam would be used.
+
+        $  xsltproc  --stringparam  mileage-rate  0.45 --stringparam hourly-rate 21 -o invoices/
+       pilot-qof-invoice-xhtml.xsl invoice.xml
+

Added: gnucash/trunk/src/optional/xsl/date-time.xsl
===================================================================
--- gnucash/trunk/src/optional/xsl/date-time.xsl	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/src/optional/xsl/date-time.xsl	2006-03-09 16:54:44 UTC (rev 13566)
@@ -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: date-time.xsl,v 1.1.2.1 2006/02/28 08:47:05 neil Exp $
+      </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>

Added: gnucash/trunk/src/optional/xsl/gnucash-gnccustomer-vcard2.xsl
===================================================================
--- gnucash/trunk/src/optional/xsl/gnucash-gnccustomer-vcard2.xsl	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/src/optional/xsl/gnucash-gnccustomer-vcard2.xsl	2006-03-09 16:54:44 UTC (rev 13566)
@@ -0,0 +1,74 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:qof-qsf="http://qof.sourceforge.net/" xmlns:str="http://xsltsl.org/string" version="1.1">
+  <xsl:import href="string.xsl"/>
+  <!-- our own gnucash standard routines -->
+  <xsl:import href="gnucash-std.xsl"/>
+  <xsl:output method="text"/>
+  <!-- Representing QSF gncAddress data in a 2.1 extended VCard 
+
+  This stylesheet converts the GnuCash output from Export Customers
+  into a simple Vcard, suitable for import into KAdddressbook. For other 
+  VCard support (e.g. for mobile phones), see other vcard XSL stylesheets in the 
+  gnucash collection.
+
+  Each VCard is written into a separate .vcf file, named after the 
+  contact described in the gncAddress records. Spaces are replaced with
+  underscores. Specify the '-o dir/' option to xsltproc to output all vcards
+  into a directory.
+  -->
+  <!-- Licence
+
+  This file is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  -->
+  <xsl:template match="/*/qof-qsf:book/qof-qsf:object[@type='gncAddress']">
+    <xsl:text>TEL;TYPE=WORK:</xsl:text>
+    <xsl:value-of select="qof-qsf:string[@type='phone']"/>
+    <xsl:text>&#10;TEL;TYPE=FAX:</xsl:text>
+    <xsl:value-of select="qof-qsf:string[@type='fax']"/>
+    <xsl:text>&#10;EMAIL:</xsl:text>
+    <xsl:value-of select="qof-qsf:string[@type='email']"/>
+    <xsl:text>&#10;ADR;TYPE=work:;;</xsl:text>
+    <xsl:value-of select="qof-qsf:string[@type='number']"/>
+    <xsl:text>;</xsl:text>
+    <xsl:value-of select="qof-qsf:string[@type='street']"/>
+    <xsl:text>;</xsl:text>
+    <xsl:value-of select="qof-qsf:string[@type='locality']"/>
+    <xsl:text>;</xsl:text>
+    <xsl:value-of select="qof-qsf:string[@type='city']"/>
+    <xsl:text>&#10;N:</xsl:text>
+    <xsl:value-of select="qof-qsf:string[@type='name']"/>
+    <xsl:text>&#10;</xsl:text>
+  </xsl:template>
+  <xsl:template match="/">
+    <xsl:for-each select="/*/qof-qsf:book/qof-qsf:object[@type='gncCustomer']">
+      <xsl:variable name="contactName">
+        <xsl:value-of select="qof-qsf:string[@type='name']"/>
+      </xsl:variable>
+      <xsl:variable name="card_title">
+        <xsl:call-template name="get_chunk_name">
+          <xsl:with-param name="entryName" select="$contactName"/>
+        </xsl:call-template>
+      </xsl:variable>
+      <!-- chunking support -->
+      <xsl:document href="{$card_title}.vcf" method="text">
+        <xsl:text>BEGIN:VCARD&#10;VERSION:2.1&#10;</xsl:text>
+        <xsl:call-template name="locate_child">
+          <xsl:with-param name="customer_object" select="."/>
+        </xsl:call-template>
+        <xsl:text>END:VCARD&#10;</xsl:text>
+      </xsl:document>
+    </xsl:for-each>
+  </xsl:template>
+</xsl:stylesheet>

Added: gnucash/trunk/src/optional/xsl/gnucash-std.xsl
===================================================================
--- gnucash/trunk/src/optional/xsl/gnucash-std.xsl	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/src/optional/xsl/gnucash-std.xsl	2006-03-09 16:54:44 UTC (rev 13566)
@@ -0,0 +1,140 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:qof-qsf="http://qof.sourceforge.net/" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:dt="http://xsltsl.org/date-time" xmlns:str="http://xsltsl.org/string" version="1.0" exclude-result-prefixes="qof-qsf html dt str">
+  <xsl:import href="date-time.xsl"/>
+  <xsl:import href="string.xsl"/>
+  <!--This stylesheet contains standard templates for QOF QSF.-->
+  <!--This is only a working prototype -->
+  <!-- Licence
+
+  This file is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  -->
+  <!-- Translation support via external parameters -->
+  <xsl:param name="html_lang">en</xsl:param>
+  <xsl:param name="encoding">iso-8859-15</xsl:param>
+  <!-- Convert gnc_numeric notation to an XSL number -->
+  <xsl:template name="numeric_to_double">
+    <xsl:param name="numeric_string"/>
+    <xsl:variable name="before" select="substring-before($numeric_string, '/')"/>
+    <xsl:variable name="after" select="substring-after($numeric_string, '/')"/>
+    <xsl:variable name="numeric" select="$before div $after"/>
+    <xsl:value-of select="number($numeric)"/>
+  </xsl:template>
+  <xsl:template name="get_chunk_name">
+    <xsl:param name="entryName"/>
+    <xsl:param name="entryCompany"/>
+    <xsl:variable name="result">
+      <xsl:choose>
+        <xsl:when test="$entryName = ''">
+          <xsl:call-template name="str:subst">
+            <xsl:with-param name="text" select="$entryCompany"/>
+            <xsl:with-param name="replace">
+              <xsl:text> </xsl:text>
+            </xsl:with-param>
+            <xsl:with-param name="with">
+              <xsl:text>_</xsl:text>
+            </xsl:with-param>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:variable name="temp">
+            <xsl:call-template name="str:subst">
+              <xsl:with-param name="text" select="$entryName"/>
+              <xsl:with-param name="replace">
+                <xsl:text> </xsl:text>
+              </xsl:with-param>
+              <xsl:with-param name="with">
+                <xsl:text>_</xsl:text>
+              </xsl:with-param>
+            </xsl:call-template>
+          </xsl:variable>
+          <xsl:call-template name="str:subst">
+            <xsl:with-param name="text" select="$temp"/>
+            <xsl:with-param name="replace">
+              <xsl:text>;</xsl:text>
+            </xsl:with-param>
+            <xsl:with-param name="with">
+              <xsl:text>_</xsl:text>
+            </xsl:with-param>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:value-of select="$result"/>
+  </xsl:template>
+  <xsl:template name="prepare_address_div">
+    <xsl:param name="address_object" select="."/>
+    <xsl:comment>this address panel can be located precisely using CSS</xsl:comment>
+    <xsl:text>&#10;</xsl:text>
+    <div class="address">
+      <h2>Customer address</h2>
+      <p class="address_para">
+        <xsl:text>&#10;</xsl:text>
+        <b>
+          <xsl:value-of select="qof-qsf:string[@type='entryCompany']"/>
+        </b>
+        <br/>
+        <xsl:text>&#10;</xsl:text>
+        <xsl:value-of select="qof-qsf:string[@type='entryAddress']"/>
+        <br/>
+        <xsl:text>&#10;</xsl:text>
+        <xsl:value-of select="qof-qsf:string[@type='entryCity']"/>
+        <br/>
+        <xsl:text>&#10;</xsl:text>
+        <xsl:value-of select="qof-qsf:string[@type='entryState']"/>
+        <br/>
+        <xsl:text>&#10;</xsl:text>
+        <xsl:value-of select="qof-qsf:string[@type='entryZip']"/>
+        <br/>
+        <xsl:text>&#10;</xsl:text>
+        <xsl:value-of select="qof-qsf:string[@type='entryCountry']"/>
+        <br/>
+        <br/>
+        <xsl:text>&#10;</xsl:text>
+        <xsl:value-of select="qof-qsf:string[@type='entryPhone1']"/>
+      </p>
+    </div>
+  </xsl:template>
+  <xsl:template name="vcard_safe">
+    <xsl:param name="address_string"/>
+    <xsl:variable name="safe_string">
+      <xsl:call-template name="str:subst">
+        <xsl:with-param name="text" select="$entryCompany"/>
+        <xsl:with-param name="replace">
+          <xsl:text>,</xsl:text>
+        </xsl:with-param>
+        <xsl:with-param name="with">
+          <xsl:text>\,</xsl:text>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:value-of select="$safe_string"/>
+  </xsl:template>
+  <!-- hierarchy support -->
+  <xsl:template name="locate_child">
+    <xsl:param name="customer_object"/>
+    <xsl:variable name="cust_addr_guid">
+      <xsl:value-of select="qof-qsf:guid[@type='addr']"/>
+    </xsl:variable>
+    <xsl:for-each select="/*/qof-qsf:book/qof-qsf:object[@type='gncAddress']">
+      <xsl:variable name="addr_guid">
+        <xsl:value-of select="qof-qsf:guid[@type='guid']"/>
+      </xsl:variable>
+      <xsl:if test="$addr_guid = $cust_addr_guid">
+        <xsl:variable name="set" select="."/>
+        <xsl:apply-templates select="$set"/>
+      </xsl:if>
+    </xsl:for-each>
+  </xsl:template>
+</xsl:stylesheet>

Added: gnucash/trunk/src/optional/xsl/string.xsl
===================================================================
--- gnucash/trunk/src/optional/xsl/string.xsl	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/src/optional/xsl/string.xsl	2006-03-09 16:54:44 UTC (rev 13566)
@@ -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: string.xsl,v 1.1.2.1 2006/02/28 08:47:05 neil Exp $
+      </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;&#x03!
 CE;&#x03
D0;&#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;&#x1!
 EAF;&#x1
EB1;&#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;&#x03!
 8F;&#x03
92;&#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;&#x1!
 EAE;&#x1
EB0;&#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>
+

Added: gnucash/trunk/src/optional/xsl/vcard-gnccustomer.pl
===================================================================
--- gnucash/trunk/src/optional/xsl/vcard-gnccustomer.pl	2006-03-09 16:50:39 UTC (rev 13565)
+++ gnucash/trunk/src/optional/xsl/vcard-gnccustomer.pl	2006-03-09 16:54:44 UTC (rev 13566)
@@ -0,0 +1,103 @@
+#!/usr/bin/perl -w
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+use Text::vCard::Addressbook;
+use strict;
+use vars qw($address_book $hex_string $num $c $d $e $i $vcard $names $name $fullname $email $address $addresses $phones $phone $filename $usage $encoding);
+
+############### USER CONFIGURATION ####################
+# Change to the encoding for you locale if your VCF data
+# contains accented characters etc.
+  $encoding = 'UTF-8';
+###############  END CONFIGURATION ####################
+
+# About
+#
+# This is a very simple file and should be simple to customise.
+# A similar file is included in pilot-qof. Currently, the script
+# needs to be told where to find the VCF file to transform and
+# expects the user to redirect output to a file:
+# $ perl vcard-gnccustomer.pl contact.vcf > contact.xml
+
+  $usage = $#ARGV + 1;
+  if($usage < 1)
+  {
+	print ("Error: please specify a .vcf file.\n\n");
+	exit;
+  }
+  $filename = $ARGV[0];
+  $address_book = Text::vCard::Addressbook->new({
+        'source_file' => $filename,  });
+  # generate a temporary GUID to relate the address to the customer
+  $hex_string = '';
+  for($d = 1;$d < 5;$d++)
+  {
+	for($c = 1; $c < 8; $c++)
+	{
+		  $num = (int(rand(99)) + 1) * 10**$c;
+	}
+	$hex_string .= sprintf("%x", $num);
+  }
+  print "<?xml version=\"1.0\" encoding=\"$encoding\"?>\n";
+  print "<qof-qsf xmlns=\"http://qof.sourceforge.net/\">\n";
+  print "  <book count=\"1\">\n";
+  print "    <book-guid/>\n";
+  print "    <object type=\"gncAddress\" count=\"1\">\n";
+  foreach $vcard ($address_book->vcards()) {
+ 	$names = $vcard->get({ 'node_type' => 'name' });
+	foreach $name (@{$names}){
+		if($name->given()) {
+			$fullname = $name->given() . " " . $name->family();
+		}
+		else {
+			$fullname = $name->family();
+		}
+		&wrap_in_qsf($fullname, "name");
+	}
+	$phones = $vcard->get('tel');
+	$i = 0;
+	foreach $phone (@{$phones}){
+		if($i == 0) {
+			&wrap_in_qsf($phone->value(), "phone");
+		}
+		if($i == 1) {
+			&wrap_in_qsf($phone->value(), "fax");
+		}
+		$i++;
+	}
+	$email = $vcard->get('email');
+	foreach $e (@{$email}){ &wrap_in_qsf($e->value(), "email"); }
+ 	$addresses = $vcard->get({ 'node_type' => 'addresses' });
+	foreach $address (@{$addresses}) {
+	        &wrap_in_qsf($address->street(), "street");
+	        &wrap_in_qsf($address->city(), "city");
+	        &wrap_in_qsf($address->region(), "locality");
+	}
+	print "      <guid type=\"guid\">$hex_string</guid>\n";
+  }
+  print "    </object>\n";
+  print "    <object type=\"gncCustomer\" count=\"1\">\n";
+  &wrap_in_qsf($fullname, "name");
+  print "      <boolean type=\"active\">true</boolean\n";
+  print "      <guid type=\"addr\">$hex_string</guid>\n";
+  print "  </book>\n";
+  print "</qof-qsf>\n\n";
+
+sub wrap_in_qsf()
+{
+	if($_[0]) { print "      <string type=\"$_[1]\">$_[0]</string>\n"; }
+	else { print "      <string type=\"$_[1]\"/>\n"; }
+};


Property changes on: gnucash/trunk/src/optional/xsl/vcard-gnccustomer.pl
___________________________________________________________________
Name: svn:executable
   + *



More information about the gnucash-changes mailing list