2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5 <!-- ********************************************************************
6 $Id: html.xsl 8556 2009-12-11 00:05:45Z bobstayton $
7 ********************************************************************
9 This file is part of the XSL DocBook Stylesheet distribution.
10 See ../README or http://docbook.sf.net/release/xsl/current/ for
11 copyright and other information.
13 ******************************************************************** -->
15 <!-- These variables set the align attribute value for HTML output based on
16 the writing-mode specified in the gentext file for the document's lang. -->
18 <xsl:variable name="direction.align.start">
20 <xsl:when test="starts-with($writing.mode, 'lr')">left</xsl:when>
21 <xsl:when test="starts-with($writing.mode, 'rl')">right</xsl:when>
22 <xsl:otherwise>left</xsl:otherwise>
26 <xsl:variable name="direction.align.end">
28 <xsl:when test="starts-with($writing.mode, 'lr')">right</xsl:when>
29 <xsl:when test="starts-with($writing.mode, 'rl')">left</xsl:when>
30 <xsl:otherwise>right</xsl:otherwise>
34 <xsl:variable name="direction.mode">
36 <xsl:when test="starts-with($writing.mode, 'lr')">ltr</xsl:when>
37 <xsl:when test="starts-with($writing.mode, 'rl')">rtl</xsl:when>
38 <xsl:otherwise>ltr</xsl:otherwise>
42 <!-- The generate.html.title template is currently used for generating HTML -->
43 <!-- "title" attributes for some inline elements only, but not for any -->
44 <!-- block elements. It is called in eleven places in the inline.xsl -->
45 <!-- file. But it's called by all the inline.* templates (e.g., -->
46 <!-- inline.boldseq), which in turn are called by other (element) -->
47 <!-- templates, so it results, currently, in supporting generation of the -->
48 <!-- HTML "title" attribute for a total of about 92 elements. -->
49 <!-- You can use mode="html.title.attribute" to get a title for -->
50 <!-- an element specified by a param, including targets of cross references. -->
51 <xsl:template name="generate.html.title">
52 <xsl:apply-templates select="." mode="html.title.attribute"/>
55 <!-- Generate a title attribute for the context node -->
56 <xsl:template match="*" mode="html.title.attribute">
57 <xsl:variable name="is.title">
58 <xsl:call-template name="gentext.template.exists">
59 <xsl:with-param name="context" select="'title'"/>
60 <xsl:with-param name="name" select="local-name(.)"/>
61 <xsl:with-param name="lang">
62 <xsl:call-template name="l10n.language"/>
67 <xsl:variable name="is.title-numbered">
68 <xsl:call-template name="gentext.template.exists">
69 <xsl:with-param name="context" select="'title-numbered'"/>
70 <xsl:with-param name="name" select="local-name(.)"/>
71 <xsl:with-param name="lang">
72 <xsl:call-template name="l10n.language"/>
77 <xsl:variable name="is.title-unnumbered">
78 <xsl:call-template name="gentext.template.exists">
79 <xsl:with-param name="context" select="'title-unnumbered'"/>
80 <xsl:with-param name="name" select="local-name(.)"/>
81 <xsl:with-param name="lang">
82 <xsl:call-template name="l10n.language"/>
87 <xsl:variable name="has.title.markup">
88 <xsl:apply-templates select="." mode="title.markup">
89 <xsl:with-param name="verbose" select="0"/>
90 </xsl:apply-templates>
93 <xsl:variable name="gentext.title">
94 <xsl:if test="$has.title.markup != '???TITLE???' and
96 $is.title-numbered != 0 or
97 $is.title-unnumbered != 0)">
98 <xsl:apply-templates select="."
99 mode="object.title.markup.textonly"/>
104 <xsl:when test="string-length($gentext.title) != 0">
105 <xsl:attribute name="title">
106 <xsl:value-of select="$gentext.title"/>
109 <!-- Fall back to alt if available -->
110 <xsl:when test="alt">
111 <xsl:attribute name="title">
112 <xsl:value-of select="normalize-space(alt)"/>
118 <xsl:template match="qandaentry" mode="html.title.attribute">
119 <xsl:apply-templates select="question" mode="html.title.attribute"/>
122 <xsl:template match="question" mode="html.title.attribute">
123 <xsl:variable name="label.text">
124 <xsl:apply-templates select="." mode="qanda.label"/>
128 <xsl:when test="string-length($label.text) != 0">
129 <xsl:attribute name="title">
130 <xsl:value-of select="$label.text"/>
133 <!-- Fall back to alt if available -->
134 <xsl:when test="alt">
135 <xsl:attribute name="title">
136 <xsl:value-of select="normalize-space(alt)"/>
142 <xsl:template name="dir">
143 <xsl:param name="inherit" select="0"/>
145 <xsl:variable name="dir">
147 <xsl:when test="@dir">
148 <xsl:value-of select="@dir"/>
150 <xsl:when test="$inherit != 0">
151 <xsl:value-of select="ancestor::*/@dir[1]"/>
156 <xsl:if test="$dir != ''">
157 <xsl:attribute name="dir">
158 <xsl:value-of select="$dir"/>
163 <xsl:template name="anchor">
164 <xsl:param name="node" select="."/>
165 <xsl:param name="conditional" select="1"/>
166 <xsl:variable name="id">
167 <xsl:call-template name="object.id">
168 <xsl:with-param name="object" select="$node"/>
171 <xsl:if test="$conditional = 0 or $node/@id or $node/@xml:id">
176 <xsl:template name="href.target.uri">
177 <xsl:param name="context" select="."/>
178 <xsl:param name="object" select="."/>
179 <xsl:text>#</xsl:text>
180 <xsl:call-template name="object.id">
181 <xsl:with-param name="object" select="$object"/>
185 <xsl:template name="href.target">
186 <xsl:param name="context" select="."/>
187 <xsl:param name="object" select="."/>
188 <xsl:text>#</xsl:text>
189 <xsl:call-template name="object.id">
190 <xsl:with-param name="object" select="$object"/>
194 <xsl:template name="href.target.with.base.dir">
195 <xsl:param name="context" select="."/>
196 <xsl:param name="object" select="."/>
197 <xsl:if test="$manifest.in.base.dir = 0">
198 <xsl:value-of select="$base.dir"/>
200 <xsl:call-template name="href.target">
201 <xsl:with-param name="context" select="$context"/>
202 <xsl:with-param name="object" select="$object"/>
206 <xsl:template name="dingbat">
207 <xsl:param name="dingbat">bullet</xsl:param>
208 <xsl:call-template name="dingbat.characters">
209 <xsl:with-param name="dingbat" select="$dingbat"/>
213 <xsl:template name="dingbat.characters">
214 <!-- now that I'm using the real serializer, all that dingbat malarky -->
215 <!-- isn't necessary anymore... -->
216 <xsl:param name="dingbat">bullet</xsl:param>
218 <xsl:when test="$dingbat='bullet'">•</xsl:when>
219 <xsl:when test="$dingbat='copyright'">©</xsl:when>
220 <xsl:when test="$dingbat='trademark'">™</xsl:when>
221 <xsl:when test="$dingbat='trade'">™</xsl:when>
222 <xsl:when test="$dingbat='registered'">®</xsl:when>
223 <xsl:when test="$dingbat='service'">(SM)</xsl:when>
224 <xsl:when test="$dingbat='nbsp'"> </xsl:when>
225 <xsl:when test="$dingbat='ldquo'">“</xsl:when>
226 <xsl:when test="$dingbat='rdquo'">”</xsl:when>
227 <xsl:when test="$dingbat='lsquo'">‘</xsl:when>
228 <xsl:when test="$dingbat='rsquo'">’</xsl:when>
229 <xsl:when test="$dingbat='em-dash'">—</xsl:when>
230 <xsl:when test="$dingbat='mdash'">—</xsl:when>
231 <xsl:when test="$dingbat='en-dash'">–</xsl:when>
232 <xsl:when test="$dingbat='ndash'">–</xsl:when>
234 <xsl:text>•</xsl:text>
239 <xsl:template name="id.warning">
240 <xsl:if test="$id.warnings != 0 and not(@id) and not(@xml:id) and parent::*">
241 <xsl:variable name="title">
243 <xsl:when test="title">
244 <xsl:value-of select="title[1]"/>
246 <xsl:when test="substring(local-name(*[1]),
247 string-length(local-name(*[1])-3) = 'info')
249 <xsl:value-of select="*[1]/title[1]"/>
251 <xsl:when test="refmeta/refentrytitle">
252 <xsl:value-of select="refmeta/refentrytitle"/>
254 <xsl:when test="refnamediv/refname">
255 <xsl:value-of select="refnamediv/refname[1]"/>
261 <xsl:text>ID recommended on </xsl:text>
262 <xsl:value-of select="local-name(.)"/>
263 <xsl:if test="$title != ''">
264 <xsl:text>: </xsl:text>
266 <xsl:when test="string-length($title) > 40">
267 <xsl:value-of select="substring($title,1,40)"/>
268 <xsl:text>...</xsl:text>
271 <xsl:value-of select="$title"/>
279 <xsl:template name="generate.class.attribute">
280 <xsl:param name="class" select="local-name(.)"/>
281 <xsl:apply-templates select="." mode="class.attribute">
282 <xsl:with-param name="class" select="$class"/>
283 </xsl:apply-templates>
286 <xsl:template match="*" mode="class.attribute">
287 <xsl:param name="class" select="local-name(.)"/>
288 <!-- permit customization of class attributes -->
289 <!-- Use element name by default -->
290 <xsl:attribute name="class">
291 <xsl:apply-templates select="." mode="class.value">
292 <xsl:with-param name="class" select="$class"/>
293 </xsl:apply-templates>
297 <xsl:template match="*" mode="class.value">
298 <xsl:param name="class" select="local-name(.)"/>
299 <!-- permit customization of class value only -->
300 <!-- Use element name by default -->
301 <xsl:value-of select="$class"/>
304 <!-- Apply common attributes such as class, lang, dir -->
305 <xsl:template name="common.html.attributes">
306 <xsl:param name="inherit" select="0"/>
307 <xsl:param name="class" select="local-name(.)"/>
308 <xsl:apply-templates select="." mode="common.html.attributes">
309 <xsl:with-param name="class" select="$class"/>
310 <xsl:with-param name="inherit" select="$inherit"/>
311 </xsl:apply-templates>
314 <xsl:template match="*" mode="common.html.attributes">
315 <xsl:param name="class" select="local-name(.)"/>
316 <xsl:param name="inherit" select="0"/>
317 <xsl:call-template name="generate.html.lang"/>
318 <xsl:call-template name="dir">
319 <xsl:with-param name="inherit" select="$inherit"/>
321 <xsl:apply-templates select="." mode="class.attribute">
322 <xsl:with-param name="class" select="$class"/>
323 </xsl:apply-templates>
324 <xsl:call-template name="generate.html.title"/>
327 <!-- Apply common attributes not including class -->
328 <xsl:template name="locale.html.attributes">
329 <xsl:apply-templates select="." mode="locale.html.attributes"/>
332 <xsl:template match="*" mode="locale.html.attributes">
333 <xsl:call-template name="generate.html.lang"/>
334 <xsl:call-template name="dir"/>
335 <xsl:call-template name="generate.html.title"/>
338 <!-- Pass through any lang attributes -->
339 <xsl:template name="generate.html.lang">
340 <xsl:apply-templates select="." mode="html.lang.attribute"/>
343 <xsl:template match="*" mode="html.lang.attribute">
344 <!-- match the attribute name to the output type -->
346 <xsl:when test="@lang and $stylesheet.result.type = 'html'">
347 <xsl:attribute name="lang">
348 <xsl:value-of select="@lang"/>
351 <xsl:when test="@lang and $stylesheet.result.type = 'xhtml'">
352 <xsl:attribute name="xml:lang">
353 <xsl:value-of select="@lang"/>
356 <xsl:when test="@xml:lang and $stylesheet.result.type = 'html'">
357 <xsl:attribute name="lang">
358 <xsl:value-of select="@xml:lang"/>
361 <xsl:when test="@xml:lang and $stylesheet.result.type = 'xhtml'">
362 <xsl:attribute name="xml:lang">
363 <xsl:value-of select="@xml:lang"/>
369 <!-- ==================================================================== -->
370 <!-- Insert link to css or insert literal CSS in head element -->
371 <xsl:template name="generate.css">
373 <xsl:when test="$generate.css.header = 0">
374 <xsl:call-template name="generate.css.links"/>
377 <xsl:call-template name="generate.css.headers"/>
382 <xsl:template name="generate.css.headers">
383 <xsl:call-template name="generate.default.css.header"/>
384 <xsl:call-template name="generate.custom.css.header"/>
387 <xsl:template name="generate.default.css.header">
388 <xsl:if test="$make.clean.html != 0 and
389 $docbook.css.source != ''">
390 <!-- Select default file relative to stylesheet -->
391 <xsl:variable name="css.node" select="document($docbook.css.source)/*[1]"/>
393 <xsl:call-template name="output.css.header">
394 <xsl:with-param name="css.node" select="$css.node"/>
399 <xsl:template name="generate.custom.css.header">
400 <xsl:if test="$custom.css.source != ''">
401 <!-- Select custom file relative to document -->
402 <xsl:variable name="css.node" select="document($custom.css.source,.)/*[1]"/>
404 <xsl:call-template name="output.css.header">
405 <xsl:with-param name="css.node" select="$css.node"/>
410 <xsl:template name="output.css.header">
411 <xsl:param name="css.node"/>
414 <xsl:when test="count($css.node) = 0">
417 <style type="text/css">
418 <xsl:copy-of select="$css.node/text()"/>
424 <!-- ==================================================================== -->
425 <xsl:template name="generate.css.links">
426 <xsl:call-template name="generate.default.css.link"/>
427 <xsl:call-template name="generate.custom.css.link"/>
430 <xsl:template name="generate.default.css.link">
431 <xsl:if test="$make.clean.html != 0 and
432 $docbook.css.link != 0 and
433 $docbook.css.source != ''">
434 <xsl:variable name="filename">
435 <xsl:call-template name="css.output.filename">
436 <xsl:with-param name="src" select="$docbook.css.source"/>
440 <xsl:call-template name="make.css.link">
441 <xsl:with-param name="css.filename" select="$filename"/>
446 <xsl:template name="generate.custom.css.link">
447 <xsl:if test="$custom.css.source != ''">
448 <xsl:variable name="filename">
449 <xsl:call-template name="css.output.filename">
450 <xsl:with-param name="src" select="$custom.css.source"/>
454 <xsl:call-template name="make.css.link">
455 <xsl:with-param name="css.filename" select="$filename"/>
460 <!-- a CSS link reference must take into account the relative
461 path to a CSS file when chunked HTML is output to more than one directory -->
462 <xsl:template name="make.css.link">
463 <xsl:param name="css.filename" select="''"/>
465 <xsl:variable name="href.to.uri" select="$css.filename"/>
467 <xsl:variable name="href.from.uri">
468 <xsl:call-template name="href.target.uri">
469 <xsl:with-param name="object" select="."/>
473 <xsl:variable name="href.to">
474 <xsl:call-template name="trim.common.uri.paths">
475 <xsl:with-param name="uriA" select="$href.to.uri"/>
476 <xsl:with-param name="uriB" select="$href.from.uri"/>
477 <xsl:with-param name="return" select="'A'"/>
481 <xsl:variable name="href.from">
482 <xsl:call-template name="trim.common.uri.paths">
483 <xsl:with-param name="uriA" select="$href.to.uri"/>
484 <xsl:with-param name="uriB" select="$href.from.uri"/>
485 <xsl:with-param name="return" select="'B'"/>
488 <xsl:variable name="depth">
489 <xsl:call-template name="count.uri.path.depth">
490 <xsl:with-param name="filename" select="$href.from"/>
493 <xsl:variable name="href">
494 <xsl:call-template name="copy-string">
495 <xsl:with-param name="string" select="'../'"/>
496 <xsl:with-param name="count" select="$depth"/>
498 <xsl:value-of select="$href.to"/>
501 <xsl:if test="string-length($css.filename) != 0">
502 <link rel="stylesheet"
508 <!-- ==================================================================== -->
510 <xsl:template name="generate.css.files">
511 <xsl:call-template name="generate.default.css.file"/>
512 <xsl:call-template name="generate.custom.css.file"/>
515 <xsl:template name="generate.default.css.file">
516 <xsl:if test="$make.clean.html != 0 and
517 $generate.css.header = 0 and
518 $docbook.css.source != ''">
519 <!-- Select default file relative to stylesheet -->
520 <xsl:variable name="css.node" select="document($docbook.css.source)/*[1]"/>
522 <xsl:call-template name="generate.css.file">
523 <xsl:with-param name="src" select="$docbook.css.source"/>
524 <xsl:with-param name="css.node" select="$css.node"/>
529 <xsl:template name="generate.custom.css.file">
530 <xsl:if test="$custom.css.source != '' and
531 $generate.css.header = 0">
532 <!-- Select custom file relative to document -->
533 <xsl:variable name="css.node" select="document($custom.css.source,.)/*[1]"/>
535 <xsl:call-template name="generate.css.file">
536 <xsl:with-param name="src" select="$custom.css.source"/>
537 <xsl:with-param name="css.node" select="$css.node"/>
542 <xsl:template name="generate.css.file">
543 <xsl:param name="css.node"/>
544 <xsl:param name="src" select="''"/>
546 <xsl:variable name="css.text" select="$css.node/text()"/>
549 <xsl:when test="count($css.node) = 0">
551 <xsl:text>ERROR: no root element for CSS source file'</xsl:text>
552 <xsl:value-of select="$src"/>
553 <xsl:text>'.</xsl:text>
557 <xsl:variable name="filename">
558 <xsl:call-template name="css.output.pathname">
559 <xsl:with-param name="src" select="$src"/>
560 <xsl:with-param name="content" select="$css.node"/>
564 <xsl:call-template name="write.text.chunk">
565 <xsl:with-param name="filename" select="$filename"/>
566 <xsl:with-param name="content" select="$css.text"/>
573 <xsl:template name="css.output.filename">
574 <xsl:param name="content"/>
575 <xsl:param name="src" select="''"/>
577 <xsl:variable name="candidate">
579 <xsl:when test="string-length($src) = 0">
581 <xsl:text>ERROR: missing CSS input filename.</xsl:text>
584 <xsl:when test="substring($src,string-length($src)-3) = '.xml'">
585 <xsl:value-of select="substring($src, 1, string-length($src) - 4)"/>
588 <xsl:value-of select="$src"/>
592 <xsl:value-of select="$candidate"/>
595 <xsl:template name="css.output.pathname">
596 <xsl:param name="content"/>
597 <xsl:param name="src" select="''"/>
599 <xsl:variable name="file">
600 <xsl:call-template name="css.output.filename">
601 <xsl:with-param name="content" select="$content"/>
602 <xsl:with-param name="src" select="$src"/>
606 <xsl:variable name="path" select="concat($base.dir, $file)"/>
607 <xsl:value-of select="$path"/>