SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
--- /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