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