Project

Profile

Help

How to connect?
Download (28.3 KB) Statistics
| Branch: | Revision:

he / tools / document-ICU.xsl @ 00082f6f

1
<?xml version="1.0" encoding="UTF-8"?>
2
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
4
  xmlns:math="http://www.w3.org/2005/xpath-functions/math"
5
  xmlns:uca="java:com.saxonica.expr.sort.UcaCollatorUsingIcu"
6
  xmlns:icuN="java:com.saxonica.config.pe.ICUNumbererPE" xmlns:f="myfunctions"
7
  xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:saxon="http://saxon.sf.net/"
8
  xmlns:X="IndirectXSLT" xmlns:doc="http://www.saxonica.com/ns/doc"
9
  exclude-result-prefixes="xs math map f uca icuN saxon xsl doc" version="3.0"> 
10

    
11
  <doc:doc>
12
    <p>This stylesheet generates sections of the Saxon documentation for the UCA/ICU collation and
13
      numbering support.</p>
14
  </doc:doc>
15

    
16
  <xsl:variable name="add.diagnostics" select="false()" as="xs:boolean" static="yes"
17
    doc:doc="Adds some diagnostic info to the resulting documentation"/>
18

    
19
  <xsl:param name="output-root" as="xs:string">locales-ICU</xsl:param>
20
  <xsl:param name="output" as="xs:string?"
21
    doc:doc="Possible output URI for use in Ant, which will be resolved relative to base-URI"
22
    >extensibility/catalog.xml</xsl:param>
23

    
24
    <xsl:variable name="base-uri" select="base-uri(/)"/>
25
  
26
  <xsl:variable name="use-last" as="map(*)" select="map{'duplicates':'use-last'}"/>
27

    
28
  <xsl:include href="map-print.xsl"/>
29
  <xsl:namespace-alias stylesheet-prefix="X" result-prefix="xsl"/>
30
  <xsl:output method="xml" indent="yes"/>
31
  <xsl:output name="text" method="text" indent="yes"/>
32

    
33
  <xsl:variable name="audit"
34
    select="'Generated from:',resolve-uri(document('')/base-uri()),format-dateTime(current-dateTime(),'[Y] [MNn] [D01] @ [H01]:[m]')"/>
35

    
36
  <xsl:variable name="abbrev"
37
    select="function($s) {string-join(tokenize($s,'-')!
38
    (lower-case(substring(.,1,1))||(if(position() gt 5) then lower-case(substring(.,2,1)) else '')),
39
    '')}"/>
40
  <xsl:function name="f:val" as="element()">
41
    <xsl:param name="s" as="xs:string"/>
42
    <span class="value">
43
      <xsl:value-of select="$s"/>
44
    </span>
45
  </xsl:function>
46
  <xsl:function name="f:val-abbrev" as="element()" expand-text="yes">
47
    <xsl:param name="s" as="xs:string"/>
48
    <span>{$s} (<span class="value">{$abbreviations($s)}</span>)</span>
49
  </xsl:function>
50
  <xsl:variable name="with-abbrev" select="function($s) {f:val-abbrev($s)}"/>
51

    
52
  <xsl:function name="f:br">
53
    <xsl:param name="in" as="item()*"/>
54
    <xsl:for-each select="$in">
55
      <xsl:sort/>
56
      <xsl:sequence select="."/>
57
      <xsl:if test="position() ne last()">
58
        <br/>
59
      </xsl:if>
60
    </xsl:for-each>
61
  </xsl:function>
62

    
63
  <xsl:variable name="langs.uca.all" as="map(xs:string,xs:string)"
64
    select="map:merge(uca:getLocales()! (let $t := tokenize(.,';') return map:entry($t[1],$t[2])), $use-last)"/>
65
  <xsl:variable name="langs.uca" as="map(xs:string,item()*)">
66
    <xsl:map>
67
      <xsl:for-each-group select="map:keys($langs.uca.all)" group-by="replace(.,'-.*','')">
68
        <xsl:map-entry key="current-grouping-key()" select="current-group()"/>
69
      </xsl:for-each-group>
70
    </xsl:map>
71
  </xsl:variable>
72

    
73
  <xsl:variable name="langs.icuN.all" as="map(xs:string,xs:string)"
74
    select="map:merge(icuN:getLocales()! (let $t := tokenize(.,';') return map:entry($t[1],$t[2])), $use-last)"/>
75
  <xsl:variable name="langs.icuN" as="map(xs:string,item()*)">
76
    <xsl:map>
77
      <xsl:for-each-group select="map:keys($langs.icuN.all)" group-by="replace(.,'-.*','')">
78
        <xsl:map-entry key="current-grouping-key()" select="current-group()"/>
79
      </xsl:for-each-group>
80
    </xsl:map>
81
  </xsl:variable>
82

    
83
  <xsl:variable name="numberings" as="map(xs:string,item()*)">
84
    <xsl:map>
85
      <xsl:for-each select="map:keys($langs.icuN)">
86
        <xsl:variable name="base" select="tokenize(.,';')"/>
87
        <xsl:variable name="numberings"
88
          select="icuN:availableSpelloutNumberings($base[1])!replace(.,'^%','')"/>
89
        <xsl:variable name="ordinal.numberings"
90
          select="icuN:availableOrdinalNumberings($base[1])!replace(.,'^%','')"/>
91
        <xsl:map-entry key="." select="$numberings,$ordinal.numberings"/>
92
      </xsl:for-each>
93
    </xsl:map>
94
  </xsl:variable>
95

    
96

    
97
  <xsl:variable name="abbreviations.normal"
98
    select="map:merge(distinct-values(map:keys($numberings)!$numberings(.))!
99
    map:entry(.,$abbrev(.)), $use-last)"/>
100
  <xsl:variable name="abbreviations.special"
101
    select="map {'spellout-cardinal-financial' : 'scfi',
102
    'spellout-cardinal-neuter' : 'scne',
103
    'spellout-ordinal-neuter' : 'sone' }"/>
104
  <xsl:variable name="abbreviations"
105
    select="map:merge(($abbreviations.normal,$abbreviations.special), $use-last)"/>
106

    
107
  <xsl:variable name="clashes"
108
    select="for $k in map:keys($abbreviations)
109
    return if($abbreviations($k) = map:keys($abbreviations)[not(. = $k)]!$abbreviations(.)) then $k else ()"/>
110
  <xsl:variable name="variables" as="map(xs:string,item()*)"
111
    select="map { 
112
    'ICU-languages' : $langs.icuN.all,
113
    'ICU-language-groups' : $langs.icuN,
114
    'ICU-abbreviations' : $abbreviations,
115
    'ICU-numberings' : $numberings }
116
    "/>
117
  <xsl:variable name="map.descriptions" as="element()*">
118
    <part name="ICU-languages" type="map(xs:string,xs:string)">
119
      <desc>Descriptions of all the languages supported</desc>
120
      <key>Language code (e.g. <code>'en-GB'</code>)</key>
121
      <value>Language description string, e.g. <code><xsl:value-of
122
            select="string-join($langs.icuN.all('en-GB')!$quoter(.),',')"/></code></value>
123
    </part>
124
    <part name="ICU-language-groups" type="map(xs:string,xs:string*)">
125
      <desc>All the language <em>groupings</em> supported for a given base language.</desc>
126
      <key>Language code (e.g. <code>az</code>)</key>
127
      <value>Sequence of language (locale) codes, e.g. <code>(<xsl:value-of
128
            select="string-join($langs.icuN('az')!$quoter(.),',')"/>)</code></value>
129
    </part>
130
    <part name="ICU-abbreviations" type="map(xs:string,xs:string)">
131
      <desc>Abbreviation codes for the numbering schemes</desc>
132
      <key>Scheme name (e.g. <code>'spellout-ordinal'</code>)</key>
133
      <value>Private tag code for the scheme, e.g. <code>'so'</code></value>
134
    </part>
135
    <part name="ICU-numberings" type="map(xs:string,xs:string*)">
136
      <desc>The numbering schemes supported for each base language</desc>
137
      <key>Language code (e.g. <code>af</code>)</key>
138
      <value>Sequence of numbering scheme names, e.g. <code>(<xsl:value-of
139
            select="string-join($numberings('af')!$quoter(.),',')"/>)</code></value>
140
    </part>
141
  </xsl:variable>
142
  <xsl:variable name="preference-order" select="icuN:getPreferences()"/>
143

    
144
  <xsl:template match="/">
145
    <xsl:call-template name="go"/>
146
  </xsl:template>
147

    
148
  <xsl:template name="go" expand-text="yes">
149
    <!-- <result>
150
      <timestamp>{current-dateTime()}</timestamp>
151
      <ICU-version>{icuN:getICUVersion()}</ICU-version>
152
    </result>-->
153
    <xsl:variable name="output-root"
154
      select="if(exists($output))
155
      then resolve-uri($output-root,xs:string(resolve-uri($output,xs:string($base-uri)))) 
156
      else $output-root"/>
157

    
158
    <xsl:result-document href="{$output-root}.xsl" expand-text="yes" xmlns="IndirectXSLT">
159
      <stylesheet version="3.0">
160
        <xsl:comment>AUTO-GENERATED: do not edit</xsl:comment>
161
        <xsl:comment>{$audit}</xsl:comment>
162
        <xsl:for-each select="map:keys($variables)">
163
          <variable name="{.}">
164
            <xsl:attribute name="select">
165
              <xsl:call-template name="map-print-XPath">
166
                <xsl:with-param name="items" select="$variables(.)"/>
167
              </xsl:call-template>
168
            </xsl:attribute>
169
          </variable>
170
        </xsl:for-each>
171
      </stylesheet>
172
    </xsl:result-document>
173

    
174
    <xsl:result-document href="{$output-root}.xml" expand-text="yes">
175
      <xsl:variable name="width" select="3"/>
176
      <section id="UCA-locales" title="UCA-supported locales">
177
        <xsl:comment>AUTO-GENERATED: do not edit</xsl:comment>
178
        <xsl:comment>{$audit}</xsl:comment>
179
        <h1>UCA-supported locales</h1>
180
        <p xsl:use-when="$add.diagnostics">{$audit}</p>
181
        <aside>Since Saxon 9.8, the ICU library is updated from version 57.1 to 59.1; which brings
182
          Unicode 9.0 support.</aside>
183
        <p>These are the locales ({count(map:keys($langs.uca))} base languages,
184
          {count(map:keys($langs.uca.all)) - count(map:keys($langs.uca))} variants) supported for
185
          collation in Saxon-PE/EE, from the library of <a href="http://site.icu-project.org/">ICU -
186
            International Components for Unicode</a>, version {icuN:getICUVersion()}, implementing
187
          UCA version {uca:getUCAVersion()}:</p>
188
        <table>
189
          <xsl:comment>{$audit}</xsl:comment>
190
          <thead>
191
            <tr>
192
              <td colspan="2">Group</td>
193
              <td colspan="{2 * $width}">Variants</td>
194
            </tr>
195
            <tr>
196
              <td>code</td>
197
              <td>language</td>
198
              <xsl:for-each select="1 to $width">
199
                <td>code</td>
200
                <td>variant</td>
201
              </xsl:for-each>
202
            </tr>
203
          </thead>
204
          <tbody>
205
            <xsl:for-each select="map:keys($langs.uca)">
206
              <xsl:sort/>
207
              <xsl:variable name="base" select="."/>
208
              <xsl:variable name="variants" select="$langs.uca(.)"/>
209
              <xsl:variable name="mod" select="(count($variants) + $width - 1) idiv $width"/>
210
              <xsl:variable name="rows" as="element()*">
211
                <xsl:for-each-group select="$variants" group-by="(position() - 1) mod $mod">
212
                  <tr>
213
                    <xsl:for-each select="current-group()">
214
                      <xsl:variable name="parts" select="tokenize(.,';')"/>
215
                      <td class="value">{.}</td>
216
                      <td>{$langs.uca.all(.)}</td>
217
                    </xsl:for-each>
218
                  </tr>
219
                </xsl:for-each-group>
220
              </xsl:variable>
221
              <xsl:for-each select="$rows">
222
                <xsl:copy>
223
                  <xsl:choose>
224
                    <xsl:when test="position() eq 1">
225
                      <xsl:attribute name="class">lang-start</xsl:attribute>
226
                      <td class="value">{$base}</td>
227
                      <td>{$langs.uca.all($base)}</td>
228
                    </xsl:when>
229
                    <xsl:otherwise>
230
                      <td/>
231
                      <td/>
232
                    </xsl:otherwise>
233
                  </xsl:choose>
234
                  <xsl:sequence select="*"/>
235
                </xsl:copy>
236
              </xsl:for-each>
237
            </xsl:for-each>
238
          </tbody>
239
        </table>
240
      </section>
241
    </xsl:result-document>
242

    
243
    <xsl:result-document href="{$output-root}-numbering.java" format="text" expand-text="no"> static
244
      { <xsl:for-each select="map:keys($abbreviations)">
245
        <xsl:sort/> schemeCodes.put("<xsl:value-of select="$abbreviations(.)"/>","%<xsl:value-of
246
          select="."/>"); </xsl:for-each> } </xsl:result-document>
247

    
248
    <xsl:result-document href="{$output-root}-numbering.xml" expand-text="yes">
249
      <section id="ICU-numbering-dates" title="Numbers and Dates from ICU">
250
        <xsl:comment>AUTO-GENERATED: do not edit</xsl:comment>
251
        <xsl:comment>{$audit}</xsl:comment>
252
        <h1>Numbers and Dates from ICU</h1>
253
        <p xsl:use-when="$add.diagnostics">The time now, in Welsh, is
254
          {format-time(current-time(),'[HWw] [mw]','cy',(),())}</p>
255
        <p><a href="http://site.icu-project.org/">ICU - International Components for Unicode</a>
256
          (ICU) provides extensive facilities for localized numbering and date formatting, which are
257
          supported in Saxon-PE and -EE from version 9.6.</p>
258
        <p>The ICU features require a sizeable (~7MByte) library which may be supplied either in the
259
          main JAR file, or as a separate JAR, which can itself either be a 'minimised' version in
260
          the Saxonica distribution, or a complete ICU4J JAR downloaded from the ICU site.</p>
261
        <p>In the case that the ICU features have <strong>not</strong> been loaded within
262
          Saxon-PE/EE, support for numbering and dates for Danish, Dutch, Flemish, French (and
263
          Belgian French), German, Italian and Swedish is provided as detailed in the table of <a
264
            href="/extensibility/config-extend/localizing/other-numberings">Numberings for selected
265
            languages</a>.</p>
266
        <h2>Numbering</h2>
267
        <p>ICU supports a large set of language-specific rulesets for supporting different forms of
268
          spelled-out numbering and digit-ordinal treatment. For example:</p>
269
        <table>
270
          <thead class="params">
271
            <tr>
272
              <td>Language</td>
273
              <td>Number</td>
274
              <td>Ruleset</td>
275
              <td>XPath</td>
276
              <td>Result</td>
277
            </tr>
278
          </thead>
279
          <tbody>
280
            <xsl:variable name="examples" as="element()*">
281
              <example lang="en;English" value="1123" scheme="spellout-cardinal"/>
282
              <example lang="en-US;English(US)" value="242" scheme="spellout-ordinal-verbose"/>
283
              <example lang="cy;Welsh" value="132" scheme="spellout-cardinal-feminine"/>
284
              <example lang="es-PT;Portugese" value="242" scheme="spellout-ordinal-feminine"/>
285
            </xsl:variable>
286
            <xsl:for-each select="$examples">
287
              <tr>
288
                <td><code>{tokenize(@lang,';')[1]}</code><br/>{tokenize(@lang,';')[2]}</td>
289
                <td>{@value}</td>
290
                <td>%{@scheme}</td>
291
                <td>
292
                  <code>format-integer({@value},'Ww','{tokenize(@lang,';')[1]}-x-{$abbreviations(@scheme)}')</code>
293
                </td>
294
                <td>{format-integer(@value,'Ww',tokenize(@lang,';')[1]||'-x-'||$abbreviations(@scheme))}</td>
295
              </tr>
296
            </xsl:for-each>
297
            <xsl:variable name="examples.ordinal" as="element()*">
298
              <example lang="en;English" value="1123" scheme="spellout-cardinal"/>
299
              <example lang="en-US;English(US)" value="242" scheme="spellout-ordinal-verbose"/>
300
              <example lang="cy;Welsh" value="132" scheme="spellout-cardinal-feminine"/>
301
              <example lang="es-PT;Portugese" value="242" scheme="spellout-ordinal-feminine"/>
302
            </xsl:variable>
303
            <xsl:for-each select="$examples.ordinal">
304
              <tr>
305
                <td><code>{tokenize(@lang,';')[1]}</code><br/>{tokenize(@lang,';')[2]}</td>
306
                <td>{@value}</td>
307
                <td/>
308
                <td>
309
                  <code>format-integer({@value},'1;o','{tokenize(@lang,';')[1]}')</code>
310
                </td>
311
                <td>{format-integer(@value,'1;o',tokenize(@lang,';')[1])}</td>
312
              </tr>
313
            </xsl:for-each>
314
          </tbody>
315
        </table>
316
        <p>In all cases it appears to be that the numbering scheme names and their behaviour is
317
          taken from the base language, with no regional variation - i.e. <code>es-PT</code> and
318
            <code>es-419</code> would produce the same results.</p>
319
        <p>To invoke one of these schemes, an IETF BCP47 standard <em>private tag</em> is appended
320
          to the language tag, with format <code>-x-<em>code</em></code>. With a very small number
321
          of exceptions (to avoid clashes) these codes are encoded as the sequence of first letters
322
          of each word, the result being all lower case. Examples of use are shown in the previous
323
          table. These private tag codes are recognised for 'word' numbering purposes on both
324
          <a class="bodylink code" href="/functions/fn/format-integer">format-integer()</a> and 
325
          <a class="bodylink code" href="/xsl-elements/number">xsl:number</a> language arguments.</p>
326
        <p>A full list of the scheme codes and their support in a given language is given in <a
327
            class="bodylink" href="ICU-numbering">Supported ICU Numbering Schemes</a>.</p>
328
        <p>In the absence of such a private tag, the following strategies are adopted:</p>
329
        <dl>
330
          <dt>Cardinal spellout</dt>
331
          <dd>When directed to generate a cardinal number using the 'w' patterns, the first of the
332
            following schemes is used, if found: <xsl:for-each select="$preference-order"
333
                ><code>spellout-cardinal{.}</code><xsl:if test="position() ne last()">,
334
              </xsl:if></xsl:for-each>. It appears that within ICU all languages contain at least
335
            one of these schemes, but if not, any scheme whose name matches the regular expression
336
              <code>^%spellout-cardinal</code> is used (choosing the first provided for the
337
            locale).</dd>
338
          <dt>Ordinal spellout</dt>
339
          <dd>When directed to generate an ordinal number using the 'w' patterns, the first of the
340
            following schemes is used, if found: <xsl:for-each select="$preference-order"
341
                ><code>spellout-ordinal{.}</code><xsl:if test="position() ne last()">,
342
              </xsl:if></xsl:for-each>. In the absence of any of these schemes, any scheme whose
343
            name matches the regular expression <code>^%spellout-ordinal</code> is used (choosing
344
            the first provided for the locale). In the case of there being <em>no</em> ordinal
345
            scheme available for the locale (or a language that does not have ordinals) the default
346
              <strong>cardinal</strong> scheme is used.</dd>
347
          <dt>Ordinal digits</dt>
348
          <dd>When producing an ordinal digit suffix (e.g. {format-integer(13,'1;o','es')} in
349
            Spanish), the 'digit-ordinal' ruleset is used by default - for those cases where there
350
            are specialist forms (e.g. Catalan and Spanish), the private tag must be set to get the
351
            specialist behaviour. </dd>
352
        </dl>
353
        <h3>English numbering</h3>
354
        <p>ICU renders <code>22</code> in words as "twenty-two", whereas Saxon has traditionally output
355
          "twenty two", with a space rather than hyphen separator. By default, for compatibility, the ICU
356
          result for all English schemes (cardinal and ordinal) is modified to use space as the
357
          separator. This can be modified by adding the extension <code>hyphen</code> or <code>nohyphen</code>
358
          to the language code: for example <code>en-x-hyphen</code> produces "twenty-two" while
359
          <code>en-x-nohyphen</code> produces "twenty two". This may be combined with other modifiers, for example
360
          <code>en-x-sov-hyphen</code> gives hyphenated verbose output.</p>
361
        <p>The default use of a '-verbose' scheme means that spellout of <code>118</code> yields
362
          "{format-integer(118,'w','en-x-scv')}", following the British usage rather than
363
          "{format-integer(118,'w','en-x-sc')}", which is the (US) shortened form. </p>
364
        <h3>Using format-picture options within spelled-out numbering</h3>
365
        <p><code>format-number()</code> and <code>format-integer()</code> can support further
366
          implementation-dependent control of numbering though parameters attached to cardinal
367
            (<code>c</code>) and ordinal (<code>o</code>) modifiers, e.g.
368
            <code>format-integer(1,'Ww;o(-er)','de')</code> which is intended to produce "Erster" in
369
          the recommended approach.</p>
370
        <p>In Saxon-PE/EE, there are two forms of such parameterisation supported for spelled-out
371
          (i.e. <code>W|w</code>) formats:</p>
372
        <ul>
373
          <li><strong><code>-<em>suffix</em></code></strong>. This requires a numbering of the given
374
            sort (cardinal or ordinal) which ends in the suffix given, if one is available for the
375
            locale in the implementation. </li>
376
          <li><strong><code>2=<em>example</em></code></strong>. This requires a numbering of the
377
            given sort (cardinal or ordinal) using the numbering scheme for which <code>2</code>
378
            would be formatted as <em>example</em> (ignoring case), if one is available for the
379
            locale in the implementation. For example <code>w;o(2=Secundo)</code> in Italian should
380
            yield "{format-integer(123,'w;o(2=Secondo)','it')}" for 123, whereas with
381
              <code>w;o(2=Seconda)</code> the result is
382
            "{format-integer(123,'w;o(2=Seconda)','it')}".</li>
383
        </ul>
384
        <p>For German (<code>lang="de"</code>), ICU does not provide case/gender-variable ordinal
385
          word numbering (i.e. only "Erste" and not "Erster"). The Saxon implementation supports the
386
                <strong><code>-<em>suffix</em></code></strong> ordinal option described above, which
387
          replaces the trailing 'e' on the generated ordinal. Thus
388
            <code>format-integer(1,'w;o(-en)','de')</code> produces
389
          "{format-integer(1,'w;o(-en)','de')}". </p>
390
        <h2>Dates</h2>
391
        <p>ICU also provides facilities for localized date formatting, principally for names of days
392
          of the week and months, though a variety of calendars and epoch naming facilities are also
393
          available. In Saxon-PE/EE naming of months and days (through picture fields on <a 
394
            class="bodylink code" href="/functions/fn/format-date">format-date()</a>) is localised through
395
          the local language in scope. These appear to be all based on the base language, with no
396
          regional variations.</p>
397
        <p>As is required from the specification, when the language locale requested is not
398
          implemented, the result of <code>format-date()</code> or <code>format-dateTime()</code> is
399
          prefixed with "[Language: <em>default language code</em>]". </p>
400
        <h2>Title Case</h2>
401
        <p>Protocols for Title Case of sequences of words can differ markedly between languages,
402
          with many keeping strictly to lower-case throughout, and a very few (such as Dutch with
403
          'iJ') having very specialist rules. In Saxon, when title case is requested (e.g.
404
            <code>Ww</code> in <code>format-integer()</code> or <code>[MNn]</code> in
405
            <code>format-date()</code>) the Saxon implementation follows these rules:</p>
406
        <ul>
407
          <li>If the case requested is <code>lower</code> or <code>upper</code>, all words in the
408
            return from ICU are forced to the appropriate case.</li>
409
          <li>If the case requested is <code>title</code> then the returned string from ICU is
410
            examined:
411
            <ul>
412
          <li>If the first two characters are uppercase followed by lowercase, then the return is
413
            inferred already to be in title case and the result is returned unmodified.</li>
414
          <li>If not, then any letter preceded by a non-letter (or at start of string) is forced to
415
            uppercase, other letters are forced to lowercase.</li>
416
          <li>Some obvious 'joiner' words (e.g. 'and' in English, 'ën' in Dutch) that would
417
            otherwise be title-cased, are forced to lower-case.</li></ul></li>
418
        </ul>
419
        <p>Note that this may have problems, i.e. a title case could be forced on a language that
420
          otherwise might only ever use a uniform case. If you discover issues in a language you are
421
          using, please let us know.</p>
422

    
423
        <div xsl:use-when="false()">
424
          <h2>Maps of features.</h2>
425
          <p>Saxon can provide a series of maps that describe the supported locales, numbering
426
            schemes and appropriate codes, which can be consulted programmatically to determine
427
            whether various forms of language and numbering are supported in the implementation.
428
            These are:</p>
429
          <table>
430
            <thead class="params">
431
              <tr>
432
                <td>Name</td>
433
                <td>Type</td>
434
                <td>Key</td>
435
                <td>Value</td>
436
                <td>Description</td>
437
              </tr>
438
            </thead>
439
            <tbody>
440
              <xsl:for-each select="$map.descriptions">
441
                <tr>
442
                  <td>{@name}</td>
443
                  <td>{@type}</td>
444
                  <td>
445
                    <xsl:sequence select="key/(*|text())"/>
446
                  </td>
447
                  <td>
448
                    <xsl:sequence select="value/(*|text())"/>
449
                  </td>
450
                  <td>
451
                    <xsl:sequence select="desc/(*|text())"/>
452
                  </td>
453
                </tr>
454
              </xsl:for-each>
455
            </tbody>
456
          </table>
457
        </div>
458
        <section id="ICU-numbering" title="Supported ICU Numbering Schemes">
459
          <h2>Supported ICU Numbering Schemes</h2>
460
          <aside>Since Saxon 9.8, the ICU library is updated from version 57.1 to 59.1; which brings
461
            Unicode 9.0 support.</aside>
462
          <p>The names of the numbering schemes and the codes to be used for them (ICU
463
            version:{icuN:getICUVersion()}) are shown in the following table, with those whose
464
            derivation differs from the standard rule (first-letter of each word) marked '*':</p>
465
          <xsl:if test="exists($clashes)">
466
            <p>Warning - use of the following codes is currently not supported, due to clashes:</p>
467
            <ul>
468
              <xsl:for-each select="$clashes">
469
                <xsl:sort/>
470
                <li>{$with-abbrev(.)}</li>
471
              </xsl:for-each>
472
            </ul>
473
          </xsl:if>
474
          <table>
475
            <thead class="params">
476
              <tr>
477
                <td>Code</td>
478
                <td>Ruleset name</td>
479
              </tr>
480
            </thead>
481
            <tbody>
482
              <xsl:variable name="special" select="map:keys($abbreviations.special)"/>
483
              <xsl:for-each select="map:keys($abbreviations)">
484
                <xsl:sort/>
485
                <tr>
486
                  <td class="value">{$abbreviations(.)}</td>
487
                  <td>{.}<xsl:if use-when="true()" test=". = $special"> * </xsl:if></td>
488
                  <!--<td>{.}<xsl:if use-when="true()" test=". = map:keys($abbreviations.special)"> * </xsl:if></td>-->
489
                </tr>
490
              </xsl:for-each>
491
            </tbody>
492
          </table>
493
          <p>These codes can be used irrespective of other control mechanisms: for example using a
494
            cardinal scheme will override an ordinal request on an <code>xsl:number</code>
495
            instruction. They are ONLY used for spelled-out numbering of words. Use of an unknown
496
            ruleset (e.g. spellout-ordinal for Welsh) will raise a warning.</p>
497
          <p>The available numbering schemes for the {count(map:keys($numberings))} languages
498
            supported for numbering in ICU version {icuN:getICUVersion()} are given in the following
499
            table:</p>
500
          <xsl:variable name="with-abbrev"
501
            select="function($s) {string-join(($s,' (',$abbreviations($s),')'),'')}"/>
502
          <table>
503
            <thead class="params">
504
              <tr>
505
                <td colspan="2">Group</td>
506
                <td colspan="1">Spellout<!-- Numbering--></td>
507
                <td>Ordinal</td>
508
              </tr>
509
              <tr>
510
                <td>code</td>
511
                <td>language</td>
512
                <td>Numbering</td>
513
                <td>Numbering</td>
514
              </tr>
515
            </thead>
516
            <tbody>
517
              <xsl:for-each select="map:keys($numberings)">
518
                <xsl:sort/>
519
                <xsl:variable name="this" select="$numberings(.)"/>
520
                <xsl:variable name="base" select="tokenize(.,';')"/>
521
                <xsl:variable name="spellout" select="$this[starts-with(.,'spellout-')]"/>
522
                <xsl:variable name="cardinals"
523
                  select="$spellout[starts-with(.,'spellout-cardinal')]"/>
524
                <xsl:variable name="ordinals" select="$spellout[starts-with(.,'spellout-ordinal')]"/>
525
                <xsl:variable name="numbers" select="$spellout[starts-with(.,'spellout-number')]"/>
526
                <xsl:variable name="ordinal.numberings" select="$this[starts-with(.,'digits')]"/>
527
                <xsl:variable name="other-rules"
528
                  select="$this[not(. = ($spellout,$ordinal.numberings))]"/>
529
                <tr>
530
                  <td class="value">{.}</td>
531
                  <td>{$langs.icuN.all(.)}{if(exists($other-rules)) then ' WARNING: other
532
                    rules:'||string-join($other-rules,',') else ''}</td>
533
                  <td>
534
                    <xsl:sequence select="f:br($spellout!f:val-abbrev(.))"/>
535
                  </td>
536
                  <td>
537
                    <xsl:sequence select="f:br($ordinal.numberings!f:val-abbrev(.))"/>
538
                  </td>
539
                </tr>
540
              </xsl:for-each>
541
            </tbody>
542
          </table>
543
        </section>
544
      </section>
545
    </xsl:result-document>
546

    
547

    
548
  </xsl:template>
549
</xsl:stylesheet>
(9-9/15)