1 <?xml version="1.0" ?> 2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 3 xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"> 4 <xsl:output method="xml" indent="yes" 5 doctype-public="-//W3C//DTD SVG 1.0//EN" 6 doctype-system="http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"/> 7 8 <xsl:variable name="text-style">font-size:10px; font-family:sans-serif;</xsl:variable> 9 10 <!-- Used to generate unique gradient fills for colors given by hex value 11 Search for generate-id to find where its used 12 --> 13 <xsl:key name="fills" match="*" use="@fill"/> 14 15 <xsl:template match="@*|node()"> 16 <xsl:copy> 17 <xsl:apply-templates select="@*|node()"/> 18 </xsl:copy> 19 </xsl:template> 20 21 <xsl:template match="svg:svg"> 22 <svg xmlns="http://www.w3.org/2000/svg"> 23 <!-- Order is important here, so the attributes below overrides the 24 originals, which are copied "wholesale" --> 25 <xsl:apply-templates select="@*" /> 26 27 <defs> 28 <linearGradient id="white" x1="0%" y1="0%" x2="0%" y2="0%"> 29 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 30 </linearGradient> 31 32 <linearGradient id="black" x1="0%" y1="0%" x2="0%" y2="0%"> 33 <stop offset="0%" style="stop-color:rgb(0,0,0);stop-opacity:1"/> 34 </linearGradient> 35 36 <linearGradient id="aquamarine" x1="0%" y1="0%" x2="100%" y2="100%"> 37 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 38 <stop offset="100%" style="stop-color:rgb(127,255,212);stop-opacity:1"/> 39 </linearGradient> 40 41 <linearGradient id="azure" x1="0%" y1="0%" x2="100%" y2="100%"> 42 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 43 <stop offset="100%" style="stop-color:rgb(240,255,255);stop-opacity:1"/> 44 </linearGradient> 45 46 <linearGradient id="blue" x1="0%" y1="0%" x2="100%" y2="100%"> 47 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 48 <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1"/> 49 </linearGradient> 50 51 <linearGradient id="blueviolet" x1="0%" y1="0%" x2="100%" y2="100%"> 52 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 53 <stop offset="100%" style="stop-color:rgb(138,43,226);stop-opacity:1"/> 54 </linearGradient> 55 56 <linearGradient id="brown" x1="0%" y1="0%" x2="100%" y2="100%"> 57 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 58 <stop offset="100%" style="stop-color:rgb(165,42,42);stop-opacity:1"/> 59 </linearGradient> 60 61 <linearGradient id="cadetblue" x1="0%" y1="0%" x2="100%" y2="100%"> 62 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 63 <stop offset="100%" style="stop-color:rgb(95,158,160);stop-opacity:1"/> 64 </linearGradient> 65 66 <linearGradient id="chocolate" x1="0%" y1="0%" x2="100%" y2="100%"> 67 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 68 <stop offset="100%" style="stop-color:rgb(210,105,30);stop-opacity:1"/> 69 </linearGradient> 70 71 <linearGradient id="cornflowerblue" x1="0%" y1="0%" x2="100%" y2="100%"> 72 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 73 <stop offset="100%" style="stop-color:rgb(100,149,237);stop-opacity:1"/> 74 </linearGradient> 75 76 <linearGradient id="crimson" x1="0%" y1="0%" x2="100%" y2="100%"> 77 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 78 <stop offset="100%" style="stop-color:rgb(220,20,60);stop-opacity:1"/> 79 </linearGradient> 80 81 <linearGradient id="cyan" x1="0%" y1="0%" x2="100%" y2="100%"> 82 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 83 <stop offset="100%" style="stop-color:rgb(0,255,255);stop-opacity:1"/> 84 </linearGradient> 85 86 <linearGradient id="darkgreen" x1="0%" y1="0%" x2="100%" y2="100%"> 87 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 88 <stop offset="100%" style="stop-color:rgb(0,100,0);stop-opacity:1"/> 89 </linearGradient> 90 91 <linearGradient id="darkorange" x1="0%" y1="0%" x2="100%" y2="100%"> 92 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 93 <stop offset="100%" style="stop-color:rgb(255,140,0);stop-opacity:1"/> 94 </linearGradient> 95 96 <linearGradient id="gold" x1="0%" y1="0%" x2="100%" y2="100%"> 97 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 98 <stop offset="100%" style="stop-color:rgb(255,215,0);stop-opacity:1"/> 99 </linearGradient> 100 101 <linearGradient id="gray" x1="0%" y1="0%" x2="100%" y2="100%"> 102 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 103 <stop offset="100%" style="stop-color:rgb(192,192,192);stop-opacity:1"/> 104 </linearGradient> 105 106 <linearGradient id="greenyellow" x1="0%" y1="0%" x2="100%" y2="100%"> 107 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 108 <stop offset="100%" style="stop-color:rgb(173,255,47);stop-opacity:1"/> 109 </linearGradient> 110 111 <linearGradient id="green" x1="0%" y1="0%" x2="100%" y2="100%"> 112 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 113 <stop offset="100%" style="stop-color:rgb(0,255,0);stop-opacity:1"/> 114 </linearGradient> 115 116 <linearGradient id="grey" x1="0%" y1="0%" x2="100%" y2="100%"> 117 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 118 <stop offset="100%" style="stop-color:rgb(192,192,192);stop-opacity:1"/> 119 </linearGradient> 120 121 <linearGradient id="hotpink" x1="0%" y1="0%" x2="100%" y2="100%"> 122 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 123 <stop offset="100%" style="stop-color:rgb(255,105,180);stop-opacity:1"/> 124 </linearGradient> 125 126 <linearGradient id="indianred" x1="0%" y1="0%" x2="100%" y2="100%"> 127 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 128 <stop offset="100%" style="stop-color:rgb(205,92,92);stop-opacity:1"/> 129 </linearGradient> 130 131 <linearGradient id="indigo" x1="0%" y1="0%" x2="100%" y2="100%"> 132 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 133 <stop offset="100%" style="stop-color:rgb(75,0,130);stop-opacity:1"/> 134 </linearGradient> 135 136 <linearGradient id="lavender" x1="0%" y1="0%" x2="100%" y2="100%"> 137 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 138 <stop offset="100%" style="stop-color:rgb(230,230,250);stop-opacity:1"/> 139 </linearGradient> 140 141 <linearGradient id="lightblue" x1="0%" y1="0%" x2="100%" y2="100%"> 142 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 143 <stop offset="100%" style="stop-color:rgb(173,216,230);stop-opacity:1"/> 144 </linearGradient> 145 146 <linearGradient id="lightgray" x1="0%" y1="0%" x2="100%" y2="100%"> 147 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 148 <stop offset="100%" style="stop-color:rgb(211,211,211);stop-opacity:1"/> 149 </linearGradient> 150 151 <linearGradient id="lightgrey" x1="0%" y1="0%" x2="100%" y2="100%"> 152 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 153 <stop offset="100%" style="stop-color:rgb(211,211,211);stop-opacity:1"/> 154 </linearGradient> 155 156 <linearGradient id="magenta" x1="0%" y1="0%" x2="100%" y2="100%"> 157 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 158 <stop offset="100%" style="stop-color:rgb(255,0,255);stop-opacity:1"/> 159 </linearGradient> 160 161 <linearGradient id="maroon" x1="0%" y1="0%" x2="100%" y2="100%"> 162 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 163 <stop offset="100%" style="stop-color:rgb(176,48,96);stop-opacity:1"/> 164 </linearGradient> 165 166 <linearGradient id="mediumblue" x1="0%" y1="0%" x2="100%" y2="100%"> 167 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 168 <stop offset="100%" style="stop-color:rgb(0,0,205);stop-opacity:1"/> 169 </linearGradient> 170 171 <linearGradient id="mediumpurple" x1="0%" y1="0%" x2="100%" y2="100%"> 172 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 173 <stop offset="100%" style="stop-color:rgb(147,112,219);stop-opacity:1"/> 174 </linearGradient> 175 176 <linearGradient id="orange" x1="0%" y1="0%" x2="100%" y2="100%"> 177 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 178 <stop offset="100%" style="stop-color:rgb(255,165,0);stop-opacity:1"/> 179 </linearGradient> 180 181 <linearGradient id="pink" x1="0%" y1="0%" x2="100%" y2="100%"> 182 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 183 <stop offset="100%" style="stop-color:rgb(255,192,203);stop-opacity:1"/> 184 </linearGradient> 185 186 <linearGradient id="purple" x1="0%" y1="0%" x2="100%" y2="100%"> 187 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 188 <stop offset="100%" style="stop-color:rgb(160,32,240);stop-opacity:1"/> 189 </linearGradient> 190 191 <linearGradient id="red" x1="0%" y1="0%" x2="100%" y2="100%"> 192 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 193 <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1"/> 194 </linearGradient> 195 196 <linearGradient id="steelblue" x1="0%" y1="0%" x2="100%" y2="100%"> 197 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 198 <stop offset="100%" style="stop-color:rgb(70,130,180);stop-opacity:1"/> 199 </linearGradient> 200 201 <linearGradient id="violet" x1="0%" y1="0%" x2="100%" y2="100%"> 202 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 203 <stop offset="100%" style="stop-color:rgb(238,130,238);stop-opacity:1"/> 204 </linearGradient> 205 206 <linearGradient id="yellow" x1="0%" y1="0%" x2="100%" y2="100%"> 207 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 208 <stop offset="100%" style="stop-color:rgb(255,255,0);stop-opacity:1"/> 209 </linearGradient> 210 211 <linearGradient id="none" x1="0%" y1="0%" x2="100%" y2="100%"> 212 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 213 <stop offset="100%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 214 </linearGradient> 215 216 <xsl:for-each select="*//*[generate-id() = generate-id(key('fills',@fill)[1])][substring(@fill,1,1)='#']"> 217 <linearGradient x1="0%" y1="0%" x2="100%" y2="100%"> 218 <xsl:attribute name="id">fill-<xsl:value-of select="substring(@fill,2,6)"/></xsl:attribute> 219 <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:1"/> 220 <stop offset="100%"> 221 <xsl:attribute name="style">stop-color:<xsl:value-of select="@fill" />;stop-opacity:1</xsl:attribute> 222 </stop> 223 </linearGradient> 224 </xsl:for-each> 225 226 </defs> 227 228 229 <xsl:apply-templates /> 230 </svg> 231 </xsl:template> 232 233 <!-- Match the top most "g" --> 234 <xsl:template match="/svg:svg/svg:g"> 235 <g> 236 <xsl:apply-templates select="@*"/> 237 <!-- Graphviz uses a polygon as the background. Don't want a gradient there --> 238 <xsl:for-each select="svg:polygon"> 239 <xsl:copy><xsl:apply-templates select="@*" /></xsl:copy> 240 </xsl:for-each> 241 <xsl:apply-templates select="svg:title|svg:g" /> 242 </g> 243 </xsl:template> 244 245 246 <xsl:template match="svg:text"> 247 <text> 248 <xsl:apply-templates select="@*" /> 249 <xsl:if test="not(@font-family) and not(@font-size)"> 250 <xsl:attribute name="style"><xsl:value-of select="$text-style" /></xsl:attribute> 251 </xsl:if> 252 <xsl:apply-templates select="text()"/> 253 </text> 254 </xsl:template> 255 256 257 <xsl:template match="svg:g"> 258 <xsl:copy> 259 <xsl:apply-templates select="@*" /> 260 <xsl:choose> 261 <!-- Handle linked groups. --> 262 <xsl:when test="svg:a"> 263 <xsl:for-each select="svg:a"> 264 <xsl:copy> 265 <xsl:apply-templates select="@*" /> 266 <xsl:call-template name="group"> 267 <xsl:with-param name="class" select="../@class"/> 268 </xsl:call-template> 269 </xsl:copy> 270 </xsl:for-each> 271 </xsl:when> 272 <!-- Handle bare groups. --> 273 <xsl:otherwise> 274 <xsl:call-template name="group"/> 275 </xsl:otherwise> 276 </xsl:choose> 277 </xsl:copy> 278 </xsl:template> 279 280 281 <xsl:template name="group"> 282 <xsl:param name="class" select="@class"/> 283 284 <xsl:for-each select="svg:polygon|svg:ellipse"> 285 <xsl:call-template name="poly-shadow" /> 286 </xsl:for-each> 287 288 <xsl:choose> 289 <!-- Rewrite node outlines. --> 290 <xsl:when test="$class='node' and svg:path|svg:polyline"> 291 <xsl:call-template name="node-outline"> 292 <xsl:with-param name="current" select="*[1]"/> 293 <xsl:with-param name="style">shadow</xsl:with-param> 294 <xsl:with-param name="first" select="true()"/> 295 </xsl:call-template> 296 </xsl:when> 297 <xsl:otherwise> 298 <xsl:for-each select="svg:path"> 299 <xsl:call-template name="path-shadow-edge" /> 300 </xsl:for-each> 301 </xsl:otherwise> 302 </xsl:choose> 303 304 <xsl:for-each select="svg:polygon|svg:ellipse"> 305 <xsl:sort select="@ry" order="descending" /> 306 <xsl:call-template name="poly-main" /> 307 </xsl:for-each> 308 309 <xsl:choose> 310 <!-- Rewrite node outlines. --> 311 <xsl:when test="$class='node' and svg:path"> 312 <xsl:for-each select="svg:path"> 313 <xsl:call-template name="node-outline"> 314 <xsl:with-param name="current" select="."/> 315 <xsl:with-param name="first" select="true()"/> 316 </xsl:call-template> 317 </xsl:for-each> 318 </xsl:when> 319 <xsl:when test="$class='node' and svg:polyline"> 320 <xsl:for-each select="svg:polyline"> 321 <xsl:call-template name="node-outline"> 322 <xsl:with-param name="current" select="."/> 323 <xsl:with-param name="first" select="true()"/> 324 </xsl:call-template> 325 </xsl:for-each> 326 </xsl:when> 327 <xsl:otherwise> 328 <xsl:for-each select="svg:path"> 329 <path><xsl:apply-templates select="@*" /></path> 330 </xsl:for-each> 331 </xsl:otherwise> 332 </xsl:choose> 333 334 <xsl:apply-templates select="svg:text" /> 335 </xsl:template> 336 337 <xsl:template name="node-outline"> 338 <xsl:param name="path-so-far"/> 339 <xsl:param name="current"/> 340 <xsl:param name="style"/> 341 <xsl:param name="first" select="false()"/> 342 343 <xsl:choose> 344 <!-- Visit each child element, collecting the path details. --> 345 <xsl:when test="$current"> 346 <xsl:choose> 347 <xsl:when test="local-name($current) = 'path'"> 348 <xsl:call-template name="filter-path"> 349 <xsl:with-param name="path-so-far" select="$path-so-far"/> 350 <xsl:with-param name="point" select="substring-before($current/@d, 'C')"/> 351 <xsl:with-param name="points" select="concat('C', substring-after($current/@d, 'C'))"/> 352 <xsl:with-param name="current" select="$current"/> 353 <xsl:with-param name="style" select="$style"/> 354 <xsl:with-param name="include" select="$first"/> 355 </xsl:call-template> 356 </xsl:when> 357 <xsl:when test="local-name($current) = 'polyline'"> 358 <xsl:call-template name="polyline-to-path"> 359 <xsl:with-param name="path-so-far" select="$path-so-far"/> 360 <xsl:with-param name="point" select="concat('M', substring-before($current/@points, ' '))"/> 361 <xsl:with-param name="points" select="substring-after($current/@points, ' ')"/> 362 <xsl:with-param name="current" select="$current"/> 363 <xsl:with-param name="style" select="$style"/> 364 <xsl:with-param name="include" select="$first"/> 365 </xsl:call-template> 366 </xsl:when> 367 <xsl:otherwise> 368 <xsl:call-template name="node-outline"> 369 <xsl:with-param name="path-so-far" select="$path-so-far"/> 370 <xsl:with-param name="current" select="$current/following-sibling::*[1]"/> 371 <xsl:with-param name="style" select="$style"/> 372 <xsl:with-param name="first" select="$first"/> 373 </xsl:call-template> 374 </xsl:otherwise> 375 </xsl:choose> 376 </xsl:when> 377 <!-- With no more elements to visit, generate the path. --> 378 <xsl:otherwise> 379 <xsl:choose> 380 <xsl:when test="$style = 'shadow'"> 381 <path style="fill: black; stroke: none; fill-opacity:0.15" transform="translate(3,3)" 382 d="{$path-so-far}"/> 383 </xsl:when> 384 <xsl:otherwise> 385 <!-- Provide the path attributes using dynamic colour discoveries. --> 386 <xsl:element name="path"> 387 <xsl:attribute name="d"><xsl:value-of select="$path-so-far"/></xsl:attribute> 388 <xsl:call-template name="make-style-attribute"> 389 <xsl:with-param name="fill" 390 select="normalize-space(substring-after(substring-before(ancestor::*[svg:polygon]/svg:polygon[1]/@style,';'),'fill:'))"/> 391 <xsl:with-param name="fill-explicit" 392 select="@fill"/> 393 <xsl:with-param name="stroke" 394 select="normalize-space(substring-after(substring-before(ancestor::*[svg:polygon]/svg:polygon[1]/@style,';'),'stroke:'))"/> 395 <xsl:with-param name="stroke-explicit">black</xsl:with-param> 396 <xsl:with-param name="none-is-transparent" select="true()"/> 397 </xsl:call-template> 398 </xsl:element> 399 </xsl:otherwise> 400 </xsl:choose> 401 </xsl:otherwise> 402 </xsl:choose> 403 </xsl:template> 404 405 <xsl:template name="filter-path"> 406 <xsl:param name="path-so-far"/> 407 <xsl:param name="point"/> 408 <xsl:param name="points"/> 409 <xsl:param name="current"/> 410 <xsl:param name="style"/> 411 <xsl:param name="include" select="true()"/> 412 413 <xsl:variable name="next" select="substring-before($points, ' ')"/> 414 <xsl:variable name="remaining" select="substring-after($points, ' ')"/> 415 416 <xsl:choose> 417 <!-- With path points remaining, include the current point if appropriate 418 and visit those remaining. --> 419 <xsl:when test="$remaining"> 420 <xsl:choose> 421 <xsl:when test="$include"> 422 <xsl:call-template name="filter-path"> 423 <xsl:with-param name="path-so-far" select="concat($path-so-far, ' ', $point)"/> 424 <xsl:with-param name="point" select="$next"/> 425 <xsl:with-param name="points" select="$remaining"/> 426 <xsl:with-param name="current" select="$current"/> 427 <xsl:with-param name="style" select="$style"/> 428 </xsl:call-template> 429 </xsl:when> 430 <xsl:otherwise> 431 <xsl:call-template name="filter-path"> 432 <xsl:with-param name="path-so-far" select="$path-so-far"/> 433 <xsl:with-param name="point" select="$next"/> 434 <xsl:with-param name="points" select="$remaining"/> 435 <xsl:with-param name="current" select="$current"/> 436 <xsl:with-param name="style" select="$style"/> 437 </xsl:call-template> 438 </xsl:otherwise> 439 </xsl:choose> 440 </xsl:when> 441 <!-- With up to one remaining after this point, include the current point, 442 if appropriate, and the one remaining. --> 443 <xsl:otherwise> 444 <xsl:choose> 445 <xsl:when test="$include"> 446 <xsl:call-template name="node-outline"> 447 <xsl:with-param name="path-so-far" select="concat($path-so-far, ' ', $point, ' ', $points)"/> 448 <xsl:with-param name="current" select="$current/following-sibling::*[1]"/> 449 <xsl:with-param name="style" select="$style"/> 450 </xsl:call-template> 451 </xsl:when> 452 <xsl:otherwise> 453 <xsl:call-template name="node-outline"> 454 <xsl:with-param name="path-so-far" select="concat($path-so-far, ' ', $points)"/> 455 <xsl:with-param name="current" select="$current/following-sibling::*[1]"/> 456 <xsl:with-param name="style" select="$style"/> 457 </xsl:call-template> 458 </xsl:otherwise> 459 </xsl:choose> 460 </xsl:otherwise> 461 </xsl:choose> 462 </xsl:template> 463 464 <xsl:template name="polyline-to-path"> 465 <xsl:param name="path-so-far"/> 466 <xsl:param name="point"/> 467 <xsl:param name="points"/> 468 <xsl:param name="current"/> 469 <xsl:param name="style"/> 470 <xsl:param name="include" select="true()"/> 471 472 <xsl:variable name="next" select="substring-before($points, ' ')"/> 473 <xsl:variable name="remaining" select="substring-after($points, ' ')"/> 474 475 <xsl:choose> 476 <!-- With path points remaining, include the current point if appropriate 477 and visit those remaining. --> 478 <xsl:when test="$remaining"> 479 <xsl:choose> 480 <xsl:when test="$include"> 481 <xsl:call-template name="polyline-to-path"> 482 <xsl:with-param name="path-so-far" select="concat($path-so-far, ' ', $point)"/> 483 <xsl:with-param name="point" select="concat('L', $next)"/> 484 <xsl:with-param name="points" select="$remaining"/> 485 <xsl:with-param name="current" select="$current"/> 486 <xsl:with-param name="style" select="$style"/> 487 </xsl:call-template> 488 </xsl:when> 489 <xsl:otherwise> 490 <xsl:call-template name="polyline-to-path"> 491 <xsl:with-param name="path-so-far" select="$path-so-far"/> 492 <xsl:with-param name="point" select="concat('L', $next)"/> 493 <xsl:with-param name="points" select="$remaining"/> 494 <xsl:with-param name="current" select="$current"/> 495 <xsl:with-param name="style" select="$style"/> 496 </xsl:call-template> 497 </xsl:otherwise> 498 </xsl:choose> 499 </xsl:when> 500 <!-- With up to one remaining after this point, include the current point, 501 if appropriate, and the one remaining. --> 502 <xsl:otherwise> 503 <xsl:choose> 504 <xsl:when test="$include"> 505 <xsl:call-template name="node-outline"> 506 <xsl:with-param name="path-so-far" select="concat($path-so-far, ' ', $point, ' L', $points)"/> 507 <xsl:with-param name="current" select="$current/following-sibling::*[2]"/> 508 <xsl:with-param name="style" select="$style"/> 509 </xsl:call-template> 510 </xsl:when> 511 <xsl:otherwise> 512 <xsl:call-template name="node-outline"> 513 <xsl:with-param name="path-so-far" select="concat($path-so-far, ' L', $points)"/> 514 <xsl:with-param name="current" select="$current/following-sibling::*[1]"/> 515 <xsl:with-param name="style" select="$style"/> 516 </xsl:call-template> 517 </xsl:otherwise> 518 </xsl:choose> 519 </xsl:otherwise> 520 </xsl:choose> 521 </xsl:template> 522 523 <xsl:template name="poly-shadow"> 524 <xsl:element name="{name()}"> 525 <xsl:apply-templates select="@*"/> 526 <xsl:attribute name="style">fill: black; stroke: none; fill-opacity:0.3</xsl:attribute> 527 <xsl:attribute name="transform">translate(3,3)</xsl:attribute> 528 </xsl:element> 529 </xsl:template> 530 531 <xsl:template name="path-shadow-edge"> 532 <xsl:element name="{name()}"> 533 <xsl:apply-templates select="@*"/> 534 <xsl:attribute name="style">fill: none; stroke: black; stroke-opacity:0.3</xsl:attribute> 535 <xsl:attribute name="transform">translate(3,3)</xsl:attribute> 536 </xsl:element> 537 </xsl:template> 538 539 <xsl:template name="poly-main"> 540 <xsl:element name="{name()}"> 541 <xsl:apply-templates select="@*" /> 542 <xsl:call-template name="make-style-attribute"> 543 <xsl:with-param name="fill" 544 select="normalize-space(substring-after(substring-before(@style,';'),'fill:'))"/> 545 <xsl:with-param name="fill-explicit" 546 select="@fill"/> 547 <xsl:with-param name="stroke" 548 select="normalize-space(substring-after(substring-after(@style,';'),'stroke:'))"/> 549 <xsl:with-param name="stroke-explicit" 550 select="@stroke"/> 551 </xsl:call-template> 552 </xsl:element> 553 </xsl:template> 554 555 <xsl:template name="path-main"> 556 <path> 557 <xsl:apply-templates select="@*" /> 558 <!-- This is somewhat broken - the gradient is set based on the position/size of the element it is used with; as a result it doesn't line up properly with the main polygon --> 559 <xsl:call-template name="make-style-attribute"> 560 <xsl:with-param name="fill" 561 select="normalize-space(substring-after(substring-before(ancestor::*[svg:polygon]/svg:polygon[1]/@style,';'),'fill:'))"/> 562 <xsl:with-param name="fill-explicit" 563 select="ancestor::*[svg:polygon]/svg:polygon[1]/@fill"/> 564 <xsl:with-param name="stroke" 565 select="normalize-space(substring-after(substring-before(ancestor::*[svg:polygon]/svg:polygon[1]/@style,';'),'stroke:'))"/> 566 <xsl:with-param name="stroke-explicit">black</xsl:with-param> 567 </xsl:call-template> 568 </path> 569 </xsl:template> 570 571 <xsl:template name="make-style-attribute"> 572 <xsl:param name="fill"/> 573 <xsl:param name="fill-explicit"/> 574 <xsl:param name="stroke"/> 575 <xsl:param name="stroke-explicit"/> 576 <xsl:param name="none-is-transparent" select="false()"/> 577 578 <xsl:attribute name="style"> 579 <xsl:choose> 580 <xsl:when test="$fill and (not($none-is-transparent) or $fill != 'none')"> 581 <xsl:call-template name="make-style-fill"> 582 <xsl:with-param name="fill" select="$fill"/> 583 </xsl:call-template> 584 </xsl:when> 585 <xsl:when test="$fill-explicit and (not($none-is-transparent) or $fill-explicit != 'none')"> 586 <xsl:choose> 587 <xsl:when test="starts-with($fill-explicit, '#')"> 588 <xsl:call-template name="make-style-fill"> 589 <xsl:with-param name="fill" select="$fill-explicit"/> 590 </xsl:call-template> 591 </xsl:when> 592 <xsl:otherwise>fill: url(#<xsl:value-of select="$fill-explicit"/>);</xsl:otherwise> 593 </xsl:choose> 594 </xsl:when> 595 <xsl:otherwise>fill: none;</xsl:otherwise> 596 </xsl:choose> 597 <xsl:choose> 598 <xsl:when test="$stroke">stroke: <xsl:value-of select="$stroke"/>;</xsl:when> 599 <xsl:when test="$stroke-explicit">stroke: <xsl:value-of select="$stroke-explicit"/>;</xsl:when> 600 <xsl:otherwise>stroke: black;</xsl:otherwise> 601 </xsl:choose> 602 </xsl:attribute> 603 </xsl:template> 604 605 <xsl:template name="make-style-fill"> 606 <xsl:param name="fill"/> 607 <xsl:choose> 608 <xsl:when test="substring($fill,1,1) = '#'">fill: url(#fill-<xsl:value-of select="substring($fill,2,6)"/>);</xsl:when> 609 <xsl:otherwise>fill: url(#<xsl:value-of select="$fill"/>);</xsl:otherwise> 610 </xsl:choose> 611 </xsl:template> 612 613 </xsl:stylesheet>