1<?xml version="1.0"?> 2<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 3 xmlns:exsl="http://exslt.org/common" 4 xmlns:set="http://exslt.org/sets" 5 exclude-result-prefixes="exsl set" 6 version="1.0"> 7 8<!-- ******************************************************************** 9 $Id: html-rtf.xsl,v 1.11 2003/11/30 19:42:23 bobstayton Exp $ 10 ******************************************************************** 11 12 This file is part of the XSL DocBook Stylesheet distribution. 13 See /README or http://nwalsh.com/docbook/xsl/ for copyright 14 and other information. 15 16 ******************************************************************** --> 17 18<!-- ==================================================================== --> 19 20<!-- This module contains templates that match against HTML nodes. It is used 21 to post-process result tree fragments for some sorts of cleanup. 22 These templates can only ever be fired by a processor that supports 23 exslt:node-set(). --> 24 25<!-- ==================================================================== --> 26 27<!-- insert.html.p mode templates insert a particular RTF at the beginning 28 of the first paragraph in the primary RTF. --> 29 30<xsl:template match="/" mode="insert.html.p"> 31 <xsl:param name="mark" select="'?'"/> 32 <xsl:apply-templates mode="insert.html.p"> 33 <xsl:with-param name="mark" select="$mark"/> 34 </xsl:apply-templates> 35</xsl:template> 36 37<xsl:template match="*" mode="insert.html.p"> 38 <xsl:param name="mark" select="'?'"/> 39 <xsl:copy> 40 <xsl:copy-of select="@*"/> 41 <xsl:apply-templates mode="insert.html.p"> 42 <xsl:with-param name="mark" select="$mark"/> 43 </xsl:apply-templates> 44 </xsl:copy> 45</xsl:template> 46 47<xsl:template xmlns:html="http://www.w3.org/1999/xhtml" 48 match="html:p|p" mode="insert.html.p"> 49 <xsl:param name="mark" select="'?'"/> 50 <xsl:copy> 51 <xsl:copy-of select="@*"/> 52 <xsl:if test="not(preceding::p|preceding::html:p)"> 53 <xsl:copy-of select="$mark"/> 54 </xsl:if> 55 <xsl:apply-templates mode="insert.html.p"> 56 <xsl:with-param name="mark" select="$mark"/> 57 </xsl:apply-templates> 58 </xsl:copy> 59</xsl:template> 60 61<xsl:template match="text()|processing-instruction()|comment()" mode="insert.html.p"> 62 <xsl:param name="mark" select="'?'"/> 63 <xsl:copy/> 64</xsl:template> 65 66<!-- ==================================================================== --> 67 68<!-- insert.html.text mode templates insert a particular RTF at the beginning 69 of the first text-node in the primary RTF. --> 70 71<xsl:template match="/" mode="insert.html.text"> 72 <xsl:param name="mark" select="'?'"/> 73 <xsl:apply-templates mode="insert.html.text"> 74 <xsl:with-param name="mark" select="$mark"/> 75 </xsl:apply-templates> 76</xsl:template> 77 78<xsl:template match="*" mode="insert.html.text"> 79 <xsl:param name="mark" select="'?'"/> 80 <xsl:copy> 81 <xsl:copy-of select="@*"/> 82 <xsl:apply-templates mode="insert.html.text"> 83 <xsl:with-param name="mark" select="$mark"/> 84 </xsl:apply-templates> 85 </xsl:copy> 86</xsl:template> 87 88<xsl:template match="text()|processing-instruction()|comment()" mode="insert.html.text"> 89 <xsl:param name="mark" select="'?'"/> 90 91 <xsl:if test="not(preceding::text())"> 92 <xsl:copy-of select="$mark"/> 93 </xsl:if> 94 95 <xsl:copy/> 96</xsl:template> 97 98<xsl:template match="processing-instruction()|comment()" mode="insert.html.text"> 99 <xsl:param name="mark" select="'?'"/> 100 <xsl:copy/> 101</xsl:template> 102 103<!-- ==================================================================== --> 104 105<!-- unwrap.p mode templates remove blocks from HTML p elements (and 106 other places where blocks aren't allowed) --> 107 108<xsl:template name="unwrap.p"> 109 <xsl:param name="p"/> 110 <xsl:choose> 111 <xsl:when test="function-available('exsl:node-set') 112 and function-available('set:leading') 113 and function-available('set:trailing')"> 114 <xsl:apply-templates select="exsl:node-set($p)" mode="unwrap.p"/> 115 </xsl:when> 116 <xsl:otherwise> 117 <xsl:copy-of select="$p"/> 118 </xsl:otherwise> 119 </xsl:choose> 120</xsl:template> 121 122<xsl:template xmlns:html="http://www.w3.org/1999/xhtml" 123 match="html:p|p" mode="unwrap.p"> 124 <!-- xmlns:html is necessary for the xhtml stylesheet case --> 125 <xsl:variable name="blocks" xmlns:html="http://www.w3.org/1999/xhtml" 126 select="address|blockquote|div|hr|h1|h2|h3|h4|h5|h6 127 |layer|p|pre|table|dl|menu|ol|ul|form 128 |html:address|html:blockquote|html:div|html:hr 129 |html:h1|html:h2|html:h3|html:h4|html:h5|html:h6 130 |html:layer|html:p|html:pre|html:table|html:dl 131 |html:menu|html:ol|html:ul|html:form"/> 132 <xsl:choose> 133 <xsl:when test="$blocks"> 134 <xsl:call-template name="unwrap.p.nodes"> 135 <xsl:with-param name="wrap" select="."/> 136 <xsl:with-param name="first" select="1"/> 137 <xsl:with-param name="nodes" select="node()"/> 138 <xsl:with-param name="blocks" select="$blocks"/> 139 </xsl:call-template> 140 </xsl:when> 141 <xsl:otherwise> 142 <xsl:copy> 143 <xsl:copy-of select="@*"/> 144 <xsl:apply-templates mode="unwrap.p"/> 145 </xsl:copy> 146 </xsl:otherwise> 147 </xsl:choose> 148</xsl:template> 149 150<xsl:template match="*" mode="unwrap.p"> 151 <xsl:copy> 152 <xsl:copy-of select="@*"/> 153 <xsl:apply-templates mode="unwrap.p"/> 154 </xsl:copy> 155</xsl:template> 156 157<xsl:template match="text()|processing-instruction()|comment()" mode="unwrap.p"> 158 <xsl:copy/> 159</xsl:template> 160 161<xsl:template name="unwrap.p.nodes"> 162 <xsl:param name="wrap" select="."/> 163 <xsl:param name="first" select="0"/> 164 <xsl:param name="nodes"/> 165 <xsl:param name="blocks"/> 166 <xsl:variable name="block" select="$blocks[1]"/> 167 168 <!-- This template should never get called if these functions aren't available --> 169 <!-- but this test is still necessary so that processors don't choke on the --> 170 <!-- function calls if they don't support the set: functions --> 171 <xsl:if test="function-available('set:leading') 172 and function-available('set:trailing')"> 173 <xsl:choose> 174 <xsl:when test="$blocks"> 175 <xsl:variable name="leading" select="set:leading($nodes,$block)"/> 176 <xsl:variable name="trailing" select="set:trailing($nodes,$block)"/> 177 178 <xsl:if test="($wrap/@id and $first = 1) or $leading"> 179 <xsl:element name="{local-name($wrap)}" namespace="{namespace-uri($wrap)}"> 180 <xsl:for-each select="$wrap/@*"> 181 <xsl:if test="$first != 0 or local-name(.) != 'id'"> 182 <xsl:copy/> 183 </xsl:if> 184 </xsl:for-each> 185 <xsl:apply-templates select="$leading" mode="unwrap.p"/> 186 </xsl:element> 187 </xsl:if> 188 189 <xsl:apply-templates select="$block" mode="unwrap.p"/> 190 191 <xsl:if test="$trailing"> 192 <xsl:call-template name="unwrap.p.nodes"> 193 <xsl:with-param name="wrap" select="$wrap"/> 194 <xsl:with-param name="nodes" select="$trailing"/> 195 <xsl:with-param name="blocks" select="$blocks[position() > 1]"/> 196 </xsl:call-template> 197 </xsl:if> 198 </xsl:when> 199 200 <xsl:otherwise> 201 <xsl:if test="($wrap/@id and $first = 1) or $nodes"> 202 <xsl:element name="{local-name($wrap)}" namespace="{namespace-uri($wrap)}"> 203 <xsl:for-each select="$wrap/@*"> 204 <xsl:if test="$first != 0 or local-name(.) != 'id'"> 205 <xsl:copy/> 206 </xsl:if> 207 </xsl:for-each> 208 <xsl:apply-templates select="$nodes" mode="unwrap.p"/> 209 </xsl:element> 210 </xsl:if> 211 </xsl:otherwise> 212 </xsl:choose> 213 </xsl:if> 214</xsl:template> 215 216<!-- ==================================================================== --> 217<!-- make.verbatim.mode replaces spaces and newlines --> 218 219<xsl:template match="/" mode="make.verbatim.mode"> 220 <xsl:apply-templates mode="make.verbatim.mode"/> 221</xsl:template> 222 223<xsl:template match="*" mode="make.verbatim.mode"> 224 <xsl:copy> 225 <xsl:copy-of select="@*"/> 226 <xsl:apply-templates mode="make.verbatim.mode"/> 227 </xsl:copy> 228</xsl:template> 229 230<xsl:template match="processing-instruction()|comment()" mode="make.verbatim.mode"> 231 <xsl:copy/> 232</xsl:template> 233 234<xsl:template match="text()" mode="make.verbatim.mode"> 235 <xsl:variable name="text" select="translate(., ' ', ' ')"/> 236 237 <xsl:choose> 238 <xsl:when test="not(contains($text, '
'))"> 239 <xsl:value-of select="$text"/> 240 </xsl:when> 241 242 <xsl:otherwise> 243 <xsl:variable name="len" select="string-length($text)"/> 244 245 <xsl:choose> 246 <xsl:when test="$len = 1"> 247 <br/><xsl:text>
</xsl:text> 248 </xsl:when> 249 250 <xsl:otherwise> 251 <xsl:variable name="half" select="$len div 2"/> 252 <xsl:call-template name="make-verbatim-recursive"> 253 <xsl:with-param name="text" select="substring($text, 1, $half)"/> 254 </xsl:call-template> 255 <xsl:call-template name="make-verbatim-recursive"> 256 <xsl:with-param name="text" 257 select="substring($text, ($half + 1), $len)"/> 258 </xsl:call-template> 259 </xsl:otherwise> 260 </xsl:choose> 261 </xsl:otherwise> 262 </xsl:choose> 263</xsl:template> 264 265<xsl:template name="make-verbatim-recursive"> 266 <xsl:param name="text" select="''"/> 267 268 <xsl:choose> 269 <xsl:when test="not(contains($text, '
'))"> 270 <xsl:value-of select="$text"/> 271 </xsl:when> 272 273 <xsl:otherwise> 274 <xsl:variable name="len" select="string-length($text)"/> 275 276 <xsl:choose> 277 <xsl:when test="$len = 1"> 278 <br/><xsl:text>
</xsl:text> 279 </xsl:when> 280 281 <xsl:otherwise> 282 <xsl:variable name="half" select="$len div 2"/> 283 <xsl:call-template name="make-verbatim-recursive"> 284 <xsl:with-param name="text" select="substring($text, 1, $half)"/> 285 </xsl:call-template> 286 <xsl:call-template name="make-verbatim-recursive"> 287 <xsl:with-param name="text" 288 select="substring($text, ($half + 1), $len)"/> 289 </xsl:call-template> 290 </xsl:otherwise> 291 </xsl:choose> 292 </xsl:otherwise> 293 </xsl:choose> 294</xsl:template> 295 296<!-- ==================================================================== --> 297 298<!-- remove.empty.div mode templates remove empty blocks --> 299 300<xsl:template name="remove.empty.div"> 301 <xsl:param name="div"/> 302 <xsl:choose> 303 <xsl:when test="function-available('exsl:node-set')"> 304 <xsl:apply-templates select="exsl:node-set($div)" mode="remove.empty.div"/> 305 </xsl:when> 306 <xsl:otherwise> 307 <xsl:copy-of select="$div"/> 308 </xsl:otherwise> 309 </xsl:choose> 310</xsl:template> 311 312<xsl:template xmlns:html="http://www.w3.org/1999/xhtml" 313 match="html:p|p|html:div|div" mode="remove.empty.div"> 314 <xsl:if test="node()"> 315 <xsl:copy> 316 <xsl:copy-of select="@*"/> 317 <xsl:apply-templates mode="remove.empty.div"/> 318 </xsl:copy> 319 </xsl:if> 320</xsl:template> 321 322<xsl:template match="*" mode="remove.empty.div"> 323 <xsl:copy> 324 <xsl:copy-of select="@*"/> 325 <xsl:apply-templates mode="remove.empty.div"/> 326 </xsl:copy> 327</xsl:template> 328 329<xsl:template match="text()|processing-instruction()|comment()" mode="remove.empty.div"> 330 <xsl:copy/> 331</xsl:template> 332 333<!-- ==================================================================== --> 334 335</xsl:stylesheet> 336