2 <xsl:stylesheet xmlns:
xsl=
"http://www.w3.org/1999/XSL/Transform"
3 xmlns:
exsl=
"http://exslt.org/common"
4 xmlns:
dyn=
"http://exslt.org/dynamic"
5 xmlns:
saxon=
"http://icl.com/saxon"
6 exclude-result-prefixes=
"exsl dyn saxon"
9 <!-- ********************************************************************
10 $Id: utility.xsl,v 1.1 2007/03/10 05:15:34 scott Exp $
11 ********************************************************************
13 This file is part of the XSL DocBook Stylesheet distribution.
14 See ../README or http://docbook.sf.net/release/xsl/current/ for
15 copyright and other information.
17 ******************************************************************** -->
19 <!-- ==================================================================== -->
21 <!-- * This file contains "utility" templates that are called multiple -->
22 <!-- * times per each Refentry. -->
24 <!-- ==================================================================== -->
26 <!-- * NOTE TO DEVELOPERS: For ease of maintenance, the current -->
27 <!-- * manpages stylesheets use the mode="bold" and mode="italic" -->
28 <!-- * templates for *anything and everything* that needs to get -->
29 <!-- * boldfaced or italicized. -->
31 <!-- * So if you add anything that needs bold or italic character -->
32 <!-- * formatting, try to apply these templates to it rather than -->
33 <!-- * writing separate code to format it. This can be a little odd if -->
34 <!-- * the content you want to format is not element content; in those -->
35 <!-- * cases, you need to turn it into element content before applying -->
36 <!-- * the template; see examples of this in the existing code. -->
38 <xsl:template mode=
"bold" match=
"*">
39 <xsl:for-each select=
"node()">
40 <xsl:text>\fB
</xsl:text>
41 <xsl:apply-templates select=
"."/>
42 <xsl:text>\fR
</xsl:text>
46 <xsl:template mode=
"italic" match=
"*">
47 <xsl:for-each select=
"node()">
48 <xsl:text>\fI
</xsl:text>
49 <xsl:apply-templates select=
"."/>
50 <xsl:text>\fR
</xsl:text>
54 <!-- ================================================================== -->
56 <!-- * NOTE TO DEVELOPERS: For ease of maintenance, the current -->
57 <!-- * manpages stylesheets use the mode="prevent.line.breaking" -->
58 <!-- * templates for *anything and everything* that needs to have -->
59 <!-- * embedded spaces turned into no-break spaces in output - in -->
60 <!-- * order to prevent that output from getting broken across lines -->
62 <!-- * So if you add anything that whose output, try to apply this -->
63 <!-- * template to it rather than writing separate code to format -->
64 <!-- * it. This can be a little odd if the content you want to -->
65 <!-- * format is not element content; in those cases, you need to -->
66 <!-- * turn it into element content before applying the template; -->
67 <!-- * see examples of this in the existing code. -->
69 <!-- * This template is currently called by the funcdef and paramdef -->
70 <!-- * and group/arg templates. -->
71 <xsl:template mode=
"prevent.line.breaking" match=
"*">
72 <xsl:variable name=
"rcontent">
73 <xsl:apply-templates/>
75 <xsl:variable name=
"content">
76 <xsl:value-of select=
"normalize-space($rcontent)"/>
78 <xsl:call-template name=
"string.subst">
79 <xsl:with-param name=
"string" select=
"$content"/>
80 <xsl:with-param name=
"target" select=
"' '"/>
81 <!-- * U+2580 is a "UPPER HALF BLOCK"; we use it here because -->
82 <!-- * if we were to just use a normal space, it would get -->
83 <!-- * replaced when normalization is done. We replace it -->
84 <!-- * later with the groff markup for non-breaking space. -->
85 <xsl:with-param name=
"replacement" select=
"'▀'"/>
89 <!-- ================================================================== -->
91 <xsl:template name=
"suppress.hyphenation">
92 <!-- * we need to suppress hyphenation inline only if hyphenation is -->
93 <!-- * actually on, and even then only outside of Cmdsynopsis and -->
94 <!-- * Funcsynopsis, where it is already always turned off -->
95 <xsl:if test=
"$man.hyphenate != 0 and
96 not(ancestor::cmdsynopsis) and
97 not(ancestor::funcsynopsis)">
98 <xsl:text>\%
</xsl:text>
102 <!-- ================================================================== -->
104 <!-- * The replace.dots.and.dashes template is used to cause real -->
105 <!-- * dots and dashes to be output in the top comment (instead of -->
106 <!-- * escaped ones as in the source for the text displayed in the -->
107 <!-- * body of the page) -->
108 <xsl:template name=
"replace.dots.and.dashes">
109 <xsl:param name=
"content">
110 <xsl:apply-templates/>
112 <xsl:variable name=
"dot-content">
113 <xsl:call-template name=
"string.subst">
114 <xsl:with-param name=
"string" select=
"$content"/>
115 <xsl:with-param name=
"target" select=
"'\.'"/>
116 <xsl:with-param name=
"replacement" select=
"'.'"/>
119 <xsl:call-template name=
"string.subst">
120 <xsl:with-param name=
"string" select=
"$dot-content"/>
121 <xsl:with-param name=
"target" select=
"'\-'"/>
122 <xsl:with-param name=
"replacement" select=
"'-'"/>
126 <!-- ================================================================== -->
128 <!-- * The nested-section-title template is called for refsect3, and any -->
129 <!-- * refsection nested more than 2 levels deep. -->
130 <xsl:template name=
"nested-section-title">
131 <!-- * The next few lines are some arcane roff code to control line -->
132 <!-- * spacing after headings. -->
133 <xsl:text>.sp
</xsl:text>
134 <xsl:text>.it
1 an-trap
</xsl:text>
135 <xsl:text>.nr an-no-space-flag
1 </xsl:text>
136 <xsl:text>.nr an-break-flag
1 </xsl:text>
137 <xsl:text>.br
</xsl:text>
138 <!-- * make title wrapper so that we can use mode="bold" template to -->
139 <!-- * apply character formatting to it -->
140 <xsl:variable name=
"title.wrapper">
142 <xsl:when test=
"title">
143 <xsl:value-of select=
"normalize-space(title[1])"/>
146 <xsl:apply-templates select=
"." mode=
"object.title.markup.textonly"/>
150 <xsl:call-template name=
"mark.subheading"/>
151 <xsl:apply-templates mode=
"bold" select=
"exsl:node-set($title.wrapper)"/>
152 <xsl:text> </xsl:text>
153 <xsl:call-template name=
"mark.subheading"/>
156 <!-- ================================================================== -->
158 <!-- * The mixed-block template jumps through a few hoops to deal with -->
159 <!-- * mixed-content blocks, so that we don't end up munging verbatim -->
160 <!-- * environments or lists and so that we don't gobble up whitespace -->
161 <!-- * when we shouldn't -->
162 <xsl:template name=
"mixed-block">
163 <xsl:for-each select=
"node()">
165 <!-- * Check to see if this node is a verbatim environment. -->
166 <!-- * If so, put a line of space before it. -->
168 <!-- * Yes, address and synopsis are vertabim environments. -->
170 <!-- * The code here previously also treated informaltable as a -->
171 <!-- * verbatim, presumably to support some kludge; I removed it -->
172 <xsl:when test=
"self::address|self::literallayout|self::programlisting|
173 self::screen|self::synopsis">
174 <xsl:text> </xsl:text>
175 <xsl:text>.sp
</xsl:text>
176 <xsl:call-template name=
"mark.up.block.start"/>
177 <xsl:apply-templates select=
"."/>
179 <!-- * Check to see if this node is a list; if it is, we don't -->
180 <!-- * want to normalize-space(), so we just apply-templates. -->
181 <!-- * Do same for all admonitions -->
182 <xsl:when test=
"(self::itemizedlist|self::orderedlist|
183 self::variablelist|self::glosslist|
184 self::simplelist[@type !='inline']|
186 self::caution|self::important|
187 self::note|self::tip|self::warning)">
188 <xsl:call-template name=
"mark.up.block.start"/>
189 <xsl:apply-templates select=
"."/>
191 <xsl:when test=
"self::text()">
192 <!-- * Check to see if this is a text node. -->
194 <!-- * If so, replace all whitespace at the beginning or end of it -->
195 <!-- * with a single linebreak. -->
197 <xsl:variable name=
"content">
198 <xsl:apply-templates select=
"."/>
201 test=
"starts-with(translate(.,'	 ',' '), ' ')
202 and preceding-sibling::node()[1][name(.)!='']
203 and normalize-space($content) != ''
205 preceding-sibling::*[1][
211 self::variablelist or
213 self::itemizedlist or
215 self::segmentedlist or
218 self::literallayout or
219 self::programlisting or
224 <xsl:text> </xsl:text>
226 <xsl:value-of select=
"normalize-space($content)"/>
228 test=
"(translate(substring(., string-length(.), 1),'	 ',' ') = ' '
229 and following-sibling::node()[1][name(.)!=''])
230 or following-sibling::node()[1][self::comment()]
231 or following-sibling::node()[1][self::processing-instruction()]
233 <xsl:if test=
"normalize-space($content) != ''
234 or concat(normalize-space($content), ' ') = ' '">
235 <xsl:text> </xsl:text>
240 <!-- * At this point, we know that this node is not a verbatim -->
241 <!-- * environment, list, admonition, or text node; so we can -->
242 <!-- * safely normalize-space() it. -->
243 <xsl:variable name=
"content">
244 <xsl:apply-templates select=
"."/>
246 <xsl:value-of select=
"normalize-space($content)"/>
250 <xsl:call-template name=
"mark.up.block.end"/>
253 <!-- ================================================================== -->
255 <!-- * Footnote and annotation contents are displayed using a hanging -->
256 <!-- * indent out to $man.indent.width If a paragraph-level block -->
257 <!-- * element (verbatim, list, or admonition) is the first block -->
258 <!-- * element nested at its same level within the same footnote or -->
259 <!-- * annotation, then we push it over by the same indent width. -->
261 <!-- * We don't reset the indent for each following sibling, but -->
262 <!-- * instead do it after for-eaching over all block siblings at -->
263 <!-- * the same level. So the effect is that if there are any -->
264 <!-- * following-sibling blocks after the block that starts this -->
265 <!-- * indent, then they just retain the indent that was already set -->
267 <xsl:template name=
"mark.up.block.start">
269 <xsl:when test=
"(ancestor::footnote
270 or ancestor::annotation)">
271 <xsl:if test=
"not(preceding-sibling::address|
272 preceding-sibling::literallayout|
273 preceding-sibling::programlisting|
274 preceding-sibling::screen|
275 preceding-sibling::synopsis|
276 preceding-sibling::itemizedlist|
277 preceding-sibling::orderedlist|
278 preceding-sibling::variablelist|
279 preceding-sibling::glosslist|
280 preceding-sibling::simplelist[@type !='inline']|
281 preceding-sibling::segmentedlist|
282 preceding-sibling::caution|
283 preceding-sibling::important|
284 preceding-sibling::note|
285 preceding-sibling::tip|
286 preceding-sibling::warning)">
287 <xsl:text>.RS
</xsl:text>
288 <xsl:if test=
"not($list-indent = '')">
289 <xsl:text> </xsl:text>
290 <xsl:value-of select=
"$list-indent"/>
292 <xsl:text> </xsl:text>
298 <!-- * Check to see if we were called from a block within a footnote or -->
299 <!-- * annotation; if so, and the block contains any nested block -->
300 <!-- * content, then we know the mark.up.block.end template was already -->
301 <!-- * called to generate a .RS macro to indent that nested block -->
302 <!-- * content; so we need to generated a .RE to set the margin back to -->
303 <!-- * where it was prior to the .RS call. -->
304 <xsl:template name=
"mark.up.block.end">
305 <xsl:if test=
"(ancestor::footnote
306 or ancestor::annotation)">
307 <xsl:if test=
"address|
316 simplelist[@type !='inline']|
323 <xsl:text> </xsl:text>
324 <xsl:text>.RE
</xsl:text>
325 <xsl:text> </xsl:text>
330 <!-- ================================================================== -->
332 <!-- * The person.name template in the HTML stylesheets outputs extra -->
333 <!-- * spaces that we need to strip out for manpages output. This -->
334 <!-- * template calls person.name, then tries to do some smart -->
335 <!-- * normalization of the result tree fragment from that. -->
336 <xsl:template name=
"person.name.normalized">
337 <xsl:variable name=
"contents">
338 <xsl:call-template name=
"person.name"/>
340 <!-- * We put the output of person.name into a node-set and then we -->
341 <!-- * check it node-by-node and strip out space only where needed. -->
342 <xsl:variable name=
"contents.tree" select=
"exsl:node-set($contents)"/>
343 <xsl:for-each select=
"$contents.tree/node()">
345 <!-- * We don't want to monkey with single spaces or commas/periods -->
346 <!-- * followed by spaces, because those are bits of text that are -->
347 <!-- * actually generated by the person.name template itself (that -->
348 <!-- * is, they're not in the source. So, we preserve them. -->
349 <xsl:when test=
". = ' ' or . = ', ' or . = '. '">
350 <xsl:value-of select=
"."/>
353 <xsl:value-of select=
"normalize-space(.)"/>
359 <!-- ================================================================== -->
361 <xsl:template name=
"make.adjusted.man.filename">
362 <xsl:param name=
"name"/>
363 <xsl:param name=
"lang"/>
364 <xsl:param name=
"name.with.lang">
366 <xsl:when test=
"not($man.output.lang.in.name.enabled = 0)
367 and ($man.output.subdirs.enabled = 0)">
368 <!-- * user has specified man.output.lang.in.name.enabled -->
369 <!-- * AND doesn't want output going into separate manN dirs, -->
370 <!-- * so we include the $lang value in the filename; e.g., -->
372 <xsl:value-of select=
"concat($name, '.', $lang)"/>
375 <!-- * user either has man.output.lang.in.name.enabled unset -->
376 <!-- * or has set it but also has man.output.subdirs.enabled -->
377 <!-- * set (in which case the $lang value is used to add a -->
378 <!-- * $lang subdir in the pathname); in either case, we don't -->
379 <!-- * want to include the $lang in the filename -->
380 <xsl:value-of select=
"$name"/>
384 <xsl:param name=
"section"/>
385 <xsl:param name=
"dirname">
386 <xsl:if test=
"not($man.output.in.separate.dir = 0)">
388 <xsl:when test=
"not($man.output.subdirs.enabled = 0)">
389 <xsl:variable name=
"lang.subdir">
390 <xsl:if test=
"not($man.output.lang.in.name.enabled = 0)">
391 <!-- * user has man.output.lang.in.name.enabled set, so -->
392 <!-- * we need add a $lang subdir -->
393 <xsl:value-of select=
"concat($lang, '/')"/>
397 select=
"concat($man.output.base.dir, $lang.subdir,
398 'man', normalize-space($section), '/')"/>
401 <xsl:value-of select=
"$man.output.base.dir"/>
406 <xsl:call-template name=
"string.subst">
407 <!-- * Replace any spaces in filename with underscores & then append -->
408 <!-- * a dot plus a section number to create the man filename -->
409 <xsl:with-param name=
"string"
410 select=
"concat($dirname,
411 normalize-space($name.with.lang),
412 '.', normalize-space($section))"/>
413 <xsl:with-param name=
"target" select=
"' '"/>
414 <xsl:with-param name=
"replacement" select=
"'_'"/>
418 <!-- ================================================================== -->
420 <!-- * Put a horizontal rule or other divider around section titles -->
421 <!-- * in roff source (just to make things easier to read). -->
422 <xsl:template name=
"mark.subheading">
423 <xsl:if test=
"$man.subheading.divider.enabled != 0">
424 <xsl:text>.\
" </xsl:text>
425 <xsl:value-of select="$man.subheading.divider
"/>
426 <xsl:text> </xsl:text>