svghmi/inline_svg.ysl2
branchsvghmi
changeset 2878 bec552270ad1
parent 2877 682bce953795
child 2904 92d115d8828d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/inline_svg.ysl2	Tue Mar 17 13:16:01 2020 +0100
@@ -0,0 +1,120 @@
+// inline_svg.ysl2
+//
+// Produce Inline SVG element of resulting XHTML page.
+
+// Identity template :
+//  - copy every attributes 
+//  - copy every sub-elements
+template "@* | node()", mode="inline_svg" {
+  // use real xsl:copy instead copy-of alias from yslt.yml2
+  if "not(@id = $discardable_elements/@id)"
+      xsl:copy apply "@* | node()", mode="inline_svg";
+}
+
+// replaces inkscape's height and width hints. forces fit
+template "svg:svg/@width", mode="inline_svg";
+template "svg:svg/@height", mode="inline_svg";
+svgtmpl "svg:svg", mode="inline_svg" svg {
+    attrib "preserveAspectRatio" > none
+    attrib "height" > 100vh
+    attrib "width" > 100vw
+    apply "@* | node()", mode="inline_svg";
+}
+// ensure that coordinate in CSV file generated by inkscape are in default reference frame
+template "svg:svg[@viewBox!=concat('0 0 ', @width, ' ', @height)]", mode="inline_svg" {
+    error > ViewBox settings other than X=0, Y=0 and Scale=1 are not supported
+}
+// ensure that coordinate in CSV file generated by inkscape match svg default unit
+template "sodipodi:namedview[@units!='px' or @inkscape:document-units!='px']", mode="inline_svg" {
+    error > All units must be set to "px" in Inkscape's document properties
+}
+
+
+//////////////// Clone Unlinking
+
+// svg:use (inkscape's clones) inside a widgets are
+// replaced by real elements they refer in order to :
+//  - allow finding "needle" element in "meter" widget,
+//    even if "needle" is in a group refered by a svg use.
+//  - if "needle" is visible through a svg:use for
+//    each instance of the widget, then needle would show
+//    the same position in all instances
+//
+// For now, clone unlinkink applies to descendants of all widget except HMI:Page
+// TODO: narrow application of clone unlinking to active elements,
+//       while keeping static decoration cloned
+const "to_unlink", "$hmi_elements[not(@id = $hmi_pages)]//svg:use";
+svgtmpl "svg:use", mode="inline_svg"
+{
+    choose {
+        when "@id = $to_unlink/@id"
+            call "unlink_clone";
+        otherwise
+            xsl:copy apply "@* | node()", mode="inline_svg";
+    }
+}
+
+// to unlink a clone, an group containing a copy of target element is created
+// that way, style and transforms can be preserved
+const "_excluded_use_attrs" {
+    name > href
+    name > width
+    name > height
+    name > x
+    name > y
+}
+const "excluded_use_attrs","exsl:node-set($_excluded_use_attrs)";
+
+svgfunc "unlink_clone"{
+    g{
+        // include non excluded attributes
+        foreach "@*[not(local-name() = $excluded_use_attrs/name)]"
+            attrib "{name()}" > «.»
+
+        const "targetid","substring-after(@xlink:href,'#')";
+        apply "//svg:*[@id = $targetid]", mode="unlink_clone"{
+            with "seed","@id";
+        }
+    }
+}
+
+// clone unlinking is really similar to deep-copy
+// all nodes are sytematically copied
+svgtmpl "@id", mode="unlink_clone" {
+    param "seed";
+    attrib "id" > «$seed»_«.»
+}
+
+svgtmpl "@*", mode="unlink_clone" xsl:copy;
+
+// copying widgets would have unwanted effect
+// instead widget is refered through a svg:use.
+svgtmpl "svg:*", mode="unlink_clone" {
+    param "seed";
+    choose {
+        // node recursive copy ends when finding a widget
+        when "@id = $hmi_elements/@id" {
+            // place a clone instead of copying
+            use{
+                attrib "xlink:href" > «concat('#',@id)»
+            }
+        }
+        otherwise {
+            xsl:copy apply "@* | node()", mode="unlink_clone" {
+                with "seed","$seed";
+            }
+        }
+    }
+}
+
+/*const "mark" > =HMI=\n*/
+
+const "result_svg" apply "/", mode="inline_svg";
+const "result_svg_ns", "exsl:node-set($result_svg)";
+
+function "debug_unlink" {
+    foreach "$to_unlink"{
+        | «@id»
+    }
+}
+!debug_output_calls.append("debug_unlink")