MoinLight

Annotated moinformat/resources/notugly.xsl

264:e54e87e26a07
2019-07-01 Paul Boddie Incorporated the notugly stylesheet into the distribution, also adding a fixlinks stylesheet which processes SVG output and introduces document index filenames where appropriate.
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>