]> git.stg.codes - stg.git/blob - doc/xslt/manpages/info.xsl
Added local binding.
[stg.git] / doc / xslt / manpages / info.xsl
1 <?xml version='1.0'?>
2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3                 xmlns:date="http://exslt.org/dates-and-times"
4                 xmlns:exsl="http://exslt.org/common"
5                 exclude-result-prefixes="date exsl"
6                 version='1.0'>
7
8 <!-- ********************************************************************
9      $Id: info.xsl 7883 2008-03-08 17:59:39Z xmldoc $
10      ********************************************************************
11
12      This file is part of the XSL DocBook Stylesheet distribution.
13      See ../README or http://docbook.sf.net/release/xsl/current/ for
14      copyright and other information.
15
16      ******************************************************************** -->
17
18   <xsl:variable name="blurb-indent">
19     <xsl:choose>
20       <xsl:when test="not($man.indent.blurbs = 0)">
21         <xsl:value-of select="$man.indent.width"/>
22       </xsl:when>
23       <xsl:when test="not($man.indent.refsect = 0)">
24         <!-- * "zq" is the name of a register we set for -->
25         <!-- * preserving the original default indent value -->
26         <!-- * when $man.indent.refsect is non-zero; -->
27         <!-- * "u" is a roff unit specifier -->
28         <xsl:text>\n(zqu</xsl:text>
29       </xsl:when>
30       <xsl:otherwise/> <!-- * otherwise, just leave it empty -->
31     </xsl:choose>
32   </xsl:variable>
33
34   <!-- ================================================================== -->
35   <!-- * About the $info param used in this stylesheet -->
36   <!-- * -->
37   <!-- * The $info param is a "master info" node set that contains -->
38   <!-- * the entire contents of the *info child of the current -->
39   <!-- * Refentry, plus the entire contents of the *info children of -->
40   <!-- * all ancestors of the current Refentry, in document order. -->
41   <!-- * -->
42   <!-- * We try to find a "best match" for selecting content from -->
43   <!-- * $infor; we look through it in reverse document order until we -->
44   <!-- * can find something usable. -->
45   <!-- * -->
46   <!-- * Specifically what the basic metadata-gathering XPath expression -->
47   <!-- * in this stylesheet does is: -->
48   <!-- * -->
49   <!-- *   1. Look through the entire "master info" node set.-->
50   <!-- *   2. Get the last node in the set that contains, for -->
51   <!-- *      example, an Author element. That amounts to being the -->
52   <!-- *      closest *info node to the Refentry - either its *info -->
53   <!-- *      child, or the *info node of its closest ancestor that -->
54   <!-- *      contains an Author. -->
55
56   <!-- ================================================================== -->
57   <!-- * Get user "refentry metadata" preferences -->
58   <!-- ================================================================== -->
59   <!-- * The DocBook XSL stylesheets include several user-configurable -->
60   <!-- * global stylesheet parameters for controlling refentry metadata -->
61   <!-- * gathering. Those parameters are not read directly by the other -->
62   <!-- * refentry metadata-gathering templates. Instead, they are read -->
63   <!-- * only by the get.refentry.metadata.prefs template, which -->
64   <!-- * assembles them into a structure that is then passed to the -->
65   <!-- * other refentry metadata-gathering template. -->
66
67   <xsl:variable name="get.refentry.metadata.prefs">
68     <!-- * get.refentry.metadata.prefs is in common/refentry.xsl -->
69     <xsl:call-template name="get.refentry.metadata.prefs"/>
70   </xsl:variable>
71
72   <xsl:variable name="refentry.metadata.prefs"
73                 select="exsl:node-set($get.refentry.metadata.prefs)"/>
74   
75   <!-- * ============================================================== -->
76   <!-- *    Get content for Author metadata field. -->
77   <!-- * ============================================================== -->
78
79   <!-- * The make.roff.metatada.author template and metadata.author -->
80   <!-- * mode are used only for populating the Author field in the -->
81   <!-- * metadata "top comment" we embed in roff source of each page. -->
82   <xsl:template name="make.roff.metadata.author">
83     <xsl:param name="info"/>
84     <xsl:param name="refname"/>
85     <xsl:choose>
86       <xsl:when test="$info//author">
87         <xsl:apply-templates
88             select="(($info[//author])[last()]//author)[1]"
89             mode="metadata.author"/>
90       </xsl:when>
91       <xsl:when test="$info//corpauthor">
92         <xsl:apply-templates
93             select="(($info[//corpauthor])[last()]//corpauthor)[1]"
94             mode="metadata.author"/>
95       </xsl:when>
96       <xsl:when test="$info//editor">
97         <xsl:apply-templates
98             select="(($info[//editor])[last()]//editor)[1]"
99             mode="metadata.author"/>
100       </xsl:when>
101       <xsl:when test="$info//corpcredit">
102         <xsl:apply-templates
103             select="(($info[//corpcredit])[last()]//corpcredit)[1]"
104             mode="metadata.author"/>
105       </xsl:when>
106       <xsl:when test="$info//othercredit">
107         <xsl:apply-templates
108             select="(($info[//othercredit])[last()]//othercredit)[1]"
109             mode="metadata.author"/>
110       </xsl:when>
111       <xsl:when test="$info//collab">
112         <xsl:apply-templates
113             select="(($info[//collab])[last()]//collab)[1]"
114             mode="metadata.author"/>
115       </xsl:when>
116       <xsl:when test="$info//orgname">
117         <xsl:apply-templates
118             select="(($info[//orgname])[last()]//orgname)[1]"
119             mode="metadata.author"/>
120       </xsl:when>
121       <xsl:when test="$info//publishername">
122         <xsl:apply-templates
123             select="(($info[//publishername])[last()]//publishername)[1]"
124             mode="metadata.author"/>
125       </xsl:when>
126       <xsl:otherwise>
127         <!-- * otherwise, we need to check to see if we have an "Author" -->
128         <!-- * or "Authors" section in the refentry -->
129         <xsl:variable name="gentext.author">
130           <xsl:text>"</xsl:text>
131           <xsl:call-template name="gentext">
132             <xsl:with-param name="key" select="'Author'"/>
133           </xsl:call-template>
134           <xsl:text>"</xsl:text>
135         </xsl:variable>
136         <xsl:variable name="gentext.AUTHOR">
137           <xsl:if test="not($gentext.author = '')">
138             <xsl:call-template name="string.upper">
139               <xsl:with-param name="string" select="$gentext.author"/>
140             </xsl:call-template>
141           </xsl:if>
142         </xsl:variable>
143         <xsl:variable name="gentext.authors">
144           <xsl:text>"</xsl:text>
145           <xsl:call-template name="gentext">
146             <xsl:with-param name="key" select="'Authors'"/>
147           </xsl:call-template>
148           <xsl:text>"</xsl:text>
149         </xsl:variable>
150         <xsl:variable name="gentext.AUTHORS">
151           <xsl:if test="not($gentext.authors = '')">
152             <xsl:call-template name="string.upper">
153               <xsl:with-param name="string" select="$gentext.authors"/>
154             </xsl:call-template>
155           </xsl:if>
156         </xsl:variable>
157         <!-- * get all refentry/refsect1/title & refentry/refsection/title -->
158         <!-- * instances, delimit each with double quotes, and put them -->
159         <!-- * into a single refsect1.titles string -->
160         <xsl:variable name="refsect1.titles">
161           <xsl:for-each select="refsect1/title">
162             <xsl:text>"</xsl:text>
163             <xsl:value-of select="normalize-space(.)"/>
164             <xsl:text>"</xsl:text>
165             <xsl:text> </xsl:text>
166           </xsl:for-each>
167           <xsl:for-each select="refsection/title">
168             <xsl:text>"</xsl:text>
169             <xsl:value-of select="normalize-space(.)"/>
170             <xsl:text>"</xsl:text>
171             <xsl:text> </xsl:text>
172           </xsl:for-each>
173         </xsl:variable>
174         <xsl:variable name="author.section.title">
175           <xsl:choose>
176             <xsl:when test="not($gentext.authors = '') and
177               contains($refsect1.titles,$gentext.authors)">
178               <xsl:value-of select="$gentext.authors"/>
179             </xsl:when>
180             <xsl:when test="not($gentext.AUTHORS = '') and
181               contains($refsect1.titles,$gentext.AUTHORS)">
182               <xsl:value-of select="$gentext.AUTHORS"/>
183             </xsl:when>
184             <xsl:when test="not($gentext.author = '') and
185               contains($refsect1.titles,$gentext.author)">
186               <xsl:value-of select="$gentext.author"/>
187             </xsl:when>
188             <xsl:when test="not($gentext.AUTHOR = '') and
189               contains($refsect1.titles,$gentext.AUTHOR)">
190               <xsl:value-of select="$gentext.AUTHOR"/>
191             </xsl:when>
192             <!-- * git docs (for one) use "DOCUMENTATION" for their authors section -->
193             <xsl:when test="contains($refsect1.titles,'Documentation')">
194               <xsl:text>Documentation</xsl:text>
195             </xsl:when>
196             <xsl:when test="contains($refsect1.titles,'DOCUMENTATION')">
197               <xsl:text>DOCUMENTATION</xsl:text>
198             </xsl:when>
199             <xsl:otherwise/> <!-- * otherwise, leave empty -->
200           </xsl:choose>
201         </xsl:variable>
202         <xsl:choose>
203           <xsl:when test="not($author.section.title = '')">
204             <!-- * if we have a non-empty $author.section.title value, -->
205             <!-- * then reference that title (instead of putting a -->
206             <!-- * specific author name) -->
207             <xsl:text>[see the </xsl:text>
208             <xsl:value-of select="$author.section.title"/>
209             <xsl:text> section]</xsl:text>
210           </xsl:when>
211           <xsl:otherwise>
212             <!-- * otherwise we have no info/author content and no Author -->
213             <!-- * or Authors section, so we insert a fixme and report -->
214             <!-- * the problem to the user -->
215             <xsl:text>[FIXME: author] [see http://docbook.sf.net/el/author]</xsl:text>
216             <xsl:if test="$refentry.meta.get.quietly = 0">
217               <xsl:call-template name="log.message">
218                 <xsl:with-param name="level">Warn</xsl:with-param>
219                 <xsl:with-param name="source" select="$refname"/>
220                 <xsl:with-param name="context-desc">meta author</xsl:with-param>
221                 <xsl:with-param name="message">
222                   <xsl:text>no refentry/info/author</xsl:text>
223                 </xsl:with-param>
224               </xsl:call-template>
225               <xsl:call-template name="log.message">
226                 <xsl:with-param name="level">Note</xsl:with-param>
227                 <xsl:with-param name="source" select="$refname"/>
228                 <xsl:with-param name="context-desc">meta author</xsl:with-param>
229                 <xsl:with-param name="message">
230                   <xsl:text>see http://docbook.sf.net/el/author</xsl:text>
231                 </xsl:with-param>
232               </xsl:call-template>
233               <xsl:call-template name="log.message">
234                 <xsl:with-param name="level">Warn</xsl:with-param>
235                 <xsl:with-param name="source" select="$refname"/>
236                 <xsl:with-param name="context-desc">meta author</xsl:with-param>
237                 <xsl:with-param name="message">
238                   <xsl:text>no author data, so inserted a fixme</xsl:text>
239                 </xsl:with-param>
240               </xsl:call-template>
241             </xsl:if>
242           </xsl:otherwise>
243         </xsl:choose>
244       </xsl:otherwise>
245     </xsl:choose>
246   </xsl:template>
247
248   <xsl:template match="author|editor|othercredit|collab" mode="metadata.author">
249     <xsl:choose>
250       <xsl:when test="collabname">
251         <!-- * If this node is a Collab, then it should have a -->
252         <!-- * Collabname child, so get that. -->
253         <xsl:variable name="contents">
254           <xsl:apply-templates select="collabname"/>
255         </xsl:variable>
256         <xsl:value-of select="normalize-space($contents)"/>
257       </xsl:when>
258       <xsl:otherwise>
259         <!-- * Otherwise, this node is not a Collab, but instead -->
260         <!-- * an author|editor|othercredit, which must have a name -->
261         <!-- * of some kind; so get that name -->
262         <xsl:call-template name="person.name.normalized"/>
263       </xsl:otherwise>
264     </xsl:choose>
265     <xsl:if test=".//email|address/otheraddr/ulink">
266       <xsl:text> </xsl:text>
267       <!-- * For each attribution found, use only the first e-mail -->
268       <!-- * address or ulink value found -->
269       <xsl:apply-templates select="(.//email|address/otheraddr/ulink)[1]"
270                            mode="metadata.author"/>
271     </xsl:if>
272   </xsl:template>
273
274   <xsl:template match="email|address/otheraddr/ulink" mode="metadata.author">
275     <xsl:text>&lt;</xsl:text>
276     <xsl:choose>
277       <xsl:when test="self::email">
278         <xsl:variable name="contents">
279           <xsl:apply-templates/>
280         </xsl:variable>
281         <xsl:value-of select="normalize-space($contents)"/>
282       </xsl:when>
283       <xsl:when test="self::ulink">
284         <xsl:variable name="contents">
285           <xsl:apply-templates select="."/>
286         </xsl:variable>
287         <xsl:value-of select="normalize-space($contents)"/>
288       </xsl:when>
289     </xsl:choose>
290     <xsl:text>&gt;</xsl:text>
291   </xsl:template>
292
293   <xsl:template match="corpauthor|corpcredit|orgname|publishername" mode="metadata.author">
294     <xsl:variable name="contents">
295       <xsl:apply-templates/>
296     </xsl:variable>
297     <xsl:value-of select="normalize-space($contents)"/>
298   </xsl:template>
299
300   <!-- * ============================================================== -->
301   <!-- *     Assemble the AUTHOR/AUTHORS section -->
302   <!-- * ============================================================== -->
303
304   <xsl:template name="author.section">
305     <xsl:param name="info"/>
306     <!-- * The $info param is a "master info" node set that contains -->
307     <!-- * the entires contents of the *info child of the current -->
308     <!-- * Refentry, plus the entire contents of the *info children of -->
309     <!-- * all ancestors of the current Refentry, in document order. -->
310     <xsl:choose>
311       <xsl:when test="$info//author|$info//editor|$info//collab|
312                       $info//corpauthor|$info//corpcredit|
313                       $info//othercredit|$info/orgname|
314                       $info/publishername|$info/publisher">
315         <xsl:variable name="authorcount">
316           <xsl:value-of
317               select="count(
318                       $info//author|$info//editor|$info//collab|
319                       $info//corpauthor|$info//corpcredit|
320                       $info//othercredit)">
321           </xsl:value-of>
322         </xsl:variable>
323         <xsl:call-template name="make.subheading">
324           <xsl:with-param name="title">
325             <xsl:call-template name="make.authorsecttitle">
326               <xsl:with-param name="authorcount" select="$authorcount"/>
327             </xsl:call-template>
328           </xsl:with-param>
329         </xsl:call-template>
330         <!-- * Now output all the actual author, editor, etc. content -->
331         <xsl:for-each
332           select="$info//author|$info//editor|$info//collab|
333           $info//corpauthor|$info//corpcredit|
334           $info//othercredit|$info/orgname|
335           $info/publishername|$info/publisher">
336           <xsl:apply-templates select="." mode="authorsect"/>
337         </xsl:for-each>
338       </xsl:when>
339       <xsl:otherwise/> <!-- * do nothing, no author info found -->
340     </xsl:choose>
341   </xsl:template>
342
343   <xsl:template name="make.authorsecttitle">
344     <!-- * If we have exactly one attributable person/entity, then output -->
345     <!-- * localized gentext for 'Author'; otherwise, output 'Authors'. -->
346     <xsl:param name="authorcount"/>
347     <xsl:param name="authorsecttitle">
348       <xsl:choose>
349         <xsl:when test="$authorcount = 1">
350           <xsl:text>Author</xsl:text>
351         </xsl:when>
352         <xsl:otherwise>
353           <xsl:text>Authors</xsl:text>
354         </xsl:otherwise>
355       </xsl:choose>
356     </xsl:param>
357     <xsl:call-template name="gentext">
358       <xsl:with-param name="key" select="$authorsecttitle"/>
359     </xsl:call-template>
360   </xsl:template>
361
362   <xsl:template match="author|editor|othercredit" mode="authorsect">
363     <xsl:variable name="person-name">
364       <xsl:call-template name="person.name.normalized"/>
365     </xsl:variable>
366     <!-- * If we have a person-name or email or ulink content, then -->
367     <!-- * output name and email or ulink content on the same line -->
368     <xsl:choose>
369       <xsl:when test="not($person-name = '') or .//email or address/otheraddr/ulink">
370         <xsl:text>.PP&#10;</xsl:text>
371         <!-- * Display person name in bold -->
372         <xsl:call-template name="bold">
373           <xsl:with-param name="node" select="exsl:node-set($person-name)"/>
374           <xsl:with-param name="context" select="."/>
375         </xsl:call-template>
376         <!-- * Display e-mail address(es) and ulink(s) on same line as name -->
377         <xsl:apply-templates select=".//email|address/otheraddr/ulink" mode="authorsect"/>
378         <xsl:text>&#10;</xsl:text>
379       </xsl:when>
380       <xsl:otherwise>
381         <xsl:text>.br&#10;</xsl:text>
382       </xsl:otherwise>
383     </xsl:choose>
384     <!-- * Display affiliation(s) on separate lines -->
385     <xsl:apply-templates select="affiliation" mode="authorsect"/>
386     <!-- * Display direct-child addresses on separate lines -->
387     <xsl:apply-templates select="address" mode="authorsect"/>
388     <!-- * Call template for handling various attribution possibilities -->
389     <xsl:call-template name="attribution">
390       <xsl:with-param name="person-name" select="$person-name"/>
391     </xsl:call-template>
392   </xsl:template>
393
394   <xsl:template match="collab" mode="authorsect">
395     <xsl:text>.PP&#10;</xsl:text>
396     <xsl:call-template name="bold">
397       <xsl:with-param name="node" select="collabname"/>
398       <xsl:with-param name="context" select="."/>
399     </xsl:call-template>
400     <!-- * Display e-mail address(es) and ulink(s) on same line as name -->
401     <xsl:apply-templates select=".//email|address/otheraddr/ulink" mode="authorsect"/>
402     <xsl:text>&#10;</xsl:text>
403     <!-- * Display affilition(s) on separate lines -->
404     <xsl:apply-templates select="affiliation" mode="authorsect"/>
405   </xsl:template>
406
407   <xsl:template match="corpauthor|corpcredit|orgname|publishername" mode="authorsect">
408     <xsl:text>.PP&#10;</xsl:text>
409     <xsl:call-template name="bold">
410       <xsl:with-param name="node" select="."/>
411       <xsl:with-param name="context" select="."/>
412     </xsl:call-template>
413     <xsl:text>&#10;</xsl:text>
414     <xsl:if test="self::publishername">
415       <!-- * Display localized "Publisher" gentext -->
416       <xsl:call-template name="publisher.attribution"/>
417     </xsl:if>
418   </xsl:template>
419
420   <xsl:template match="publisher" mode="authorsect">
421     <xsl:text>.PP&#10;</xsl:text>
422     <xsl:call-template name="bold">
423       <xsl:with-param name="node" select="publishername"/>
424       <xsl:with-param name="context" select="."/>
425     </xsl:call-template>
426     <!-- * Display e-mail address(es) and ulink(s) on same line as name -->
427     <xsl:apply-templates select=".//email|address/otheraddr/ulink" mode="authorsect"/>
428     <!-- * Display addresses on separate lines -->
429     <xsl:apply-templates select="address" mode="authorsect"/>
430     <!-- * Display localized "Publisher" literal -->
431     <xsl:call-template name="publisher.attribution"/>
432   </xsl:template>
433
434   <xsl:template name="publisher.attribution">
435     <xsl:text>&#10;</xsl:text>
436     <xsl:text>.RS</xsl:text> 
437     <xsl:if test="not($blurb-indent = '')">
438       <xsl:text> </xsl:text>
439       <xsl:value-of select="$blurb-indent"/>
440     </xsl:if>
441     <xsl:text>&#10;</xsl:text>
442     <xsl:call-template name="gentext">
443       <xsl:with-param name="key" select="'Publisher'"/>
444     </xsl:call-template>
445     <xsl:text>.&#10;</xsl:text>
446     <xsl:text>.RE&#10;</xsl:text> 
447   </xsl:template>
448
449   <xsl:template match="email|address/otheraddr/ulink" mode="authorsect">
450     <xsl:choose>
451       <xsl:when test="preceding-sibling::*[descendant-or-self::email]
452                       or preceding-sibling::address/otheraddr/ulink
453                       or ancestor::address[preceding-sibling::*[descendant-or-self::email]]
454                       or ancestor::address[preceding-sibling::address/otheraddr/ulink]">
455         <!-- * This is not the first instance, so do nothing. -->
456       </xsl:when>
457       <xsl:otherwise>
458         <!-- * This is first instances of an e-mail address or ulink, -->
459         <!-- * so put a space before it. -->
460         <xsl:text> </xsl:text>
461       </xsl:otherwise>
462     </xsl:choose>
463     <!-- * Note that the reason for the \& character after the opening -->
464     <!-- * angle bracket and before the closing angle bracket is to -->
465     <!-- * prevent groff from inserting a linebreak at those points and -->
466     <!-- * outputting a hyphen character where the break occurs -->
467     <xsl:text>&lt;\&amp;</xsl:text>
468     <xsl:choose>
469       <xsl:when test="self::email">
470         <xsl:variable name="contents">
471           <xsl:apply-templates/>
472         </xsl:variable>
473         <xsl:value-of select="normalize-space($contents)"/>
474       </xsl:when>
475       <xsl:when test="self::ulink">
476         <xsl:variable name="contents">
477           <xsl:apply-templates select="."/>
478         </xsl:variable>
479         <xsl:value-of select="normalize-space($contents)"/>
480       </xsl:when>
481     </xsl:choose>
482     <xsl:text>\&amp;&gt;</xsl:text>
483     <xsl:choose>
484       <xsl:when test="not(following-sibling::*[descendant-or-self::email]
485                       or following-sibling::address/otheraddr/ulink
486                       or ancestor::address[following-sibling::*[descendant-or-self::email]]
487                       or ancestor::address[following-sibling::address/otheraddr/ulink])">
488         <!-- * This is the final instance, so do nothing. -->
489       </xsl:when>
490       <xsl:otherwise>
491         <!-- * Separate multiple e-mail addresses or ulinks with a comma -->
492         <xsl:text>, </xsl:text>
493       </xsl:otherwise>
494     </xsl:choose>
495   </xsl:template>
496
497   <xsl:template match="affiliation" mode="authorsect">
498     <!-- * Get the string value of the contents of this Affiliation. If the -->
499     <!-- * affiliation only contains an Address child whose only content is -->
500     <!-- * an email address or ulink, then these contents will end up empty. -->
501     <xsl:variable name="contents">
502       <xsl:apply-templates mode="authorsect"/>
503     </xsl:variable>
504     <!-- * If contents are actually empty except for an email address -->
505     <!-- * or ulink, then output nothing. -->
506     <xsl:if test="$contents != ''">
507       <xsl:text>.br&#10;</xsl:text>
508       <xsl:for-each select="shortaffil|jobtitle|orgname|orgdiv|address">
509         <!-- * only display output of nodes other than email or ulink -->
510         <xsl:apply-templates select="node()[not(self::email) and not(self::otheraddr/ulink)]"/>
511         <xsl:choose>
512           <xsl:when test="position() = last()"/> <!-- do nothing -->
513           <xsl:otherwise>
514             <!-- * only add comma if the node has a child node other than -->
515             <!-- * an email address or ulink -->
516             <xsl:if test="child::node()[not(self::email) and not(self::otheraddr/ulink)]">
517               <xsl:text>, </xsl:text>
518             </xsl:if>
519           </xsl:otherwise>
520         </xsl:choose>
521       </xsl:for-each>
522       <xsl:text>&#10;</xsl:text>
523       <xsl:choose>
524         <xsl:when test="position() = last()"/> <!-- do nothing -->
525         <xsl:otherwise>
526           <!-- * put a line break after every Affiliation instance except -->
527           <!-- * the last one in the set -->
528           <xsl:text>.br&#10;</xsl:text>
529         </xsl:otherwise>
530       </xsl:choose>
531     </xsl:if>
532   </xsl:template>
533
534   <xsl:template match="address" mode="authorsect">
535     <xsl:variable name="contents"
536                   select="normalize-space(node()[not(self::email)
537                           and not(self::otheraddr/ulink)])"/>
538     <!-- * If this contents of this Address do not contain anything except -->
539     <!-- * an email address or ulink, then output nothing. -->
540     <xsl:if test="$contents != ''">
541       <xsl:text>&#10;</xsl:text>
542       <xsl:text>.br&#10;</xsl:text>
543       <!--* Skip email and ulink descendants of Address (rendered elsewhere) -->
544       <xsl:apply-templates select="node()[not(self::email) and not(self::otheraddr/ulink)]"/>
545     </xsl:if>
546   </xsl:template>
547
548   <xsl:template name="attribution">
549     <xsl:param name="person-name"/>
550     <xsl:param name="refname" select="ancestor::refentry/refnamediv[1]/refname[1]"/>
551     <!-- * Determine appropriate attribution for a particular person's role. -->
552     <xsl:choose>
553       <!-- * if we have a *blurb or contrib, just use that -->
554       <xsl:when test="contrib|personblurb|authorblurb">
555         <xsl:apply-templates select="contrib|personblurb|authorblurb" mode="authorsect"/>
556         <xsl:text>&#10;</xsl:text>
557       </xsl:when>
558       <xsl:otherwise>
559         <!-- * otherwise we have no attribution information to use... -->
560         <xsl:if test="not($person-name = '')">
561           <!-- * if we have a person name or organization name -->
562           <!-- * ($person-name can actually be an orgname, not just a -->
563           <!-- * person name), then report to the user that we are -->
564           <!-- * lacking attribution information for that person -->
565           <xsl:if test="$refentry.meta.get.quietly = 0">
566             <xsl:call-template name="log.message">
567               <xsl:with-param name="level">Warn</xsl:with-param>
568               <xsl:with-param name="source" select="$refname"/>
569               <xsl:with-param name="context-desc">AUTHOR sect.</xsl:with-param>
570               <xsl:with-param name="message">
571                 <xsl:text>no personblurb|contrib for </xsl:text>
572                 <xsl:value-of select="$person-name"/>
573               </xsl:with-param>
574             </xsl:call-template>
575             <xsl:call-template name="log.message">
576               <xsl:with-param name="level">Note</xsl:with-param>
577               <xsl:with-param name="source" select="$refname"/>
578               <xsl:with-param name="context-desc">AUTHOR sect.</xsl:with-param>
579               <xsl:with-param name="message">
580                 <xsl:text>see see http://docbook.sf.net/el/contrib</xsl:text>
581               </xsl:with-param>
582             </xsl:call-template>
583             <xsl:call-template name="log.message">
584               <xsl:with-param name="level">Note</xsl:with-param>
585               <xsl:with-param name="source" select="$refname"/>
586               <xsl:with-param name="context-desc">AUTHOR sect.</xsl:with-param>
587               <xsl:with-param name="message">
588                 <xsl:text>see see http://docbook.sf.net/el/personblurb</xsl:text>
589               </xsl:with-param>
590             </xsl:call-template>
591           </xsl:if>
592         </xsl:if>
593         <xsl:choose>
594           <!-- * If we have no *blurb or contrib, but this is an Author or -->
595           <!-- * Editor, then render the corresponding localized gentext -->
596           <xsl:when test="self::author">
597             <xsl:text>&#10;</xsl:text>
598             <xsl:text>.RS</xsl:text> 
599             <xsl:if test="not($blurb-indent = '')">
600               <xsl:text> </xsl:text>
601               <xsl:value-of select="$blurb-indent"/>
602             </xsl:if>
603             <xsl:text>&#10;</xsl:text>
604             <xsl:call-template name="gentext">
605               <xsl:with-param name="key" select="'Author'"/>
606             </xsl:call-template>
607             <xsl:text>.&#10;</xsl:text>
608             <xsl:text>.RE&#10;</xsl:text> 
609           </xsl:when>
610           <xsl:when test="self::editor">
611             <xsl:text>&#10;</xsl:text>
612             <xsl:text>.RS</xsl:text> 
613             <xsl:if test="not($blurb-indent = '')">
614               <xsl:text> </xsl:text>
615               <xsl:value-of select="$blurb-indent"/>
616             </xsl:if>
617             <xsl:text>&#10;</xsl:text>
618             <xsl:call-template name="gentext">
619               <xsl:with-param name="key" select="'Editor'"/>
620             </xsl:call-template>
621             <xsl:text>.&#10;</xsl:text>
622             <xsl:text>.RE&#10;</xsl:text> 
623           </xsl:when>
624           <!-- * If we have no *blurb or contrib, but this is an Othercredit, -->
625           <!-- * check value of Class attribute and use corresponding gentext. -->
626           <xsl:when test="self::othercredit">
627             <xsl:choose>
628               <xsl:when test="@class and @class != 'other'">
629                 <xsl:text>&#10;</xsl:text>
630                 <xsl:text>.RS</xsl:text> 
631                 <xsl:if test="not($blurb-indent = '')">
632                   <xsl:text> </xsl:text>
633                   <xsl:value-of select="$blurb-indent"/>
634                 </xsl:if>
635                 <xsl:text>&#10;</xsl:text>
636                 <xsl:call-template name="gentext">
637                   <xsl:with-param name="key" select="@class"/>
638                 </xsl:call-template>
639                 <xsl:text>.&#10;</xsl:text>
640                 <xsl:text>.RE&#10;</xsl:text> 
641               </xsl:when>
642               <xsl:otherwise>
643                 <!-- * We have an Othercredit, but no usable value for the Class -->
644                 <!-- * attribute, so nothing to show, do nothing -->
645               </xsl:otherwise>
646             </xsl:choose>
647           </xsl:when>
648           <xsl:otherwise>
649             <!-- * We have no *blurb or contrib or anything else we can use to -->
650             <!-- * display appropriate attribution for this person, so do nothing -->
651           </xsl:otherwise>
652         </xsl:choose>
653       </xsl:otherwise>
654     </xsl:choose>
655   </xsl:template>
656
657   <xsl:template match="personblurb|authorblurb" mode="authorsect">
658     <xsl:call-template name="mark.up.blurb.or.contrib"/>
659     <!-- * yeah, it's possible for a *blurb to have a "title" -->
660     <xsl:apply-templates select="title"/>
661     <xsl:apply-templates select="*[not(self::title)]"/>
662     <!-- * If this *blurb has a sibling "name" element of some kind, then -->
663     <!-- * the mark.up.blurb.or.contrib template will generated an "RS" -->
664     <!-- * call that will cause it to be indented; so we need to call -->
665     <!-- * "RE" to restore the previous indent level -->
666     <xsl:if test="../personname|../surname|../firstname
667       |../othername|../lineage|../honorific
668       |../affiliation|../email|../address">
669       <xsl:text>.RE&#10;</xsl:text> 
670     </xsl:if>
671   </xsl:template>
672
673   <xsl:template match="personblurb/title|authorblurb/title">
674     <!-- * always render period after title -->
675     <xsl:variable name="contents">
676       <xsl:apply-templates/>
677     </xsl:variable>
678     <xsl:value-of select="normalize-space($contents)"/>
679     <xsl:text>.</xsl:text>
680     <!-- * render space after Title+period if the title is followed -->
681     <!-- * by something element content -->
682     <xsl:if test="following-sibling::*[name() != '']">
683       <xsl:text> </xsl:text>
684     </xsl:if>
685   </xsl:template>
686
687   <xsl:template match="contrib" mode="authorsect">
688     <xsl:call-template name="mark.up.blurb.or.contrib"/>
689     <xsl:variable name="contents">
690       <xsl:apply-templates/>
691     </xsl:variable>
692     <xsl:value-of select="normalize-space($contents)"/>
693     <xsl:text>&#10;</xsl:text>
694     <xsl:if test="../personname|../surname|../firstname
695       |../othername|../lineage|../honorific
696       |../affiliation|../email|../address">
697       <xsl:text>.RE&#10;</xsl:text> 
698     </xsl:if>
699   </xsl:template>
700
701   <xsl:template name="mark.up.blurb.or.contrib">
702     <xsl:choose>
703       <!-- * If this *blurb has a sibling "name" element of some kind, then -->
704       <!-- * we are already outputting the name content, and we need to -->
705       <!-- * indent the *blurb content after that. -->
706       <xsl:when
707           test="../personname|../surname|../firstname
708                 |../othername|../lineage|../honorific
709                 |../affiliation|../email|../address">
710         <xsl:text>&#10;</xsl:text>
711         <xsl:text>.RS</xsl:text> 
712         <xsl:if test="not($blurb-indent = '')">
713           <xsl:text> </xsl:text>
714           <xsl:value-of select="$blurb-indent"/>
715         </xsl:if>
716       </xsl:when>
717       <xsl:otherwise>
718         <!-- * otherwise, we have no "name" content, so don't indent; -->
719         <!-- * instead, decide if we need a .PP or just a .br -->
720         <xsl:choose>
721           <xsl:when test="not(preceding-sibling::*)">
722             <!-- * if this *blurb or contrib has no preceding -->
723             <!-- * siblings, then we need to start a new paragraph -->
724             <xsl:text>.PP</xsl:text>
725           </xsl:when>
726           <xsl:otherwise>
727             <!-- * otherwise, this has no preceding siblings, so -->
728             <!-- * just put a linebreak -->
729             <xsl:text>.br</xsl:text>
730           </xsl:otherwise>
731         </xsl:choose>
732       </xsl:otherwise>
733     </xsl:choose>
734     <xsl:text>&#10;</xsl:text>
735   </xsl:template>
736
737   <!-- * ============================================================== -->
738   <!-- *     Assemble the COPYRIGHT section -->
739   <!-- * ============================================================== -->
740   <!-- * The COPYRIGHT section is output only if a copyright or -->
741   <!-- * legalnotice is found. It contains the copyright contents -->
742   <!-- * followed by the legalnotice contents. -->
743   <xsl:template name="copyright.section">
744     <xsl:param name="info"/>
745     <xsl:choose>
746       <xsl:when test="$info//copyright|$info//legalnotice">
747         <xsl:call-template name="make.subheading">
748           <xsl:with-param name="title">
749             <xsl:call-template name="gentext">
750               <xsl:with-param name="key">Copyright</xsl:with-param>
751             </xsl:call-template>
752           </xsl:with-param>
753         </xsl:call-template>
754         <xsl:text>.br&#10;</xsl:text>
755         <!-- * the copyright mode="titlepage.mode" template is -->
756         <!-- * imported from the HTML stylesheets -->
757         <xsl:for-each select="
758           (($info[//copyright])[last()]//copyright)
759           | (($info[//legalnotice])[last()]//legalnotice)">
760           <xsl:choose>
761             <xsl:when test="local-name(.) = 'copyright'">
762               <xsl:variable name="contents">
763                 <xsl:apply-templates select="." mode="titlepage.mode"/>
764               </xsl:variable>
765               <xsl:value-of select="normalize-space($contents)"/>
766               <xsl:text>&#10;</xsl:text>
767               <xsl:text>.br&#10;</xsl:text>
768             </xsl:when>
769             <xsl:otherwise>
770               <xsl:apply-templates select="." mode="titlepage.mode"/>
771               <xsl:text>&#10;</xsl:text>
772               <xsl:text>.sp&#10;</xsl:text>
773             </xsl:otherwise>
774           </xsl:choose>
775         </xsl:for-each>
776       </xsl:when>
777       <xsl:otherwise/> <!-- * do nothing, no copyright or legalnotice found -->
778     </xsl:choose>
779   </xsl:template>
780
781   <xsl:template match="legalnotice">
782     <xsl:apply-templates/>
783   </xsl:template>
784
785   <!-- * ============================================================== -->
786
787   <!-- * suppress refmeta and all *info (we grab what we need from them -->
788   <!-- * elsewhere) -->
789
790   <xsl:template match="refmeta"/>
791
792   <xsl:template match="info|refentryinfo|referenceinfo|refsynopsisdivinfo
793                        |refsectioninfo|refsect1info|refsect2info|refsect3info
794                        |setinfo|bookinfo|articleinfo|chapterinfo|sectioninfo
795                        |sect1info|sect2info|sect3info|sect4info|sect5info
796                        |partinfo|prefaceinfo|appendixinfo|docinfo"/>
797
798   <!-- ============================================================== -->
799   
800 </xsl:stylesheet>