43 const "svg_root_id", "/svg:svg/@id"; |
43 const "svg_root_id", "/svg:svg/@id"; |
44 const "hmi_elements", "//svg:*[starts-with(@inkscape:label, 'HMI:')]"; |
44 const "hmi_elements", "//svg:*[starts-with(@inkscape:label, 'HMI:')]"; |
45 |
45 |
46 include detachable_pages.ysl2 |
46 include detachable_pages.ysl2 |
47 |
47 |
48 //////////////// Inline SVG |
48 include inline_svg.ysl2 |
49 |
|
50 // Identity template : |
|
51 // - copy every attributes |
|
52 // - copy every sub-elements |
|
53 template "@* | node()", mode="inline_svg" { |
|
54 // use real xsl:copy instead copy-of alias from yslt.yml2 |
|
55 if "not(@id = $discardable_elements/@id)" |
|
56 xsl:copy apply "@* | node()", mode="inline_svg"; |
|
57 } |
|
58 |
|
59 // replaces inkscape's height and width hints. forces fit |
|
60 template "svg:svg/@width", mode="inline_svg"; |
|
61 template "svg:svg/@height", mode="inline_svg"; |
|
62 svgtmpl "svg:svg", mode="inline_svg" svg { |
|
63 attrib "preserveAspectRatio" > none |
|
64 attrib "height" > 100vh |
|
65 attrib "width" > 100vw |
|
66 apply "@* | node()", mode="inline_svg"; |
|
67 } |
|
68 // ensure that coordinate in CSV file generated by inkscape are in default reference frame |
|
69 template "svg:svg[@viewBox!=concat('0 0 ', @width, ' ', @height)]", mode="inline_svg" { |
|
70 error > ViewBox settings other than X=0, Y=0 and Scale=1 are not supported |
|
71 } |
|
72 // ensure that coordinate in CSV file generated by inkscape match svg default unit |
|
73 template "sodipodi:namedview[@units!='px' or @inkscape:document-units!='px']", mode="inline_svg" { |
|
74 error > All units must be set to "px" in Inkscape's document properties |
|
75 } |
|
76 |
|
77 |
|
78 //////////////// Clone Unlinking |
|
79 |
|
80 // svg:use (inkscape's clones) inside a widgets are |
|
81 // replaced by real elements they refer in order to : |
|
82 // - allow finding "needle" element in "meter" widget, |
|
83 // even if "needle" is in a group refered by a svg use. |
|
84 // - if "needle" is visible through a svg:use for |
|
85 // each instance of the widget, then needle would show |
|
86 // the same position in all instances |
|
87 // |
|
88 // For now, clone unlinkink applies to descendants of all widget except HMI:Page |
|
89 // TODO: narrow application of clone unlinking to active elements, |
|
90 // while keeping static decoration cloned |
|
91 const "to_unlink", "$hmi_elements[not(@id = $hmi_pages)]//svg:use"; |
|
92 svgtmpl "svg:use", mode="inline_svg" |
|
93 { |
|
94 choose { |
|
95 when "@id = $to_unlink/@id" |
|
96 call "unlink_clone"; |
|
97 otherwise |
|
98 xsl:copy apply "@* | node()", mode="inline_svg"; |
|
99 } |
|
100 } |
|
101 |
|
102 // to unlink a clone, an group containing a copy of target element is created |
|
103 // that way, style and transforms can be preserved |
|
104 const "_excluded_use_attrs" { |
|
105 name > href |
|
106 name > width |
|
107 name > height |
|
108 name > x |
|
109 name > y |
|
110 } |
|
111 const "excluded_use_attrs","exsl:node-set($_excluded_use_attrs)"; |
|
112 |
|
113 svgfunc "unlink_clone"{ |
|
114 g{ |
|
115 // include non excluded attributes |
|
116 foreach "@*[not(local-name() = $excluded_use_attrs/name)]" |
|
117 attrib "{name()}" > «.» |
|
118 |
|
119 const "targetid","substring-after(@xlink:href,'#')"; |
|
120 apply "//svg:*[@id = $targetid]", mode="unlink_clone"{ |
|
121 with "seed","@id"; |
|
122 } |
|
123 } |
|
124 } |
|
125 |
|
126 // clone unlinking is really similar to deep-copy |
|
127 // all nodes are sytematically copied |
|
128 svgtmpl "@id", mode="unlink_clone" { |
|
129 param "seed"; |
|
130 attrib "id" > «$seed»_«.» |
|
131 } |
|
132 |
|
133 svgtmpl "@*", mode="unlink_clone" xsl:copy; |
|
134 |
|
135 // copying widgets would have unwanted effect |
|
136 // instead widget is refered through a svg:use. |
|
137 svgtmpl "svg:*", mode="unlink_clone" { |
|
138 param "seed"; |
|
139 choose { |
|
140 // node recursive copy ends when finding a widget |
|
141 when "@id = $hmi_elements/@id" { |
|
142 // place a clone instead of copying |
|
143 use{ |
|
144 attrib "xlink:href" > «concat('#',@id)» |
|
145 } |
|
146 } |
|
147 otherwise { |
|
148 xsl:copy apply "@* | node()", mode="unlink_clone" { |
|
149 with "seed","$seed"; |
|
150 } |
|
151 } |
|
152 } |
|
153 } |
|
154 |
|
155 /*const "mark" > =HMI=\n*/ |
|
156 |
|
157 const "result_svg" apply "/", mode="inline_svg"; |
|
158 const "result_svg_ns", "exsl:node-set($result_svg)"; |
|
159 |
49 |
160 template "/" { |
50 template "/" { |
161 comment > Made with SVGHMI. https://beremiz.org |
51 comment > Made with SVGHMI. https://beremiz.org |
162 |
52 |
163 // use python to call all debug output from included definitions |
53 // use python to call all debug output from included definitions |
164 // '&bug' is a workaround for pyPEG that choke on yml2 python results not parsing to a single call |
54 // '&bug' is a workaround for pyPEG that choke on yml2 python results not parsing to a single call |
165 !"&bug {"+"\n".join(["comment {\n| \n| %s:\n call \"%s\";\n| \n}"%(n,n) for n in debug_output_calls]) +"}"! |
55 !"&bug {"+"\n".join(["comment {\n| \n| %s:\n call \"%s\";\n| \n}"%(n,n) for n in debug_output_calls]) +"}"! |
166 |
56 |
167 comment { |
|
168 | Unlinked : |
|
169 foreach "$to_unlink"{ |
|
170 | «@id» |
|
171 } |
|
172 } |
|
173 /**/ |
|
174 html xmlns="http://www.w3.org/1999/xhtml" |
57 html xmlns="http://www.w3.org/1999/xhtml" |
175 xmlns:svg="http://www.w3.org/2000/svg" |
58 xmlns:svg="http://www.w3.org/2000/svg" |
176 xmlns:xlink="http://www.w3.org/1999/xlink" { |
59 xmlns:xlink="http://www.w3.org/1999/xlink" { |
177 head; |
60 head; |
178 body style="margin:0;overflow:hidden;" { |
61 body style="margin:0;overflow:hidden;" { |