|
1 <?xml version="1.0"?> |
|
2 |
|
3 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:s="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> |
|
4 <xsl:output method="xml"/> |
|
5 <xsl:param name="Data"/> <!-- The data to be overlayed onto the SVG model --> |
|
6 <xsl:param name="Prefix"><xsl:apply-templates select="/" mode="my-prefix"/></xsl:param> <!-- The prefix for the ID, in case the plain ID is already taken --> |
|
7 <xsl:param name="Event"><xsl:apply-templates select="/" mode="my-event"/></xsl:param> <!-- The behaviour for opening the ID section: click, popup, or mouseover. 'click' will display the group when the component is clicked. 'popup' will display the group when the component is moved over, with only one group showing at a time. 'mouseover' will display the group only when the mouse is over the component. --> |
|
8 <xsl:key name="id" match="s:g" use="@id"/> <!-- find id of only groups --> |
|
9 |
|
10 <!-- should override the following: |
|
11 |
|
12 <xsl:template match="*" mode="my-script"/> for any custom scripts (called on root node in $Data) |
|
13 <xsl:template match="*" mode="my-defs"/> for any custom defs (styles, shapes, etc) (called on root node in $Data) |
|
14 <xsl:template match="/" mode="my-legend"/> for any additional legend areas (called on the top-level document in $Data) |
|
15 <xsl:template match="*" mode="my-release-version"/> for custom release version text (called on tspan element containing text) |
|
16 <xsl:template match="s:g" mode="my-overlay"><xsl:with-param name="id"/> the content of the group to be displayed on an event |
|
17 <xsl:template match="/" mode="my-prefix"/> in case the plain ID is taken, this prefix can be applied to the new groups (called on the top-level document in SVG model) |
|
18 <xsl:template match="/" mode="my-event"/> events can be popup, click or mouseover (the default). Also can be set by parameter |
|
19 <xsl:template match="*" mode="is-present"><xsl:param name="id"/> return '1' if component with $id exists, or leave empty if not |
|
20 --> |
|
21 |
|
22 <!-- no custom scripts or defs by default --> |
|
23 <xsl:template match="*" mode="my-script"/> |
|
24 <xsl:template match="*" mode="my-defs"/> |
|
25 |
|
26 <xsl:template match="/" mode="my-legend"/> <!-- no new legend --> |
|
27 <xsl:template match="*" mode="my-release-version"><xsl:value-of select="."/> </xsl:template> <!-- just use existing text --> |
|
28 |
|
29 <xsl:template match="*" mode="my-overlay"/> <!-- no content by default --> |
|
30 <xsl:template match="*" mode="my-content"/> <!-- no content by default --> |
|
31 <xsl:template match="/" mode="my-prefix">o-</xsl:template> <!-- "o-" prefix by default --> |
|
32 <xsl:template match="/" mode="my-additional-content"/> <!-- no content by default --> |
|
33 |
|
34 <xsl:template match="/" mode="my-event">mouseover</xsl:template> <!-- default event is mouseover --> |
|
35 <xsl:template match="*" mode="is-present"><xsl:param name="id"/></xsl:template> <!-- not present by default --> |
|
36 |
|
37 <xsl:template match="/" mode="my-valid-items">component collection package layer</xsl:template> |
|
38 |
|
39 <!-- ======= main code follows ======= --> |
|
40 |
|
41 <xsl:template match="/s:svg"> |
|
42 <s:svg><xsl:apply-templates select="@*|node()"/> |
|
43 <xsl:apply-templates select="//s:g[@id and ancestor-or-self::s:g[@class='collection' or @class='package' or @class='layer']]" mode="overlay"/> |
|
44 <xsl:apply-templates select="/" mode="my-additional-content"/> |
|
45 </s:svg> |
|
46 </xsl:template> |
|
47 |
|
48 <!-- print custom scripts last --> |
|
49 <xsl:template match="s:script[count(following::s:script)=0]"> |
|
50 <xsl:copy><xsl:copy-of select="@*|node()"/></xsl:copy> |
|
51 <xsl:variable name="scripts" select="//s:script"/> |
|
52 <xsl:choose> |
|
53 <xsl:when test="$Data!=''"> |
|
54 <xsl:apply-templates select="document($Data,/)/*" mode="my-script"> |
|
55 <xsl:with-param name="scripts" select="$scripts"/> |
|
56 </xsl:apply-templates> |
|
57 </xsl:when> |
|
58 <xsl:otherwise> |
|
59 <xsl:apply-templates select="." mode="my-script"> |
|
60 <xsl:with-param name="scripts" select="$scripts"/> |
|
61 </xsl:apply-templates> |
|
62 </xsl:otherwise> |
|
63 </xsl:choose> |
|
64 </xsl:template> |
|
65 |
|
66 <!-- print custom defs last --> |
|
67 <xsl:template match="s:defs[count(following::s:defs)=0]"> |
|
68 <xsl:copy><xsl:copy-of select="@*|node()"/></xsl:copy> |
|
69 <xsl:variable name="defs" select="//s:defs"/> |
|
70 <xsl:choose> |
|
71 <xsl:when test="$Data!=''"> |
|
72 <xsl:apply-templates select="document($Data,/)/*" mode="my-defs"> |
|
73 <xsl:with-param name="defs" select="$defs"/> |
|
74 </xsl:apply-templates> |
|
75 </xsl:when> |
|
76 <xsl:otherwise> |
|
77 <xsl:apply-templates select="." mode="my-defs"> |
|
78 <xsl:with-param name="defs" select="$defs"/> |
|
79 </xsl:apply-templates> |
|
80 </xsl:otherwise> |
|
81 </xsl:choose> |
|
82 </xsl:template> |
|
83 |
|
84 |
|
85 <xsl:template match="s:g[(@class='component' or @class='layer-detail' or @class='package' or @class='collection')]"> |
|
86 <xsl:variable name="id"> |
|
87 <xsl:choose> |
|
88 <xsl:when test="@id"><xsl:value-of select="@id"/></xsl:when> |
|
89 <xsl:when test="@name"><xsl:value-of select="translate(@name,' ','')"/></xsl:when> |
|
90 </xsl:choose> |
|
91 </xsl:variable> |
|
92 <xsl:copy> |
|
93 <xsl:apply-templates select="@*[name()!='id']"/> |
|
94 <xsl:variable name="items"><xsl:apply-templates select="/" mode="my-valid-items"/></xsl:variable> |
|
95 <xsl:variable name="found"> |
|
96 <xsl:choose> |
|
97 <xsl:when test="$Data='' and not(contains(concat(' ',$items,' '),concat(' ',@class,' ')))"/> |
|
98 <xsl:when test="$Data=''">1</xsl:when> |
|
99 <xsl:otherwise> |
|
100 <xsl:apply-templates select="document($Data,/)/*" mode="is-present"> |
|
101 <xsl:with-param name="id" select="$id"/> |
|
102 </xsl:apply-templates> |
|
103 </xsl:otherwise> |
|
104 </xsl:choose> |
|
105 </xsl:variable> |
|
106 <xsl:if test="$id!='' and $found!=''"> |
|
107 <xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute> |
|
108 </xsl:if> |
|
109 <xsl:choose> |
|
110 <xsl:when test="$found='' "/> |
|
111 <xsl:when test="$Event='click' "> |
|
112 <xsl:attribute name="onclick">on(clear('<xsl:value-of select="concat($Prefix,$id)"/>'))</xsl:attribute> |
|
113 </xsl:when> |
|
114 <xsl:when test="$Event='popup' "> |
|
115 <xsl:attribute name="onmouseover">on(clear('<xsl:value-of select="concat($Prefix,$id)"/>'))</xsl:attribute> |
|
116 </xsl:when> |
|
117 <xsl:otherwise> |
|
118 <xsl:attribute name="onmouseover">on('<xsl:value-of select="concat($Prefix,$id)"/>')</xsl:attribute> |
|
119 <xsl:attribute name="onmouseout">off('<xsl:value-of select="concat($Prefix,$id)"/>')</xsl:attribute> |
|
120 </xsl:otherwise> |
|
121 </xsl:choose> |
|
122 <xsl:apply-templates select="node()"/> |
|
123 </xsl:copy> |
|
124 </xsl:template> |
|
125 |
|
126 <xsl:template match="s:g" mode="overlay"> |
|
127 <xsl:variable name="id" select="@id"/> |
|
128 <xsl:variable name="found"> |
|
129 <xsl:apply-templates select="document($Data,/)/*" mode="is-present"> |
|
130 <xsl:with-param name="id" select="$id"/> |
|
131 </xsl:apply-templates> |
|
132 </xsl:variable> <!-- no overlay if no data file --> |
|
133 <xsl:if test="$Data!='' and $found!=''"> |
|
134 <s:g visibility="hidden" id="{concat($Prefix,$id)}"> |
|
135 <xsl:apply-templates select="." mode="my-overlay"> |
|
136 <xsl:with-param name="id" select="$id"/> |
|
137 </xsl:apply-templates> |
|
138 </s:g> |
|
139 </xsl:if> |
|
140 </xsl:template> |
|
141 |
|
142 <xsl:template match="node()|@*"> |
|
143 <xsl:copy> |
|
144 <xsl:apply-templates select="node()|@*"/> |
|
145 </xsl:copy> |
|
146 </xsl:template> |
|
147 |
|
148 |
|
149 <!-- ====== positions in model ===============--> |
|
150 |
|
151 |
|
152 <xsl:template match="s:g" mode="item-width"> |
|
153 <xsl:choose> |
|
154 <xsl:when test="s:use and not(s:rect)"><xsl:value-of select="s:use[1]/@width"/></xsl:when> |
|
155 <xsl:otherwise><xsl:value-of select="s:rect[1]/@width"/></xsl:otherwise> |
|
156 </xsl:choose> |
|
157 </xsl:template> |
|
158 |
|
159 <xsl:template match="s:g" mode="item-pos"> |
|
160 <xsl:choose> |
|
161 <xsl:when test="s:use and not(s:rect)"><xsl:apply-templates select="s:use[1]" mode="position"/></xsl:when> |
|
162 <xsl:otherwise><xsl:apply-templates select="s:rect[1]" mode="position"/></xsl:otherwise> |
|
163 </xsl:choose> |
|
164 </xsl:template> |
|
165 |
|
166 <xsl:template match="s:g" mode="height"> |
|
167 <xsl:choose> |
|
168 <xsl:when test="s:use and not(s:rect)"><xsl:value-of select="s:use[1]/@height"/></xsl:when> |
|
169 <xsl:otherwise><xsl:value-of select="s:rect[1]/@height"/></xsl:otherwise> |
|
170 </xsl:choose> |
|
171 </xsl:template> |
|
172 |
|
173 <xsl:template match="s:rect|s:use" mode="position"> |
|
174 <xsl:variable name="pos"> |
|
175 <xsl:call-template name="sumpos"><xsl:with-param name="list"> |
|
176 <xsl:value-of select="concat(@x,' ',@y)"/> <xsl:apply-templates select="ancestor::s:g[@transform]" mode="position"/> |
|
177 </xsl:with-param> |
|
178 </xsl:call-template> |
|
179 </xsl:variable> |
|
180 <xsl:value-of select="concat(substring-before($pos, ' ') + @width *0.5 ,',',substring-after($pos, ' ') + @height *0.5 )"/> |
|
181 </xsl:template> |
|
182 |
|
183 <xsl:template match="s:g" mode="position"> |
|
184 <xsl:variable name="pos" select="normalize-space(substring-before(substring-after(substring-after(@transform,'translate'),'('),')'))"/> |
|
185 <xsl:choose> |
|
186 <xsl:when test="contains($pos,' ')"> + <xsl:value-of select="$pos"/></xsl:when> |
|
187 <xsl:otherwise> + <xsl:value-of select="$pos"/> 0</xsl:otherwise> |
|
188 </xsl:choose> |
|
189 </xsl:template> |
|
190 |
|
191 |
|
192 <xsl:template name="sumpos"><xsl:param name="list"/> |
|
193 <xsl:variable name="cur" select="normalize-space(substring-before($list,'+'))"/> |
|
194 <xsl:choose> |
|
195 <xsl:when test="$cur=''"><xsl:value-of select="normalize-space($list)"/></xsl:when> |
|
196 <xsl:otherwise> |
|
197 <xsl:variable name="x" select="substring-before($cur,' ')"/> |
|
198 <xsl:variable name="y" select="substring-after($cur,' ')"/> |
|
199 <xsl:variable name="next"> |
|
200 <xsl:call-template name="sumpos"> |
|
201 <xsl:with-param name="list" select="substring-after($list,'+')"/> |
|
202 </xsl:call-template> |
|
203 </xsl:variable> |
|
204 <xsl:variable name="x1" select="substring-before($next,' ')"/> |
|
205 <xsl:variable name="y1" select="substring-after($next,' ')"/> |
|
206 <xsl:value-of select="concat($x1 + $x,' ', $y1 + $y)"/> |
|
207 </xsl:otherwise> |
|
208 </xsl:choose> |
|
209 </xsl:template> |
|
210 |
|
211 <!-- cleanup empty links --> |
|
212 <xsl:template match="s:a"> |
|
213 <xsl:choose> |
|
214 <xsl:when test="@*"><xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy></xsl:when> |
|
215 <xsl:otherwise> |
|
216 <xsl:apply-templates/> |
|
217 </xsl:otherwise> |
|
218 </xsl:choose> |
|
219 </xsl:template> |
|
220 |
|
221 |
|
222 <!-- ====== legend stuff ===============--> |
|
223 |
|
224 <xsl:template match="*" mode="legend-ext-width">20</xsl:template> |
|
225 <xsl:template match="s:g[@class='legend']"> |
|
226 <xsl:call-template name="insert-legend"><xsl:with-param name="width"><xsl:apply-templates select="." mode="legend-ext-width"/></xsl:with-param> |
|
227 </xsl:call-template> |
|
228 </xsl:template> |
|
229 |
|
230 <xsl:template name="insert-legend"><xsl:param name="width"/> |
|
231 <xsl:copy> |
|
232 <xsl:copy-of select="@*[name()!='transform']"/> |
|
233 <xsl:attribute name="transform"> |
|
234 <xsl:value-of select="substring-before(@transform,'(')"/> |
|
235 <xsl:variable name="t" select="normalize-space(substring-after(@transform,'('))"/> |
|
236 <xsl:value-of select="concat('(',substring-before($t,' ') - $width ,' ')"/> |
|
237 <xsl:value-of select="substring-after($t,' ')"/> |
|
238 </xsl:attribute> |
|
239 <xsl:apply-templates mode="insert-legend"> |
|
240 <xsl:with-param name="width" select="$width"/> |
|
241 </xsl:apply-templates > |
|
242 </xsl:copy> |
|
243 </xsl:template> |
|
244 |
|
245 <xsl:template match="*" mode="insert-legend"><xsl:copy-of select="."/></xsl:template> |
|
246 |
|
247 <xsl:template match="s:text|s:tspan" mode="insert-legend"><xsl:param name="width"/> |
|
248 <xsl:copy> |
|
249 <xsl:copy-of select="@*[name()!='x']"/> |
|
250 <xsl:attribute name="x"><xsl:value-of select="@x + $width"/></xsl:attribute> |
|
251 <xsl:choose> |
|
252 <xsl:when test="@id='release-version'"> |
|
253 <xsl:apply-templates select="." mode="my-release-version"/> |
|
254 </xsl:when> |
|
255 <xsl:otherwise> |
|
256 <xsl:apply-templates mode="insert-legend"><xsl:with-param name="width" select="$width"/></xsl:apply-templates> |
|
257 </xsl:otherwise> |
|
258 </xsl:choose> |
|
259 </xsl:copy> |
|
260 </xsl:template> |
|
261 |
|
262 <xsl:template match="s:rect" mode="insert-legend"><xsl:param name="width"/> |
|
263 <xsl:copy> |
|
264 <xsl:copy-of select="@*[name()!='width']"/> |
|
265 <xsl:attribute name="width"><xsl:value-of select="@width + $width"/></xsl:attribute> |
|
266 <xsl:copy-of select="*|text()"/> |
|
267 </xsl:copy> |
|
268 </xsl:template> |
|
269 |
|
270 <xsl:template match="s:g" mode="insert-legend"><xsl:param name="width"/> |
|
271 <xsl:copy><xsl:copy-of select="@*"/> |
|
272 <xsl:apply-templates mode="insert-legend"><xsl:with-param name="width" select="$width"/></xsl:apply-templates> |
|
273 </xsl:copy> |
|
274 </xsl:template> |
|
275 |
|
276 |
|
277 <xsl:template match="s:g[@id='legend-box']/s:g" mode="insert-legend"><xsl:param name="width"/> |
|
278 <xsl:copy> |
|
279 <xsl:copy-of select="@*"/> |
|
280 <xsl:apply-templates/> |
|
281 <xsl:if test="$width!=0"> |
|
282 <s:g> |
|
283 <xsl:attribute name="transform">translate(<xsl:value-of select="preceding-sibling::s:rect[1]/@width - 5"/>)</xsl:attribute> |
|
284 <xsl:variable name="legend" select="."/> |
|
285 <xsl:choose> |
|
286 <xsl:when test="$Data!=''"> |
|
287 <xsl:apply-templates select="document($Data,/)" mode="my-legend"> |
|
288 <xsl:with-param name="legend" select="$legend"/> |
|
289 </xsl:apply-templates> |
|
290 </xsl:when> |
|
291 <xsl:otherwise> |
|
292 <xsl:apply-templates select="/" mode="my-legend"> |
|
293 <xsl:with-param name="legend" select="$legend"/> |
|
294 </xsl:apply-templates> |
|
295 </xsl:otherwise> |
|
296 </xsl:choose> |
|
297 </s:g> |
|
298 </xsl:if> |
|
299 </xsl:copy> |
|
300 </xsl:template> |
|
301 |
|
302 <!-- ======= an default implementation for SVG ======= --> |
|
303 |
|
304 <!-- find all SVG groups with an ID in the model and make them mouse-overs --> |
|
305 |
|
306 |
|
307 <!-- copy all scripts from other SVG --> |
|
308 <xsl:template match="/s:svg" mode="my-script"><xsl:copy-of select="//s:script"/></xsl:template> |
|
309 |
|
310 <!-- copy all defs from other SVG --> |
|
311 <xsl:template match="/s:svg" mode="my-defs"><xsl:copy-of select="//s:defs"/></xsl:template> |
|
312 |
|
313 <!-- position over the component --> |
|
314 <xsl:template match="s:g" mode="my-overlay"><xsl:param name="id"/> |
|
315 <xsl:variable name="pos"><xsl:apply-templates select="." mode="item-pos"/></xsl:variable> |
|
316 <xsl:variable name="w"><xsl:apply-templates select="." mode="item-width"/></xsl:variable> |
|
317 <xsl:attribute name="transform">translate(<xsl:value-of select="concat(substring-before($pos,','), ' ',substring-after($pos,',') + $w *0.5)"/>) <xsl:value-of select="@transform"/></xsl:attribute> |
|
318 <xsl:apply-templates select="document($Data,/)/*" mode="my-content"> |
|
319 <xsl:with-param name="id" select="$id"/> |
|
320 </xsl:apply-templates> |
|
321 </xsl:template> |
|
322 |
|
323 <xsl:template match="/s:svg" mode="my-content"><xsl:param name="id"/> |
|
324 <xsl:copy-of select="key('id',$id)"/> |
|
325 </xsl:template> |
|
326 |
|
327 <xsl:template match="/s:svg" mode="is-present"><xsl:param name="id"/> |
|
328 <xsl:if test="key('id',$id)">1</xsl:if> |
|
329 </xsl:template> |
|
330 |
|
331 |
|
332 </xsl:stylesheet> |