]> git.stg.codes - stg.git/blob - doc/xslt/common/olink.xsl
Ticket 37. The policy name added for the DENY value message in the
[stg.git] / doc / xslt / common / olink.xsl
1 <?xml version="1.0"?>
2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3                 version="1.0">
4
5 <!-- ********************************************************************
6      $Id: olink.xsl 8592 2010-03-16 16:40:43Z bobstayton $
7      ********************************************************************
8
9      This file is part of the DocBook XSL Stylesheet distribution.
10      See ../README or http://docbook.sf.net/ for copyright
11      copyright and other information.
12
13      ******************************************************************** -->
14
15 <!-- Create keys for quickly looking up olink targets -->
16 <xsl:key name="targetdoc-key" match="document" use="@targetdoc" />
17 <xsl:key name="targetptr-key"  match="div|obj"
18          use="concat(ancestor::document/@targetdoc, '/',
19                      @targetptr, '/', ancestor::document/@lang)" />
20
21 <!-- Return filename of database -->
22 <xsl:template name="select.target.database">
23   <xsl:param name="targetdoc.att" select="''"/>
24   <xsl:param name="targetptr.att" select="''"/>
25   <xsl:param name="olink.lang" select="''"/>
26
27   <!-- use root's xml:base if exists -->
28   <xsl:variable name="xml.base" select="/*/@xml:base"/>
29
30   <!-- This selection can be customized if needed -->
31   <xsl:variable name="target.database.filename">
32     <xsl:choose>
33       <xsl:when test="$xml.base != '' and
34                    not(starts-with($target.database.document, 'file:/')) and
35                    not(starts-with($target.database.document, '/'))">
36         <xsl:call-template name="systemIdToBaseURI">
37           <xsl:with-param name="systemId" select="$xml.base"/>
38         </xsl:call-template>
39         <xsl:value-of select="$target.database.document"/>
40       </xsl:when>
41       <xsl:otherwise>
42         <xsl:value-of select="$target.database.document"/>
43       </xsl:otherwise>
44     </xsl:choose>
45   </xsl:variable>
46
47   <xsl:variable name="target.database" 
48       select="document($target.database.filename,/)"/>
49
50   <xsl:choose>
51     <!-- Was the database document parameter not set? -->
52     <xsl:when test="$target.database.document = ''">
53       <xsl:message>
54         <xsl:text>Olinks not processed: must specify a </xsl:text>
55         <xsl:text>$target.database.document parameter&#10;</xsl:text>
56         <xsl:text>when using olinks with targetdoc </xsl:text>
57         <xsl:text>and targetptr attributes.</xsl:text>
58       </xsl:message>
59     </xsl:when>
60     <!-- Did it not open? Should be a targetset element -->
61     <xsl:when test="not($target.database/*)">
62       <xsl:message>
63         <xsl:text>Olink error: could not open target database '</xsl:text>
64         <xsl:value-of select="$target.database.filename"/>
65         <xsl:text>'.</xsl:text>
66       </xsl:message>
67     </xsl:when>
68     <xsl:otherwise>
69       <xsl:value-of select="$target.database.filename"/>
70     </xsl:otherwise>
71   </xsl:choose>
72 </xsl:template>
73
74 <xsl:template name="select.olink.key">
75   <xsl:param name="targetdoc.att" select="''"/>
76   <xsl:param name="targetptr.att" select="''"/>
77   <xsl:param name="olink.lang" select="''"/>
78   <xsl:param name="target.database"/>
79
80   <xsl:if test="$target.database/*">
81     <xsl:variable name="olink.fallback.sequence">
82       <xsl:call-template name="select.olink.lang.fallback">
83         <xsl:with-param name="olink.lang" select="$olink.lang"/>
84       </xsl:call-template>
85     </xsl:variable>
86   
87     <!-- Recurse through the languages until you find a match -->
88     <xsl:call-template name="select.olink.key.in.lang">
89       <xsl:with-param name="targetdoc.att" select="$targetdoc.att"/>
90       <xsl:with-param name="targetptr.att" select="$targetptr.att"/>
91       <xsl:with-param name="olink.lang" select="$olink.lang"/>
92       <xsl:with-param name="target.database" select="$target.database"/>
93       <xsl:with-param name="fallback.index" select="1"/>
94       <xsl:with-param name="olink.fallback.sequence"
95                       select="$olink.fallback.sequence"/>
96     </xsl:call-template>
97   </xsl:if>
98   
99 </xsl:template>
100
101 <!-- Locate olink key in a particular language -->
102 <xsl:template name="select.olink.key.in.lang">
103   <xsl:param name="targetdoc.att" select="''"/>
104   <xsl:param name="targetptr.att" select="''"/>
105   <xsl:param name="olink.lang" select="''"/>
106   <xsl:param name="target.database"/>
107   <xsl:param name="fallback.index" select="1"/>
108   <xsl:param name="olink.fallback.sequence" select="''"/>
109   
110   <xsl:variable name="target.lang">
111     <xsl:call-template name="select.target.lang">
112       <xsl:with-param name="fallback.index" select="$fallback.index"/>
113       <xsl:with-param name="olink.fallback.sequence"
114                       select="$olink.fallback.sequence"/>
115     </xsl:call-template>
116   </xsl:variable>
117
118   <xsl:if test="$olink.debug != 0">
119     <xsl:message><xsl:text>Olink debug: cases for targetdoc='</xsl:text>
120       <xsl:value-of select="$targetdoc.att"/>
121       <xsl:text>' and targetptr='</xsl:text>
122       <xsl:value-of select="$targetptr.att"/>
123       <xsl:text>' in language '</xsl:text>
124       <xsl:value-of select="$target.lang"/>
125       <xsl:text>'.</xsl:text>
126     </xsl:message>
127   </xsl:if>
128
129   <!-- Customize these cases if you want different selection logic -->
130   <xsl:variable name="CaseA">
131     <!-- targetdoc.att = not blank
132          targetptr.att = not blank
133     -->
134     <xsl:if test="$targetdoc.att != '' and
135                   $targetptr.att != ''">
136       <xsl:for-each select="$target.database">
137         <xsl:variable name="key" 
138                       select="concat($targetdoc.att, '/', 
139                                      $targetptr.att, '/',
140                                      $target.lang)"/>
141         <xsl:choose>
142           <xsl:when test="key('targetptr-key', $key)[1]/@href != ''">
143             <xsl:value-of select="$key"/>
144             <xsl:if test="$olink.debug != 0">
145               <xsl:message>Olink debug: CaseA matched.</xsl:message>
146             </xsl:if>
147           </xsl:when>
148           <xsl:when test="$olink.debug != 0">
149             <xsl:message>Olink debug: CaseA NOT matched</xsl:message>
150           </xsl:when>
151         </xsl:choose>
152       </xsl:for-each>
153     </xsl:if>
154   </xsl:variable>
155
156   <xsl:variable name="CaseB">
157     <!-- targetdoc.att = not blank
158          targetptr.att = not blank
159          prefer.internal.olink = not zero
160          current.docid = not blank 
161     -->
162     <xsl:if test="$targetdoc.att != '' and
163                   $targetptr.att != '' and
164                   $current.docid != '' and
165                   $prefer.internal.olink != 0">
166       <xsl:for-each select="$target.database">
167         <xsl:variable name="key" 
168                       select="concat($current.docid, '/', 
169                                      $targetptr.att, '/',
170                                      $target.lang)"/>
171         <xsl:choose>
172           <xsl:when test="key('targetptr-key', $key)[1]/@href != ''">
173             <xsl:value-of select="$key"/>
174             <xsl:if test="$olink.debug != 0">
175               <xsl:message>Olink debug: CaseB matched.</xsl:message>
176             </xsl:if>
177           </xsl:when>
178           <xsl:when test="$olink.debug != 0">
179             <xsl:message>Olink debug: CaseB NOT matched</xsl:message>
180           </xsl:when>
181         </xsl:choose>
182       </xsl:for-each>
183     </xsl:if>
184   </xsl:variable>
185
186   <xsl:variable name="CaseC">
187     <!-- targetdoc.att = blank
188          targetptr.att = not blank
189          current.docid = not blank 
190     -->
191     <xsl:if test="string-length($targetdoc.att) = 0 and
192                   $targetptr.att != '' and
193                   $current.docid != ''">
194       <!-- Must use a for-each to change context for keys to work -->
195       <xsl:for-each select="$target.database">
196         <xsl:variable name="key" 
197                       select="concat($current.docid, '/', 
198                                      $targetptr.att, '/',
199                                      $target.lang)"/>
200         <xsl:choose>
201           <xsl:when test="key('targetptr-key', $key)[1]/@href != ''">
202             <xsl:value-of select="$key"/>
203             <xsl:if test="$olink.debug != 0">
204               <xsl:message>Olink debug: CaseC matched.</xsl:message>
205             </xsl:if>
206           </xsl:when>
207           <xsl:when test="$olink.debug != 0">
208             <xsl:message>Olink debug: CaseC NOT matched.</xsl:message>
209           </xsl:when>
210         </xsl:choose>
211       </xsl:for-each>
212     </xsl:if>
213   </xsl:variable>
214
215   <xsl:variable name="CaseD">
216     <!-- targetdoc.att = blank
217          targetptr.att = not blank
218          current.docid = blank 
219     -->
220     <!-- This is possible if only one document in the database -->
221     <xsl:if test="string-length($targetdoc.att) = 0 and
222                   $targetptr.att != '' and
223                   string-length($current.docid) = 0 and
224                   count($target.database//document) = 1">
225       <xsl:for-each select="$target.database">
226         <xsl:variable name="key" 
227                       select="concat(.//document/@targetdoc, '/', 
228                                      $targetptr.att, '/',
229                                      $target.lang)"/>
230         <xsl:choose>
231           <xsl:when test="key('targetptr-key', $key)[1]/@href != ''">
232             <xsl:value-of select="$key"/>
233             <xsl:if test="$olink.debug != 0">
234               <xsl:message>Olink debug: CaseD matched.</xsl:message>
235             </xsl:if>
236           </xsl:when>
237           <xsl:when test="$olink.debug != 0">
238             <xsl:message>Olink debug: CaseD NOT matched</xsl:message>
239           </xsl:when>
240         </xsl:choose>
241       </xsl:for-each>
242     </xsl:if>
243   </xsl:variable>
244
245   <xsl:variable name="CaseE">
246     <!-- targetdoc.att = not blank
247          targetptr.att = blank
248     -->
249     <xsl:if test="$targetdoc.att != '' and
250                   string-length($targetptr.att) = 0">
251
252       <!-- Try the document's root element id -->
253       <xsl:variable name="rootid">
254         <xsl:choose>
255           <xsl:when test="$target.lang != ''">
256             <xsl:value-of select="$target.database//document[@targetdoc = $targetdoc.att and @lang = $target.lang]/*[1]/@targetptr"/>
257           </xsl:when>
258           <xsl:otherwise>
259             <xsl:value-of select="$target.database//document[@targetdoc = $targetdoc.att and not(@lang)]/*[1]/@targetptr"/>
260           </xsl:otherwise>
261         </xsl:choose>
262       </xsl:variable>
263
264       <xsl:for-each select="$target.database">
265         <xsl:variable name="key" 
266                       select="concat($targetdoc.att, '/', 
267                                      $rootid, '/',
268                                      $target.lang)"/>
269         <xsl:choose>
270           <xsl:when test="key('targetptr-key', $key)[1]/@href != ''">
271             <xsl:value-of select="$key"/>
272             <xsl:if test="$olink.debug != 0">
273               <xsl:message>Olink debug: CaseE matched.</xsl:message>
274             </xsl:if>
275           </xsl:when>
276           <xsl:when test="$olink.debug != 0">
277             <xsl:message>Olink debug: CaseE NOT matched.</xsl:message>
278           </xsl:when>
279         </xsl:choose>
280       </xsl:for-each>
281     </xsl:if>
282   </xsl:variable>
283
284   <xsl:variable name="CaseF">
285     <!-- targetdoc.att = not blank
286          targetptr.att = blank
287          prefer.internal.olink = not zero
288          current.docid = not blank 
289     -->
290     <xsl:if test="$targetdoc.att != '' and
291                   string-length($targetptr.att) = 0 and
292                   $current.docid != '' and
293                   $prefer.internal.olink != 0">
294       <!-- Try the document's root element id -->
295       <xsl:variable name="rootid">
296         <xsl:choose>
297           <xsl:when test="$target.lang != ''">
298             <xsl:value-of select="$target.database//document[@targetdoc = $current.docid and @lang = $target.lang]/*[1]/@targetptr"/>
299           </xsl:when>
300           <xsl:otherwise>
301             <xsl:value-of select="$target.database//document[@targetdoc = $current.docid and not(@lang)]/*[1]/@targetptr"/>
302           </xsl:otherwise>
303         </xsl:choose>
304       </xsl:variable>
305
306       <xsl:for-each select="$target.database">
307         <xsl:variable name="key" 
308                       select="concat($current.docid, '/', 
309                                      $rootid, '/',
310                                      $target.lang)"/>
311         <xsl:choose>
312           <xsl:when test="key('targetptr-key', $key)[1]/@href != ''">
313             <xsl:value-of select="$key"/>
314             <xsl:if test="$olink.debug != 0">
315               <xsl:message>Olink debug: CaseF matched.</xsl:message>
316             </xsl:if>
317           </xsl:when>
318           <xsl:when test="$olink.debug != 0">
319             <xsl:message>Olink debug: CaseF NOT matched.</xsl:message>
320           </xsl:when>
321         </xsl:choose>
322       </xsl:for-each>
323     </xsl:if>
324   </xsl:variable>
325
326   <!-- Now select the best match. Customize the order if needed -->
327   <xsl:variable name="selected.key">
328     <xsl:choose>
329       <xsl:when test="$CaseB != ''">
330         <xsl:value-of select="$CaseB"/>
331         <xsl:if test="$olink.debug != 0">
332           <xsl:message>
333             <xsl:text>Olink debug: CaseB key is the final selection: </xsl:text>
334             <xsl:value-of select="$CaseB"/>
335           </xsl:message>
336         </xsl:if>
337       </xsl:when>
338       <xsl:when test="$CaseA != ''">
339         <xsl:value-of select="$CaseA"/>
340         <xsl:if test="$olink.debug != 0">
341           <xsl:message>
342             <xsl:text>Olink debug: CaseA key is the final selection: </xsl:text>
343             <xsl:value-of select="$CaseA"/>
344           </xsl:message>
345         </xsl:if>
346       </xsl:when>
347       <xsl:when test="$CaseC != ''">
348         <xsl:value-of select="$CaseC"/>
349         <xsl:if test="$olink.debug != 0">
350           <xsl:message>
351             <xsl:text>Olink debug: CaseC key is the final selection: </xsl:text>
352             <xsl:value-of select="$CaseC"/>
353           </xsl:message>
354         </xsl:if>
355       </xsl:when>
356       <xsl:when test="$CaseD != ''">
357         <xsl:value-of select="$CaseD"/>
358         <xsl:if test="$olink.debug != 0">
359           <xsl:message>
360             <xsl:text>Olink debug: CaseD key is the final selection: </xsl:text>
361             <xsl:value-of select="$CaseD"/>
362           </xsl:message>
363         </xsl:if>
364       </xsl:when>
365       <xsl:when test="$CaseF != ''">
366         <xsl:value-of select="$CaseF"/>
367         <xsl:if test="$olink.debug != 0">
368           <xsl:message>
369             <xsl:text>Olink debug: CaseF key is the final selection: </xsl:text>
370             <xsl:value-of select="$CaseF"/>
371           </xsl:message>
372         </xsl:if>
373       </xsl:when>
374       <xsl:when test="$CaseE != ''">
375         <xsl:value-of select="$CaseE"/>
376         <xsl:if test="$olink.debug != 0">
377           <xsl:message>
378             <xsl:text>Olink debug: CaseE key is the final selection: </xsl:text>
379             <xsl:value-of select="$CaseE"/>
380           </xsl:message>
381         </xsl:if>
382       </xsl:when>
383       <xsl:otherwise>
384         <xsl:if test="$olink.debug != 0">
385           <xsl:message>
386             <xsl:text>Olink debug: No case matched for lang '</xsl:text>
387             <xsl:value-of select="$target.lang"/>
388             <xsl:text>'.</xsl:text>
389           </xsl:message>
390         </xsl:if>
391       </xsl:otherwise>
392     </xsl:choose>
393   </xsl:variable>
394
395   <xsl:choose>
396     <xsl:when test="$selected.key != ''">
397       <xsl:value-of select="$selected.key"/>
398     </xsl:when>
399     <xsl:when test="string-length($selected.key) = 0 and 
400                     string-length($target.lang) = 0">
401       <!-- No match on last try, and we are done -->
402     </xsl:when>
403     <xsl:otherwise>
404       <!-- Recurse through next language -->
405       <xsl:call-template name="select.olink.key.in.lang">
406         <xsl:with-param name="targetdoc.att" select="$targetdoc.att"/>
407         <xsl:with-param name="targetptr.att" select="$targetptr.att"/>
408         <xsl:with-param name="olink.lang" select="$olink.lang"/>
409         <xsl:with-param name="target.database" select="$target.database"/>
410         <xsl:with-param name="fallback.index" select="$fallback.index + 1"/>
411         <xsl:with-param name="olink.fallback.sequence"
412                         select="$olink.fallback.sequence"/>
413       </xsl:call-template>
414     </xsl:otherwise>
415   </xsl:choose>
416
417 </xsl:template>
418
419 <xsl:template name="select.target.lang">
420   <xsl:param name="fallback.index" select="1"/>
421   <xsl:param name="olink.fallback.sequence" select="''"/>
422
423   <!-- recurse backwards to find the lang matching the index -->
424   <xsl:variable name="firstlang" 
425                 select="substring-before($olink.fallback.sequence, ' ')"/>
426   <xsl:variable name="rest" 
427                 select="substring-after($olink.fallback.sequence, ' ')"/>
428   <xsl:choose>
429     <xsl:when test="$fallback.index = 1">
430       <xsl:value-of select="$firstlang"/>
431     </xsl:when>
432     <xsl:when test="$fallback.index &gt; 1">
433       <xsl:call-template name="select.target.lang">
434         <xsl:with-param name="fallback.index" select="$fallback.index - 1"/>
435         <xsl:with-param name="olink.fallback.sequence"
436                         select="$rest"/>
437       </xsl:call-template>
438     </xsl:when>
439     <xsl:otherwise>
440     </xsl:otherwise>
441   </xsl:choose>
442 </xsl:template>
443
444 <xsl:template name="select.olink.lang.fallback">
445   <xsl:param name="olink.lang" select="''"/>
446
447   <!-- Prefer language of the olink element -->
448   <xsl:value-of select="concat(normalize-space(concat($olink.lang, ' ', 
449                         $olink.lang.fallback.sequence)), ' ')"/>
450 </xsl:template>
451
452 <!-- Returns the complete olink href value if found -->
453 <xsl:template name="make.olink.href">
454   <xsl:param name="olink.key" select="''"/>
455   <xsl:param name="target.database"/>
456
457   <xsl:if test="$olink.key != ''">
458     <xsl:variable name="target.href" >
459       <xsl:for-each select="$target.database" >
460         <xsl:value-of select="key('targetptr-key', $olink.key)[1]/@href" />
461       </xsl:for-each>
462     </xsl:variable>
463   
464     <xsl:variable name="targetdoc">
465       <xsl:value-of select="substring-before($olink.key, '/')"/>
466     </xsl:variable>
467   
468     <!-- Does the target database use a sitemap? -->
469     <xsl:variable name="use.sitemap">
470       <xsl:choose>
471         <xsl:when test="$target.database//sitemap">1</xsl:when>
472         <xsl:otherwise>0</xsl:otherwise>
473       </xsl:choose>
474     </xsl:variable>
475   
476   
477     <!-- Get the baseuri for this targetptr -->
478     <xsl:variable name="baseuri" >
479       <xsl:choose>
480         <!-- Does the database use a sitemap? -->
481         <xsl:when test="$use.sitemap != 0" >
482           <xsl:choose>
483             <!-- Was current.docid parameter set? -->
484             <xsl:when test="$current.docid != ''">
485               <!-- Was it found in the database? -->
486               <xsl:variable name="currentdoc.key" >
487                 <xsl:for-each select="$target.database" >
488                   <xsl:value-of select="key('targetdoc-key',
489                                         $current.docid)[1]/@targetdoc" />
490                 </xsl:for-each>
491               </xsl:variable>
492               <xsl:choose>
493                 <xsl:when test="$currentdoc.key != ''">
494                   <xsl:for-each select="$target.database" >
495                     <xsl:call-template name="targetpath" >
496                       <xsl:with-param name="dirnode" 
497                           select="key('targetdoc-key', $current.docid)[1]/parent::dir"/>
498                       <xsl:with-param name="targetdoc" select="$targetdoc"/>
499                     </xsl:call-template>
500                   </xsl:for-each >
501                 </xsl:when>
502                 <xsl:otherwise>
503                   <xsl:message>
504                     <xsl:text>Olink error: cannot compute relative </xsl:text>
505                     <xsl:text>sitemap path because $current.docid '</xsl:text>
506                     <xsl:value-of select="$current.docid"/>
507                     <xsl:text>' not found in target database.</xsl:text>
508                   </xsl:message>
509                 </xsl:otherwise>
510               </xsl:choose>
511             </xsl:when>
512             <xsl:otherwise>
513               <xsl:message>
514                 <xsl:text>Olink warning: cannot compute relative </xsl:text>
515                 <xsl:text>sitemap path without $current.docid parameter</xsl:text>
516               </xsl:message>
517             </xsl:otherwise>
518           </xsl:choose> 
519           <!-- In either case, add baseuri from its document entry-->
520           <xsl:variable name="docbaseuri">
521             <xsl:for-each select="$target.database" >
522               <xsl:value-of select="key('targetdoc-key', $targetdoc)[1]/@baseuri" />
523             </xsl:for-each>
524           </xsl:variable>
525           <xsl:if test="$docbaseuri != ''" >
526             <xsl:value-of select="$docbaseuri"/>
527           </xsl:if>
528         </xsl:when>
529         <!-- No database sitemap in use -->
530         <xsl:otherwise>
531           <!-- Just use any baseuri from its document entry -->
532           <xsl:variable name="docbaseuri">
533             <xsl:for-each select="$target.database" >
534               <xsl:value-of select="key('targetdoc-key', $targetdoc)[1]/@baseuri" />
535             </xsl:for-each>
536           </xsl:variable>
537           <xsl:if test="$docbaseuri != ''" >
538             <xsl:value-of select="$docbaseuri"/>
539           </xsl:if>
540         </xsl:otherwise>
541       </xsl:choose>
542     </xsl:variable>
543   
544     <!-- Form the href information -->
545     <xsl:if test="$baseuri != ''">
546       <xsl:value-of select="$baseuri"/>
547       <xsl:if test="substring($target.href,1,1) != '#'">
548         <!--xsl:text>/</xsl:text-->
549       </xsl:if>
550     </xsl:if>
551     <!-- optionally turn off frag for PDF references -->
552     <xsl:if test="not($insert.olink.pdf.frag = 0 and
553           translate(substring($baseuri, string-length($baseuri) - 3),
554                     'PDF', 'pdf') = '.pdf'
555           and starts-with($target.href, '#') )">
556       <xsl:value-of select="$target.href"/>
557     </xsl:if>
558   </xsl:if>
559 </xsl:template>
560
561 <!-- Computes the href of the object containing the olink element -->
562 <xsl:template name="olink.from.uri">
563   <xsl:param name="target.database"/>
564   <xsl:param name="object" select="NotAnElement"/>
565   <xsl:param name="object.targetdoc" select="$current.docid"/>
566   <xsl:param name="object.lang" 
567            select="concat($object/ancestor::*[last()]/@lang,
568                           $object/ancestor::*[last()]/@xml:lang)"/>
569
570   <xsl:variable name="parent.id">
571     <xsl:call-template name="object.id">
572       <xsl:with-param name="object" select="$object"/>
573     </xsl:call-template>
574   </xsl:variable>
575
576   <!-- Get the olink key for the parent of olink element -->
577   <xsl:variable name="from.key">
578     <xsl:call-template name="select.olink.key">
579       <xsl:with-param name="targetdoc.att" select="$object.targetdoc"/>
580       <xsl:with-param name="targetptr.att" select="$parent.id"/>
581       <xsl:with-param name="olink.lang" select="$object.lang"/>
582       <xsl:with-param name="target.database" select="$target.database"/>
583     </xsl:call-template>
584   </xsl:variable>
585
586   <xsl:variable name="from.olink.href">
587     <xsl:for-each select="$target.database" >
588       <xsl:value-of select="key('targetptr-key', $from.key)[1]/@href" />
589     </xsl:for-each>
590   </xsl:variable>
591
592   <xsl:choose>
593     <!-- we found the olink object -->
594     <xsl:when test="$from.olink.href != ''">
595       <xsl:value-of select="$from.olink.href"/>
596     </xsl:when>
597     <xsl:when test="not($object/parent::*)">
598       <xsl:value-of select="$from.olink.href"/>
599     </xsl:when>
600     <xsl:otherwise>
601       <!-- recurse upward in current document -->
602       <xsl:call-template name="olink.from.uri">
603         <xsl:with-param name="target.database" select="$target.database"/>
604         <xsl:with-param name="object" select="$object/parent::*"/>
605         <xsl:with-param name="object.targetdoc" select="$object.targetdoc"/>
606         <xsl:with-param name="object.lang" select="$object.lang"/>
607       </xsl:call-template>
608     </xsl:otherwise>
609   </xsl:choose>
610
611 </xsl:template>
612
613 <xsl:template name="olink.hottext">
614   <xsl:param name="target.database"/>
615   <xsl:param name="olink.lang" select="''"/>
616   <xsl:param name="olink.key" select="''"/>
617   <xsl:param name="referrer" select="."/>
618   <xsl:param name="xrefstyle">
619     <xsl:choose>
620       <xsl:when test="@role and not(@xrefstyle) 
621                       and $use.role.as.xrefstyle != 0">
622         <xsl:value-of select="@role"/>
623       </xsl:when>
624       <xsl:otherwise>
625         <xsl:value-of select="@xrefstyle"/>
626       </xsl:otherwise>
627     </xsl:choose>
628   </xsl:param>
629
630   <xsl:choose>
631     <!-- If it has elements or text (not just PI or comment) -->
632     <xsl:when test="child::text() or child::*">
633       <xsl:apply-templates/>
634     </xsl:when>
635     <xsl:when test="$olink.key != ''">
636       <!-- Get the xref text for this record -->
637       <xsl:variable name="xref.text" >
638         <xsl:for-each select="$target.database" >
639           <xsl:call-template name="insert.targetdb.data">
640             <xsl:with-param name="data"
641                   select="key('targetptr-key', $olink.key)[1]/xreftext/node()" />
642           </xsl:call-template>
643         </xsl:for-each>
644       </xsl:variable>
645
646       <xsl:variable name="xref.number" >
647         <xsl:for-each select="$target.database" >
648           <xsl:value-of select="key('targetptr-key', $olink.key)[1]/@number" />
649         </xsl:for-each>
650       </xsl:variable>
651
652       <xsl:variable name="target.elem" >
653         <xsl:for-each select="$target.database" >
654           <xsl:value-of select="key('targetptr-key', $olink.key)[1]/@element" />
655         </xsl:for-each>
656       </xsl:variable>
657
658       <xsl:variable name="lang">
659         <xsl:variable name="candidate">
660           <xsl:for-each select="$target.database" >
661             <xsl:value-of 
662                       select="key('targetptr-key', $olink.key)[1]/@lang" />
663           </xsl:for-each>
664         </xsl:variable>
665         <xsl:choose>
666           <xsl:when test="$candidate != ''">
667             <xsl:value-of select="$candidate"/>
668           </xsl:when>
669           <xsl:otherwise>
670             <xsl:value-of select="$olink.lang"/>
671           </xsl:otherwise>
672         </xsl:choose>
673       </xsl:variable>
674
675       <xsl:variable name="targetdoc">
676         <xsl:value-of select="substring-before($olink.key, '/')"/>
677       </xsl:variable>
678
679       <xsl:choose>
680         <xsl:when test="$xrefstyle != '' and
681                         starts-with(normalize-space($xrefstyle), 'select:') and
682                         (contains($xrefstyle, 'nodocname') or
683                         contains($xrefstyle, 'nopage')) and
684                         not(contains($xrefstyle, 'title')) and
685                         not(contains($xrefstyle, 'label'))"> 
686           <xsl:copy-of select="$xref.text"/>
687         </xsl:when>
688         <xsl:when test="$xrefstyle != ''">
689           <xsl:if test="$olink.debug != 0">
690             <xsl:message>
691               <xsl:text>xrefstyle is '</xsl:text>
692               <xsl:value-of select="$xrefstyle"/>
693               <xsl:text>'.</xsl:text>
694             </xsl:message>
695           </xsl:if>
696           <xsl:variable name="template">
697             <xsl:choose>
698               <xsl:when test="starts-with(normalize-space($xrefstyle),
699                                           'select:')">
700                 <xsl:call-template name="make.gentext.template">
701                   <xsl:with-param name="xrefstyle" select="$xrefstyle"/>
702                   <xsl:with-param name="purpose" select="'olink'"/>
703                   <xsl:with-param name="referrer" select="."/>
704                   <xsl:with-param name="target.elem" select="$target.elem"/>
705                 </xsl:call-template>
706               </xsl:when>
707               <xsl:when test="starts-with(normalize-space($xrefstyle),
708                                           'template:')">
709                 <xsl:value-of select="substring-after(
710                                  normalize-space($xrefstyle), 'template:')"/>
711               </xsl:when>
712               <xsl:otherwise>
713                 <!-- Look for Gentext template with @style attribute -->
714                 <!-- Must compare to no style value because gentext.template
715                      falls back to no style -->
716
717                 <xsl:variable name="xref-context">
718                   <xsl:call-template name="gentext.template">
719                     <xsl:with-param name="context" select="'xref'"/>
720                     <xsl:with-param name="name" select="$target.elem"/>
721                     <xsl:with-param name="lang" select="$lang"/>
722                   </xsl:call-template>
723                 </xsl:variable>
724
725                 <xsl:variable name="styled-xref-context">
726                   <xsl:call-template name="gentext.template">
727                     <xsl:with-param name="context" select="'xref'"/>
728                     <xsl:with-param name="name" select="$target.elem"/>
729                     <xsl:with-param name="lang" select="$lang"/>
730                     <xsl:with-param name="xrefstyle" select="$xrefstyle"/>
731                   </xsl:call-template>
732                 </xsl:variable>
733
734                 <xsl:variable name="xref-number-context">
735                   <xsl:call-template name="gentext.template">
736                     <xsl:with-param name="context" select="'xref-number'"/>
737                     <xsl:with-param name="name" select="$target.elem"/>
738                     <xsl:with-param name="lang" select="$lang"/>
739                   </xsl:call-template>
740                 </xsl:variable>
741
742                 <xsl:variable name="styled-xref-number-context">
743                   <xsl:call-template name="gentext.template">
744                     <xsl:with-param name="context" select="'xref-number'"/>
745                     <xsl:with-param name="name" select="$target.elem"/>
746                     <xsl:with-param name="lang" select="$lang"/>
747                     <xsl:with-param name="xrefstyle" select="$xrefstyle"/>
748                   </xsl:call-template>
749                 </xsl:variable>
750
751                 <xsl:variable name="xref-number-and-title-context">
752                   <xsl:call-template name="gentext.template">
753                     <xsl:with-param name="context" 
754                                     select="'xref-number-and-title'"/>
755                     <xsl:with-param name="name" select="$target.elem"/>
756                     <xsl:with-param name="lang" select="$lang"/>
757                   </xsl:call-template>
758                 </xsl:variable>
759
760                 <xsl:variable name="styled-xref-number-and-title-context">
761                   <xsl:call-template name="gentext.template">
762                     <xsl:with-param name="context" 
763                                     select="'xref-number-and-title'"/>
764                     <xsl:with-param name="name" select="$target.elem"/>
765                     <xsl:with-param name="lang" select="$lang"/>
766                     <xsl:with-param name="xrefstyle" select="$xrefstyle"/>
767                   </xsl:call-template>
768                 </xsl:variable>
769
770                 <xsl:choose>
771                   <xsl:when test="$xref-number-and-title-context != 
772                                  $styled-xref-number-and-title-context and
773                                  $xref.number != '' and
774                                  $xref.with.number.and.title != 0">
775                     <xsl:value-of 
776                             select="$styled-xref-number-and-title-context"/>
777                   </xsl:when>
778                   <xsl:when test="$xref-number-context != 
779                                  $styled-xref-number-context and
780                                  $xref.number != ''">
781                     <xsl:value-of select="$styled-xref-number-context"/>
782                   </xsl:when>
783                   <xsl:when test="$xref-context != $styled-xref-context">
784                     <xsl:value-of select="$styled-xref-context"/>
785                   </xsl:when>
786                   <xsl:when test="$xref-number-and-title-context != '' and
787                                  $xref.number != '' and
788                                  $xref.with.number.and.title != 0">
789                     <xsl:value-of 
790                             select="$xref-number-and-title-context"/>
791                     <xsl:if test="$olink.debug">
792                       <xsl:message>
793                         <xsl:text>Olink error: no gentext template</xsl:text>
794                         <xsl:text> exists for xrefstyle '</xsl:text>
795                         <xsl:value-of select="$xrefstyle"/>
796                         <xsl:text>' for element '</xsl:text>
797                         <xsl:value-of select="$target.elem"/>
798                         <xsl:text>' in language '</xsl:text>
799                         <xsl:value-of select="$lang"/>
800                         <xsl:text>' in context 'xref-number-and-title</xsl:text>
801                         <xsl:text>'. Using template without @style.</xsl:text>
802                       </xsl:message>
803                     </xsl:if>
804                   </xsl:when>
805                   <xsl:when test="$xref-number-context != '' and
806                                  $xref.number != ''">
807                     <xsl:value-of select="$xref-number-context"/>
808                     <xsl:if test="$olink.debug">
809                       <xsl:message>
810                         <xsl:text>Olink error: no gentext template</xsl:text>
811                         <xsl:text> exists for xrefstyle '</xsl:text>
812                         <xsl:value-of select="$xrefstyle"/>
813                         <xsl:text>' for element '</xsl:text>
814                         <xsl:value-of select="$target.elem"/>
815                         <xsl:text>' in language '</xsl:text>
816                         <xsl:value-of select="$lang"/>
817                         <xsl:text>' in context 'xref-number</xsl:text>
818                         <xsl:text>'. Using template without @style.</xsl:text>
819                       </xsl:message>
820                     </xsl:if>
821                   </xsl:when>
822                   <xsl:when test="$xref-context != ''">
823                     <xsl:value-of select="$xref-context"/>
824                     <xsl:if test="$olink.debug">
825                       <xsl:message>
826                         <xsl:text>Olink error: no gentext template</xsl:text>
827                         <xsl:text> exists for xrefstyle '</xsl:text>
828                         <xsl:value-of select="$xrefstyle"/>
829                         <xsl:text>' for element '</xsl:text>
830                         <xsl:value-of select="$target.elem"/>
831                         <xsl:text>' in language '</xsl:text>
832                         <xsl:value-of select="$lang"/>
833                         <xsl:text>' in context 'xref</xsl:text>
834                         <xsl:text>'. Using template without @style.</xsl:text>
835                       </xsl:message>
836                     </xsl:if>
837                   </xsl:when>
838                   <xsl:otherwise>
839                     <xsl:message>
840                       <xsl:text>Olink error: no gentext template</xsl:text>
841                       <xsl:text> exists for xrefstyle '</xsl:text>
842                       <xsl:value-of select="$xrefstyle"/>
843                       <xsl:text>' for element '</xsl:text>
844                       <xsl:value-of select="$target.elem"/>
845                       <xsl:text>' in language '</xsl:text>
846                       <xsl:value-of select="$lang"/>
847                       <xsl:text>'. Trying '%t'.</xsl:text>
848                     </xsl:message>
849                     <xsl:value-of select="'%t'"/>
850                   </xsl:otherwise>
851                 </xsl:choose>
852               </xsl:otherwise>
853             </xsl:choose>
854           </xsl:variable>
855
856           <xsl:if test="$olink.debug != 0">
857             <xsl:message>
858               <xsl:text>Olink debug: xrefstyle template is '</xsl:text>
859               <xsl:value-of select="$template"/>
860               <xsl:text>'.</xsl:text>
861             </xsl:message>
862           </xsl:if>
863
864           <xsl:call-template name="substitute-markup">
865             <xsl:with-param name="template" select="$template"/>
866             <xsl:with-param name="title">
867               <xsl:for-each select="$target.database" >
868                 <xsl:call-template name="insert.targetdb.data">
869                   <xsl:with-param name="data"
870                                   select="key('targetptr-key', $olink.key)/ttl/node()"/>
871                 </xsl:call-template>
872               </xsl:for-each>
873             </xsl:with-param>
874             <xsl:with-param name="label">
875               <xsl:for-each select="$target.database" >
876                 <xsl:value-of 
877                         select="key('targetptr-key', $olink.key)[1]/@number" />
878               </xsl:for-each>
879             </xsl:with-param>
880             <xsl:with-param name="pagenumber">
881               <xsl:for-each select="$target.database" >
882                 <xsl:value-of 
883                         select="key('targetptr-key', $olink.key)[1]/@page" />
884               </xsl:for-each>
885             </xsl:with-param>
886             <xsl:with-param name="docname">
887               <xsl:for-each select="$target.database" >
888                 <xsl:call-template name="insert.targetdb.data">
889                   <xsl:with-param name="data"
890                        select="key('targetdoc-key', $targetdoc)[1]/div[1]/ttl/node()" />
891                 </xsl:call-template>
892               </xsl:for-each>
893             </xsl:with-param>
894           </xsl:call-template>
895         </xsl:when>
896
897         <xsl:when test="$use.local.olink.style != 0">
898
899           <!-- Is autonumbering on? -->
900           <xsl:variable name="target.number">
901             <xsl:for-each select="$target.database" >
902               <xsl:value-of 
903                       select="key('targetptr-key', $olink.key)[1]/@number" />
904             </xsl:for-each>
905           </xsl:variable>
906
907           <xsl:variable name="autonumber">
908             <xsl:choose>
909               <xsl:when test="$target.number != ''">1</xsl:when>
910               <xsl:otherwise>0</xsl:otherwise>
911             </xsl:choose>
912           </xsl:variable>
913         
914           <xsl:variable name="number-and-title-template">
915             <xsl:call-template name="gentext.template.exists">
916               <xsl:with-param name="context" select="'xref-number-and-title'"/>
917               <xsl:with-param name="name" select="$target.elem"/>
918             </xsl:call-template>
919           </xsl:variable>
920         
921           <xsl:variable name="number-template">
922             <xsl:call-template name="gentext.template.exists">
923               <xsl:with-param name="context" select="'xref-number'"/>
924               <xsl:with-param name="name" select="$target.elem"/>
925             </xsl:call-template>
926           </xsl:variable>
927         
928           <xsl:variable name="context">
929             <xsl:choose>
930               <xsl:when test="string($autonumber) != 0 
931                               and $number-and-title-template != 0
932                               and $xref.with.number.and.title != 0">
933                  <xsl:value-of select="'xref-number-and-title'"/>
934               </xsl:when>
935               <xsl:when test="string($autonumber) != 0 
936                               and $number-template != 0">
937                  <xsl:value-of select="'xref-number'"/>
938               </xsl:when>
939               <xsl:otherwise>
940                  <xsl:value-of select="'xref'"/>
941               </xsl:otherwise>
942             </xsl:choose>
943           </xsl:variable>
944         
945           <xsl:variable name="template">
946             <xsl:call-template name="gentext.template">
947               <xsl:with-param name="context" select="$context"/>
948               <xsl:with-param name="name" select="$target.elem"/>
949               <xsl:with-param name="lang" select="$lang"/>
950             </xsl:call-template>
951           </xsl:variable>
952
953           <xsl:call-template name="substitute-markup">
954             <xsl:with-param name="template" select="$template"/>
955             <xsl:with-param name="title">
956               <xsl:for-each select="$target.database" >
957                 <xsl:call-template name="insert.targetdb.data">
958                   <xsl:with-param name="data"
959                                select="key('targetptr-key', $olink.key)[1]/ttl/node()" />
960                 </xsl:call-template>
961               </xsl:for-each>
962             </xsl:with-param>
963             <xsl:with-param name="label">
964               <xsl:for-each select="$target.database" >
965                 <xsl:call-template name="insert.targetdb.data">
966                   <xsl:with-param name="data"
967                           select="key('targetptr-key', $olink.key)[1]/@number" />
968                 </xsl:call-template>
969               </xsl:for-each>
970             </xsl:with-param>
971           </xsl:call-template>
972         </xsl:when>
973         <xsl:when test="$xref.text !=''">
974           <xsl:copy-of select="$xref.text"/>
975         </xsl:when>
976         <xsl:otherwise>
977           <xsl:message>
978             <xsl:text>Olink error: no generated text for </xsl:text>
979             <xsl:text>targetdoc/targetptr/lang = '</xsl:text>
980             <xsl:value-of select="$olink.key"/>
981             <xsl:text>'.</xsl:text>
982           </xsl:message>
983           <xsl:text>????</xsl:text>
984         </xsl:otherwise>
985       </xsl:choose>
986     </xsl:when>
987     <xsl:when test="@targetdoc != '' or @targetptr != ''">
988       <xsl:if test="$olink.key != ''">
989         <xsl:message>
990           <xsl:text>Olink error: no generated text for </xsl:text>
991           <xsl:text>targetdoc/targetptr/lang = '</xsl:text>
992           <xsl:value-of select="$olink.key"/>
993           <xsl:text>'.</xsl:text>
994         </xsl:message>
995       </xsl:if>
996       <xsl:text>????</xsl:text>
997     </xsl:when>
998     <xsl:otherwise>
999       <!-- old style olink -->
1000       <xsl:call-template name="olink.outline">
1001         <xsl:with-param name="outline.base.uri"
1002                         select="unparsed-entity-uri(@targetdocent)"/>
1003         <xsl:with-param name="localinfo" select="@localinfo"/>
1004         <xsl:with-param name="return" select="'xreftext'"/>
1005       </xsl:call-template>
1006     </xsl:otherwise>
1007   </xsl:choose>
1008 </xsl:template>
1009
1010 <xsl:template name="insert.targetdb.data">
1011   <xsl:param name="data"/>
1012   <!-- Customize this to massage data further -->
1013   <xsl:copy-of select="$data"/>
1014 </xsl:template>
1015
1016 <xsl:template match="*" mode="olink.docname.markup">
1017   <!-- No-op for now -->
1018 </xsl:template>
1019
1020 <xsl:template name="targetpath">
1021   <xsl:param name="dirnode" />
1022   <xsl:param name="targetdoc" select="''"/>
1023
1024 <!-- 
1025 <xsl:message>dirnode is <xsl:value-of select="$dirnode/@name"/></xsl:message>
1026 <xsl:message>targetdoc is <xsl:value-of select="$targetdoc"/></xsl:message>
1027 -->
1028   <!-- recursive template generates path to olink target directory -->
1029   <xsl:choose>
1030     <!-- Have we arrived at the final path step? -->
1031     <xsl:when test="$dirnode/child::document[@targetdoc = $targetdoc]">
1032       <!-- We are done -->
1033     </xsl:when>
1034     <!-- Have we reached the top without a match? -->
1035     <xsl:when test="local-name($dirnode) != 'dir'" >
1036         <xsl:message>Olink error: cannot locate targetdoc <xsl:value-of select="$targetdoc"/> in sitemap</xsl:message>
1037     </xsl:when>
1038     <!-- Is the target in a descendant? -->
1039     <xsl:when test="$dirnode/descendant::document/@targetdoc = $targetdoc">
1040       <xsl:variable name="step" select="$dirnode/child::dir[descendant::document/@targetdoc = $targetdoc]"/>
1041       <xsl:if test = "$step">
1042         <xsl:value-of select="$step/@name"/>
1043         <xsl:text>/</xsl:text>
1044       </xsl:if>
1045       <!-- Now recurse with the child -->
1046       <xsl:call-template name="targetpath" >
1047         <xsl:with-param name="dirnode" select="$step"/>
1048         <xsl:with-param name="targetdoc" select="$targetdoc"/>
1049       </xsl:call-template>
1050     </xsl:when>
1051     <!-- Otherwise we need to move up a step -->
1052     <xsl:otherwise>
1053       <xsl:if test="$dirnode/parent::dir">
1054         <xsl:text>../</xsl:text>
1055       </xsl:if>
1056       <xsl:call-template name="targetpath" >
1057         <xsl:with-param name="dirnode" select="$dirnode/parent::*"/>
1058         <xsl:with-param name="targetdoc" select="$targetdoc"/>
1059       </xsl:call-template>
1060     </xsl:otherwise>
1061   </xsl:choose>
1062 </xsl:template>
1063
1064 <xsl:template name="olink.page.citation">
1065   <xsl:param name="olink.key" select="''"/>
1066   <xsl:param name="olink.lang" select="'en'"/>
1067   <xsl:param name="target.database"/>
1068   <xsl:param name="linkend" select="''"/>
1069   <xsl:param name="xrefstyle">
1070     <xsl:choose>
1071       <xsl:when test="@role and not(@xrefstyle) 
1072                       and $use.role.as.xrefstyle != 0">
1073         <xsl:value-of select="@role"/>
1074       </xsl:when>
1075       <xsl:otherwise>
1076         <xsl:value-of select="@xrefstyle"/>
1077       </xsl:otherwise>
1078     </xsl:choose>
1079   </xsl:param>
1080
1081   <xsl:variable name="targetdoc">
1082     <xsl:value-of select="substring-before($olink.key, '/')"/>
1083   </xsl:variable>
1084
1085   <xsl:choose>
1086     <xsl:when test="$linkend != ''">
1087       <xsl:call-template name="xref.page.citation">
1088         <xsl:with-param name="linkend" select="$linkend"/>
1089         <xsl:with-param name="target" select="key('id', $linkend)"/>
1090         <xsl:with-param name="xrefstyle" select="$xrefstyle"/>
1091       </xsl:call-template>
1092     </xsl:when>
1093     <xsl:when test="not(starts-with(normalize-space($xrefstyle),
1094                         'select:') 
1095                 and (contains($xrefstyle, 'page')
1096                      or contains($xrefstyle, 'Page')))
1097                 and $current.docid != '' 
1098                 and $current.docid != $targetdoc
1099                 and $insert.olink.page.number = 'yes' ">
1100   
1101       <xsl:variable name="page-number">
1102         <xsl:for-each select="$target.database" >
1103           <xsl:value-of 
1104                  select="key('targetptr-key', $olink.key)[1]/@page" />
1105         </xsl:for-each>
1106       </xsl:variable>
1107   
1108       <xsl:if test="$page-number != ''">
1109         <xsl:call-template name="substitute-markup">
1110           <xsl:with-param name="template">
1111             <xsl:call-template name="gentext.template">
1112               <xsl:with-param name="name" select="'olink.page.citation'"/>
1113               <xsl:with-param name="context" select="'xref'"/>
1114               <xsl:with-param name="lang" select="$olink.lang"/>
1115             </xsl:call-template>
1116           </xsl:with-param>
1117           <xsl:with-param name="pagenumber" select="$page-number"/>
1118         </xsl:call-template>
1119       </xsl:if>
1120   
1121     </xsl:when>
1122   </xsl:choose>
1123 </xsl:template>
1124
1125 <xsl:template name="olink.document.citation">
1126   <xsl:param name="olink.key" select="''"/>
1127   <xsl:param name="olink.lang" select="'en'"/>
1128   <xsl:param name="target.database"/>
1129   <xsl:param name="xrefstyle">
1130     <xsl:choose>
1131       <xsl:when test="@role and not(@xrefstyle) 
1132                       and $use.role.as.xrefstyle != 0">
1133         <xsl:value-of select="@role"/>
1134       </xsl:when>
1135       <xsl:otherwise>
1136         <xsl:value-of select="@xrefstyle"/>
1137       </xsl:otherwise>
1138     </xsl:choose>
1139   </xsl:param>
1140
1141   <xsl:variable name="page">
1142     <xsl:for-each select="$target.database" >
1143       <xsl:value-of 
1144              select="key('targetptr-key', $olink.key)[1]/@page" />
1145     </xsl:for-each>
1146   </xsl:variable>
1147
1148   <xsl:variable name="targetdoc">
1149     <xsl:value-of select="substring-before($olink.key, '/')"/>
1150   </xsl:variable>
1151
1152   <xsl:variable name="targetptr">
1153     <xsl:value-of 
1154           select="substring-before(substring-after($olink.key, '/'), '/')"/>
1155   </xsl:variable>
1156
1157   <!-- Don't add docname if pointing to root element -->
1158   <xsl:variable name="rootptr">
1159     <xsl:for-each select="$target.database" >
1160       <xsl:value-of 
1161              select="key('targetdoc-key', $targetdoc)[1]/div[1]/@targetptr" />
1162     </xsl:for-each>
1163   </xsl:variable>
1164
1165   <xsl:variable name="docname">
1166     <xsl:for-each select="$target.database" >
1167       <xsl:call-template name="insert.targetdb.data">
1168         <xsl:with-param name="data"
1169              select="key('targetdoc-key', $targetdoc)[1]/div[1]/ttl/node()" />
1170       </xsl:call-template>
1171     </xsl:for-each>
1172   </xsl:variable>
1173
1174   <xsl:if test="not(starts-with(normalize-space($xrefstyle), 'select:') 
1175               and (contains($xrefstyle, 'docname')))
1176               and ($olink.doctitle = 'yes' or $olink.doctitle = '1')
1177               and $current.docid != '' 
1178               and $rootptr != $targetptr
1179               and $current.docid != $targetdoc
1180               and $docname != ''">
1181     <xsl:call-template name="substitute-markup">
1182       <xsl:with-param name="template">
1183         <xsl:call-template name="gentext.template">
1184           <xsl:with-param name="name" select="'olink.document.citation'"/>
1185           <xsl:with-param name="context" select="'xref'"/>
1186           <xsl:with-param name="lang" select="$olink.lang"/>
1187         </xsl:call-template>
1188       </xsl:with-param>
1189       <xsl:with-param name="docname" select="$docname"/>
1190       <xsl:with-param name="pagenumber" select="$page"/>
1191     </xsl:call-template>
1192   </xsl:if>
1193 </xsl:template>
1194
1195 <xsl:template name="xref.page.citation">
1196   <!-- Determine if this xref should have a page citation.
1197        Context node is the xref or local olink element -->
1198   <xsl:param name="linkend" select="@linkend"/>
1199   <xsl:param name="target" select="key('id', $linkend)"/>
1200   <xsl:param name="xrefstyle">
1201     <xsl:choose>
1202       <xsl:when test="@role and not(@xrefstyle) 
1203                       and $use.role.as.xrefstyle != 0">
1204         <xsl:value-of select="@role"/>
1205       </xsl:when>
1206       <xsl:otherwise>
1207         <xsl:value-of select="@xrefstyle"/>
1208       </xsl:otherwise>
1209     </xsl:choose>
1210   </xsl:param>
1211
1212   <xsl:if test="not(starts-with(normalize-space($xrefstyle),'select:')
1213                     and (contains($xrefstyle, 'page')
1214                          or contains($xrefstyle, 'Page')))
1215                 and ( $insert.xref.page.number = 'yes' 
1216                    or $insert.xref.page.number = '1')
1217                 or local-name($target) = 'para'">
1218     <xsl:apply-templates select="$target" mode="page.citation">
1219       <xsl:with-param name="id" select="$linkend"/>
1220     </xsl:apply-templates>
1221   </xsl:if>
1222 </xsl:template>
1223
1224 </xsl:stylesheet>
1225