SVGHMI: added inline_svg.ysl2 svghmi
authorEdouard Tisserant
Tue, 17 Mar 2020 13:16:01 +0100
branchsvghmi
changeset 2878 bec552270ad1
parent 2877 682bce953795
child 2879 58e6a91dc37f
SVGHMI: added inline_svg.ysl2
svghmi/gen_index_xhtml.xslt
svghmi/gen_index_xhtml.ysl2
svghmi/inline_svg.ysl2
--- a/svghmi/gen_index_xhtml.xslt	Tue Mar 17 11:24:07 2020 +0100
+++ b/svghmi/gen_index_xhtml.xslt	Tue Mar 17 13:16:01 2020 +0100
@@ -521,6 +521,13 @@
     <xsl:apply-templates mode="inline_svg" select="/"/>
   </xsl:variable>
   <xsl:variable name="result_svg_ns" select="exsl:node-set($result_svg)"/>
+  <xsl:template name="debug_unlink">
+    <xsl:for-each select="$to_unlink">
+      <xsl:value-of select="@id"/>
+      <xsl:text>
+</xsl:text>
+    </xsl:for-each>
+  </xsl:template>
   <xsl:template match="/">
     <xsl:comment>
       <xsl:text>Made with SVGHMI. https://beremiz.org</xsl:text>
@@ -553,6 +560,15 @@
 </xsl:text>
     </xsl:comment>
     <xsl:comment>
+      <xsl:text>
+</xsl:text>
+      <xsl:text>debug_unlink:
+</xsl:text>
+      <xsl:call-template name="debug_unlink"/>
+      <xsl:text>
+</xsl:text>
+    </xsl:comment>
+    <xsl:comment>
       <xsl:text>Unlinked :
 </xsl:text>
       <xsl:for-each select="$to_unlink">
--- a/svghmi/gen_index_xhtml.ysl2	Tue Mar 17 11:24:07 2020 +0100
+++ b/svghmi/gen_index_xhtml.ysl2	Tue Mar 17 13:16:01 2020 +0100
@@ -45,117 +45,7 @@
 
     include detachable_pages.ysl2
 
-    //////////////// Inline SVG
-
-    // 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)";
+    include inline_svg.ysl2
 
     template "/" {
         comment > Made with SVGHMI. https://beremiz.org
@@ -164,13 +54,6 @@
         // '&bug' is a workaround for pyPEG that choke on yml2 python results not parsing to a single call
         !"&bug {"+"\n".join(["comment {\n| \n| %s:\n call \"%s\";\n| \n}"%(n,n) for n in debug_output_calls]) +"}"!
 
-        comment {
-            | Unlinked :
-            foreach "$to_unlink"{
-                | «@id»
-            }
-        }
-        /**/
         html xmlns="http://www.w3.org/1999/xhtml"
              xmlns:svg="http://www.w3.org/2000/svg"
              xmlns:xlink="http://www.w3.org/1999/xlink" {
--- /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")