SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with. svghmi
authorEdouard Tisserant
Fri, 09 Aug 2019 12:11:31 +0200
branchsvghmi
changeset 2753 9a7e12e96399
parent 2752 a8c9b7f0a54a
child 2754 a46311f88604
SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
svghmi/Makefile
svghmi/gen_index_xhtml.xslt
svghmi/gen_index_xhtml.ysl2
svghmi/svghmi.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/Makefile	Fri Aug 09 12:11:31 2019 +0200
@@ -0,0 +1,25 @@
+#! gmake
+
+# Makefile to generate XSLT stylesheets from ysl2 files in the same directory
+
+# This uses YML2. 
+#   hg clone https://pep.foundation/dev/repos/yml2/
+
+# It should be just fine if yml2 is cloned just asside beremiz
+# otherwise, point yml2path to yml2 source directory
+#   make yml2path=path/to/yml/dir
+
+yml2path ?= $(abspath ../../yml2)
+
+ysl2files := $(wildcard *.ysl2)
+xsltfiles := $(patsubst %.ysl2, %.xslt, $(ysl2files))
+
+all:$(xsltfiles)
+
+%.xslt: %.ysl2 ../yslt_noindent.yml2
+	$(yml2path)/yml2c -I $(yml2path):../ $< -o $@.tmp
+	xmlstarlet fo $@.tmp > $@
+	rm $@.tmp
+	
+clean:
+	rm -f $(xsltfiles)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/gen_index_xhtml.xslt	Fri Aug 09 12:11:31 2019 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:exsl="http://exslt.org/common" xmlns:ns="beremiz" xmlns:cc="http://creativecommons.org/ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
+  <xsl:output method="xml"/>
+  <xsl:variable name="geometry" select="ns:GetSVGGeometry()"/>
+  <xsl:template match="@* | node()">
+    <xsl:copy>
+      <xsl:apply-templates select="@* | node()"/>
+    </xsl:copy>
+  </xsl:template>
+  <xsl:template match="/">
+    <xsl:copy>
+      <xsl:apply-templates mode="testgeo" select="$geometry"/>
+      <xsl:apply-templates select="@* | node()"/>
+    </xsl:copy>
+  </xsl:template>
+  <xsl:template mode="testgeo" match="bbox">
+    <xsl:comment>
+      <xsl:text>ID: </xsl:text>
+      <xsl:value-of select="@id"/>
+      <xsl:text> x: </xsl:text>
+      <xsl:value-of select="@x"/>
+      <xsl:text> y: </xsl:text>
+      <xsl:value-of select="@y"/>
+      <xsl:text> w: </xsl:text>
+      <xsl:value-of select="@w"/>
+      <xsl:text> h: </xsl:text>
+      <xsl:value-of select="@h"/>
+    </xsl:comment>
+  </xsl:template>
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/gen_index_xhtml.ysl2	Fri Aug 09 12:11:31 2019 +0200
@@ -0,0 +1,44 @@
+include yslt_noindent.yml2
+istylesheet 
+            /* From Inkscape */
+            xmlns:dc="http://purl.org/dc/elements/1.1/"
+            xmlns:cc="http://creativecommons.org/ns#"
+            xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+            xmlns:svg="http://www.w3.org/2000/svg"
+            xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+            xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+
+            /* Our namespace to invoke python code */
+            xmlns:ns="beremiz"
+            extension-element-prefixes="ns" 
+            exclude-result-prefixes="ns" {
+    
+    /* This retrieves geometry obtained through "inkscape -S" 
+     * already parsed by python and presented as a list of 
+     * <bbox x="0" y="0" w="42" h="42">
+     */
+    variable "geometry", "ns:GetSVGGeometry()";
+   
+    /* Identity template :
+     *  - copy every attributes 
+     *  - copy every sub-elements
+     */
+    template "@* | node()" {
+      /* use real xsl:copy instead copy-of alias from yslt.yml2 */
+      xsl:copy apply "@* | node()";
+    }
+
+    /* copy root node and add geometry as comment for a test */
+    template "/" {
+      xsl:copy {
+          apply "$geometry", mode="testgeo";
+          apply "@* | node()";
+      }
+    }
+
+    template "bbox", mode="testgeo"{
+          comment {
+              > ID: «@id» x: «@x» y: «@y» w: «@w» h: «@h»
+          }
+    }
+}
--- a/svghmi/svghmi.py	Fri Aug 09 12:07:33 2019 +0200
+++ b/svghmi/svghmi.py	Fri Aug 09 12:11:31 2019 +0200
@@ -15,6 +15,7 @@
 import util.paths as paths
 from POULibrary import POULibrary
 from docutil import open_svg
+from lxml import etree
 
 HMI_TYPES_DESC = {
     "HMI_CLASS":{},
@@ -26,6 +27,10 @@
 
 HMI_TYPES = HMI_TYPES_DESC.keys()
 
+from XSLTransform import XSLTransform
+
+ScriptDirectory = paths.AbsDir(__file__)
+
 class SVGHMILibrary(POULibrary):
     def GetLibraryPath(self):
          return paths.AbsNeighbourFile(__file__, "pous.xml")
@@ -42,7 +47,7 @@
         svghmi_c_file = open(svghmi_c_filepath, 'r')
         svghmi_c_code = svghmi_c_file.read()
         svghmi_c_file.close()
-        svghmi_c_code = svghmi_c_code % { "the code": "/* TODO */"}
+        svghmi_c_code = svghmi_c_code % { "hmi_tree": "TODO !!!"}
 
         gen_svghmi_c_path = os.path.join(buildpath, "svghmi.c")
         gen_svghmi_c = open(gen_svghmi_c_path, 'w')
@@ -92,6 +97,11 @@
                             self._getSVGpath())
         return True
 
+    def GetSVGGeometry(self):
+        # TODO : invoke inskscape -S, csv-parse output, produce elements
+        return [etree.Element("bbox", id="blah0", x="1", y="2", w="3", h="4"),
+                etree.Element("bbox", id="blah1", x="5", y="6", w="7", h="8")]
+
     def CTNGenerate_C(self, buildpath, locations):
         """
         Return C code generated by iec2c compiler
@@ -104,11 +114,25 @@
 
         svgfile = self._getSVGpath()
         if os.path.exists(svgfile):
-            # TODO : call xslt transform on Inkscape's SVG to generate
+
+            # TODO : move to __init__
+            transform = XSLTransform(os.path.join(ScriptDirectory, "gen_index_xhtml.xslt"),
+                          [("GetSVGGeometry", lambda *_ignored:self.GetSVGGeometry())])
+
+
+            # load svg as a DOM with Etree
+            svgdom = etree.parse(svgfile)
+
+            # call xslt transform on Inkscape's SVG to generate XHTML
+            result = transform.transform(svgdom)
+           
+            print(str(result))
+            print(transform.xslt.error_log)
+
+            # TODO
             #   - Errors on HMI semantics
-            #   - Target XHTML as a DOM
             #   - ... maybe something to have a global view of what is declared in SVG.
-            pass
+
         else:
             # TODO : use default svg that expose the HMI tree as-is 
             pass