]> git.stg.codes - stg.git/blob - doc/xslt/slides/keynote/xsltsl/math.xsl
Infer DST from the current locale for mktime.
[stg.git] / doc / xslt / slides / keynote / xsltsl / math.xsl
1 <?xml version="1.0"?>
2 <xsl:stylesheet version="1.0"
3   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4   xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
5   xmlns:math="http://xsltsl.org/math"
6   exclude-result-prefixes="doc math">
7
8   <doc:reference xmlns="">
9     <referenceinfo>
10       <releaseinfo role="meta">
11         $Id: math.xsl 3991 2004-11-10 06:51:55Z balls $
12       </releaseinfo>
13       <author>
14         <surname>Ball</surname>
15         <firstname>Steve</firstname>
16       </author>
17       <copyright>
18         <year>2004</year>
19         <year>2002</year>
20         <holder>Steve Ball</holder>
21       </copyright>
22     </referenceinfo>
23
24     <title>Math Module</title>
25
26     <partintro>
27       <section>
28         <title>Introduction</title>
29
30         <para>This module provides mathematical functions.</para>
31       </section>
32     </partintro>
33
34   </doc:reference>
35
36   <doc:template name="math:power" xmlns="">
37     <refpurpose>Power</refpurpose>
38
39     <refdescription>
40       <para>Raises a number to a power.</para>
41     </refdescription>
42
43     <refparameter>
44       <variablelist>
45         <varlistentry>
46           <term>base</term>
47           <listitem>
48             <para>The base number.  Must be a number.</para>
49           </listitem>
50         </varlistentry>
51         <varlistentry>
52           <term>power</term>
53           <listitem>
54             <para>The power to raise the number to.  Must be an integer.</para>
55           </listitem>
56         </varlistentry>
57       </variablelist>
58     </refparameter>
59
60     <refreturn>
61       <para>Returns base multiplied by itself power times.  If the base or power are not numbers or if the power is fractional then an empty string is returned.</para>
62     </refreturn>
63   </doc:template>
64
65   <xsl:template name="math:power">
66     <xsl:param name="base"/>
67     <xsl:param name="power"/>
68
69     <xsl:choose>
70       <xsl:when test='$power = "0" and $base = "0"'>
71         <xsl:text>1</xsl:text>
72       </xsl:when>
73       <xsl:when test='$power = "0" and number($base)'>
74         <xsl:text>1</xsl:text>
75       </xsl:when>
76       <xsl:when test='$power = "0" and not(number($base))'/>
77       <xsl:when test='$base = "0" and number($power)'>
78         <xsl:text>0</xsl:text>
79       </xsl:when>
80
81       <xsl:when test='not(number($base)) or not(number($power))'/>
82
83       <xsl:when test='floor(number($power)) != number($power)'/>
84
85       <xsl:when test='number($power) &lt; 0'>
86         <xsl:variable name='x'>
87           <xsl:call-template name='math:power'>
88             <xsl:with-param name='base' select='$base'/>
89             <xsl:with-param name='power' select='-1 * $power'/>
90           </xsl:call-template>
91         </xsl:variable>
92         <xsl:value-of select='1 div $x'/>
93       </xsl:when>
94
95       <xsl:when test='number($power) = 1'>
96         <xsl:value-of select='$base'/>
97       </xsl:when>
98
99       <xsl:when test='number($power) &gt; 0'>
100         <xsl:variable name='x'>
101           <xsl:call-template name='math:power'>
102             <xsl:with-param name='base' select='$base'/>
103             <xsl:with-param name='power' select='$power - 1'/>
104           </xsl:call-template>
105         </xsl:variable>
106         <xsl:value-of select='$base * $x'/>
107       </xsl:when>
108       <xsl:otherwise/>
109     </xsl:choose>
110   </xsl:template>
111
112   <doc:template name="math:abs" xmlns="">
113     <refpurpose>Absolute Value</refpurpose>
114
115     <refdescription>
116       <para>Absolute value of a number.</para>
117     </refdescription>
118
119     <refparameter>
120       <variablelist>
121         <varlistentry>
122           <term>number</term>
123           <listitem>
124             <para>The number.  Must be a number.</para>
125           </listitem>
126         </varlistentry>
127       </variablelist>
128     </refparameter>
129
130     <refreturn>
131       <para>Returns the absolute value of the number.</para>
132     </refreturn>
133   </doc:template>
134
135   <xsl:template name="math:abs">
136     <xsl:param name="number"/>
137
138     <xsl:choose>
139       <xsl:when test='$number &lt; 0'>
140         <xsl:value-of select='$number * -1'/>
141       </xsl:when>
142       <xsl:when test='$number >= 0'>
143         <xsl:value-of select='$number'/>
144       </xsl:when>
145     </xsl:choose>
146   </xsl:template>
147
148   <doc:template name="math:cvt-hex-decimal" xmlns="">
149     <refpurpose>Conversion</refpurpose>
150
151     <refdescription>
152       <para>Converts a hexidecimal value to a decimal value.</para>
153     </refdescription>
154
155     <refparameter>
156       <variablelist>
157         <varlistentry>
158           <term>value</term>
159           <listitem>
160             <para>The hexidecimal number.  Must be a number in hexidecimal format.</para>
161           </listitem>
162         </varlistentry>
163       </variablelist>
164     </refparameter>
165
166     <refreturn>
167       <para>Returns the value as a decimal string.  If the value is not a number then a NaN value is returned.</para>
168     </refreturn>
169   </doc:template>
170
171   <xsl:template name="math:cvt-hex-decimal">
172     <xsl:param name="value"/>
173
174     <xsl:choose>
175       <xsl:when test='$value = ""'/>
176
177       <xsl:when test='string-length($value) = 1'>
178         <xsl:call-template name='math:cvt-hex-decimal-digit'>
179           <xsl:with-param name='digit' select='$value'/>
180         </xsl:call-template>
181       </xsl:when>
182       <xsl:otherwise>
183         <xsl:variable name='first-digit'>
184           <xsl:call-template name='math:cvt-hex-decimal-digit'>
185             <xsl:with-param name='digit' select='substring($value, 1, 1)'/>
186           </xsl:call-template>
187         </xsl:variable>
188         <xsl:variable name='remainder'>
189           <xsl:call-template name='math:cvt-hex-decimal'>
190             <xsl:with-param name='value' select='substring($value, 2)'/>
191           </xsl:call-template>
192         </xsl:variable>
193
194         <xsl:value-of select='$first-digit * 16 + $remainder'/>
195       </xsl:otherwise>
196     </xsl:choose>
197   </xsl:template>
198
199   <xsl:template name='math:cvt-hex-decimal-digit'>
200     <xsl:param name='digit' select='0'/>
201     <xsl:choose>
202       <xsl:when test='$digit &lt;= 9'>
203         <xsl:value-of select='$digit'/>
204       </xsl:when>
205       <xsl:when test='$digit = "a" or $digit = "A"'>10</xsl:when>
206       <xsl:when test='$digit = "b" or $digit = "B"'>11</xsl:when>
207       <xsl:when test='$digit = "c" or $digit = "C"'>12</xsl:when>
208       <xsl:when test='$digit = "d" or $digit = "D"'>13</xsl:when>
209       <xsl:when test='$digit = "e" or $digit = "E"'>14</xsl:when>
210       <xsl:when test='$digit = "f" or $digit = "F"'>15</xsl:when>
211     </xsl:choose>
212   </xsl:template>
213
214   <doc:template name="math:cvt-decimal-hex" xmlns="">
215     <refpurpose>Conversion</refpurpose>
216
217     <refdescription>
218       <para>Converts a decimal value to a hexidecimal value.</para>
219     </refdescription>
220
221     <refparameter>
222       <variablelist>
223         <varlistentry>
224           <term>value</term>
225           <listitem>
226             <para>The decimal number.</para>
227           </listitem>
228         </varlistentry>
229       </variablelist>
230     </refparameter>
231
232     <refreturn>
233       <para>Returns the value as a hexidecimal string (lowercase).  If the value is not a number then a NaN value is returned.</para>
234     </refreturn>
235   </doc:template>
236
237   <xsl:template name="math:cvt-decimal-hex">
238     <xsl:param name="value"/>
239
240     <xsl:choose>
241       <xsl:when test='$value = "0"'>0</xsl:when>
242       <xsl:when test='not(number($value))'>NaN</xsl:when>
243
244       <xsl:when test='$value div 16 >= 1'>
245         <xsl:call-template name='math:cvt-decimal-hex'>
246           <xsl:with-param name='value' select='floor($value div 16)'/>
247         </xsl:call-template>
248         <xsl:call-template name='math:cvt-decimal-hex'>
249           <xsl:with-param name='value' select='$value mod 16'/>
250         </xsl:call-template>
251       </xsl:when>
252       <xsl:when test='$value = 10'>a</xsl:when>
253       <xsl:when test='$value = 11'>b</xsl:when>
254       <xsl:when test='$value = 12'>c</xsl:when>
255       <xsl:when test='$value = 13'>d</xsl:when>
256       <xsl:when test='$value = 14'>e</xsl:when>
257       <xsl:when test='$value = 15'>f</xsl:when>
258       <xsl:otherwise>
259         <xsl:value-of select='$value'/>
260       </xsl:otherwise>
261     </xsl:choose>
262   </xsl:template>
263
264   <doc:template name="math:ordinal" xmlns="">
265     <refpurpose>Ordinal number</refpurpose>
266
267     <refdescription>
268       <para>Gives the ordinal number of a given counting number.  For example, 1 becomes "1st".</para>
269     </refdescription>
270
271     <refparameter>
272       <variablelist>
273         <varlistentry>
274           <term>number</term>
275           <listitem>
276             <para>An integer number.</para>
277           </listitem>
278         </varlistentry>
279       </variablelist>
280     </refparameter>
281
282     <refreturn>
283       <para>Returns the number with an ordinal suffix.</para>
284     </refreturn>
285   </doc:template>
286
287   <xsl:template name="math:ordinal">
288     <xsl:param name="number"/>
289
290     <xsl:choose>
291       <xsl:when test='$number &lt; 0'/>
292       <xsl:otherwise>
293         <xsl:value-of select='$number'/>
294         <xsl:choose>
295           <xsl:when test='$number = 11 or $number = 12 or $number = 13'>th</xsl:when>
296           <xsl:when test='$number mod 10 = 1'>st</xsl:when>
297           <xsl:when test='$number mod 10 = 2'>nd</xsl:when>
298           <xsl:when test='$number mod 10 = 3'>rd</xsl:when>
299           <xsl:otherwise>th</xsl:otherwise>
300         </xsl:choose>
301       </xsl:otherwise>
302     </xsl:choose>
303   </xsl:template>
304
305
306   <doc:template name="math:ordinal-as-word" xmlns="">
307     <refpurpose>Returns an ordinal number</refpurpose>
308
309     <refdescription>
310       <para>This template returns the ordinal number for a given counting number as a word.  For example "first" for 1.</para>
311       <para>Only handles numbers less than 10000000 (ten million).</para>
312     </refdescription>
313
314     <refparameter>
315       <variablelist>
316         <varlistentry>
317           <term>number</term>
318           <listitem>
319             <para>The counting number.</para>
320           </listitem>
321         </varlistentry>
322         <varlistentry>
323           <term>conjunctive</term>
324           <listitem>
325             <para>Whether to add the word "and" to the result, for example "one hundred and first" rather than "one hundred first".  Default is "yes".</para>
326           </listitem>
327         </varlistentry>
328       </variablelist>
329     </refparameter>
330
331     <refreturn>
332       <para>Returns the ordinal number as a string.</para>
333     </refreturn>
334   </doc:template>
335
336   <xsl:template name="math:ordinal-as-word">
337     <xsl:param name="number" select="0"/>
338     <xsl:param name='conjunctive' select='"yes"'/>
339     <xsl:param name='preceding' select='0'/>
340
341     <xsl:choose>
342       <xsl:when test='$preceding = 1 and $number = 0'/>
343       <xsl:when test='$number = 0'>zeroth</xsl:when>
344
345       <xsl:when test="$number &lt; 1 or $number != floor($number)"/>
346
347       <xsl:when test='$number = 1'>
348         <xsl:if test='$preceding = 1'> and </xsl:if>
349         <xsl:text>first</xsl:text>
350       </xsl:when>
351       <xsl:when test='$number = 2'>
352         <xsl:if test='$preceding = 1'> and </xsl:if>
353         <xsl:text>second</xsl:text>
354       </xsl:when>
355       <xsl:when test='$number = 3'>
356         <xsl:if test='$preceding = 1'> and </xsl:if>
357         <xsl:text>third</xsl:text>
358       </xsl:when>
359       <xsl:when test='$number = 4'>
360         <xsl:if test='$preceding = 1'> and </xsl:if>
361         <xsl:text>fourth</xsl:text>
362       </xsl:when>
363       <xsl:when test='$number = 5'>
364         <xsl:if test='$preceding = 1'> and </xsl:if>
365         <xsl:text>fifth</xsl:text>
366       </xsl:when>
367       <xsl:when test='$number = 6'>
368         <xsl:if test='$preceding = 1'> and </xsl:if>
369         <xsl:text>sixth</xsl:text>
370       </xsl:when>
371       <xsl:when test='$number = 7'>
372         <xsl:if test='$preceding = 1'> and </xsl:if>
373         <xsl:text>seventh</xsl:text>
374       </xsl:when>
375       <xsl:when test='$number = 8'>
376         <xsl:if test='$preceding = 1'> and </xsl:if>
377         <xsl:text>eighth</xsl:text>
378       </xsl:when>
379       <xsl:when test='$number = 9'>
380         <xsl:if test='$preceding = 1'> and </xsl:if>
381         <xsl:text>ninth</xsl:text>
382       </xsl:when>
383       <xsl:when test='$number = 10'>
384         <xsl:if test='$preceding = 1'> and </xsl:if>
385         <xsl:text>tenth</xsl:text>
386       </xsl:when>
387       <xsl:when test='$number = 11'>
388         <xsl:if test='$preceding = 1'> and </xsl:if>
389         <xsl:text>eleventh</xsl:text>
390       </xsl:when>
391       <xsl:when test='$number = 12'>
392         <xsl:if test='$preceding = 1'> and </xsl:if>
393         <xsl:text>twelveth</xsl:text>
394       </xsl:when>
395       <xsl:when test='$number = 13'>
396         <xsl:if test='$preceding = 1'> and </xsl:if>
397         <xsl:text>thirteenth</xsl:text>
398       </xsl:when>
399       <xsl:when test='$number = 14'>
400         <xsl:if test='$preceding = 1'> and </xsl:if>
401         <xsl:text>fourteenth</xsl:text>
402       </xsl:when>
403       <xsl:when test='$number = 15'>
404         <xsl:if test='$preceding = 1'> and </xsl:if>
405         <xsl:text>fifteenth</xsl:text>
406       </xsl:when>
407       <xsl:when test='$number = 16'>
408         <xsl:if test='$preceding = 1'> and </xsl:if>
409         <xsl:text>sixteenth</xsl:text>
410       </xsl:when>
411       <xsl:when test='$number = 17'>
412         <xsl:if test='$preceding = 1'> and </xsl:if>
413         <xsl:text>seventeenth</xsl:text>
414       </xsl:when>
415       <xsl:when test='$number = 18'>
416         <xsl:if test='$preceding = 1'> and </xsl:if>
417         <xsl:text>eighteenth</xsl:text>
418       </xsl:when>
419       <xsl:when test='$number = 19'>
420         <xsl:if test='$preceding = 1'> and </xsl:if>
421         <xsl:text>nineteenth</xsl:text>
422       </xsl:when>
423       <xsl:when test='$number = 20'>
424         <xsl:if test='$preceding = 1'> and </xsl:if>
425         <xsl:text>twentieth</xsl:text>
426       </xsl:when>
427       <xsl:when test='$number = 30'>
428         <xsl:if test='$preceding = 1'> and </xsl:if>
429         <xsl:text>thirtieth</xsl:text>
430       </xsl:when>
431       <xsl:when test='$number = 40'>
432         <xsl:if test='$preceding = 1'> and </xsl:if>
433         <xsl:text>fortieth</xsl:text>
434       </xsl:when>
435       <xsl:when test='$number = 50'>
436         <xsl:if test='$preceding = 1'> and </xsl:if>
437         <xsl:text>fiftieth</xsl:text>
438       </xsl:when>
439       <xsl:when test='$number = 60'>
440         <xsl:if test='$preceding = 1'> and </xsl:if>
441         <xsl:text>sixtieth</xsl:text>
442       </xsl:when>
443       <xsl:when test='$number = 70'>
444         <xsl:if test='$preceding = 1'> and </xsl:if>
445         <xsl:text>seventieth</xsl:text>
446       </xsl:when>
447       <xsl:when test='$number = 80'>
448         <xsl:if test='$preceding = 1'> and </xsl:if>
449         <xsl:text>eightieth</xsl:text>
450       </xsl:when>
451       <xsl:when test='$number = 90'>
452         <xsl:if test='$preceding = 1'> and </xsl:if>
453         <xsl:text>ninetieth</xsl:text>
454       </xsl:when>
455
456       <xsl:when test='$number mod 1000000 = 0'>
457         <xsl:call-template name='math:number-as-word'>
458           <xsl:with-param name='number' select='floor($number div 1000000)'/>
459         </xsl:call-template>
460         <xsl:text> millionth</xsl:text>
461       </xsl:when>
462       <xsl:when test='$number &lt; 1000000 and $number mod 1000 = 0'>
463         <xsl:if test='$preceding = 1 and $conjunctive'> and </xsl:if>
464         <xsl:call-template name='math:number-as-word'>
465           <xsl:with-param name='number' select='floor($number div 1000)'/>
466         </xsl:call-template>
467         <xsl:text> thousandth</xsl:text>
468       </xsl:when>
469       <xsl:when test='$number &lt; 1000 and $number mod 100 = 0'>
470         <xsl:if test='$preceding = 1 and $conjunctive'> and </xsl:if>
471         <xsl:call-template name='math:number-as-word'>
472           <xsl:with-param name='number' select='floor($number div 100)'/>
473         </xsl:call-template>
474         <xsl:text> hundredth</xsl:text>
475       </xsl:when>
476
477       <xsl:when test='$number &gt; 1000000'>
478         <xsl:if test='$preceding = 1'>
479           <xsl:text> </xsl:text>
480           <xsl:if test='$conjunctive'>and </xsl:if>
481         </xsl:if>
482         <xsl:call-template name='math:number-as-word'>
483           <xsl:with-param name='number' select='floor($number div 1000000) * 1000000'/>
484         </xsl:call-template>
485         <xsl:choose>
486           <xsl:when
487             test='(floor(floor(($number mod 1000000) + 0.1) div 100000) > 0 and $number mod 100000 > 0) or
488             (floor(floor(($number mod 100000) + 0.1) div 10000) > 0 and $number mod 10000 > 0) or
489             (floor(floor(($number mod 10000) + 0.1) div 1000) > 0 and $number mod 1000 > 0) or
490             (floor(floor(($number mod 1000) + 0.1) div 100) > 0 and $number mod 100 > 0) or
491             (floor(floor(($number mod 100) + 0.1) div 10) > 0 and $number mod 10 > 0 and $number mod 100 > 20)'>
492             <xsl:text> </xsl:text>
493             <xsl:call-template name='math:ordinal-as-word'>
494               <xsl:with-param name='number' select='floor(($number mod 1000000) + 0.1)'/>
495               <xsl:with-param name='conjunctive' select='$conjunctive'/>
496               <xsl:with-param name='preceding' select='0'/>
497             </xsl:call-template>
498           </xsl:when>
499           <xsl:otherwise>
500             <xsl:call-template name='math:ordinal-as-word'>
501               <xsl:with-param name='number' select='floor(($number mod 1000000) + 0.1)'/>
502               <xsl:with-param name='conjunctive' select='$conjunctive'/>
503               <xsl:with-param name='preceding' select='1'/>
504             </xsl:call-template>
505           </xsl:otherwise>
506         </xsl:choose>
507       </xsl:when>
508       <xsl:when test='$number &gt; 1000'>
509         <xsl:if test='$preceding = 1'>
510           <xsl:text> </xsl:text>
511           <xsl:if test='$conjunctive'>and </xsl:if>
512         </xsl:if>
513         <xsl:call-template name='math:number-as-word'>
514           <xsl:with-param name='number' select='floor($number div 1000) * 1000'/>
515           <xsl:with-param name='conjunctive' select='$conjunctive'/>
516         </xsl:call-template>
517         <xsl:choose>
518           <xsl:when test='floor(floor(($number mod 1000) + 0.1) div 100) > 0'>
519             <xsl:text> </xsl:text>
520             <xsl:call-template name='math:ordinal-as-word'>
521               <xsl:with-param name='number' select='floor(($number mod 1000) + 0.1)'/>
522               <xsl:with-param name='conjunctive' select='$conjunctive'/>
523               <xsl:with-param name='preceding' select='0'/>
524             </xsl:call-template>
525           </xsl:when>
526           <xsl:otherwise>
527             <xsl:call-template name='math:ordinal-as-word'>
528               <xsl:with-param name='number' select='floor(($number mod 1000) + 0.1)'/>
529               <xsl:with-param name='conjunctive' select='$conjunctive'/>
530               <xsl:with-param name='preceding' select='1'/>
531             </xsl:call-template>
532           </xsl:otherwise>
533         </xsl:choose>
534       </xsl:when>
535       <xsl:when test='$number &gt; 100'>
536         <xsl:if test='$preceding = 1'>
537           <xsl:text> </xsl:text>
538           <xsl:if test='$conjunctive'>and </xsl:if>
539         </xsl:if>
540         <xsl:call-template name='math:number-as-word'>
541           <xsl:with-param name='number' select='floor($number div 100) * 100'/>
542         </xsl:call-template>
543         <xsl:call-template name='math:ordinal-as-word'>
544           <xsl:with-param name='number' select='floor(($number mod 100) + 0.1)'/>
545           <xsl:with-param name='conjunctive' select='$conjunctive'/>
546           <xsl:with-param name='preceding' select='1'/>
547         </xsl:call-template>
548       </xsl:when>
549
550       <xsl:when test='$number &gt; 20'>
551         <xsl:if test='$preceding = 1'>
552           <xsl:text> </xsl:text>
553           <xsl:if test='$conjunctive'>and </xsl:if>
554         </xsl:if>
555         <xsl:call-template name='math:number-as-word'>
556           <xsl:with-param name='number' select='floor($number div 10) * 10'/>
557         </xsl:call-template>
558         <xsl:text> </xsl:text>
559         <xsl:call-template name='math:ordinal-as-word'>
560           <xsl:with-param name='number' select='floor(($number mod 10) + 0.1)'/>
561           <xsl:with-param name='conjunctive' select='$conjunctive'/>
562         </xsl:call-template>
563       </xsl:when>
564
565       <xsl:otherwise/>
566     </xsl:choose>
567   </xsl:template>
568
569   <doc:template name="math:number-as-word" xmlns="">
570     <refpurpose>Returns a number as a word</refpurpose>
571
572     <refdescription>
573       <para>This template returns the word for a given integer number, for example "one" for 1.</para>
574       <para>Only handles numbers less than 10000000 (ten million).</para>
575     </refdescription>
576
577     <refparameter>
578       <variablelist>
579         <varlistentry>
580           <term>number</term>
581           <listitem>
582             <para>The counting number.</para>
583           </listitem>
584         </varlistentry>
585         <varlistentry>
586           <term>conjunctive</term>
587           <listitem>
588             <para>Adds the word "and" where appropriate, for example.</para>
589           </listitem>
590         </varlistentry>
591       </variablelist>
592     </refparameter>
593
594     <refreturn>
595       <para>Returns the number as a string.</para>
596     </refreturn>
597   </doc:template>
598
599   <xsl:template name="math:number-as-word">
600     <xsl:param name="number" select="0"/>
601     <xsl:param name='conjunctive' select='true()'/>
602
603     <xsl:choose>
604
605       <xsl:when test='$number = 0'>zero</xsl:when>
606
607       <xsl:when test='$number &lt; 0'>
608         <xsl:text>minus </xsl:text>
609         <xsl:call-template name='math:number-as-word'>
610           <xsl:with-param name='number' select='-1 * $number'/>
611         </xsl:call-template>
612       </xsl:when>
613
614       <xsl:when test="$number != floor($number)"/>
615
616       <xsl:when test='$number mod 1000000 = 0'>
617         <xsl:call-template name='math:number-as-word'>
618           <xsl:with-param name='number' select='floor($number div 1000000)'/>
619         </xsl:call-template>
620         <xsl:text> million</xsl:text>
621       </xsl:when>
622       <xsl:when test='$number &gt;= 1000000'>
623         <xsl:call-template name='math:number-as-word'>
624           <xsl:with-param name='number' select='floor($number div 1000000)'/>
625         </xsl:call-template>
626         <xsl:text> million </xsl:text>
627         <xsl:call-template name='math:number-as-word'>
628           <xsl:with-param name='number' select='floor(($number mod 1000000) + 0.1)'/>
629         </xsl:call-template>
630       </xsl:when>
631       <xsl:when test='$number mod 1000 = 0'>
632         <xsl:call-template name='math:number-as-word'>
633           <xsl:with-param name='number' select='floor($number div 1000)'/>
634         </xsl:call-template>
635         <xsl:text> thousand</xsl:text>
636       </xsl:when>
637       <xsl:when test='$number &gt;= 1000'>
638         <xsl:call-template name='math:number-as-word'>
639           <xsl:with-param name='number' select='floor($number div 1000)'/>
640         </xsl:call-template>
641         <xsl:text> thousand </xsl:text>
642         <xsl:if test='$conjunctive and floor(floor(($number mod 1000) + 0.1) div 100) = 0'>and </xsl:if>
643         <xsl:call-template name='math:number-as-word'>
644           <xsl:with-param name='number' select='floor(($number mod 1000) + 0.1)'/>
645         </xsl:call-template>
646       </xsl:when>
647       <xsl:when test='$number mod 100 = 0'>
648         <xsl:call-template name='math:number-as-word'>
649           <xsl:with-param name='number' select='floor($number div 100)'/>
650         </xsl:call-template>
651         <xsl:text> hundred</xsl:text>
652       </xsl:when>
653       <xsl:when test='$number &gt;= 100'>
654         <xsl:call-template name='math:number-as-word'>
655           <xsl:with-param name='number' select='floor($number div 100)'/>
656         </xsl:call-template>
657         <xsl:text> hundred </xsl:text>
658         <xsl:if test='$conjunctive'>and </xsl:if>
659         <xsl:call-template name='math:number-as-word'>
660           <xsl:with-param name='number' select='floor(($number mod 100) + 0.1)'/>
661         </xsl:call-template>
662       </xsl:when>
663
664       <xsl:when test='$number = 1'>one</xsl:when>
665       <xsl:when test='$number = 2'>two</xsl:when>
666       <xsl:when test='$number = 3'>three</xsl:when>
667       <xsl:when test='$number = 4'>four</xsl:when>
668       <xsl:when test='$number = 5'>five</xsl:when>
669       <xsl:when test='$number = 6'>six</xsl:when>
670       <xsl:when test='$number = 7'>seven</xsl:when>
671       <xsl:when test='$number = 8'>eight</xsl:when>
672       <xsl:when test='$number = 9'>nine</xsl:when>
673       <xsl:when test='$number = 10'>ten</xsl:when>
674       <xsl:when test='$number = 11'>eleven</xsl:when>
675       <xsl:when test='$number = 12'>twelve</xsl:when>
676       <xsl:when test='$number = 13'>thirteen</xsl:when>
677       <xsl:when test='$number = 14'>fourteen</xsl:when>
678       <xsl:when test='$number = 15'>fifteen</xsl:when>
679       <xsl:when test='$number = 16'>sixteen</xsl:when>
680       <xsl:when test='$number = 17'>seventeen</xsl:when>
681       <xsl:when test='$number = 18'>eighteen</xsl:when>
682       <xsl:when test='$number = 19'>nineteen</xsl:when>
683       <xsl:when test='$number = 20'>twenty</xsl:when>
684       <xsl:when test='$number = 30'>thirty</xsl:when>
685       <xsl:when test='$number = 40'>forty</xsl:when>
686       <xsl:when test='$number = 50'>fifty</xsl:when>
687       <xsl:when test='$number = 60'>sixty</xsl:when>
688       <xsl:when test='$number = 70'>seventy</xsl:when>
689       <xsl:when test='$number = 80'>eighty</xsl:when>
690       <xsl:when test='$number = 90'>ninety</xsl:when>
691
692       <xsl:when test='$number &lt; 100'>
693         <xsl:call-template name='math:number-as-word'>
694           <xsl:with-param name='number' select='floor($number div 10) * 10'/>
695         </xsl:call-template>
696         <xsl:text> </xsl:text>
697         <xsl:call-template name='math:number-as-word'>
698           <xsl:with-param name='number' select='floor(($number mod 10) + 0.1)'/>
699         </xsl:call-template>
700       </xsl:when>
701     </xsl:choose>
702   </xsl:template>
703 </xsl:stylesheet>
704