]> git.stg.codes - stg.git/blob - doc/xslt/html/autoidx.xsl
Set output encoding to utf-8.
[stg.git] / doc / xslt / html / autoidx.xsl
1 <?xml version="1.0"?>
2 <!DOCTYPE xsl:stylesheet [
3 <!ENTITY % common.entities SYSTEM "../common/entities.ent">
4 %common.entities;
5 ]>
6 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
7                 xmlns:exslt="http://exslt.org/common"
8                 extension-element-prefixes="exslt"
9                 exclude-result-prefixes="exslt"
10                 version="1.0">
11
12 <!-- ********************************************************************
13      $Id: autoidx.xsl 8516 2009-08-12 02:54:56Z abdelazer $
14      ********************************************************************
15
16      This file is part of the XSL DocBook Stylesheet distribution.
17      See ../README or http://docbook.sf.net/release/xsl/current/ for
18      copyright and other information.
19
20      ******************************************************************** -->
21
22 <!-- ==================================================================== -->
23 <!-- The "basic" method derived from Jeni Tennison's work. -->
24 <!-- The "kosek" method contributed by Jirka Kosek. -->
25 <!-- The "kimber" method contributed by Eliot Kimber of Innodata Isogen. -->
26
27 <xsl:variable name="kimber.imported" select="0"/>
28 <xsl:variable name="kosek.imported" select="0"/>
29
30 <xsl:key name="letter"
31          match="indexterm"
32          use="translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;)"/>
33
34 <xsl:key name="primary"
35          match="indexterm"
36          use="&primary;"/>
37
38 <xsl:key name="secondary"
39          match="indexterm"
40          use="concat(&primary;, &sep;, &secondary;)"/>
41
42 <xsl:key name="tertiary"
43          match="indexterm"
44          use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
45
46 <xsl:key name="endofrange"
47          match="indexterm[@class='endofrange']"
48          use="@startref"/>
49
50 <xsl:key name="primary-section"
51          match="indexterm[not(secondary) and not(see)]"
52          use="concat(&primary;, &sep;, &section.id;)"/>
53
54 <xsl:key name="secondary-section"
55          match="indexterm[not(tertiary) and not(see)]"
56          use="concat(&primary;, &sep;, &secondary;, &sep;, &section.id;)"/>
57
58 <xsl:key name="tertiary-section"
59          match="indexterm[not(see)]"
60          use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, &section.id;)"/>
61
62 <xsl:key name="see-also"
63          match="indexterm[seealso]"
64          use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, seealso)"/>
65
66 <xsl:key name="see"
67          match="indexterm[see]"
68          use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see)"/>
69
70 <xsl:key name="sections" match="*[@id or @xml:id]" use="@id|@xml:id"/>
71
72
73 <xsl:template name="generate-index">
74   <xsl:param name="scope" select="(ancestor::book|/)[last()]"/>
75
76   <xsl:choose>
77     <xsl:when test="$index.method = 'kosek'">
78       <xsl:call-template name="generate-kosek-index">
79         <xsl:with-param name="scope" select="$scope"/>
80       </xsl:call-template>
81     </xsl:when>
82     <xsl:when test="$index.method = 'kimber'">
83       <xsl:call-template name="generate-kimber-index">
84         <xsl:with-param name="scope" select="$scope"/>
85       </xsl:call-template>
86     </xsl:when>
87
88     <xsl:otherwise>
89       <xsl:call-template name="generate-basic-index">
90         <xsl:with-param name="scope" select="$scope"/>
91       </xsl:call-template>
92     </xsl:otherwise>
93   </xsl:choose>
94 </xsl:template>
95       
96 <xsl:template name="generate-basic-index">
97   <xsl:param name="scope" select="NOTANODE"/>
98
99   <xsl:variable name="role">
100     <xsl:if test="$index.on.role != 0">
101       <xsl:value-of select="@role"/>
102     </xsl:if>
103   </xsl:variable>
104
105   <xsl:variable name="type">
106     <xsl:if test="$index.on.type != 0">
107       <xsl:value-of select="@type"/>
108     </xsl:if>
109   </xsl:variable>
110
111   <xsl:variable name="terms"
112                 select="//indexterm
113                         [count(.|key('letter',
114                           translate(substring(&primary;, 1, 1),
115                              &lowercase;,
116                              &uppercase;))
117                           [&scope;][1]) = 1
118                           and not(@class = 'endofrange')]"/>
119
120   <xsl:variable name="alphabetical"
121                 select="$terms[contains(concat(&lowercase;, &uppercase;),
122                                         substring(&primary;, 1, 1))]"/>
123
124   <xsl:variable name="others" select="$terms[not(contains(concat(&lowercase;,
125                                                  &uppercase;),
126                                              substring(&primary;, 1, 1)))]"/>
127   <div class="index">
128     <xsl:if test="$others">
129       <xsl:choose>
130         <xsl:when test="normalize-space($type) != '' and 
131                         $others[@type = $type][count(.|key('primary', &primary;)[&scope;][1]) = 1]">
132           <div class="indexdiv">
133             <h3>
134               <xsl:call-template name="gentext">
135                 <xsl:with-param name="key" select="'index symbols'"/>
136               </xsl:call-template>
137             </h3>
138             <dl>
139               <xsl:apply-templates select="$others[count(.|key('primary', &primary;)[&scope;][1]) = 1]"
140                                    mode="index-symbol-div">
141                 <xsl:with-param name="position" select="position()"/>                                
142                 <xsl:with-param name="scope" select="$scope"/>
143                 <xsl:with-param name="role" select="$role"/>
144                 <xsl:with-param name="type" select="$type"/>
145                 <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
146               </xsl:apply-templates>
147             </dl>
148           </div>
149         </xsl:when>
150         <xsl:when test="normalize-space($type) != ''"> 
151           <!-- Output nothing, as there isn't a match for $other using this $type -->
152         </xsl:when>  
153         <xsl:otherwise>
154           <div class="indexdiv">
155             <h3>
156               <xsl:call-template name="gentext">
157                 <xsl:with-param name="key" select="'index symbols'"/>
158               </xsl:call-template>
159             </h3>
160             <dl>
161               <xsl:apply-templates select="$others[count(.|key('primary',
162                                           &primary;)[&scope;][1]) = 1]"
163                                   mode="index-symbol-div">
164                 <xsl:with-param name="position" select="position()"/>                                
165                 <xsl:with-param name="scope" select="$scope"/>
166                 <xsl:with-param name="role" select="$role"/>
167                 <xsl:with-param name="type" select="$type"/>
168                 <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
169               </xsl:apply-templates>
170             </dl>
171           </div>
172         </xsl:otherwise>
173       </xsl:choose>
174     </xsl:if>
175
176     <xsl:apply-templates select="$alphabetical[count(.|key('letter',
177                                  translate(substring(&primary;, 1, 1),
178                                            &lowercase;,&uppercase;))[&scope;][1]) = 1]"
179                          mode="index-div-basic">
180       <xsl:with-param name="position" select="position()"/>
181       <xsl:with-param name="scope" select="$scope"/>
182       <xsl:with-param name="role" select="$role"/>
183       <xsl:with-param name="type" select="$type"/>
184       <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
185     </xsl:apply-templates>
186   </div>
187 </xsl:template>
188
189 <!-- This template not used if html/autoidx-kosek.xsl is imported -->
190 <xsl:template name="generate-kosek-index">
191   <xsl:param name="scope" select="NOTANODE"/>
192
193   <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
194   <xsl:if test="contains($vendor, 'libxslt')">
195     <xsl:message terminate="yes">
196       <xsl:text>ERROR: the 'kosek' index method does not </xsl:text>
197       <xsl:text>work with the xsltproc XSLT processor.</xsl:text>
198     </xsl:message>
199   </xsl:if>
200
201
202   <xsl:if test="$exsl.node.set.available = 0">
203     <xsl:message terminate="yes">
204       <xsl:text>ERROR: the 'kosek' index method requires the </xsl:text>
205       <xsl:text>exslt:node-set() function. Use a processor that </xsl:text>
206       <xsl:text>has it, or use a different index method.</xsl:text>
207     </xsl:message>
208   </xsl:if>
209
210   <xsl:if test="$kosek.imported = 0">
211     <xsl:message terminate="yes">
212       <xsl:text>ERROR: the 'kosek' index method requires the&#xA;</xsl:text>
213       <xsl:text>kosek index extensions be imported:&#xA;</xsl:text>
214       <xsl:text>  xsl:import href="html/autoidx-kosek.xsl"</xsl:text>
215     </xsl:message>
216   </xsl:if>
217
218 </xsl:template>
219
220 <!-- This template not used if html/autoidx-kimber.xsl is imported -->
221 <xsl:template name="generate-kimber-index">
222   <xsl:param name="scope" select="NOTANODE"/>
223
224   <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
225   <xsl:if test="not(contains($vendor, 'SAXON '))">
226     <xsl:message terminate="yes">
227       <xsl:text>ERROR: the 'kimber' index method requires the </xsl:text>
228       <xsl:text>Saxon version 6 or 8 XSLT processor.</xsl:text>
229     </xsl:message>
230   </xsl:if>
231
232   <xsl:if test="$kimber.imported = 0">
233     <xsl:message terminate="yes">
234       <xsl:text>ERROR: the 'kimber' index method requires the&#xA;</xsl:text>
235       <xsl:text>kimber index extensions be imported:&#xA;</xsl:text>
236       <xsl:text>  xsl:import href="html/autoidx-kimber.xsl"</xsl:text>
237     </xsl:message>
238   </xsl:if>
239
240 </xsl:template>
241
242 <xsl:template match="indexterm" mode="index-div-basic">
243   <xsl:param name="scope" select="."/>
244   <xsl:param name="role" select="''"/>
245   <xsl:param name="type" select="''"/>
246
247   <xsl:variable name="key"
248                 select="translate(substring(&primary;, 1, 1),
249                          &lowercase;,&uppercase;)"/>
250
251   <xsl:if test="key('letter', $key)[&scope;]
252                 [count(.|key('primary', &primary;)[&scope;][1]) = 1]">
253     <div class="indexdiv">
254       <xsl:if test="contains(concat(&lowercase;, &uppercase;), $key)">
255         <h3>
256           <xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/>
257         </h3>
258       </xsl:if>
259       <dl>
260         <xsl:apply-templates select="key('letter', $key)[&scope;]
261                                      [count(.|key('primary', &primary;)
262                                      [&scope;][1])=1]"
263                              mode="index-primary">
264           <xsl:with-param name="position" select="position()"/>
265           <xsl:with-param name="scope" select="$scope"/>
266           <xsl:with-param name="role" select="$role"/>
267           <xsl:with-param name="type" select="$type"/>
268           <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
269         </xsl:apply-templates>
270       </dl>
271     </div>
272   </xsl:if>
273 </xsl:template>
274
275 <xsl:template match="indexterm" mode="index-symbol-div">
276   <xsl:param name="scope" select="/"/>
277   <xsl:param name="role" select="''"/>
278   <xsl:param name="type" select="''"/>
279
280   <xsl:variable name="key" select="translate(substring(&primary;, 1, 1),
281                                              &lowercase;,&uppercase;)"/>
282
283   <xsl:apply-templates select="key('letter', $key)
284                                [&scope;][count(.|key('primary', &primary;)[1]) = 1]"
285                        mode="index-primary">
286     <xsl:with-param name="position" select="position()"/>
287     <xsl:with-param name="scope" select="$scope"/>
288     <xsl:with-param name="role" select="$role"/>
289     <xsl:with-param name="type" select="$type"/>
290     <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
291   </xsl:apply-templates>
292 </xsl:template>
293
294 <xsl:template match="indexterm" mode="index-primary">
295   <xsl:param name="scope" select="."/>
296   <xsl:param name="role" select="''"/>
297   <xsl:param name="type" select="''"/>
298
299   <xsl:variable name="key" select="&primary;"/>
300   <xsl:variable name="refs" select="key('primary', $key)[&scope;]"/>
301   <dt>
302     <xsl:for-each select="$refs/primary">
303       <xsl:if test="@id or @xml:id">
304         <a name="{(@id|@xml:id)[1]}"/>
305       </xsl:if>
306     </xsl:for-each>
307     <xsl:value-of select="primary"/>
308     <xsl:choose>
309       <xsl:when test="$index.links.to.section = 1">
310         <xsl:for-each select="$refs[generate-id() = generate-id(key('primary-section', concat($key, &sep;, &section.id;))[&scope;][1])]">
311           <xsl:apply-templates select="." mode="reference">
312             <xsl:with-param name="position" select="position()"/>
313             <xsl:with-param name="scope" select="$scope"/>
314             <xsl:with-param name="role" select="$role"/>
315             <xsl:with-param name="type" select="$type"/>
316           </xsl:apply-templates>
317         </xsl:for-each>
318       </xsl:when>
319       <xsl:otherwise>
320         <xsl:for-each select="$refs[&scope;]">
321           <xsl:apply-templates select="." mode="reference">
322             <xsl:with-param name="position" select="position()"/>
323             <xsl:with-param name="scope" select="$scope"/>
324             <xsl:with-param name="role" select="$role"/>
325             <xsl:with-param name="type" select="$type"/>
326           </xsl:apply-templates>
327         </xsl:for-each>
328       </xsl:otherwise>
329     </xsl:choose>
330
331     <xsl:if test="$refs[not(secondary)]/*[self::see]">
332       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &sep;, &sep;, see))[&scope;][1])]"
333                            mode="index-see">
334         <xsl:with-param name="position" select="position()"/>
335         <xsl:with-param name="scope" select="$scope"/>
336         <xsl:with-param name="role" select="$role"/>
337         <xsl:with-param name="type" select="$type"/>
338         <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
339       </xsl:apply-templates>
340     </xsl:if>
341   </dt>
342   <xsl:if test="$refs/secondary or $refs[not(secondary)]/*[self::seealso]">
343     <dd>
344       <dl>
345         <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &sep;, &sep;, seealso))[&scope;][1])]"
346                              mode="index-seealso">
347           <xsl:with-param name="position" select="position()"/>
348           <xsl:with-param name="scope" select="$scope"/>
349           <xsl:with-param name="role" select="$role"/>
350           <xsl:with-param name="type" select="$type"/>
351           <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
352         </xsl:apply-templates>
353         <xsl:apply-templates select="$refs[secondary and count(.|key('secondary', concat($key, &sep;, &secondary;))[&scope;][1]) = 1]" 
354                              mode="index-secondary">
355           <xsl:with-param name="position" select="position()"/>
356           <xsl:with-param name="scope" select="$scope"/>
357           <xsl:with-param name="role" select="$role"/>
358           <xsl:with-param name="type" select="$type"/>
359           <xsl:sort select="translate(&secondary;, &lowercase;, &uppercase;)"/>
360         </xsl:apply-templates>
361       </dl>
362     </dd>
363   </xsl:if>
364 </xsl:template>
365
366 <xsl:template match="indexterm" mode="index-secondary">
367   <xsl:param name="scope" select="."/>
368   <xsl:param name="role" select="''"/>
369   <xsl:param name="type" select="''"/>
370
371   <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;)"/>
372   <xsl:variable name="refs" select="key('secondary', $key)[&scope;]"/>
373   <dt>
374     <xsl:for-each select="$refs/secondary">
375       <xsl:if test="@id or @xml:id">
376         <a name="{(@id|@xml:id)[1]}"/>
377       </xsl:if>
378     </xsl:for-each>
379     <xsl:value-of select="secondary"/>
380     <xsl:choose>
381       <xsl:when test="$index.links.to.section = 1">
382         <xsl:for-each select="$refs[generate-id() = generate-id(key('secondary-section', concat($key, &sep;, &section.id;))[&scope;][1])]">
383           <xsl:apply-templates select="." mode="reference">
384             <xsl:with-param name="position" select="position()"/>
385             <xsl:with-param name="scope" select="$scope"/>
386             <xsl:with-param name="role" select="$role"/>
387             <xsl:with-param name="type" select="$type"/>
388           </xsl:apply-templates>
389         </xsl:for-each>
390       </xsl:when>
391       <xsl:otherwise>
392         <xsl:for-each select="$refs[&scope;]">
393           <xsl:apply-templates select="." mode="reference">
394             <xsl:with-param name="position" select="position()"/>
395             <xsl:with-param name="scope" select="$scope"/>
396             <xsl:with-param name="role" select="$role"/>
397             <xsl:with-param name="type" select="$type"/>
398           </xsl:apply-templates>
399         </xsl:for-each>
400       </xsl:otherwise>
401     </xsl:choose>
402
403     <xsl:if test="$refs[not(tertiary)]/*[self::see]">
404       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, see))[&scope;][1])]"
405                            mode="index-see">
406         <xsl:with-param name="position" select="position()"/>
407         <xsl:with-param name="scope" select="$scope"/>
408         <xsl:with-param name="role" select="$role"/>
409         <xsl:with-param name="type" select="$type"/>
410         <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
411       </xsl:apply-templates>
412     </xsl:if>
413   </dt>
414   <xsl:if test="$refs/tertiary or $refs[not(tertiary)]/*[self::seealso]">
415     <dd>
416       <dl>
417         <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, seealso))[&scope;][1])]"
418                              mode="index-seealso">
419           <xsl:with-param name="position" select="position()"/>
420           <xsl:with-param name="scope" select="$scope"/>
421           <xsl:with-param name="role" select="$role"/>
422           <xsl:with-param name="type" select="$type"/>
423           <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
424         </xsl:apply-templates>
425         <xsl:apply-templates select="$refs[tertiary and count(.|key('tertiary', concat($key, &sep;, &tertiary;))[&scope;][1]) = 1]" 
426                              mode="index-tertiary">
427           <xsl:with-param name="position" select="position()"/>
428           <xsl:with-param name="scope" select="$scope"/>
429           <xsl:with-param name="role" select="$role"/>
430           <xsl:with-param name="type" select="$type"/>
431           <xsl:sort select="translate(&tertiary;, &lowercase;, &uppercase;)"/>
432         </xsl:apply-templates>
433       </dl>
434     </dd>
435   </xsl:if>
436 </xsl:template>
437
438 <xsl:template match="indexterm" mode="index-tertiary">
439   <xsl:param name="scope" select="."/>
440   <xsl:param name="role" select="''"/>
441   <xsl:param name="type" select="''"/>
442
443   <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
444   <xsl:variable name="refs" select="key('tertiary', $key)[&scope;]"/>
445   <dt>
446     <xsl:for-each select="$refs/tertiary">
447       <xsl:if test="@id or @xml:id">
448         <a name="{(@id|@xml:id)[1]}"/>
449       </xsl:if>
450     </xsl:for-each>
451     <xsl:value-of select="tertiary"/>
452     <xsl:choose>
453       <xsl:when test="$index.links.to.section = 1">
454         <xsl:for-each select="$refs[generate-id() = generate-id(key('tertiary-section', concat($key, &sep;, &section.id;))[&scope;][1])]">
455           <xsl:apply-templates select="." mode="reference">
456             <xsl:with-param name="position" select="position()"/>
457             <xsl:with-param name="scope" select="$scope"/>
458             <xsl:with-param name="role" select="$role"/>
459             <xsl:with-param name="type" select="$type"/>
460           </xsl:apply-templates>
461         </xsl:for-each>
462       </xsl:when>
463       <xsl:otherwise>
464         <xsl:for-each select="$refs[&scope;]">
465           <xsl:apply-templates select="." mode="reference">
466             <xsl:with-param name="position" select="position()"/>
467             <xsl:with-param name="scope" select="$scope"/>
468             <xsl:with-param name="role" select="$role"/>
469             <xsl:with-param name="type" select="$type"/>
470           </xsl:apply-templates>
471         </xsl:for-each>
472       </xsl:otherwise>
473     </xsl:choose>
474
475     <xsl:if test="$refs/see">
476       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see))[&scope;][1])]"
477                            mode="index-see">
478         <xsl:with-param name="position" select="position()"/>
479         <xsl:with-param name="scope" select="$scope"/>
480         <xsl:with-param name="role" select="$role"/>
481         <xsl:with-param name="type" select="$type"/>
482         <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
483       </xsl:apply-templates>
484     </xsl:if>
485   </dt>
486   <xsl:if test="$refs/seealso">
487     <dd>
488       <dl>
489         <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, seealso))[&scope;][1])]"
490                              mode="index-seealso">
491           <xsl:with-param name="position" select="position()"/>
492           <xsl:with-param name="scope" select="$scope"/>
493           <xsl:with-param name="role" select="$role"/>
494           <xsl:with-param name="type" select="$type"/>
495           <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
496         </xsl:apply-templates>
497       </dl>
498     </dd>
499   </xsl:if>
500 </xsl:template>
501
502 <xsl:template match="indexterm" mode="reference">
503   <xsl:param name="scope" select="."/>
504   <xsl:param name="role" select="''"/>
505   <xsl:param name="type" select="''"/>
506   <xsl:param name="position"/>
507   
508   <xsl:variable name="term.separator">
509     <xsl:call-template name="index.separator">
510       <xsl:with-param name="key" select="'index.term.separator'"/>
511     </xsl:call-template>
512   </xsl:variable>
513
514   <xsl:variable name="number.separator">
515     <xsl:call-template name="index.separator">
516       <xsl:with-param name="key" select="'index.number.separator'"/>
517     </xsl:call-template>
518   </xsl:variable>
519
520   <xsl:variable name="range.separator">
521     <xsl:call-template name="index.separator">
522       <xsl:with-param name="key" select="'index.range.separator'"/>
523     </xsl:call-template>
524   </xsl:variable>
525
526   <xsl:choose>
527     <xsl:when test="$position = 1">
528       <xsl:value-of select="$term.separator"/>
529     </xsl:when>
530     <xsl:otherwise>
531       <xsl:value-of select="$number.separator"/>
532     </xsl:otherwise>
533   </xsl:choose>
534
535   <xsl:choose>
536     <xsl:when test="@zone and string(@zone)">
537       <xsl:call-template name="reference">
538         <xsl:with-param name="zones" select="normalize-space(@zone)"/>
539         <xsl:with-param name="position" select="position()"/>
540         <xsl:with-param name="scope" select="$scope"/>
541         <xsl:with-param name="role" select="$role"/>
542         <xsl:with-param name="type" select="$type"/>
543       </xsl:call-template>
544     </xsl:when>
545     <xsl:otherwise>
546       <a>
547         <xsl:apply-templates select="." mode="class.attribute"/>
548         <xsl:variable name="title">
549           <xsl:choose>
550             <xsl:when test="&section;/titleabbrev and $index.prefer.titleabbrev != 0">
551               <xsl:apply-templates select="&section;" mode="titleabbrev.markup"/>
552             </xsl:when>
553             <xsl:otherwise>
554               <xsl:apply-templates select="&section;" mode="title.markup"/>
555             </xsl:otherwise>
556           </xsl:choose>
557         </xsl:variable>
558
559         <xsl:attribute name="href">
560           <xsl:choose>
561             <xsl:when test="$index.links.to.section = 1">
562               <xsl:call-template name="href.target">
563                 <xsl:with-param name="object" select="&section;"/>
564                 <xsl:with-param name="context" select="//index[&scope;][1]"/>
565               </xsl:call-template>
566             </xsl:when>
567             <xsl:otherwise>
568               <xsl:call-template name="href.target">
569                 <xsl:with-param name="object" select="."/>
570                 <xsl:with-param name="context" select="//index[&scope;][1]"/>
571               </xsl:call-template>
572             </xsl:otherwise>
573           </xsl:choose>
574
575         </xsl:attribute>
576
577         <xsl:value-of select="$title"/> <!-- text only -->
578       </a>
579
580       <xsl:variable name="id" select="(@id|@xml:id)[1]"/>
581       <xsl:if test="key('endofrange', $id)[&scope;]">
582         <xsl:apply-templates select="key('endofrange', $id)[&scope;][last()]"
583                              mode="reference">
584           <xsl:with-param name="position" select="position()"/>
585           <xsl:with-param name="scope" select="$scope"/>
586           <xsl:with-param name="role" select="$role"/>
587           <xsl:with-param name="type" select="$type"/>
588           <xsl:with-param name="separator" select="$range.separator"/>
589         </xsl:apply-templates>
590       </xsl:if>
591     </xsl:otherwise>
592   </xsl:choose>
593 </xsl:template>
594
595 <xsl:template name="reference">
596   <xsl:param name="scope" select="."/>
597   <xsl:param name="role" select="''"/>
598   <xsl:param name="type" select="''"/>
599   <xsl:param name="zones"/>
600
601   <xsl:choose>
602     <xsl:when test="contains($zones, ' ')">
603       <xsl:variable name="zone" select="substring-before($zones, ' ')"/>
604       <xsl:variable name="target" select="key('sections', $zone)"/>
605
606       <a>
607         <xsl:apply-templates select="." mode="class.attribute"/>
608         <xsl:attribute name="href">
609           <xsl:call-template name="href.target">
610             <xsl:with-param name="object" select="$target[1]"/>
611             <xsl:with-param name="context" select="//index[&scope;][1]"/>
612           </xsl:call-template>
613         </xsl:attribute>
614         <xsl:apply-templates select="$target[1]" mode="index-title-content"/>
615       </a>
616       <xsl:text>, </xsl:text>
617       <xsl:call-template name="reference">
618         <xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
619         <xsl:with-param name="position" select="position()"/>
620         <xsl:with-param name="scope" select="$scope"/>
621         <xsl:with-param name="role" select="$role"/>
622         <xsl:with-param name="type" select="$type"/>
623       </xsl:call-template>
624     </xsl:when>
625     <xsl:otherwise>
626       <xsl:variable name="zone" select="$zones"/>
627       <xsl:variable name="target" select="key('sections', $zone)"/>
628
629       <a>
630         <xsl:apply-templates select="." mode="class.attribute"/>
631         <xsl:attribute name="href">
632           <xsl:call-template name="href.target">
633             <xsl:with-param name="object" select="$target[1]"/>
634             <xsl:with-param name="context" select="//index[&scope;][1]"/>
635           </xsl:call-template>
636         </xsl:attribute>
637         <xsl:apply-templates select="$target[1]" mode="index-title-content"/>
638       </a>
639     </xsl:otherwise>
640   </xsl:choose>
641 </xsl:template>
642
643 <xsl:template match="indexterm" mode="index-see">
644   <xsl:param name="scope" select="."/>
645   <xsl:param name="role" select="''"/>
646   <xsl:param name="type" select="''"/>
647
648   <xsl:text> (</xsl:text>
649   <xsl:call-template name="gentext">
650     <xsl:with-param name="key" select="'see'"/>
651   </xsl:call-template>
652   <xsl:text> </xsl:text>
653   <xsl:value-of select="see"/>
654   <xsl:text>)</xsl:text>
655 </xsl:template>
656
657 <xsl:template match="indexterm" mode="index-seealso">
658   <xsl:param name="scope" select="."/>
659   <xsl:param name="role" select="''"/>
660   <xsl:param name="type" select="''"/>
661
662   <xsl:for-each select="seealso">
663     <xsl:sort select="translate(., &lowercase;, &uppercase;)"/>
664     <dt>
665     <xsl:text>(</xsl:text>
666     <xsl:call-template name="gentext">
667       <xsl:with-param name="key" select="'seealso'"/>
668     </xsl:call-template>
669     <xsl:text> </xsl:text>
670     <xsl:value-of select="."/>
671     <xsl:text>)</xsl:text>
672     </dt>
673   </xsl:for-each>
674 </xsl:template>
675
676 <xsl:template match="*" mode="index-title-content">
677   <xsl:variable name="title">
678     <xsl:apply-templates select="&section;" mode="title.markup"/>
679   </xsl:variable>
680
681   <xsl:value-of select="$title"/>
682 </xsl:template>
683
684 <xsl:template name="index.separator">
685   <xsl:param name="key" select="''"/>
686   <xsl:param name="lang">
687     <xsl:call-template name="l10n.language"/>
688   </xsl:param>
689
690   <xsl:choose>
691     <xsl:when test="$key = 'index.term.separator'">
692       <xsl:choose>
693         <!-- Use the override if not blank -->
694         <xsl:when test="$index.term.separator != ''">
695           <xsl:copy-of select="$index.term.separator"/>
696         </xsl:when>
697         <xsl:otherwise>
698           <xsl:call-template name="gentext.template">
699             <xsl:with-param name="lang" select="$lang"/>
700             <xsl:with-param name="context">index</xsl:with-param>
701             <xsl:with-param name="name">term-separator</xsl:with-param>
702           </xsl:call-template>
703         </xsl:otherwise>
704       </xsl:choose>
705     </xsl:when>
706     <xsl:when test="$key = 'index.number.separator'">
707       <xsl:choose>
708         <!-- Use the override if not blank -->
709         <xsl:when test="$index.number.separator != ''">
710           <xsl:copy-of select="$index.number.separator"/>
711         </xsl:when>
712         <xsl:otherwise>
713           <xsl:call-template name="gentext.template">
714             <xsl:with-param name="lang" select="$lang"/>
715             <xsl:with-param name="context">index</xsl:with-param>
716             <xsl:with-param name="name">number-separator</xsl:with-param>
717           </xsl:call-template>
718         </xsl:otherwise>
719       </xsl:choose>
720     </xsl:when>
721     <xsl:when test="$key = 'index.range.separator'">
722       <xsl:choose>
723         <!-- Use the override if not blank -->
724         <xsl:when test="$index.range.separator != ''">
725           <xsl:copy-of select="$index.range.separator"/>
726         </xsl:when>
727         <xsl:otherwise>
728           <xsl:call-template name="gentext.template">
729             <xsl:with-param name="lang" select="$lang"/>
730             <xsl:with-param name="context">index</xsl:with-param>
731             <xsl:with-param name="name">range-separator</xsl:with-param>
732           </xsl:call-template>
733         </xsl:otherwise>
734       </xsl:choose>
735     </xsl:when>
736   </xsl:choose>
737 </xsl:template>
738
739 </xsl:stylesheet>