oops, SetZoomFactor is not accessable in managed
[moon.git] / tools / svg2xaml / svg2xaml_standalone.xslt
blob4827253e362e0d71a77ca4c9e79f05bae8867c38
1 <?xml version="1.0" encoding="UTF-8"?>
3 <!--
4 //
5 // svg2xaml_standalone.xslt
6 //
7 // This stylesheet converts svg to xaml, without using the node-set function
8 //
9 //
12 // Author:
13 // Andreia Gaita (avidigal@novell.com)
15 // Copyright 2007 Novell, Inc.
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
24 //
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
27 //
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 -->
38 <xsl:stylesheet version="1.0"
39 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
40 xmlns:svg="http://www.w3.org/2000/svg"
41 xmlns:xlink="http://www.w3.org/1999/xlink"
42 xmlns:xaml="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
43 exclude-result-prefixes="svg xsl xaml xlink"
46 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
48 <!--- maps svg names into xaml names -->
49 <xsl:variable name="mappings">
50 <mappings>
51 <mapping name="id" value="Name" type="attribute"/>
53 <mapping name="stroke" value="Stroke" type="attribute"/>
54 <mapping name="fill" value="Fill" type="attribute">
55 <ignore>none</ignore>
56 </mapping>
57 <mapping name="fill" parent="text" value="Foreground" type="attribute"/>
58 <mapping name="transform" value="RenderTransform" type="element" template="transform" prefixParent="true"/>
59 <mapping name="gradientTransform" value="RenderTransform" type="element" template="transform" prefixParent="true"/>
60 <mapping name="viewBox" value="RenderTransform" type="element" template="viewBox" prefixParent="true" names="x y Width Height" filter="local"/>
62 <mapping name="stroke-linejoin" value="StrokeLineJoin" type="attribute"/>
63 <mapping name="stroke-width" value="StrokeThickness" type="attribute"/>
64 <mapping name="stroke-linecap" value="StrokeEndLineCap" type="attribute" />
66 <mapping name="font-size" value="FontSize" type="attribute"/>
67 <mapping name="text-anchor" value="AlignmentX" type="attribute">
68 <value name="middle" value="Centered"></value>
69 </mapping>
70 <mapping name="x" value="Canvas.Left" type="attribute" filter="local"/>
71 <mapping name="y" value="Canvas.Top" type="attribute" filter="local"/>
73 <mapping name="x" value="X" parent="viewBox" type="attribute" filter="local" op="mul" opval="-1">
74 <ignore>0</ignore>
75 </mapping>
76 <mapping name="y" value="Y" parent="viewBox" type="attribute" filter="local" op="mul" opval="-1">
77 <ignore>0</ignore>
78 </mapping>
79 <mapping name="rx" value="Width" type="attribute" filter="local"/>
80 <mapping name="ry" value="Height" type="attribute" filter="local"/>
81 <mapping name="cx" value="Canvas.Left" type="attribute" filter="local"/>
82 <mapping name="cy" value="Canvas.Top" type="attribute" filter="local"/>
83 <mapping name="r" type="attribute"/>
84 <mapping name="r" value="X" parent="radialGradient" prefix="Radius" type="attribute"/>
85 <mapping name="offset" value="Offset" type="attribute" />
86 <mapping name="stop-color" value="Color" type="attribute" />
87 <mapping name="style" value="Style" type="attribute" />
88 <mapping name="d" value="Data" type="attribute" />
89 <mapping name="xlink:href" />
91 <mapping name="path" value="Path" type="element"/>
92 <mapping name="text" value="Text" type="element"/>
93 <mapping name="ellipse" value="Ellipse" type="element"/>
94 <mapping name="circle" value="Ellipse" type="element"/>
95 <mapping name="linearGradient" value="LinearGradientBrush" type="element"/>
96 <mapping name="radialGradient" value="RadialGradientBrush" type="element"/>
97 <mapping name="stop" value="GradientStop" type="element"/>
99 </mappings>
100 </xsl:variable>
102 <!-- START HERE -->
104 <xsl:template match="/">
105 <xsl:apply-templates />
106 </xsl:template>
108 <xsl:template match="svg:svg">
110 <xsl:variable name="inheritable-settings">
111 <settings>
112 <xsl:call-template name="parse-attributes">
113 <xsl:with-param name="node" select="."/>
114 <xsl:with-param name="filter" select="'inherit'"/>
115 </xsl:call-template>
116 </settings>
117 </xsl:variable>
119 <xsl:variable name="inheritable-attributes">
120 <defaults>
121 <xsl:copy-of select="$inheritable-settings/settings/@*"/>
122 </defaults>
123 </xsl:variable>
125 <xsl:variable name="local-settings">
126 <settings>
127 <xsl:call-template name="parse-attributes">
128 <xsl:with-param name="name" select="'Canvas'"/>
129 <xsl:with-param name="node" select="."/>
130 <xsl:with-param name="filter" select="'local'"/>
131 </xsl:call-template>
132 </settings>
133 </xsl:variable>
135 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
137 <!-- output the local settings -->
138 <xsl:copy-of select="$local-settings/settings/@*"/>
140 <!-- search and output the node element settings, adding the Canvas. prefix-->
141 <xsl:for-each select="$inheritable-settings/settings/*">
142 <xsl:element name="Canvas.{name(.)}">
143 <xsl:copy-of select="@*"/>
144 <xsl:copy-of select="child::*"/>
145 </xsl:element>
146 </xsl:for-each>
148 <xsl:copy-of select="$local-settings/settings/child::*"/>
150 <xsl:apply-templates>
151 <xsl:with-param name="defaults" select="$inheritable-attributes"/>
152 </xsl:apply-templates>
154 </Canvas>
156 </xsl:template>
158 <!-- A element - for links -->
159 <xsl:template match="svg:a">
160 <!-- inherited transformations -->
161 <xsl:param name="transform"/>
162 <!-- inherited defaults -->
163 <xsl:param name="defaults" />
165 <xsl:apply-templates>
166 <xsl:with-param name="transform" select="$transform"/>
167 <xsl:with-param name="defaults" select="$defaults"/>
168 </xsl:apply-templates>
169 </xsl:template>
171 <!-- g element - children inherit these values and transforms -->
172 <xsl:template match="svg:g">
173 <xsl:param name="transform"/>
174 <xsl:param name="defaults" />
176 <!-- gather up the default values for the children to have -->
177 <xsl:variable name="defs">
178 <defaults>
179 <!-- get the parent's defaults, if any -->
180 <xsl:copy-of select="$defaults/defaults/@*"/>
181 <xsl:call-template name="parse-attributes">
182 <xsl:with-param name="node" select="."/>
183 </xsl:call-template>
184 <xsl:copy-of select="$defaults/defaults/*"/>
185 </defaults>
186 </xsl:variable>
188 <!-- get any transformations and store to send to the children -->
189 <xsl:variable name="local-transform">
190 <TransformGroup
191 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
192 <xsl:call-template name="split">
193 <xsl:with-param name="template" select="'transform'"/>
194 <xsl:with-param name="str" select="@transform"/>
195 <xsl:with-param name="separator"><xsl:value-of select="' '"/></xsl:with-param>
196 </xsl:call-template>
197 <xsl:if test="$transform">
198 <xsl:copy-of select="$transform/xaml:TransformGroup/*"/>
199 </xsl:if>
200 </TransformGroup>
201 </xsl:variable>
203 <xsl:choose>
205 <!-- if there are more than 1 children, it's a group transform, send the whole $transform value -->
206 <xsl:when test="@transform and count(child::*) > 1">
207 <xsl:apply-templates>
208 <xsl:with-param name="transform" select="$local-transform"/>
209 <xsl:with-param name="defaults" select="$defs"/>
210 </xsl:apply-templates>
211 </xsl:when>
213 <xsl:otherwise>
215 <!-- if there is only one children or there is no transformation to apply, cut out the TransformGroup tag (it might be empty, which is good) -->
216 <xsl:apply-templates>
217 <xsl:with-param name="transform" select="$local-transform/xaml:TransformGroup/*"/>
218 <xsl:with-param name="defaults" select="$defs"/>
219 </xsl:apply-templates>
221 </xsl:otherwise>
223 </xsl:choose>
225 </xsl:template>
228 <!-- drawing children - they're all the same, really -->
229 <xsl:template match="svg:path | svg:circle | svg:ellipse | svg:rect | svg:line | svg:polyline | svg:polygon">
230 <!-- inherited transformations -->
231 <xsl:param name="transform"/>
232 <!-- inherited defaults -->
233 <xsl:param name="defaults" />
235 <xsl:variable name="name" select="name(.)"/>
236 <xsl:element name="{$mappings/mappings/mapping[@name=$name]/@value}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
238 <!-- process the attributes and store them in a variable for later use -->
239 <xsl:variable name="local-attributes">
240 <attributes>
241 <xsl:call-template name="parse-attributes">
242 <xsl:with-param name="name" select="$mappings/mappings/mapping[@name=$name]/@value"/>
243 <xsl:with-param name="node" select="."/>
244 </xsl:call-template>
245 </attributes>
246 </xsl:variable>
248 <!-- inherit parents attributes -->
249 <xsl:copy-of select="$defaults/defaults/@*"/>
250 <!-- output this node's attributes -->
251 <xsl:copy-of select="$local-attributes/xaml:attributes/@*"/>
253 <xsl:if test="not(@fill) and not($defaults/defaults/@Fill) and not($local-attributes/xaml:attributes/@Fill)">
254 <xsl:attribute name="Fill">#000</xsl:attribute>
255 </xsl:if>
257 <!-- check if there are transforms inherited from the parent and aggregate them all into one -->
258 <xsl:choose>
259 <xsl:when test="$local-attributes/xaml:attributes/*[contains(name(.), 'Transform')]">
260 <xsl:element name="{$mappings/mappings/mapping[@name=$name]/@value}.RenderTransform"
261 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
262 <xsl:choose>
263 <xsl:when test="$transform and $transform[name(.)='TransformGroup']">
264 <TransformGroup
265 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
267 <xsl:copy-of select="$transform/*"/>
268 <xsl:copy-of select="$local-attributes/xaml:attributes/*[contains(name(.), 'Transform')]"/>
270 </TransformGroup>
271 </xsl:when>
272 <xsl:otherwise>
273 <xsl:if test="$transform">
274 <xsl:copy-of select="$transform"/>
275 </xsl:if>
276 <xsl:copy-of select="$local-attributes/xaml:attributes/*[contains(name(.), 'Transform')]"/>
277 </xsl:otherwise>
278 </xsl:choose>
279 </xsl:element>
280 </xsl:when>
281 <xsl:otherwise>
282 <xsl:if test="$transform">
283 <xsl:element name="{$mappings/mappings/mapping[@name=$name]/@value}.RenderTransform" namespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
284 <xsl:copy-of select="$transform"/>
285 </xsl:element>
286 </xsl:if>
287 </xsl:otherwise>
288 </xsl:choose>
290 <!-- output remaning attributes that got turned into elements and that were not outputted in the above group -->
291 <xsl:copy-of select="$local-attributes/xaml:attributes/*[not(contains(name(.), 'Transform'))]"/>
293 </xsl:element>
294 </xsl:template>
296 <xsl:template match="svg:text">
297 <!-- inherited transformations -->
298 <xsl:param name="transform"/>
299 <!-- inherited defaults -->
300 <xsl:param name="defaults" />
302 <xsl:variable name="attributes">
303 <attributes>
304 <xsl:call-template name="parse-attributes">
305 <xsl:with-param name="node" select="."/>
306 </xsl:call-template>
307 </attributes>
308 </xsl:variable>
310 <TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
311 <xsl:copy-of select="$attributes/attributes/@*[name(.) != 'Text']"/>
312 <Run><xsl:value-of select="$attributes/attributes/@Text"/></Run>
313 </TextBlock>
314 </xsl:template>
317 <xsl:template match="svg:defs" mode="defaults">
318 <xsl:apply-templates mode="defaults" />
319 </xsl:template>
321 <xsl:template match="svg:*" mode="defaults">
322 <xsl:variable name="name" select="name()"/>
323 <xsl:if test="$mappings/mappings/mapping[@name=$name and @type='element']">
324 <xsl:element name="{$mappings/mappings/mapping[@name=$name and @type='element']/@value}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
325 <xsl:call-template name="parse-attributes">
326 <xsl:with-param name="name" select="$mappings/mappings/mapping[@name=$name and @type='element']/@value"/>
327 <xsl:with-param name="node" select="."/>
328 </xsl:call-template>
330 <xsl:apply-templates mode="defaults" />
331 </xsl:element>
332 </xsl:if>
333 </xsl:template>
335 <!-- DEFAULT TEMPLATES
336 These are just default implementations that don't really do anything.
339 <xsl:template match="svg:*">
340 <!-- inherited transformations -->
341 <xsl:param name="transform"/>
342 <!-- inherited defaults -->
343 <xsl:param name="defaults" />
345 <xsl:apply-templates>
346 <xsl:with-param name="transform" select="$transform"/>
347 <xsl:with-param name="defaults" select="$defaults"/>
348 </xsl:apply-templates>
349 </xsl:template>
351 <xsl:template match="text()" mode="#all">
352 </xsl:template>
354 <!-- ######## HELPER TEMPLATES ####### -->
356 <!-- transform template - to turn transform="..." properties into Transform* elements -->
357 <xsl:template name="transform">
358 <xsl:param name="name"/>
359 <xsl:param name="str"/>
360 <xsl:param name="prefix"/>
362 <!-- check what the separator is on the list of values to process -->
363 <xsl:variable name="separator">
364 <xsl:choose>
365 <xsl:when test="contains($str, ',')">,</xsl:when>
366 <xsl:otherwise> </xsl:otherwise>
367 </xsl:choose>
368 </xsl:variable>
370 <!-- each transformation outputs slightly different nodes, so check one by one -->
372 <xsl:if test="starts-with($str, 'translate')">
373 <xsl:element name="{prefix}TranslateTransform" namespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
375 <xsl:call-template name="splitCoords">
376 <xsl:with-param name="str" select="substring-before(substring-after($str, 'translate('), ')')"/>
377 <xsl:with-param name="separator"><xsl:value-of select="string($separator)"/></xsl:with-param>
378 </xsl:call-template>
380 </xsl:element>
381 </xsl:if>
382 <xsl:if test="starts-with($str, 'rotate')">
383 <xsl:element name="RotateTransform" namespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
384 <xsl:attribute name="Angle"><xsl:value-of select="substring-before(substring-after($str, 'rotate('), ')')"/></xsl:attribute>
385 <xsl:if test="../@rx">
386 <xsl:attribute name="CenterX"><xsl:value-of select="../@rx"/></xsl:attribute>
387 </xsl:if>
388 <xsl:if test="../@ry">
389 <xsl:attribute name="CenterY"><xsl:value-of select="../@ry"/></xsl:attribute>
390 </xsl:if>
391 <xsl:if test="../@r">
392 <xsl:attribute name="CenterX"><xsl:value-of select="../@r"/></xsl:attribute>
393 <xsl:attribute name="CenterY"><xsl:value-of select="../@r"/></xsl:attribute>
394 </xsl:if>
396 </xsl:element>
397 </xsl:if>
398 <xsl:if test="starts-with($str, 'scale')">
399 <xsl:element name="ScaleTransform" namespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
400 <xsl:call-template name="splitCoords">
401 <xsl:with-param name="str" select="substring-before(substring-after($str, 'scale('), ')')"/>
402 <xsl:with-param name="prefix" select="'Scale'"/>
403 <xsl:with-param name="separator" select="string($separator)"/>
404 </xsl:call-template>
405 </xsl:element>
406 </xsl:if>
407 <xsl:if test="starts-with($str, 'matrix')">
408 <xsl:element name="MatrixTransform" namespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
409 <xsl:attribute name="Matrix"><xsl:value-of select="substring-before(substring-after($str, 'matrix('), ')')"/></xsl:attribute>
410 </xsl:element>
411 </xsl:if>
413 </xsl:template>
415 <!-- template to process the viewBox property of the svg and turn it into properties of the canvas -->
416 <xsl:template name="viewBox">
417 <xsl:param name="mapping"/>
418 <xsl:param name="str"/>
419 <xsl:param name="prefix"/>
421 <xsl:variable name="attributes">
422 <attributes>
423 <xsl:call-template name="match-name-value">
424 <xsl:with-param name="names"><xsl:value-of select="$mapping/@names"/></xsl:with-param>
425 <xsl:with-param name="values"><xsl:value-of select="$str"/></xsl:with-param>
426 <xsl:with-param name="separator" select="' '"/>
427 </xsl:call-template>
428 </attributes>
429 </xsl:variable>
431 <xsl:copy-of select="$attributes/attributes/@Width"/>
432 <xsl:copy-of select="$attributes/attributes/@Height"/>
434 <xsl:variable name="transform">
435 <transform>
436 <xsl:call-template name="parse-attributes">
437 <xsl:with-param name="node" select="$attributes/attributes"/>
438 </xsl:call-template>
439 </transform>
440 </xsl:variable>
442 <xsl:if test="$transform and count($transform/transform/@*) > 0 or count($transform/transform/*) > 0">
443 <xsl:element name="{$prefix}RenderTransform" namespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
444 <xsl:element name="TranslateTransform" namespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
445 <xsl:copy-of select="$transform/transform/@*"/>
446 <xsl:copy-of select="$transform/transform/*"/>
447 </xsl:element>
448 </xsl:element>
449 </xsl:if>
451 </xsl:template>
454 <!-- template to build attribute nodes with pair values separated by $separator with names separated by $separator -->
455 <xsl:template name="match-name-value">
456 <xsl:param name="names"/>
457 <xsl:param name="values"/>
458 <xsl:param name="separator"/>
460 <xsl:choose>
461 <xsl:when test="contains($names, $separator)">
462 <xsl:attribute name="{substring-before($names, $separator)}"><xsl:value-of select="substring-before($values, $separator)"/></xsl:attribute>
464 <xsl:call-template name="match-name-value">
465 <xsl:with-param name="names" select="substring-after($names, $separator)"/>
466 <xsl:with-param name="values" select="substring-after($values, $separator)"/>
467 <xsl:with-param name="separator" select="$separator"/>
468 </xsl:call-template>
469 </xsl:when>
470 <xsl:otherwise>
471 <xsl:attribute name="{$names}"><xsl:value-of select="$values"/></xsl:attribute>
472 </xsl:otherwise>
473 </xsl:choose>
474 </xsl:template>
476 <xsl:template name="splitCoords">
477 <xsl:param name="mapping"/>
478 <xsl:param name="str"/>
479 <xsl:param name="prefix"/>
480 <xsl:param name="separator"/>
481 <xsl:param name="n" select="1"/>
483 <xsl:choose>
484 <!--- stupid contains thinks an empty space is equal to no space at all... -->
485 <xsl:when test="contains($str,$separator) and substring-after($str, $separator) != $str">
486 <xsl:choose>
487 <xsl:when test="$n = 1 and (not($mapping) or ($mapping/ignore != substring-before($str, $separator)))">
488 <xsl:attribute name="{$prefix}X"><xsl:value-of select="substring-before($str, $separator)"/></xsl:attribute>
489 </xsl:when>
490 <xsl:when test="$n = 2 and (not($mapping) or ($mapping/ignore != substring-before($str, $separator)))">
491 <xsl:attribute name="{$prefix}Y"><xsl:value-of select="substring-before($str, $separator)"/></xsl:attribute>
492 </xsl:when>
493 <xsl:when test="$n = 3 and (not($mapping) or ($mapping/ignore != substring-before($str, $separator)))">
494 <xsl:attribute name="{$prefix}Width"><xsl:value-of select="substring-before($str, $separator)"/></xsl:attribute>
495 </xsl:when>
496 <xsl:when test="$n = 4 and (not($mapping) or ($mapping/ignore != substring-before($str, $separator)))">
497 <xsl:attribute name="{$prefix}Height"><xsl:value-of select="substring-before($str, $separator)"/></xsl:attribute>
498 </xsl:when>
499 </xsl:choose>
501 <!-- recurse again cutting out the part we've processed -->
502 <xsl:call-template name="splitCoords">
503 <xsl:with-param name="mapping" select="$mapping"/>
504 <xsl:with-param name="str" select="substring-after($str, $separator)"/>
505 <xsl:with-param name="prefix" select="$prefix"/>
506 <xsl:with-param name="separator" select="$separator"/>
507 <xsl:with-param name="n" select="$n + 1"/>
508 </xsl:call-template>
509 </xsl:when>
510 <xsl:otherwise>
511 <!-- this is the last one, end recursion -->
512 <xsl:choose>
513 <xsl:when test="$n = 1 and (not($mapping) or ($mapping/ignore != $str))">
514 <xsl:attribute name="{$prefix}X"><xsl:value-of select="$str"/></xsl:attribute>
515 </xsl:when>
516 <xsl:when test="$n = 2 and (not($mapping) or ($mapping/ignore != $str))">
517 <xsl:attribute name="{$prefix}Y"><xsl:value-of select="$str"/></xsl:attribute>
518 </xsl:when>
519 <xsl:when test="$n = 3 and (not($mapping) or ($mapping/ignore != $str))">
520 <xsl:attribute name="{$prefix}Width"><xsl:value-of select="$str"/></xsl:attribute>
521 </xsl:when>
522 <xsl:when test="$n = 4 and (not($mapping) or ($mapping/ignore != $str))">
523 <xsl:attribute name="{$prefix}Height"><xsl:value-of select="$str"/></xsl:attribute>
524 </xsl:when>
525 </xsl:choose>
526 </xsl:otherwise>
527 </xsl:choose>
529 </xsl:template>
531 <!-- call a template by name -->
532 <xsl:template name="process-template">
533 <xsl:param name="mapping"/>
534 <xsl:param name="name"/>
535 <xsl:param name="template"/>
536 <xsl:param name="str"/>
537 <xsl:param name="prefix"/>
539 <xsl:choose>
540 <xsl:when test="$template = 'transform'">
541 <xsl:call-template name="transform">
542 <xsl:with-param name="name" select="$name"/>
543 <xsl:with-param name="str" select="$str"/>
544 <xsl:with-param name="prefix" select="$prefix"/>
545 </xsl:call-template>
546 </xsl:when>
547 <xsl:when test="$template = 'viewBox'">
548 <xsl:call-template name="viewBox">
549 <xsl:with-param name="mapping" select="$mapping"/>
550 <xsl:with-param name="name" select="$name"/>
551 <xsl:with-param name="str" select="$str"/>
552 <xsl:with-param name="prefix" select="$prefix"/>
553 </xsl:call-template>
554 </xsl:when>
555 </xsl:choose>
557 </xsl:template>
559 <!-- helper template to recursively split a string and call another template to output each component -->
560 <xsl:template name="split">
561 <xsl:param name="template"/>
562 <xsl:param name="str"/>
563 <xsl:param name="separator"/>
564 <xsl:choose>
565 <xsl:when test="contains($str,$separator)">
566 <xsl:call-template name="process-template">
567 <xsl:with-param name="template" select="$template"/>
568 <xsl:with-param name="str" select="substring-before($str,$separator)"/>
569 </xsl:call-template>
570 <xsl:call-template name="split">
571 <xsl:with-param name="template" select="$template"/>
572 <xsl:with-param name="str" select="substring-after($str,$separator)"/>
573 <xsl:with-param name="separator" select="$separator"/>
574 </xsl:call-template>
575 </xsl:when>
576 <xsl:otherwise>
577 <xsl:call-template name="process-template">
578 <xsl:with-param name="template" select="$template"/>
579 <xsl:with-param name="str" select="$str"/>
580 </xsl:call-template>
582 </xsl:otherwise>
583 </xsl:choose>
584 </xsl:template>
586 <!-- helper template to recursively process a name-value pair in $str separated by $separator, and
587 call the attributes template to turn it into an attribute -->
588 <xsl:template name="name-value">
589 <xsl:param name="str"/>
590 <xsl:param name="separator"/>
591 <xsl:param name="separator2" select="':'"/>
593 <!-- trim -->
594 <xsl:variable name="input" select="normalize-space($str)"/>
596 <xsl:if test="$input != ''">
597 <xsl:choose>
598 <!--- if there are more to process, recurse -->
599 <xsl:when test="contains($input,$separator)">
600 <xsl:variable name="attribute">
601 <attribute>
602 <xsl:attribute name="{normalize-space(substring-before(substring-before($input,$separator), $separator2))}"><xsl:value-of select="normalize-space(substring-after(substring-before($input,$separator), $separator2))"/></xsl:attribute>
603 </attribute>
604 </xsl:variable>
606 <xsl:call-template name="parse-attributes">
607 <xsl:with-param name="node" select="$attribute/attribute"/>
608 </xsl:call-template>
610 <!-- recursiveness, here we go -->
611 <xsl:call-template name="name-value">
612 <xsl:with-param name="str" select="substring-after($input,$separator)"/>
613 <xsl:with-param name="separator" select="$separator"/>
614 <xsl:with-param name="separator2" select="$separator2"/>
615 </xsl:call-template>
616 </xsl:when>
618 <!-- we're at the last one, stop here -->
619 <xsl:otherwise>
620 <xsl:variable name="attribute">
621 <attribute>
622 <xsl:attribute name="{normalize-space(substring-before($input, $separator2))}"><xsl:value-of select="normalize-space(substring-after($input, $separator2))"/></xsl:attribute>
623 </attribute>
624 </xsl:variable>
625 <xsl:call-template name="parse-attributes">
626 <xsl:with-param name="node" select="$attribute/attribute"/>
627 </xsl:call-template>
629 </xsl:otherwise>
630 </xsl:choose>
631 </xsl:if>
632 </xsl:template>
634 <!-- transform attributes by finding their correspondence in the mappings table. If they're marked as elements or need
635 specific templates to be processed, call those -->
636 <xsl:template name="parse-attributes">
637 <xsl:param name="name"/>
638 <xsl:param name="node"/>
639 <xsl:param name="filter"/>
640 <xsl:param name="parent"/>
642 <xsl:variable name="prefix">
643 <xsl:if test="$name"><xsl:value-of select="$name"/>.</xsl:if>
644 </xsl:variable>
646 <xsl:variable name="local-parent">
647 <xsl:choose>
648 <xsl:when test="$parent"><xsl:value-of select="$parent"/>.</xsl:when>
649 <xsl:otherwise><xsl:value-of select="name(.)"/></xsl:otherwise>
650 </xsl:choose>
651 </xsl:variable>
653 <xsl:for-each select="$node/@*">
654 <xsl:variable name="attname" select="name(.)"/>
657 <xsl:variable name="mapping">
658 <xsl:choose>
659 <xsl:when test="$mappings/mappings/mapping[@name=$attname and @parent=$local-parent]"><xsl:copy-of select="$mappings/mappings/mapping[@name=$attname and @parent=$local-parent]" /></xsl:when>
660 <xsl:otherwise><xsl:copy-of select="$mappings/mappings/mapping[@name=$attname]" /></xsl:otherwise>
661 </xsl:choose>
662 </xsl:variable>
664 <xsl:if test="$mapping/mapping and (not($filter) or ($mapping/mapping[@parent=$local-parent and @filter = $filter]) or ($mapping/mapping[not(@parent) and @filter = $filter]) or ($mapping/mapping[not(@filter)]))">
666 <xsl:choose>
668 <!-- process attributes that need to be processed with a specific template (like transforms) -->
669 <xsl:when test="$mapping/mapping[@template != '']">
670 <xsl:call-template name="process-template">
671 <xsl:with-param name="mapping" select="$mapping/mapping"/>
672 <xsl:with-param name="name" select="$attname"/>
673 <xsl:with-param name="template" select="$mapping/mapping/@template"/>
674 <xsl:with-param name="str" select="."/>
675 <xsl:with-param name="prefix" select="$prefix"/>
676 </xsl:call-template>
677 </xsl:when>
679 <!-- process normal attributes -->
680 <xsl:otherwise>
681 <xsl:choose>
683 <!-- first do the custom attributes -->
684 <xsl:when test="$attname='r' and $local-parent = 'circle'">
685 <xsl:if test="not(../@cx)">
686 <xsl:attribute name="Canvas.Left"><xsl:value-of select=". * -1"/></xsl:attribute>
687 </xsl:if>
689 <xsl:if test="not(../@cy)">
690 <xsl:attribute name="Canvas.Top"><xsl:value-of select=". * -1"/></xsl:attribute>
691 </xsl:if>
693 <xsl:attribute name="Width"><xsl:value-of select=". * 2"/></xsl:attribute>
694 <xsl:attribute name="Height"><xsl:value-of select=". * 2"/></xsl:attribute>
696 </xsl:when>
697 <xsl:when test="$attname='r' and $local-parent != 'circle'">
698 <xsl:attribute name="{$mapping/mapping/@prefix}X">
699 <xsl:call-template name="output-attribute-value">
700 <xsl:with-param name="mapping" select="$mapping/mapping"/>
701 <xsl:with-param name="value" select="."/>
702 </xsl:call-template>
703 </xsl:attribute>
704 <xsl:attribute name="{$mapping/mapping/@prefix}Y">
705 <xsl:call-template name="output-attribute-value">
706 <xsl:with-param name="mapping" select="$mapping/mapping"/>
707 <xsl:with-param name="value" select="."/>
708 </xsl:call-template>
709 </xsl:attribute>
710 </xsl:when>
711 <xsl:when test="$attname='rx'">
712 <xsl:attribute name="Width"><xsl:value-of select=". * 2"/></xsl:attribute>
713 <xsl:attribute name="Canvas.Left"><xsl:value-of select=". * -1"/></xsl:attribute>
714 </xsl:when>
715 <xsl:when test="$attname='ry'">
716 <xsl:attribute name="Height"><xsl:value-of select=". * 2"/></xsl:attribute>
717 <xsl:attribute name="Canvas.Top"><xsl:value-of select=". * -1"/></xsl:attribute>
718 </xsl:when>
719 <xsl:when test="$attname='cx'">
720 <xsl:attribute name="Canvas.Left">
721 <xsl:choose>
722 <xsl:when test="../@rx"><xsl:value-of select=". - ../@rx"/></xsl:when>
723 <xsl:otherwise><xsl:value-of select=". - ../@r"/></xsl:otherwise>
724 </xsl:choose>
725 </xsl:attribute>
726 </xsl:when>
727 <xsl:when test="$attname='cy'">
728 <xsl:attribute name="Canvas.Top">
729 <xsl:choose>
730 <xsl:when test="../@ry"><xsl:value-of select=". - ../@ry"/></xsl:when>
731 <xsl:otherwise><xsl:value-of select=". - ../@r"/></xsl:otherwise>
732 </xsl:choose>
733 </xsl:attribute>
734 </xsl:when>
736 <xsl:when test="$attname='style'">
737 <xsl:variable name="style">
738 <style>
739 <xsl:call-template name="name-value">
740 <xsl:with-param name="str" select="."/>
741 <xsl:with-param name="separator" select="';'"/>
742 </xsl:call-template>
743 </style>
744 </xsl:variable>
746 <xsl:variable name="defs" select="//svg:defs"/>
747 <xsl:variable name="style-elements">
748 <style-elements>
749 <xsl:for-each select="$style/style/@*">
750 <xsl:choose>
751 <xsl:when test="contains(., 'url')">
752 <xsl:element name="{$name}.{name()}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
753 <xsl:variable name="ref" select="substring-before(substring-after(., 'url(#'), ')')"/>
754 <xsl:apply-templates select="$defs/*[@id=$ref]" mode="defaults"/>
755 </xsl:element>
756 </xsl:when>
757 <xsl:otherwise>
758 <xsl:copy-of select="."/>
759 </xsl:otherwise>
760 </xsl:choose>
761 </xsl:for-each>
762 </style-elements>
763 </xsl:variable>
765 <xsl:copy-of select="$style-elements/style-elements/@*" />
766 <xsl:copy-of select="$style-elements/style-elements/*" />
767 </xsl:when>
769 <xsl:when test="$attname='xlink:href'">
770 <xsl:variable name="defs" select="//svg:defs"/>
771 <xsl:variable name="style-elements">
772 <style-elements>
773 <xsl:variable name="ref" select="substring-after(., '#')"/>
774 <xsl:apply-templates select="$defs/*[@id=$ref]" mode="defaults"/>
775 </style-elements>
776 </xsl:variable>
778 <xsl:call-template name="recursive-copy">
779 <xsl:with-param name="node" select="$style-elements/style-elements" />
780 </xsl:call-template>
781 </xsl:when>
784 <!-- if it's not a custom one, check the mappings -->
785 <!-- if there is a mapping for this attribute (ignore parent) and the value is not marked to ignore -->
786 <xsl:when test="not($mapping/mapping/ignore = normalize-space(.))">
787 <xsl:attribute name="{$mapping/mapping/@value}">
788 <xsl:choose>
789 <xsl:when test="$mapping/mapping/value[@name=current()]"><xsl:value-of select="$mapping/mapping/value[@name=current()]/@value"/></xsl:when>
790 <xsl:otherwise>
791 <xsl:call-template name="output-attribute-value">
792 <xsl:with-param name="mapping" select="$mapping/mapping"/>
793 <xsl:with-param name="value" select="."/>
794 </xsl:call-template>
795 </xsl:otherwise>
796 </xsl:choose>
797 </xsl:attribute>
798 </xsl:when>
799 </xsl:choose>
800 </xsl:otherwise>
801 </xsl:choose>
803 </xsl:if>
805 </xsl:for-each>
807 <!-- output any text value -->
808 <xsl:if test="text() and $mappings/mappings/mapping[@name=$local-parent]">
809 <xsl:attribute name="{$mappings/mappings/mapping[@name=$local-parent]/@value}"><xsl:value-of select="."/></xsl:attribute>
810 </xsl:if>
812 </xsl:template>
814 <xsl:template name="output-attribute-value">
815 <xsl:param name="mapping"/>
816 <xsl:param name="value"/>
818 <xsl:choose>
819 <xsl:when test="$mapping/@op = 'mul'"><xsl:value-of select="$value * $mapping/@opval"/></xsl:when>
820 <xsl:when test="$mapping/@op = 'add'"><xsl:value-of select="$value + $mapping/@opval"/></xsl:when>
821 <xsl:when test="$mapping/@op = 'sub'"><xsl:value-of select="$value - $mapping/@opval"/></xsl:when>
822 <xsl:when test="$mapping/@op = 'div'"><xsl:value-of select="$value div $mapping/@opval"/></xsl:when>
823 <xsl:otherwise><xsl:value-of select="$value"/></xsl:otherwise>
824 </xsl:choose>
825 </xsl:template>
827 <xsl:template name="recursive-copy">
828 <xsl:param name="node" />
830 <xsl:for-each select="$node/*">
831 <xsl:choose>
832 <xsl:when test="count(child::*) = 0"><xsl:copy-of select="." /></xsl:when>
833 <xsl:otherwise>
834 <xsl:copy-of select="@*"/>
835 <xsl:call-template name="recursive-copy">
836 <xsl:with-param name="node" select="." />
837 </xsl:call-template>
838 </xsl:otherwise>
839 </xsl:choose>
840 </xsl:for-each>
841 </xsl:template>
843 <!-- ######## END OF HELPER TEMPLATES ####### -->
845 </xsl:stylesheet>