]> git.stg.codes - stg.git/blob - doc/xslt/fo/autoidx.xsl
Massive refactoring.
[stg.git] / doc / xslt / fo / 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:fo="http://www.w3.org/1999/XSL/Format"
8                 xmlns:rx="http://www.renderx.com/XSL/Extensions"
9                 xmlns:axf="http://www.antennahouse.com/names/XSL/Extensions"
10                 xmlns:exslt="http://exslt.org/common"
11                 extension-element-prefixes="exslt"
12                 exclude-result-prefixes="exslt"
13                 version="1.0">
14
15 <!-- ********************************************************************
16      $Id: autoidx.xsl 8399 2009-04-08 07:37:42Z bobstayton $
17      ********************************************************************
18
19      This file is part of the DocBook XSL Stylesheet distribution.
20      See ../README or http://docbook.sf.net/ for copyright
21      copyright and other information.
22
23      ******************************************************************** -->
24
25 <!-- ==================================================================== -->
26 <!-- The "basic" method derived from Jeni Tennison's work. -->
27 <!-- The "kosek" method contributed by Jirka Kosek. -->
28 <!-- The "kimber" method contributed by Eliot Kimber of Innodata Isogen. -->
29
30 <!-- Importing module for kimber or kosek method overrides one of these -->
31 <xsl:param name="kimber.imported" select="0"/>
32 <xsl:param name="kosek.imported" select="0"/>
33
34 <!-- These keys used primary in all methods -->
35 <xsl:key name="letter"
36          match="indexterm"
37          use="translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;)"/>
38
39 <xsl:key name="primary"
40          match="indexterm"
41          use="&primary;"/>
42
43 <xsl:key name="secondary"
44          match="indexterm"
45          use="concat(&primary;, &sep;, &secondary;)"/>
46
47 <xsl:key name="tertiary"
48          match="indexterm"
49          use="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
50
51 <xsl:key name="endofrange"
52          match="indexterm[@class='endofrange']"
53          use="@startref"/>
54
55 <xsl:key name="see-also"
56          match="indexterm[seealso]"
57          use="concat(&primary;, &sep;, 
58                      &secondary;, &sep;, 
59                      &tertiary;, &sep;, seealso)"/>
60
61 <xsl:key name="see"
62          match="indexterm[see]"
63          use="concat(&primary;, &sep;, 
64                      &secondary;, &sep;, 
65                      &tertiary;, &sep;, see)"/>
66
67
68 <xsl:template name="generate-index">
69   <xsl:param name="scope" select="(ancestor::book|/)[last()]"/>
70
71   <xsl:choose>
72     <xsl:when test="$index.method = 'kosek'">
73       <xsl:call-template name="generate-kosek-index">
74         <xsl:with-param name="scope" select="$scope"/>
75       </xsl:call-template>
76     </xsl:when>
77     <xsl:when test="$index.method = 'kimber'">
78       <xsl:call-template name="generate-kimber-index">
79         <xsl:with-param name="scope" select="$scope"/>
80       </xsl:call-template>
81     </xsl:when>
82
83     <xsl:otherwise>
84       <xsl:call-template name="generate-basic-index">
85         <xsl:with-param name="scope" select="$scope"/>
86       </xsl:call-template>
87     </xsl:otherwise>
88   </xsl:choose>
89 </xsl:template>
90       
91 <xsl:template name="generate-basic-index">
92   <xsl:param name="scope" select="NOTANODE"/>
93
94   <xsl:variable name="role">
95     <xsl:if test="$index.on.role != 0">
96       <xsl:value-of select="@role"/>
97     </xsl:if>
98   </xsl:variable>
99
100   <xsl:variable name="type">
101     <xsl:if test="$index.on.type != 0">
102       <xsl:value-of select="@type"/>
103     </xsl:if>
104   </xsl:variable>
105
106   <xsl:variable name="terms"
107                 select="//indexterm
108                         [count(.|key('letter',
109                           translate(substring(&primary;, 1, 1),
110                              &lowercase;,
111                              &uppercase;))
112                           [&scope;][1]) = 1
113                           and not(@class = 'endofrange')]"/>
114
115   <xsl:variable name="alphabetical"
116                 select="$terms[contains(concat(&lowercase;, &uppercase;),
117                                         substring(&primary;, 1, 1))]"/>
118
119   <xsl:variable name="others" select="$terms[not(contains(
120                                         concat(&lowercase;,
121                                         &uppercase;),
122                                         substring(&primary;, 1, 1)))]"/>
123   <fo:block>
124     <xsl:if test="$others">
125       <xsl:call-template name="indexdiv.title">
126         <xsl:with-param name="titlecontent">
127           <xsl:call-template name="gentext">
128             <xsl:with-param name="key" select="'index symbols'"/>
129           </xsl:call-template>
130         </xsl:with-param>
131       </xsl:call-template>
132
133       <fo:block>
134         <xsl:apply-templates select="$others[count(.|key('primary',
135                                      &primary;)[&scope;][1]) = 1]"
136                              mode="index-symbol-div">
137           <xsl:with-param name="scope" select="$scope"/>
138           <xsl:with-param name="role" select="$role"/>
139           <xsl:with-param name="type" select="$type"/>
140           <xsl:sort select="translate(&primary;, &lowercase;, 
141                             &uppercase;)"/>
142         </xsl:apply-templates>
143       </fo:block>
144     </xsl:if>
145
146     <xsl:apply-templates select="$alphabetical[count(.|key('letter',
147                                  translate(substring(&primary;, 1, 1),
148                                            &lowercase;,&uppercase;))
149                                            [&scope;][1]) = 1]"
150                          mode="index-div-basic">
151       <xsl:with-param name="scope" select="$scope"/>
152       <xsl:with-param name="role" select="$role"/>
153       <xsl:with-param name="type" select="$type"/>
154       <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
155     </xsl:apply-templates>
156   </fo:block>
157 </xsl:template>
158
159 <!-- This template not used if fo/autoidx-kosek.xsl is imported -->
160 <xsl:template name="generate-kosek-index">
161   <xsl:param name="scope" select="NOTANODE"/>
162
163   <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
164   <xsl:if test="contains($vendor, 'libxslt')">
165     <xsl:message terminate="yes">
166       <xsl:text>ERROR: the 'kosek' index method does not </xsl:text>
167       <xsl:text>work with the xsltproc XSLT processor.</xsl:text>
168     </xsl:message>
169   </xsl:if>
170
171
172   <xsl:if test="$exsl.node.set.available = 0">
173     <xsl:message terminate="yes">
174       <xsl:text>ERROR: the 'kosek' index method requires the </xsl:text>
175       <xsl:text>exslt:node-set() function. Use a processor that </xsl:text>
176       <xsl:text>has it, or use a different index method.</xsl:text>
177     </xsl:message>
178   </xsl:if>
179
180   <xsl:if test="$kosek.imported = 0">
181     <xsl:message terminate="yes">
182       <xsl:text>ERROR: the 'kosek' index method requires the&#xA;</xsl:text>
183       <xsl:text>kosek index extensions be imported:&#xA;</xsl:text>
184       <xsl:text>  xsl:import href="fo/autoidx-kosek.xsl"</xsl:text>
185     </xsl:message>
186   </xsl:if>
187
188 </xsl:template>
189
190
191 <!-- This template not used if fo/autoidx-kimber.xsl is imported -->
192 <xsl:template name="generate-kimber-index">
193   <xsl:param name="scope" select="NOTANODE"/>
194
195   <xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
196   <xsl:if test="not(contains($vendor, 'SAXON '))">
197     <xsl:message terminate="yes">
198       <xsl:text>ERROR: the 'kimber' index method requires the </xsl:text>
199       <xsl:text>Saxon version 6 or 8 XSLT processor.</xsl:text>
200     </xsl:message>
201   </xsl:if>
202
203   <xsl:if test="$kimber.imported = 0">
204     <xsl:message terminate="yes">
205       <xsl:text>ERROR: the 'kimber' index method requires the&#xA;</xsl:text>
206       <xsl:text>kimber index extensions be imported:&#xA;</xsl:text>
207       <xsl:text>  xsl:import href="fo/autoidx-kimber.xsl"</xsl:text>
208     </xsl:message>
209   </xsl:if>
210
211 </xsl:template>
212
213 <xsl:template match="indexterm" mode="index-div-basic">
214   <xsl:param name="scope" select="."/>
215   <xsl:param name="role" select="''"/>
216   <xsl:param name="type" select="''"/>
217
218   <xsl:variable name="key"
219                 select="translate(substring(&primary;, 1, 1),
220                          &lowercase;,&uppercase;)"/>
221
222   <xsl:if test="key('letter', $key)[&scope;]
223                 [count(.|key('primary', &primary;)[&scope;][1]) = 1]">
224     <fo:block>
225       <xsl:if test="contains(concat(&lowercase;, &uppercase;), $key)">
226         <xsl:call-template name="indexdiv.title">
227           <xsl:with-param name="titlecontent">
228             <xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/>
229           </xsl:with-param>
230         </xsl:call-template>
231       </xsl:if>
232       <fo:block xsl:use-attribute-sets="index.entry.properties">
233         <xsl:apply-templates select="key('letter', $key)[&scope;]
234                                      [count(.|key('primary', &primary;)
235                                      [&scope;][1])=1]"
236                              mode="index-primary">
237           <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
238           <xsl:with-param name="scope" select="$scope"/>
239           <xsl:with-param name="role" select="$role"/>
240           <xsl:with-param name="type" select="$type"/>
241         </xsl:apply-templates>
242       </fo:block>
243     </fo:block>
244   </xsl:if>
245 </xsl:template>
246
247 <xsl:template match="indexterm" mode="index-symbol-div">
248   <xsl:param name="scope" select="."/>
249   <xsl:param name="role" select="''"/>
250   <xsl:param name="type" select="''"/>
251
252   <xsl:variable name="key"
253                 select="translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;)"/>
254
255   <fo:block xsl:use-attribute-sets="index.entry.properties">
256     <xsl:apply-templates select="key('letter', $key)[&scope;][count(.|key('primary', &primary;)[&scope;][1]) = 1]"
257                          mode="index-primary">
258       <xsl:with-param name="scope" select="$scope"/>
259       <xsl:with-param name="role" select="$role"/>
260       <xsl:with-param name="type" select="$type"/>
261       <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
262     </xsl:apply-templates>
263   </fo:block>
264 </xsl:template>
265
266 <xsl:template match="indexterm" mode="index-primary">
267   <xsl:param name="scope" select="."/>
268   <xsl:param name="role" select="''"/>
269   <xsl:param name="type" select="''"/>
270
271   <xsl:variable name="key" select="&primary;"/>
272   <xsl:variable name="refs" select="key('primary', $key)[&scope;]"/>
273
274   <xsl:variable name="term.separator">
275     <xsl:call-template name="index.separator">
276       <xsl:with-param name="key" select="'index.term.separator'"/>
277     </xsl:call-template>
278   </xsl:variable>
279
280   <xsl:variable name="range.separator">
281     <xsl:call-template name="index.separator">
282       <xsl:with-param name="key" select="'index.range.separator'"/>
283     </xsl:call-template>
284   </xsl:variable>
285
286   <xsl:variable name="number.separator">
287     <xsl:call-template name="index.separator">
288       <xsl:with-param name="key" select="'index.number.separator'"/>
289     </xsl:call-template>
290   </xsl:variable>
291
292   <fo:block>
293     <xsl:if test="$axf.extensions != 0">
294       <xsl:attribute name="axf:suppress-duplicate-page-number">true</xsl:attribute>
295     </xsl:if>
296
297     <xsl:for-each select="$refs/primary">
298       <xsl:if test="@id or @xml:id">
299         <fo:inline id="{(@id|@xml:id)[1]}"/>
300       </xsl:if>
301     </xsl:for-each>
302
303     <xsl:value-of select="primary"/>
304
305     <xsl:choose>
306       <xsl:when test="$xep.extensions != 0">
307         <xsl:if test="$refs[not(see) and not(secondary)]">
308           <xsl:copy-of select="$term.separator"/>
309           <xsl:variable name="primary" select="&primary;"/>
310           <xsl:variable name="primary.significant" select="concat(&primary;, $significant.flag)"/>
311           <rx:page-index list-separator="{$number.separator}"
312                          range-separator="{$range.separator}">
313             <xsl:if test="$refs[@significance='preferred'][not(see) and not(secondary)]">
314               <rx:index-item xsl:use-attribute-sets="index.preferred.page.properties xep.index.item.properties"
315                 ref-key="{$primary.significant}"/>
316             </xsl:if>
317             <xsl:if test="$refs[not(@significance) or @significance!='preferred'][not(see) and not(secondary)]">
318               <rx:index-item xsl:use-attribute-sets="xep.index.item.properties"
319                 ref-key="{$primary}"/>
320             </xsl:if>
321           </rx:page-index>        
322         </xsl:if>
323       </xsl:when>
324       <xsl:otherwise>
325         <xsl:variable name="page-number-citations">
326           <xsl:for-each select="$refs[not(see) 
327                                 and not(secondary)]">
328             <xsl:apply-templates select="." mode="reference">
329               <xsl:with-param name="scope" select="$scope"/>
330               <xsl:with-param name="role" select="$role"/>
331               <xsl:with-param name="type" select="$type"/>
332               <xsl:with-param name="position" select="position()"/>
333             </xsl:apply-templates>
334           </xsl:for-each>
335         </xsl:variable>
336
337         <xsl:choose>
338           <xsl:when test="$passivetex.extensions != '0'">
339             <fotex:sort xmlns:fotex="http://www.tug.org/fotex">
340               <xsl:copy-of select="$page-number-citations"/>
341             </fotex:sort>
342           </xsl:when>
343           <xsl:otherwise>
344             <xsl:copy-of select="$page-number-citations"/>
345           </xsl:otherwise>
346         </xsl:choose>
347       </xsl:otherwise>
348     </xsl:choose>
349
350     <xsl:if test="$refs[not(secondary)]/*[self::see]">
351       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &sep;, &sep;, see))[&scope;][1])]"
352                            mode="index-see">
353          <xsl:with-param name="scope" select="$scope"/>
354          <xsl:with-param name="role" select="$role"/>
355          <xsl:with-param name="type" select="$type"/>
356          <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
357       </xsl:apply-templates>
358     </xsl:if>
359
360   </fo:block>
361
362   <xsl:if test="$refs/secondary or $refs[not(secondary)]/*[self::seealso]">
363     <fo:block start-indent="1pc">
364       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &sep;, &sep;, seealso))[&scope;][1])]"
365                            mode="index-seealso">
366          <xsl:with-param name="scope" select="$scope"/>
367          <xsl:with-param name="role" select="$role"/>
368          <xsl:with-param name="type" select="$type"/>
369          <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
370       </xsl:apply-templates>
371       <xsl:apply-templates select="$refs[secondary and count(.|key('secondary', concat($key, &sep;, &secondary;))[&scope;][1]) = 1]"
372                            mode="index-secondary">
373        <xsl:with-param name="scope" select="$scope"/>
374        <xsl:with-param name="role" select="$role"/>
375        <xsl:with-param name="type" select="$type"/>
376        <xsl:sort select="translate(&secondary;, &lowercase;, &uppercase;)"/>
377       </xsl:apply-templates>
378     </fo:block>
379   </xsl:if>
380 </xsl:template>
381
382 <xsl:template match="indexterm" mode="index-secondary">
383   <xsl:param name="scope" select="."/>
384   <xsl:param name="role" select="''"/>
385   <xsl:param name="type" select="''"/>
386
387   <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;)"/>
388   <xsl:variable name="refs" select="key('secondary', $key)[&scope;]"/>
389
390   <xsl:variable name="term.separator">
391     <xsl:call-template name="index.separator">
392       <xsl:with-param name="key" select="'index.term.separator'"/>
393     </xsl:call-template>
394   </xsl:variable>
395
396   <xsl:variable name="range.separator">
397     <xsl:call-template name="index.separator">
398       <xsl:with-param name="key" select="'index.range.separator'"/>
399     </xsl:call-template>
400   </xsl:variable>
401
402   <xsl:variable name="number.separator">
403     <xsl:call-template name="index.separator">
404       <xsl:with-param name="key" select="'index.number.separator'"/>
405     </xsl:call-template>
406   </xsl:variable>
407
408   <fo:block>
409     <xsl:if test="$axf.extensions != 0">
410       <xsl:attribute name="axf:suppress-duplicate-page-number">true</xsl:attribute>
411     </xsl:if>
412
413     <xsl:for-each select="$refs/secondary">
414       <xsl:if test="@id or @xml:id">
415         <fo:inline id="{(@id|@xml:id)[1]}"/>
416       </xsl:if>
417     </xsl:for-each>
418
419     <xsl:value-of select="secondary"/>
420
421     <xsl:choose>
422       <xsl:when test="$xep.extensions != 0">
423         <xsl:if test="$refs[not(see) and not(tertiary)]">
424           <xsl:copy-of select="$term.separator"/>
425           <xsl:variable name="primary" select="&primary;"/>
426           <xsl:variable name="secondary" select="&secondary;"/>
427           <xsl:variable name="primary.significant" select="concat(&primary;, $significant.flag)"/>
428           <rx:page-index list-separator="{$number.separator}"
429                          range-separator="{$range.separator}">
430             <xsl:if test="$refs[@significance='preferred'][not(see) and not(tertiary)]">
431               <rx:index-item xsl:use-attribute-sets="index.preferred.page.properties xep.index.item.properties">
432                 <xsl:attribute name="ref-key">
433                   <xsl:value-of select="$primary.significant"/>
434                   <xsl:text>, </xsl:text>
435                   <xsl:value-of select="$secondary"/>
436                 </xsl:attribute>
437               </rx:index-item>
438             </xsl:if>
439             <xsl:if test="$refs[not(@significance) or @significance!='preferred'][not(see) and not(tertiary)]">
440               <rx:index-item xsl:use-attribute-sets="xep.index.item.properties">
441                 <xsl:attribute name="ref-key">
442                   <xsl:value-of select="$primary"/>
443                   <xsl:text>, </xsl:text>
444                   <xsl:value-of select="$secondary"/>
445                 </xsl:attribute>
446               </rx:index-item>
447             </xsl:if>
448           </rx:page-index>
449         </xsl:if>
450       </xsl:when>
451       <xsl:otherwise>
452         <xsl:variable name="page-number-citations">
453           <xsl:for-each select="$refs[not(see) 
454                                 and not(tertiary)]">
455             <xsl:apply-templates select="." mode="reference">
456               <xsl:with-param name="scope" select="$scope"/>
457               <xsl:with-param name="role" select="$role"/>
458               <xsl:with-param name="type" select="$type"/>
459               <xsl:with-param name="position" select="position()"/>
460             </xsl:apply-templates>
461           </xsl:for-each>
462         </xsl:variable>
463
464         <xsl:choose>
465           <xsl:when test="$passivetex.extensions != '0'">
466             <fotex:sort xmlns:fotex="http://www.tug.org/fotex">
467               <xsl:copy-of select="$page-number-citations"/>
468             </fotex:sort>
469           </xsl:when>
470           <xsl:otherwise>
471             <xsl:copy-of select="$page-number-citations"/>
472           </xsl:otherwise>
473         </xsl:choose>
474       </xsl:otherwise>
475     </xsl:choose>
476
477     <xsl:if test="$refs[not(tertiary)]/*[self::see]">
478       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, see))[&scope;][1])]"
479                            mode="index-see">
480         <xsl:with-param name="scope" select="$scope"/>
481         <xsl:with-param name="role" select="$role"/>
482         <xsl:with-param name="type" select="$type"/>
483         <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
484       </xsl:apply-templates>
485     </xsl:if>
486
487   </fo:block>
488
489   <xsl:if test="$refs/tertiary or $refs[not(tertiary)]/*[self::seealso]">
490     <fo:block start-indent="2pc">
491       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, seealso))[&scope;][1])]"
492                            mode="index-seealso">
493           <xsl:with-param name="scope" select="$scope"/>
494           <xsl:with-param name="role" select="$role"/>
495           <xsl:with-param name="type" select="$type"/>
496           <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
497       </xsl:apply-templates>
498       <xsl:apply-templates select="$refs[tertiary and count(.|key('tertiary', concat($key, &sep;, &tertiary;))[&scope;][1]) = 1]" 
499                            mode="index-tertiary">
500           <xsl:with-param name="scope" select="$scope"/>
501           <xsl:with-param name="role" select="$role"/>
502           <xsl:with-param name="type" select="$type"/>
503           <xsl:sort select="translate(&tertiary;, &lowercase;, &uppercase;)"/>
504       </xsl:apply-templates>
505     </fo:block>
506   </xsl:if>
507 </xsl:template>
508
509 <xsl:template match="indexterm" mode="index-tertiary">
510   <xsl:param name="scope" select="."/>
511   <xsl:param name="role" select="''"/>
512   <xsl:param name="type" select="''"/>
513   <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
514   <xsl:variable name="refs" select="key('tertiary', $key)[&scope;]"/>
515
516   <xsl:variable name="term.separator">
517     <xsl:call-template name="index.separator">
518       <xsl:with-param name="key" select="'index.term.separator'"/>
519     </xsl:call-template>
520   </xsl:variable>
521
522   <xsl:variable name="range.separator">
523     <xsl:call-template name="index.separator">
524       <xsl:with-param name="key" select="'index.range.separator'"/>
525     </xsl:call-template>
526   </xsl:variable>
527
528   <xsl:variable name="number.separator">
529     <xsl:call-template name="index.separator">
530       <xsl:with-param name="key" select="'index.number.separator'"/>
531     </xsl:call-template>
532   </xsl:variable>
533
534   <fo:block>
535     <xsl:if test="$axf.extensions != 0">
536       <xsl:attribute name="axf:suppress-duplicate-page-number">true</xsl:attribute>
537     </xsl:if>
538
539     <xsl:for-each select="$refs/tertiary">
540       <xsl:if test="@id or @xml:id">
541         <fo:inline id="{(@id|@xml:id)[1]}"/>
542       </xsl:if>
543     </xsl:for-each>
544
545     <xsl:value-of select="tertiary"/>
546
547     <xsl:choose>
548       <xsl:when test="$xep.extensions != 0">
549         <xsl:if test="$refs[not(see)]">
550           <xsl:copy-of select="$term.separator"/>
551           <xsl:variable name="primary" select="&primary;"/>
552           <xsl:variable name="secondary" select="&secondary;"/>
553           <xsl:variable name="tertiary" select="&tertiary;"/>
554           <xsl:variable name="primary.significant" select="concat(&primary;, $significant.flag)"/>
555           <rx:page-index list-separator="{$number.separator}"
556                          range-separator="{$range.separator}">
557             <xsl:if test="$refs[@significance='preferred'][not(see)]">
558               <rx:index-item xsl:use-attribute-sets="index.preferred.page.properties xep.index.item.properties">
559                 <xsl:attribute name="ref-key">
560                   <xsl:value-of select="$primary.significant"/>
561                   <xsl:text>, </xsl:text>
562                   <xsl:value-of select="$secondary"/>
563                   <xsl:text>, </xsl:text>
564                   <xsl:value-of select="$tertiary"/>
565                 </xsl:attribute>
566               </rx:index-item>
567             </xsl:if>
568             <xsl:if test="$refs[not(@significance) or @significance!='preferred'][not(see)]">
569               <rx:index-item xsl:use-attribute-sets="xep.index.item.properties">
570                 <xsl:attribute name="ref-key">
571                   <xsl:value-of select="$primary"/>
572                   <xsl:text>, </xsl:text>
573                   <xsl:value-of select="$secondary"/>
574                   <xsl:text>, </xsl:text>
575                   <xsl:value-of select="$tertiary"/>
576                 </xsl:attribute>
577               </rx:index-item>
578             </xsl:if>
579           </rx:page-index>
580         </xsl:if>
581       </xsl:when>
582       <xsl:otherwise>
583         <xsl:variable name="page-number-citations">
584           <xsl:for-each select="$refs[not(see)]">
585             <xsl:apply-templates select="." mode="reference">
586               <xsl:with-param name="scope" select="$scope"/>
587               <xsl:with-param name="role" select="$role"/>
588               <xsl:with-param name="type" select="$type"/>
589               <xsl:with-param name="position" select="position()"/>
590             </xsl:apply-templates>
591           </xsl:for-each>
592         </xsl:variable>
593
594         <xsl:choose>
595           <xsl:when test="$passivetex.extensions != '0'">
596             <fotex:sort xmlns:fotex="http://www.tug.org/fotex">
597               <xsl:copy-of select="$page-number-citations"/>
598             </fotex:sort>
599           </xsl:when>
600           <xsl:otherwise>
601             <xsl:copy-of select="$page-number-citations"/>
602           </xsl:otherwise>
603         </xsl:choose>
604       </xsl:otherwise>
605     </xsl:choose>
606
607     <xsl:if test="$refs/see">
608       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see))[&scope;][1])]"
609                            mode="index-see">
610         <xsl:with-param name="scope" select="$scope"/>
611         <xsl:with-param name="role" select="$role"/>
612         <xsl:with-param name="type" select="$type"/>
613         <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
614       </xsl:apply-templates>
615     </xsl:if>
616
617   </fo:block>
618
619   <xsl:if test="$refs/seealso">
620     <fo:block>
621       <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, seealso))[&scope;][1])]"
622                            mode="index-seealso">
623         <xsl:with-param name="scope" select="$scope"/>
624         <xsl:with-param name="role" select="$role"/>
625         <xsl:with-param name="type" select="$type"/>
626         <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
627       </xsl:apply-templates>
628     </fo:block>
629   </xsl:if>
630 </xsl:template>
631
632 <xsl:template match="indexterm" mode="reference">
633   <xsl:param name="scope" select="."/>
634   <xsl:param name="role" select="''"/>
635   <xsl:param name="type" select="''"/>
636   <xsl:param name="position" select="0"/>
637   <xsl:param name="separator" select="''"/>
638
639   <xsl:variable name="term.separator">
640     <xsl:call-template name="index.separator">
641       <xsl:with-param name="key" select="'index.term.separator'"/>
642     </xsl:call-template>
643   </xsl:variable>
644
645   <xsl:variable name="range.separator">
646     <xsl:call-template name="index.separator">
647       <xsl:with-param name="key" select="'index.range.separator'"/>
648     </xsl:call-template>
649   </xsl:variable>
650
651   <xsl:variable name="number.separator">
652     <xsl:call-template name="index.separator">
653       <xsl:with-param name="key" select="'index.number.separator'"/>
654     </xsl:call-template>
655   </xsl:variable>
656
657   <xsl:choose>
658     <xsl:when test="$separator != ''">
659       <xsl:value-of select="$separator"/>
660     </xsl:when>
661     <xsl:when test="$position = 1">
662       <xsl:value-of select="$term.separator"/>
663     </xsl:when>
664     <xsl:otherwise>
665       <xsl:value-of select="$number.separator"/>
666     </xsl:otherwise>
667   </xsl:choose>
668
669   <xsl:choose>
670     <xsl:when test="@zone and string(@zone)">
671       <xsl:call-template name="reference">
672         <xsl:with-param name="zones" select="normalize-space(@zone)"/>
673         <xsl:with-param name="scope" select="$scope"/>
674         <xsl:with-param name="role" select="$role"/>
675         <xsl:with-param name="type" select="$type"/>
676       </xsl:call-template>
677     </xsl:when>
678     <xsl:when test="ancestor::*[contains(local-name(),'info') and not(starts-with(local-name(),'info'))]">
679       <xsl:call-template name="info.reference">
680         <xsl:with-param name="scope" select="$scope"/>
681         <xsl:with-param name="role" select="$role"/>
682         <xsl:with-param name="type" select="$type"/>
683       </xsl:call-template>
684     </xsl:when>
685     <xsl:otherwise>
686       <xsl:variable name="id">
687         <xsl:call-template name="object.id"/>
688       </xsl:variable>
689
690       <fo:basic-link internal-destination="{$id}"
691                      xsl:use-attribute-sets="index.page.number.properties">
692         <fo:page-number-citation ref-id="{$id}"/>
693       </fo:basic-link>
694
695       <xsl:if test="key('endofrange', $id)[&scope;]">
696         <xsl:apply-templates select="key('endofrange', $id)[&scope;][last()]"
697                              mode="reference">
698           <xsl:with-param name="scope" select="$scope"/>
699           <xsl:with-param name="role" select="$role"/>
700           <xsl:with-param name="type" select="$type"/>
701           <xsl:with-param name="separator" select="$range.separator"/>
702         </xsl:apply-templates>
703       </xsl:if>
704     </xsl:otherwise>
705   </xsl:choose>
706 </xsl:template>
707
708 <xsl:template name="reference">
709   <xsl:param name="scope" select="."/>
710   <xsl:param name="role" select="''"/>
711   <xsl:param name="type" select="''"/>
712   <xsl:param name="zones"/>
713
714   <xsl:variable name="number.separator">
715     <xsl:call-template name="index.separator">
716       <xsl:with-param name="key" select="'index.number.separator'"/>
717     </xsl:call-template>
718   </xsl:variable>
719
720   <xsl:choose>
721     <xsl:when test="contains($zones, ' ')">
722       <xsl:variable name="zone" select="substring-before($zones, ' ')"/>
723       <xsl:variable name="target" select="key('id', $zone)"/>
724
725       <xsl:variable name="id">
726         <xsl:call-template name="object.id">
727            <xsl:with-param name="object" select="$target[1]"/>
728         </xsl:call-template>
729       </xsl:variable>
730
731       <fo:basic-link internal-destination="{$id}"
732                      xsl:use-attribute-sets="index.page.number.properties">
733         <fo:page-number-citation ref-id="{$id}"/>
734       </fo:basic-link>
735
736       <xsl:if test="$passivetex.extensions = '0'">
737         <xsl:copy-of select="$number.separator"/>
738       </xsl:if>
739       <xsl:call-template name="reference">
740         <xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
741         <xsl:with-param name="scope" select="$scope"/>
742         <xsl:with-param name="role" select="$role"/>
743         <xsl:with-param name="type" select="$type"/>
744       </xsl:call-template>
745     </xsl:when>
746     <xsl:otherwise>
747       <xsl:variable name="zone" select="$zones"/>
748       <xsl:variable name="target" select="key('id', $zone)"/>
749
750       <xsl:variable name="id">
751         <xsl:call-template name="object.id">
752           <xsl:with-param name="object" select="$target[1]"/>
753         </xsl:call-template>
754       </xsl:variable>
755
756       <fo:basic-link internal-destination="{$id}"
757                      xsl:use-attribute-sets="index.page.number.properties">
758         <fo:page-number-citation ref-id="{$id}"/>
759       </fo:basic-link>
760     </xsl:otherwise>
761   </xsl:choose>
762 </xsl:template>
763
764 <xsl:template name="info.reference">
765   <!-- This is not perfect. It doesn't treat indexterm inside info element as a range covering whole parent of info.
766        It also not work when there is no ID generated for parent element. But it works in the most common cases. -->
767   <xsl:param name="scope" select="."/>
768   <xsl:param name="role" select="''"/>
769   <xsl:param name="type" select="''"/>
770
771   <xsl:variable name="target" select="(ancestor::appendix|ancestor::article|ancestor::bibliography|ancestor::book|
772                                        ancestor::chapter|ancestor::glossary|ancestor::part|ancestor::preface|
773                                        ancestor::refentry|ancestor::reference|ancestor::refsect1|ancestor::refsect2|
774                                        ancestor::refsect3|ancestor::refsection|ancestor::refsynopsisdiv|
775                                        ancestor::sect1|ancestor::sect2|ancestor::sect3|ancestor::sect4|ancestor::sect5|
776                                        ancestor::section|ancestor::setindex|ancestor::set|ancestor::sidebar|ancestor::mediaobject)[&scope;]"/>
777   
778   <xsl:variable name="id">
779     <xsl:call-template name="object.id">
780       <xsl:with-param name="object" select="$target[position() = last()]"/>
781     </xsl:call-template>
782   </xsl:variable>
783   
784   <fo:basic-link internal-destination="{$id}"
785                  xsl:use-attribute-sets="index.page.number.properties">
786     <fo:page-number-citation ref-id="{$id}"/>
787   </fo:basic-link>
788 </xsl:template>
789
790 <xsl:template match="indexterm" mode="index-see">
791    <xsl:param name="scope" select="."/>
792   <xsl:param name="role" select="''"/>
793   <xsl:param name="type" select="''"/>
794
795    <fo:inline>
796      <xsl:text> (</xsl:text>
797      <xsl:call-template name="gentext">
798        <xsl:with-param name="key" select="'see'"/>
799      </xsl:call-template>
800      <xsl:text> </xsl:text>
801      <xsl:value-of select="see"/>
802      <xsl:text>)</xsl:text>
803    </fo:inline>
804 </xsl:template>
805
806 <xsl:template match="indexterm" mode="index-seealso">
807    <xsl:param name="scope" select="."/>
808   <xsl:param name="role" select="''"/>
809   <xsl:param name="type" select="''"/>
810
811   <xsl:for-each select="seealso">
812     <xsl:sort select="translate(., &lowercase;, &uppercase;)"/>
813     <fo:block>
814       <xsl:text>(</xsl:text>
815       <xsl:call-template name="gentext">
816         <xsl:with-param name="key" select="'seealso'"/>
817       </xsl:call-template>
818       <xsl:text> </xsl:text>
819       <xsl:value-of select="."/>
820       <xsl:text>)</xsl:text>
821     </fo:block>
822   </xsl:for-each>
823
824 </xsl:template>
825
826 <!-- ====================================================================== -->
827
828 <xsl:template name="generate-index-markup">
829   <xsl:param name="scope" select="(ancestor::book|/)[last()]"/>
830   <xsl:param name="role" select="@role"/>
831   <xsl:param name="type" select="@type"/>
832
833   <xsl:variable name="terms" select="$scope//indexterm[count(.|key('letter',
834                                      translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;))[&scope;][1]) = 1]"/>
835   <xsl:variable name="alphabetical"
836                 select="$terms[contains(concat(&lowercase;, &uppercase;),
837                                         substring(&primary;, 1, 1))]"/>
838   <xsl:variable name="others" select="$terms[not(contains(concat(&lowercase;,
839                                                  &uppercase;),
840                                              substring(&primary;, 1, 1)))]"/>
841
842   <xsl:text>&lt;index&gt;&#10;</xsl:text>
843   <xsl:if test="$others">
844     <xsl:text>&#10;&lt;indexdiv&gt;&#10;</xsl:text>
845     <xsl:text>&lt;title&gt;</xsl:text>
846     <xsl:call-template name="gentext">
847       <xsl:with-param name="key" select="'index symbols'"/>
848     </xsl:call-template>
849     <xsl:text>&lt;/title&gt;&#10;</xsl:text>
850     <xsl:apply-templates select="$others[count(.|key('primary',
851                                  &primary;)[&scope;][1]) = 1]"
852                          mode="index-symbol-div-markup">
853       <xsl:with-param name="scope" select="$scope"/>
854       <xsl:with-param name="role" select="$role"/>
855       <xsl:with-param name="type" select="$type"/>
856       <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
857     </xsl:apply-templates>
858     <xsl:text>&lt;/indexdiv&gt;&#10;</xsl:text>
859   </xsl:if>
860
861   <xsl:apply-templates select="$alphabetical[count(.|key('letter',
862                                translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;))[&scope;][1]) = 1]"
863                        mode="index-div-markup">
864       <xsl:with-param name="scope" select="$scope"/>
865       <xsl:with-param name="role" select="$role"/>
866       <xsl:with-param name="type" select="$type"/>
867       <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
868   </xsl:apply-templates>
869   <xsl:text>&lt;/index&gt;&#10;</xsl:text>
870 </xsl:template>
871
872 <xsl:template match="*" mode="index-markup">
873   <xsl:param name="scope" select="."/>
874   <xsl:param name="role" select="''"/>
875   <xsl:param name="type" select="''"/>
876
877   <xsl:text>&lt;</xsl:text>
878   <xsl:value-of select="local-name(.)"/>
879   <xsl:text>&gt;&#10;</xsl:text>
880   <xsl:apply-templates mode="index-markup">
881     <xsl:with-param name="scope" select="$scope"/>
882     <xsl:with-param name="role" select="$role"/>
883     <xsl:with-param name="type" select="$type"/>
884   </xsl:apply-templates>
885 </xsl:template>
886
887 <xsl:template match="indexterm" mode="index-div-markup">
888   <xsl:param name="scope" select="."/>
889   <xsl:param name="role" select="''"/>
890   <xsl:param name="type" select="''"/>
891   <xsl:variable name="key" select="translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;)"/>
892   <xsl:text>&#10;&lt;indexdiv&gt;&#10;</xsl:text>
893   <xsl:text>&lt;title&gt;</xsl:text>
894   <xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/>
895   <xsl:text>&lt;/title&gt;&#10;</xsl:text>
896
897   <xsl:apply-templates select="key('letter', $key)[&scope;][count(.|key('primary', &primary;)[&scope;][1]) = 1]"
898                        mode="index-primary-markup">
899     <xsl:with-param name="scope" select="$scope"/>
900     <xsl:with-param name="role" select="$role"/>
901     <xsl:with-param name="type" select="$type"/>
902     <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
903   </xsl:apply-templates>
904   <xsl:text>&lt;/indexdiv&gt;&#10;</xsl:text>
905 </xsl:template>
906
907 <xsl:template match="indexterm" mode="index-symbol-div-markup">
908   <xsl:param name="scope" select="."/>
909   <xsl:param name="role" select="''"/>
910   <xsl:param name="type" select="''"/>
911   <xsl:variable name="key" select="translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;)"/>
912
913   <xsl:apply-templates select="key('letter', $key)[&scope;][count(.|key('primary', &primary;)[&scope;][1]) = 1]"
914                        mode="index-primary-markup">
915     <xsl:with-param name="scope" select="$scope"/>
916     <xsl:with-param name="role" select="$role"/>
917     <xsl:with-param name="type" select="$type"/>
918     <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
919   </xsl:apply-templates>
920 </xsl:template>
921
922 <xsl:template match="indexterm" mode="index-primary-markup">
923   <xsl:param name="scope" select="."/>
924   <xsl:param name="role" select="''"/>
925   <xsl:param name="type" select="''"/>
926   <xsl:variable name="key" select="&primary;"/>
927   <xsl:variable name="refs" select="key('primary', $key)[&scope;]"/>
928   <xsl:variable name="pages" select="$refs[not(see) and not(seealso)]"/>
929
930   <xsl:text>&#10;&lt;indexentry&gt;&#10;</xsl:text>
931   <xsl:text>&lt;primaryie&gt;</xsl:text>
932   <xsl:text>&lt;phrase&gt;</xsl:text>
933   <xsl:call-template name="escape-text">
934     <xsl:with-param name="text" select="string(primary)"/>
935   </xsl:call-template>
936   <xsl:text>&lt;/phrase&gt;</xsl:text>
937   <xsl:if test="$pages">,</xsl:if>
938   <xsl:text>&#10;</xsl:text>
939
940   <xsl:for-each select="$pages">
941     <xsl:apply-templates select="." mode="reference-markup">
942       <xsl:with-param name="scope" select="$scope"/>
943       <xsl:with-param name="role" select="$role"/>
944       <xsl:with-param name="type" select="$type"/>
945     </xsl:apply-templates>
946   </xsl:for-each>
947
948   <xsl:text>&lt;/primaryie&gt;&#10;</xsl:text>
949
950   <xsl:if test="$refs/secondary or $refs[not(secondary)]/*[self::see or self::seealso]">
951     <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &sep;, &sep;, see))[&scope;][1])]"
952                          mode="index-see-markup">
953       <xsl:with-param name="scope" select="$scope"/>
954       <xsl:with-param name="role" select="$role"/>
955       <xsl:with-param name="type" select="$type"/>
956       <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
957     </xsl:apply-templates>
958
959     <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &sep;, &sep;, seealso))[&scope;][1])]"
960                          mode="index-seealso-markup">
961       <xsl:with-param name="scope" select="$scope"/>
962       <xsl:with-param name="role" select="$role"/>
963       <xsl:with-param name="type" select="$type"/>
964       <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
965     </xsl:apply-templates>
966
967     <xsl:apply-templates select="$refs[secondary and count(.|key('secondary', concat($key, &sep;, &secondary;))[&scope;][1]) = 1]" 
968                          mode="index-secondary-markup">
969       <xsl:with-param name="scope" select="$scope"/>
970       <xsl:with-param name="role" select="$role"/>
971       <xsl:with-param name="type" select="$type"/>
972       <xsl:sort select="translate(&secondary;, &lowercase;, &uppercase;)"/>
973     </xsl:apply-templates>
974   </xsl:if>
975   <xsl:text>&lt;/indexentry&gt;&#10;</xsl:text>
976 </xsl:template>
977
978 <xsl:template match="indexterm" mode="index-secondary-markup">
979   <xsl:param name="scope" select="."/>
980   <xsl:param name="role" select="''"/>
981   <xsl:param name="type" select="''"/>
982   <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;)"/>
983   <xsl:variable name="refs" select="key('secondary', $key)[&scope;]"/>
984   <xsl:variable name="pages" select="$refs[not(see) and not(seealso)]"/>
985
986   <xsl:text>&lt;secondaryie&gt;</xsl:text>
987   <xsl:text>&lt;phrase&gt;</xsl:text>
988   <xsl:call-template name="escape-text">
989     <xsl:with-param name="text" select="string(secondary)"/>
990   </xsl:call-template>
991   <xsl:text>&lt;/phrase&gt;</xsl:text>
992   <xsl:if test="$pages">,</xsl:if>
993   <xsl:text>&#10;</xsl:text>
994
995   <xsl:for-each select="$pages">
996     <xsl:apply-templates select="." mode="reference-markup">
997       <xsl:with-param name="scope" select="$scope"/>
998       <xsl:with-param name="role" select="$role"/>
999       <xsl:with-param name="type" select="$type"/>
1000     </xsl:apply-templates>
1001   </xsl:for-each>
1002
1003   <xsl:text>&lt;/secondaryie&gt;&#10;</xsl:text>
1004
1005   <xsl:if test="$refs/tertiary or $refs[not(tertiary)]/*[self::see or self::seealso]">
1006     <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, see))[&scope;][1])]"
1007                          mode="index-see-markup">
1008       <xsl:with-param name="scope" select="$scope"/>
1009       <xsl:with-param name="role" select="$role"/>
1010       <xsl:with-param name="type" select="$type"/>
1011       <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
1012     </xsl:apply-templates>
1013     <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, seealso))[&scope;][1])]"
1014                          mode="index-seealso-markup">
1015       <xsl:with-param name="scope" select="$scope"/>
1016       <xsl:with-param name="role" select="$role"/>
1017       <xsl:with-param name="type" select="$type"/>
1018       <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
1019     </xsl:apply-templates>
1020     <xsl:apply-templates select="$refs[tertiary and count(.|key('tertiary', concat($key, &sep;, &tertiary;))[&scope;][1]) = 1]" 
1021                          mode="index-tertiary-markup">
1022       <xsl:with-param name="scope" select="$scope"/>
1023       <xsl:with-param name="role" select="$role"/>
1024       <xsl:with-param name="type" select="$type"/>
1025       <xsl:sort select="translate(&tertiary;, &lowercase;, &uppercase;)"/>
1026     </xsl:apply-templates>
1027   </xsl:if>
1028 </xsl:template>
1029
1030 <xsl:template match="indexterm" mode="index-tertiary-markup">
1031   <xsl:param name="scope" select="."/>
1032   <xsl:param name="role" select="''"/>
1033   <xsl:param name="type" select="''"/>
1034   <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/>
1035   <xsl:variable name="refs" select="key('tertiary', $key)[&scope;]"/>
1036   <xsl:variable name="pages" select="$refs[not(see) and not(seealso)]"/>
1037
1038   <xsl:text>&lt;tertiaryie&gt;</xsl:text>
1039   <xsl:text>&lt;phrase&gt;</xsl:text>
1040   <xsl:call-template name="escape-text">
1041     <xsl:with-param name="text" select="string(tertiary)"/>
1042   </xsl:call-template>
1043   <xsl:text>&lt;/phrase&gt;</xsl:text>
1044   <xsl:if test="$pages">,</xsl:if>
1045   <xsl:text>&#10;</xsl:text>
1046
1047   <xsl:for-each select="$pages">
1048     <xsl:apply-templates select="." mode="reference-markup">
1049       <xsl:with-param name="scope" select="$scope"/>
1050       <xsl:with-param name="role" select="$role"/>
1051       <xsl:with-param name="type" select="$type"/>
1052     </xsl:apply-templates>
1053   </xsl:for-each>
1054
1055   <xsl:text>&lt;/tertiaryie&gt;&#10;</xsl:text>
1056
1057   <xsl:variable name="see" select="$refs/see | $refs/seealso"/>
1058   <xsl:if test="$see">
1059     <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see))[&scope;][1])]"
1060                          mode="index-see-markup">
1061       <xsl:with-param name="scope" select="$scope"/>
1062       <xsl:with-param name="role" select="$role"/>
1063       <xsl:with-param name="type" select="$type"/>
1064       <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/>
1065     </xsl:apply-templates>
1066     <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, seealso))[&scope;][1])]"
1067                          mode="index-seealso-markup">
1068       <xsl:with-param name="scope" select="$scope"/>
1069       <xsl:with-param name="role" select="$role"/>
1070       <xsl:with-param name="type" select="$type"/>
1071       <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/>
1072     </xsl:apply-templates>
1073   </xsl:if>
1074 </xsl:template>
1075
1076 <xsl:template match="indexterm" mode="reference-markup">
1077   <xsl:param name="scope" select="."/>
1078   <xsl:param name="role" select="''"/>
1079   <xsl:param name="type" select="''"/>
1080
1081   <xsl:choose>
1082     <xsl:when test="@zone and string(@zone)">
1083       <xsl:call-template name="reference-markup">
1084         <xsl:with-param name="zones" select="normalize-space(@zone)"/>
1085         <xsl:with-param name="scope" select="$scope"/>
1086         <xsl:with-param name="role" select="$role"/>
1087         <xsl:with-param name="type" select="$type"/>
1088       </xsl:call-template>
1089     </xsl:when>
1090     <xsl:otherwise>
1091       <xsl:variable name="id">
1092         <xsl:call-template name="object.id"/>
1093       </xsl:variable>
1094
1095
1096       <xsl:choose>
1097         <xsl:when test="@startref and @class='endofrange'">
1098           <xsl:text>&lt;phrase role="pageno"&gt;</xsl:text>
1099           <xsl:text>&lt;link linkend="</xsl:text>
1100           <xsl:value-of select="@startref"/>
1101           <xsl:text>"&gt;</xsl:text>
1102           <fo:basic-link internal-destination="{@startref}"
1103                      xsl:use-attribute-sets="index.page.number.properties">
1104             <fo:page-number-citation ref-id="{@startref}"/>
1105             <xsl:text>-</xsl:text>
1106             <fo:page-number-citation ref-id="{$id}"/>
1107           </fo:basic-link>
1108           <xsl:text>&lt;/link&gt;</xsl:text>
1109           <xsl:text>&lt;/phrase&gt;&#10;</xsl:text>
1110         </xsl:when>
1111         <xsl:otherwise>
1112           <xsl:text>&lt;phrase role="pageno"&gt;</xsl:text>
1113           <xsl:if test="$id">
1114             <xsl:text>&lt;link linkend="</xsl:text>
1115             <xsl:value-of select="$id"/>
1116             <xsl:text>"&gt;</xsl:text>
1117           </xsl:if>
1118           <fo:basic-link internal-destination="{$id}"
1119                      xsl:use-attribute-sets="index.page.number.properties">
1120             <fo:page-number-citation ref-id="{$id}"/>
1121           </fo:basic-link>
1122           <xsl:if test="$id">
1123             <xsl:text>&lt;/link&gt;</xsl:text>
1124           </xsl:if>
1125           <xsl:text>&lt;/phrase&gt;&#10;</xsl:text>
1126         </xsl:otherwise>
1127       </xsl:choose>
1128     </xsl:otherwise>
1129   </xsl:choose>
1130 </xsl:template>
1131
1132 <xsl:template name="reference-markup">
1133   <xsl:param name="scope" select="."/>
1134   <xsl:param name="role" select="''"/>
1135   <xsl:param name="type" select="''"/>
1136   <xsl:param name="zones"/>
1137   <xsl:choose>
1138     <xsl:when test="contains($zones, ' ')">
1139       <xsl:variable name="zone" select="substring-before($zones, ' ')"/>
1140       <xsl:variable name="target" select="key('id', $zone)[&scope;]"/>
1141
1142       <xsl:variable name="id">
1143         <xsl:call-template name="object.id">
1144           <xsl:with-param name="object" select="$target[1]"/>
1145         </xsl:call-template>
1146       </xsl:variable>
1147
1148       <xsl:text>&lt;phrase fole="pageno"&gt;</xsl:text>
1149       <xsl:if test="$target[1]/@id or $target[1]/@xml:id">
1150         <xsl:text>&lt;link linkend="</xsl:text>
1151         <xsl:value-of select="$id"/>
1152         <xsl:text>"&gt;</xsl:text>
1153       </xsl:if>
1154       <fo:basic-link internal-destination="{$id}"
1155                      xsl:use-attribute-sets="index.page.number.properties">
1156         <fo:page-number-citation ref-id="{$id}"/>
1157       </fo:basic-link>
1158       <xsl:if test="$target[1]/@id or $target[1]/@xml:id">
1159         <xsl:text>&lt;/link&gt;</xsl:text>
1160       </xsl:if>
1161       <xsl:text>&lt;/phrase&gt;&#10;</xsl:text>
1162
1163       <xsl:call-template name="reference">
1164         <xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
1165         <xsl:with-param name="scope" select="$scope"/>
1166         <xsl:with-param name="role" select="$role"/>
1167         <xsl:with-param name="type" select="$type"/>
1168       </xsl:call-template>
1169     </xsl:when>
1170     <xsl:otherwise>
1171       <xsl:variable name="zone" select="$zones"/>
1172       <xsl:variable name="target" select="key('id', $zone)[&scope;]"/>
1173
1174       <xsl:variable name="id">
1175         <xsl:call-template name="object.id">
1176           <xsl:with-param name="object" select="$target[1]"/>
1177         </xsl:call-template>
1178       </xsl:variable>
1179
1180       <xsl:text>&lt;phrase role="pageno"&gt;</xsl:text>
1181       <xsl:if test="$target[1]/@id or target[1]/@xml:id">
1182         <xsl:text>&lt;link linkend="</xsl:text>
1183         <xsl:value-of select="$id"/>
1184         <xsl:text>"&gt;</xsl:text>
1185       </xsl:if>
1186       <fo:basic-link internal-destination="{$id}"
1187                      xsl:use-attribute-sets="index.page.number.properties">
1188         <fo:page-number-citation ref-id="{$id}"/>
1189       </fo:basic-link>
1190       <xsl:if test="$target[1]/@id or target[1]/@xml:id">
1191         <xsl:text>&lt;/link&gt;</xsl:text>
1192       </xsl:if>
1193       <xsl:text>&lt;/phrase&gt;&#10;</xsl:text>
1194     </xsl:otherwise>
1195   </xsl:choose>
1196 </xsl:template>
1197
1198 <xsl:template match="indexterm" mode="index-see-markup">
1199   <xsl:param name="scope" select="."/>
1200   <xsl:param name="role" select="''"/>
1201   <xsl:param name="type" select="''"/>
1202   <fo:block>
1203     <xsl:text>&lt;seeie&gt;</xsl:text>
1204     <xsl:text>&lt;phrase&gt;</xsl:text>
1205     <xsl:call-template name="escape-text">
1206       <xsl:with-param name="text" select="string(see)"/>
1207     </xsl:call-template>
1208     <xsl:text>&lt;/phrase&gt;</xsl:text>
1209     <xsl:text>&lt;/seeie&gt;&#10;</xsl:text>
1210   </fo:block>
1211 </xsl:template>
1212
1213 <xsl:template match="indexterm" mode="index-seealso-markup">
1214   <xsl:param name="scope" select="."/>
1215   <xsl:param name="role" select="''"/>
1216   <xsl:param name="type" select="''"/>
1217   <fo:block>
1218     <xsl:text>&lt;seealsoie&gt;</xsl:text>
1219     <xsl:text>&lt;phrase&gt;</xsl:text>
1220     <xsl:call-template name="escape-text">
1221       <xsl:with-param name="text" select="string(seealso)"/>
1222     </xsl:call-template>
1223     <xsl:text>&lt;/phrase&gt;</xsl:text>
1224     <xsl:text>&lt;/seealsoie&gt;&#10;</xsl:text>
1225   </fo:block>
1226 </xsl:template>
1227
1228 <xsl:template name="escape-text">
1229   <xsl:param name="text" select="''"/>
1230
1231   <xsl:variable name="ltpos" select="substring-before($text, '&lt;')"/>
1232   <xsl:variable name="amppos" select="substring-before($text, '&amp;')"/>
1233
1234   <xsl:choose>
1235     <xsl:when test="contains($text,'&lt;') and contains($text, '&amp;')
1236                     and string-length($ltpos) &lt; string-length($amppos)">
1237       <xsl:value-of select="$ltpos"/>
1238       <xsl:text>&amp;lt;</xsl:text>
1239       <xsl:call-template name="escape-text">
1240         <xsl:with-param name="text" select="substring-after($text, '&lt;')"/>
1241       </xsl:call-template>
1242     </xsl:when>
1243
1244     <xsl:when test="contains($text,'&lt;') and contains($text, '&amp;')
1245                     and string-length($amppos) &lt; string-length($ltpos)">
1246       <xsl:value-of select="$amppos"/>
1247       <xsl:text>&amp;amp;</xsl:text>
1248       <xsl:call-template name="escape-text">
1249         <xsl:with-param name="text" select="substring-after($text, '&amp;')"/>
1250       </xsl:call-template>
1251     </xsl:when>
1252
1253     <xsl:when test="contains($text, '&lt;')">
1254       <xsl:value-of select="$ltpos"/>
1255       <xsl:text>&amp;lt;</xsl:text>
1256       <xsl:call-template name="escape-text">
1257         <xsl:with-param name="text" select="substring-after($text, '&lt;')"/>
1258       </xsl:call-template>
1259     </xsl:when>
1260
1261     <xsl:when test="contains($text, '&amp;')">
1262       <xsl:value-of select="$amppos"/>
1263       <xsl:text>&amp;amp;</xsl:text>
1264       <xsl:call-template name="escape-text">
1265         <xsl:with-param name="text" select="substring-after($text, '&amp;')"/>
1266       </xsl:call-template>
1267     </xsl:when>
1268
1269     <xsl:otherwise>
1270       <xsl:value-of select="$text"/>
1271     </xsl:otherwise>
1272   </xsl:choose>
1273 </xsl:template>
1274
1275 <xsl:template name="index.separator">
1276   <xsl:param name="key" select="''"/>
1277   <xsl:param name="lang">
1278     <xsl:call-template name="l10n.language"/>
1279   </xsl:param>
1280
1281   <xsl:choose>
1282     <xsl:when test="$key = 'index.term.separator'">
1283       <xsl:choose>
1284         <!-- Use the override if not blank -->
1285         <xsl:when test="$index.term.separator != ''">
1286           <xsl:copy-of select="$index.term.separator"/>
1287         </xsl:when>
1288         <xsl:otherwise>
1289           <xsl:call-template name="gentext.template">
1290             <xsl:with-param name="lang" select="$lang"/>
1291             <xsl:with-param name="context">index</xsl:with-param>
1292             <xsl:with-param name="name">term-separator</xsl:with-param>
1293           </xsl:call-template>
1294         </xsl:otherwise>
1295       </xsl:choose>
1296     </xsl:when>
1297     <xsl:when test="$key = 'index.number.separator'">
1298       <xsl:choose>
1299         <!-- Use the override if not blank -->
1300         <xsl:when test="$index.number.separator != ''">
1301           <xsl:copy-of select="$index.number.separator"/>
1302         </xsl:when>
1303         <xsl:otherwise>
1304           <xsl:call-template name="gentext.template">
1305             <xsl:with-param name="lang" select="$lang"/>
1306             <xsl:with-param name="context">index</xsl:with-param>
1307             <xsl:with-param name="name">number-separator</xsl:with-param>
1308           </xsl:call-template>
1309         </xsl:otherwise>
1310       </xsl:choose>
1311     </xsl:when>
1312     <xsl:when test="$key = 'index.range.separator'">
1313       <xsl:choose>
1314         <!-- Use the override if not blank -->
1315         <xsl:when test="$index.range.separator != ''">
1316           <xsl:copy-of select="$index.range.separator"/>
1317         </xsl:when>
1318         <xsl:otherwise>
1319           <xsl:call-template name="gentext.template">
1320             <xsl:with-param name="lang" select="$lang"/>
1321             <xsl:with-param name="context">index</xsl:with-param>
1322             <xsl:with-param name="name">range-separator</xsl:with-param>
1323           </xsl:call-template>
1324         </xsl:otherwise>
1325       </xsl:choose>
1326     </xsl:when>
1327   </xsl:choose>
1328 </xsl:template>
1329
1330 </xsl:stylesheet>