Attachment 'svgpathconsolidater.xsl'

Download

   1 <?xml version="1.0" encoding="ISO-8859-1"?>
   2 
   3 <!--
   4     SVG path consolidater
   5 
   6     This consolidates consecutive <path> elements.
   7 
   8     Copyright (c) 2006 Awarix, Inc. All rights reserved.
   9 
  10     Redistribution and use in source and binary forms, with or without
  11     modification, are permitted provided that the following conditions are met:
  12 
  13         * Redistributions of source code must retain the above copyright
  14           notice, this list of conditions and the following disclaimer.
  15         * Redistributions in binary form must reproduce the above copyright
  16           notice, this list of conditions and the following disclaimer in the
  17           documentation and/or other materials provided with the distribution.
  18         * Neither the name Awarix nor the names of its contributors may be used
  19           to endorse or promote products derived from this software without
  20           specific prior written permission.
  21 
  22     THIS SOFTWARE IS PROVIDED BY AWARIX AND CONTRIBUTORS ``AS IS'' AND ANY
  23     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25     DISCLAIMED. IN NO EVENT SHALL AWARIX AND CONTRIBUTORS BE LIABLE FOR ANY
  26     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  29     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32 
  33     $Id: svgpathconsolidater.xsl 11021 2006-10-20 01:41:34Z archie $
  34 -->
  35 
  36 <xsl:transform version="1.0"
  37   xmlns="http://www.w3.org/2000/svg"
  38   xmlns:svg="http://www.w3.org/2000/svg"
  39   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  40 
  41     <xsl:output method="xml" encoding="UTF-8" indent="yes" media-type="text/svg+xml"/>
  42 
  43     <xsl:variable name="revision">$Id: svgpathconsolidater.xsl 11021 2006-10-20 01:41:34Z archie $</xsl:variable>
  44 
  45     <!-- Maximum number of consecutive paths to consolidate -->
  46     <xsl:variable name="MAX_PATHS" select="100"/>
  47 
  48     <xsl:template match="/">
  49         <xsl:copy>
  50             <xsl:value-of select="'&#10;'"/>
  51             <xsl:comment> Paths consolidated via Awarix SVG path consolidater. </xsl:comment>
  52             <xsl:value-of select="'&#10;'"/>
  53             <xsl:comment> Copyright (c) 2006 Awarix, Inc. All rights reserved. </xsl:comment>
  54             <xsl:value-of select="'&#10;'"/>
  55             <xsl:comment><xsl:value-of select="concat(' ', $revision, ' ')"/></xsl:comment>
  56             <xsl:value-of select="'&#10;'"/>
  57             <xsl:value-of select="'&#10;'"/>
  58             <xsl:apply-templates select="@*|node()|processing-instruction()"/>
  59         </xsl:copy>
  60     </xsl:template>
  61 
  62     <!--
  63         Match nodes that have two or more <path> elements as children
  64     -->
  65     <xsl:template match="svg:path">
  66 
  67         <!-- Get preceding sibling -->
  68         <xsl:variable name="prec" select="preceding-sibling::*[1]"/>
  69 
  70         <!-- Only recurse on the first <path> in a sequence -->
  71         <xsl:if test="namespace-uri(.) = 'http://www.w3.org/2000/svg' and local-name(.) = 'path'
  72           and (not($prec) or namespace-uri($prec) != 'http://www.w3.org/2000/svg' or local-name($prec) != 'path')">
  73             <xsl:call-template name="consolidatePaths">
  74                 <xsl:with-param name="node" select="."/>
  75             </xsl:call-template>
  76         </xsl:if>
  77     </xsl:template>
  78 
  79     <!-- Consolidate a path with its consecutive subsequent siblings -->
  80     <xsl:template name="consolidatePaths">
  81         <xsl:param name="node"/>
  82 
  83         <!-- Count how many subsequent siblings are compatible -->
  84         <xsl:variable name="numCompatibleSiblings">
  85             <xsl:call-template name="countCompatibleFollowers">
  86                 <xsl:with-param name="firstNode" select="$node"/>
  87                 <xsl:with-param name="nextNode" select="$node/following-sibling::*[1]"/>
  88             </xsl:call-template>
  89         </xsl:variable>
  90 
  91         <!-- Emit path with consolidated description -->
  92         <path>
  93             <xsl:apply-templates select="$node/@*[namespace-uri(.)
  94               or (local-name(.) != 'd' and local-name(.) != 'pathLength')]"/>
  95             <xsl:attribute name="d">
  96                 <xsl:value-of select="$node/@d"/>
  97                 <xsl:for-each select="$node/following-sibling::*[position() &lt;= $numCompatibleSiblings]">
  98                     <xsl:call-template name="appendPathDescription">
  99                         <xsl:with-param name="node" select="."/>
 100                     </xsl:call-template>
 101                 </xsl:for-each>
 102             </xsl:attribute>
 103         </path>
 104         <xsl:value-of select="'&#10;'"/>
 105 
 106         <!-- Get the next unconsolidated sibling and recurse if it's a <path> -->
 107         <xsl:variable name="nextSibling" select="$node/following-sibling::*[$numCompatibleSiblings + 1]"/>
 108         <xsl:if test="namespace-uri($nextSibling) = 'http://www.w3.org/2000/svg' and local-name($nextSibling) = 'path'">
 109             <xsl:call-template name="consolidatePaths">
 110                 <xsl:with-param name="node" select="$nextSibling"/>
 111             </xsl:call-template>
 112         </xsl:if>
 113     </xsl:template>
 114 
 115     <!-- Template to count how many subsequent siblings are compatible -->
 116     <xsl:template name="countCompatibleFollowers">
 117         <xsl:param name="firstNode"/>
 118         <xsl:param name="nextNode"/>
 119         <xsl:param name="count" select="0"/>
 120         <xsl:choose>
 121             <xsl:when test="namespace-uri($nextNode) = 'http://www.w3.org/2000/svg' and local-name($nextNode) = 'path'">
 122                 <xsl:variable name="nextNodeIsCompatible">
 123                     <xsl:call-template name="sameAttributes">
 124                         <xsl:with-param name="node1" select="$firstNode"/>
 125                         <xsl:with-param name="node2" select="$nextNode"/>
 126                     </xsl:call-template>
 127                 </xsl:variable>
 128                 <xsl:choose>
 129                     <xsl:when test="$count &lt; $MAX_PATHS and $nextNodeIsCompatible = 'true'">
 130                         <xsl:call-template name="countCompatibleFollowers">
 131                             <xsl:with-param name="firstNode" select="$firstNode"/>
 132                             <xsl:with-param name="nextNode" select="$nextNode/following-sibling::*[1]"/>
 133                             <xsl:with-param name="count" select="$count + 1"/>
 134                         </xsl:call-template>
 135                     </xsl:when>
 136                     <xsl:otherwise>
 137                         <xsl:value-of select="$count"/>
 138                     </xsl:otherwise>
 139                 </xsl:choose>
 140             </xsl:when>
 141             <xsl:otherwise>
 142                 <xsl:value-of select="$count"/>
 143             </xsl:otherwise>
 144         </xsl:choose>
 145     </xsl:template>
 146 
 147     <!-- Template to append a path descriptions -->
 148     <xsl:template name="appendPathDescription">
 149         <xsl:param name="node"/>
 150         <xsl:choose>
 151             <xsl:when test="substring(normalize-space($node/@d), 1, 1) = 'm'">
 152                 <xsl:value-of select="concat(' M', substring(normalize-space($node/@d), 2))"/>
 153             </xsl:when>
 154             <xsl:otherwise>
 155                 <xsl:value-of select="concat(' ', normalize-space($node/@d))"/>
 156             </xsl:otherwise>
 157         </xsl:choose>
 158     </xsl:template>
 159 
 160     <!-- Determine if two path nodes have the same attributes besides 'd' and 'pathLength' -->
 161     <xsl:template name="sameAttributes">
 162         <xsl:param name="node1"/>
 163         <xsl:param name="node2"/>
 164         <xsl:variable name="result1">
 165             <xsl:for-each select="$node1/@*[namespace-uri(.) or (local-name(.) != 'd' and local-name(.) != 'pathLength')]">
 166                 <xsl:call-template name="hasSameAttribute">
 167                     <xsl:with-param name="node" select="$node2"/>
 168                     <xsl:with-param name="uri" select="namespace-uri(.)"/>
 169                     <xsl:with-param name="name" select="local-name(.)"/>
 170                     <xsl:with-param name="value" select="string(.)"/>
 171                 </xsl:call-template>
 172             </xsl:for-each>
 173         </xsl:variable>
 174         <xsl:variable name="result2">
 175             <xsl:if test="$result1 = ''">
 176                 <xsl:for-each select="$node2/@*[namespace-uri(.) or (local-name(.) != 'd' and local-name(.) != 'pathLength')]">
 177                     <xsl:call-template name="hasSameAttribute">
 178                         <xsl:with-param name="node" select="$node1"/>
 179                         <xsl:with-param name="uri" select="namespace-uri(.)"/>
 180                         <xsl:with-param name="name" select="local-name(.)"/>
 181                         <xsl:with-param name="value" select="string(.)"/>
 182                     </xsl:call-template>
 183                 </xsl:for-each>
 184             </xsl:if>
 185         </xsl:variable>
 186         <xsl:variable name="result">
 187             <xsl:choose>
 188                 <xsl:when test="$result1 = '' and $result2 = ''">true</xsl:when>
 189                 <xsl:otherwise>false</xsl:otherwise>
 190             </xsl:choose>
 191         </xsl:variable>
 192         <xsl:value-of select="$result"/>
 193     </xsl:template>
 194 
 195     <!-- Determine node has the specified attribute and value -->
 196     <xsl:template name="hasSameAttribute">
 197         <xsl:param name="node"/>
 198         <xsl:param name="uri"/>
 199         <xsl:param name="name"/>
 200         <xsl:param name="value"/>
 201         <xsl:if test="count($node/@*[namespace-uri(.) = $uri and local-name(.) = $name and string(.) = $value]) = 0">
 202             <xsl:value-of select="concat('@', $name)"/>
 203         </xsl:if>
 204     </xsl:template>
 205 
 206     <!-- Copy everything else unmodified -->
 207     <xsl:template match="@*|node()">
 208         <xsl:copy>
 209             <xsl:apply-templates select="@*|node()"/>
 210         </xsl:copy>
 211     </xsl:template>
 212 
 213 </xsl:transform>

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.