SVGHMI : create hmi_tree.ysl2, rename bbox_intersect.ysl2 into geometry.ysl2 and move more code into. Add per included ysl2 file debug output.
--- a/svghmi/Makefile Mon Mar 16 18:27:49 2020 +0100
+++ b/svghmi/Makefile Tue Mar 17 07:39:50 2020 +0100
@@ -12,11 +12,12 @@
yml2path ?= $(abspath ../../yml2)
ysl2files := gen_index_xhtml.ysl2
+ysl2includes := geometry.ysl2 hmi_tree.ysl2
xsltfiles := $(patsubst %.ysl2, %.xslt, $(ysl2files))
all:$(xsltfiles)
-%.xslt: %.ysl2 svghmi.js ../yslt_noindent.yml2
+%.xslt: %.ysl2 $(ysl2includes) svghmi.js ../yslt_noindent.yml2
$(yml2path)/yml2c -I $(yml2path):../ $< -o $@.tmp
xmlstarlet fo $@.tmp > $@
rm $@.tmp
--- a/svghmi/bbox_intersect.ysl2 Mon Mar 16 18:27:49 2020 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-// bbox_intersect.ysl2
-//
-// bounding boxes intersection tests
-
-// Rates 1D intersection of 2 segments A and B
-// described respectively with a0,a1 and b0,b1
-def "func:intersect_1d" {
- // it is assumed that a1 > a0 and b1 > b0
- param "a0";
- param "a1";
- param "b0";
- param "b1";
-
- const "d0", "$a0 >= $b0";
- const "d1", "$a1 >= $b1";
- choose {
- when "not($d0) and $d1"
- // b contained in a
- // a0<b0 b1<a1
- // a +--------+
- // b +--+
- result "3";
- when "$d0 and not($d1)"
- // a contained in b
- // b0<a0 a1<b1
- // a +--+
- // b +--------+
- result "2";
- when "$d0 and $d1 and $a0 < $b1"
- // a and b are overlapped
- // b0<a0<b1<a1
- // a +-----+
- // b +-----+
- result "1";
- when "not($d0) and not($d1) and $b0 < $a1"
- // a and b are overlapped
- // a0<b0<a1<b1
- // a +-----+
- // b +-----+
- result "1";
- // since orientation doesn't matter,
- // rated same as previous symetrical overlapping
- otherwise
- result "0"; /* no intersection*/
- }
-}
-
-
-// Rates intersection A and B areas described with x,y,w and h
-// attributes passed as $a and $b parameters.
-//
-// returns :
-// 0 - no intersection
-// .-----.
-// .-----. | b|
-// | | | |
-// | | '-----'
-// |a |
-// '-----'
-//
-// 1 - overlapping
-// .-----.
-// .---|--. b|
-// | | | |
-// | '-----'
-// |a |
-// '------'
-//
-// 2 - overlapping
-// .-----.
-// | a |
-// .---|-----|---.
-// | '-----' |
-// | b |
-// '-------------'
-//
-// 3 - overlapping
-// .-----.
-// | b |
-// .---|-----|---.
-// | '-----' |
-// | a |
-// '-------------'
-//
-// 4 - a contained in b
-// .-------------.
-// | .-----. |
-// | | a | |
-// |b '-----' |
-// '-------------'
-//
-// 6 - overlapping
-// .----.
-// | b|
-// .---|----|---.
-// |a | | |
-// '---|----|---'
-// '----'
-//
-// 9 - b contained in a
-// .-------------.
-// | .-----. |
-// | | b | |
-// |a '-----' |
-// '-------------'
-//
-def "func:intersect" {
- param "a";
- param "b";
-
- const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)";
-
- choose{
- when "$x_intersect != 0"{
- const "y_intersect", "func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)";
- result "$x_intersect * $y_intersect";
- }
- otherwise result "0";
- }
-}
--- a/svghmi/gen_index_xhtml.xslt Mon Mar 16 18:27:49 2020 +0100
+++ b/svghmi/gen_index_xhtml.xslt Tue Mar 17 07:39:50 2020 +0100
@@ -1,11 +1,8 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:func="http://exslt.org/functions" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg" xmlns:str="http://exslt.org/strings" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ns="beremiz" xmlns:cc="http://creativecommons.org/ns#" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" extension-element-prefixes="ns func exsl regexp str dyn" version="1.0" exclude-result-prefixes="ns str regexp exsl func dyn">
<xsl:output method="xml" cdata-section-elements="xhtml:script"/>
- <xsl:variable name="geometry" select="ns:GetSVGGeometry()"/>
- <xsl:variable name="hmitree" select="ns:GetHMITree()"/>
<xsl:variable name="svg_root_id" select="/svg:svg/@id"/>
<xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/>
- <xsl:variable name="hmi_geometry" select="$geometry[@Id = $hmi_elements/@id]"/>
<xsl:variable name="hmi_pages" select="$hmi_elements[func:parselabel(@inkscape:label)/widget/@type = 'Page']"/>
<xsl:variable name="default_page">
<xsl:choose>
@@ -54,6 +51,25 @@
</xsl:otherwise>
</xsl:choose>
</func:function>
+ <xsl:variable name="geometry" select="ns:GetSVGGeometry()"/>
+ <xsl:template name="debug_geometry">
+ <xsl:text>GEOMETRY : ID, x, y, w, h
+</xsl:text>
+ <xsl:for-each select="$geometry[@Id = $hmi_elements/@id]">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@Id"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@x"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@y"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@w"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@h"/>
+ <xsl:text>
+</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
<func:function name="func:intersect_1d">
<xsl:param name="a0"/>
<xsl:param name="a1"/>
@@ -98,7 +114,7 @@
<xsl:variable name="groups" select="/svg:svg | //svg:g"/>
<xsl:variable name="g" select="$geometry[@Id = $elt/@id]"/>
<xsl:variable name="candidates" select="$geometry[@Id != $elt/@id]"/>
- <func:result select="$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]"/>
+ <func:result select="$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]"/>
</func:function>
<func:function name="func:all_related_elements">
<xsl:param name="page"/>
@@ -140,6 +156,7 @@
</func:function>
<xsl:variable name="_detachable_elements" select="func:detachable_elements($hmi_pages)"/>
<xsl:variable name="detachable_elements" select="$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]"/>
+ <xsl:variable name="hmitree" select="ns:GetHMITree()"/>
<xsl:variable name="_indexed_hmitree">
<xsl:apply-templates mode="index" select="$hmitree"/>
</xsl:variable>
@@ -319,7 +336,13 @@
<xsl:text>Made with SVGHMI. https://beremiz.org</xsl:text>
</xsl:comment>
<xsl:comment>
- <xsl:apply-templates mode="testgeo" select="$hmi_geometry"/>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>debug_geometry:
+</xsl:text>
+ <xsl:call-template name="debug_geometry"/>
+ <xsl:text>
+</xsl:text>
</xsl:comment>
<xsl:comment>
<xsl:apply-templates mode="testtree" select="$hmitree"/>
@@ -1445,20 +1468,6 @@
<xsl:text>//})();
</xsl:text>
</xsl:template>
- <xsl:template mode="testgeo" match="bbox">
- <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:text>
-</xsl:text>
- </xsl:template>
<xsl:template mode="testtree" match="*">
<xsl:param name="indent" select="''"/>
<xsl:value-of select="$indent"/>
--- a/svghmi/gen_index_xhtml.ysl2 Mon Mar 16 18:27:49 2020 +0100
+++ b/svghmi/gen_index_xhtml.ysl2 Tue Mar 17 07:39:50 2020 +0100
@@ -17,6 +17,8 @@
in xsl decl svgtmpl(match, xmlns="http://www.w3.org/2000/svg") alias template;
in xsl decl svgfunc(name, xmlns="http://www.w3.org/2000/svg") alias template;
+!debug_output_calls = []
+
istylesheet
/* From Inkscape */
xmlns:dc="http://purl.org/dc/elements/1.1/"
@@ -33,16 +35,9 @@
extension-element-prefixes="ns func exsl regexp str dyn"
exclude-result-prefixes="ns str regexp exsl func dyn" {
- /* 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">
- */
- const "geometry", "ns:GetSVGGeometry()";
- const "hmitree", "ns:GetHMITree()";
const "svg_root_id", "/svg:svg/@id";
const "hmi_elements", "//svg:*[starts-with(@inkscape:label, 'HMI:')]";
- const "hmi_geometry", "$geometry[@Id = $hmi_elements/@id]";
const "hmi_pages", "$hmi_elements[func:parselabel(@inkscape:label)/widget/@type = 'Page']";
@@ -85,19 +80,8 @@
}
}
- include bbox_intersect.ysl2
-
- // return overlapping geometry for a given element
- // all intersercting element are returned
- // except groups, that must be contained to be counted in
- def "func:overlapping_geometry" {
- param "elt";
- const "groups", "/svg:svg | //svg:g";
- const "g", "$geometry[@Id = $elt/@id]";
- const "candidates", "$geometry[@Id != $elt/@id]";
- result """$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or
- (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]""";
- }
+ include geometry.ysl2
+
def "func:all_related_elements" {
param "page";
@@ -155,47 +139,7 @@
const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]";
- //////////////// HMI Tree Index
-
- const "_indexed_hmitree" apply "$hmitree", mode="index";
- const "indexed_hmitree", "exsl:node-set($_indexed_hmitree)";
-
- template "*", mode="index" {
- param "index", "0";
- param "parentpath", "''";
- const "content" {
- const "path"
- choose {
- when "local-name() = 'HMI_ROOT'" > «$parentpath»
- otherwise > «$parentpath»/«@name»
- }
- choose {
- when "not(local-name() = $categories/noindex)" {
- xsl:copy {
- attrib "index" > «$index»
- attrib "hmipath" > «$path»
- foreach "@*" xsl:copy;
- }
- apply "*[1]", mode="index"{
- with "index", "$index + 1";
- with "parentpath" > «$path»
- }
- }
- otherwise {
- apply "*[1]", mode="index"{
- with "index", "$index";
- with "parentpath" > «$path»
- }
- }
- }
- }
-
- copy "$content";
- apply "following-sibling::*[1]", mode="index" {
- with "index", "$index + count(exsl:node-set($content)/*)";
- with "parentpath" > «$parentpath»
- }
- }
+ include hmi_tree.ysl2
def "func:is_descendant_path" {
@@ -316,13 +260,14 @@
const "result_svg" apply "/", mode="inline_svg";
const "result_svg_ns", "exsl:node-set($result_svg)";
- /* copy root node and add geometry as comment for a test */
template "/" {
comment > Made with SVGHMI. https://beremiz.org
- /* DEBUG DATA */
- comment {
- apply "$hmi_geometry", mode="testgeo";
- }
+
+ // use python to call all debug output from included definitions
+ // '&bug' is a workaround for old pyPEG that choke on empty python results
+ !"&bug "+"\n".join(["comment {|\n| %s:\n call \"%s\";\n| \n}"%(n,n) for n in debug_output_calls])!
+
+ // TODO
comment {
apply "$hmitree", mode="testtree";
}
@@ -570,10 +515,6 @@
/**/
- template "bbox", mode="testgeo"{
- | ID: «@Id» x: «@x» y: «@y» w: «@w» h: «@h»
- }
-
template "*", mode="testtree"{
param "indent", "''";
> «$indent» «local-name()»
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/geometry.ysl2 Tue Mar 17 07:39:50 2020 +0100
@@ -0,0 +1,145 @@
+// geometry.ysl2
+//
+// Geometry (bounding box intersection) definitions
+
+// 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">
+const "geometry", "ns:GetSVGGeometry()";
+
+// Debug data
+function "debug_geometry" {
+ | GEOMETRY : ID, x, y, w, h
+ foreach "$geometry[@Id = $hmi_elements/@id]"
+ | «@Id» «@x» «@y» «@w» «@h»
+}
+!debug_output_calls.append("debug_geometry")
+
+// Rates 1D intersection of 2 segments A and B
+// described respectively with a0,a1 and b0,b1
+def "func:intersect_1d" {
+ // it is assumed that a1 > a0 and b1 > b0
+ param "a0";
+ param "a1";
+ param "b0";
+ param "b1";
+
+ const "d0", "$a0 >= $b0";
+ const "d1", "$a1 >= $b1";
+ choose {
+ when "not($d0) and $d1"
+ // b contained in a
+ // a0<b0 b1<a1
+ // a +--------+
+ // b +--+
+ result "3";
+ when "$d0 and not($d1)"
+ // a contained in b
+ // b0<a0 a1<b1
+ // a +--+
+ // b +--------+
+ result "2";
+ when "$d0 and $d1 and $a0 < $b1"
+ // a and b are overlapped
+ // b0<a0<b1<a1
+ // a +-----+
+ // b +-----+
+ result "1";
+ when "not($d0) and not($d1) and $b0 < $a1"
+ // a and b are overlapped
+ // a0<b0<a1<b1
+ // a +-----+
+ // b +-----+
+ result "1";
+ // since orientation doesn't matter,
+ // rated same as previous symetrical overlapping
+ otherwise
+ result "0"; /* no intersection*/
+ }
+}
+
+
+// Rates intersection A and B areas described with x,y,w and h
+// attributes passed as $a and $b parameters.
+//
+// returns :
+// 0 - no intersection
+// .-----.
+// .-----. | b|
+// | | | |
+// | | '-----'
+// |a |
+// '-----'
+//
+// 1 - overlapping
+// .-----.
+// .---|--. b|
+// | | | |
+// | '-----'
+// |a |
+// '------'
+//
+// 2 - overlapping
+// .-----.
+// | a |
+// .---|-----|---.
+// | '-----' |
+// | b |
+// '-------------'
+//
+// 3 - overlapping
+// .-----.
+// | b |
+// .---|-----|---.
+// | '-----' |
+// | a |
+// '-------------'
+//
+// 4 - a contained in b
+// .-------------.
+// | .-----. |
+// | | a | |
+// |b '-----' |
+// '-------------'
+//
+// 6 - overlapping
+// .----.
+// | b|
+// .---|----|---.
+// |a | | |
+// '---|----|---'
+// '----'
+//
+// 9 - b contained in a
+// .-------------.
+// | .-----. |
+// | | b | |
+// |a '-----' |
+// '-------------'
+//
+def "func:intersect" {
+ param "a";
+ param "b";
+
+ const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)";
+
+ choose{
+ when "$x_intersect != 0"{
+ const "y_intersect", "func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)";
+ result "$x_intersect * $y_intersect";
+ }
+ otherwise result "0";
+ }
+}
+
+// return overlapping geometry for a given element
+// all intersercting element are returned
+// except groups, that must be contained to be counted in
+def "func:overlapping_geometry" {
+ param "elt";
+ const "groups", "/svg:svg | //svg:g";
+ const "g", "$geometry[@Id = $elt/@id]";
+ const "candidates", "$geometry[@Id != $elt/@id]";
+ result """$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or
+ (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]""";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/hmi_tree.ysl2 Tue Mar 17 07:39:50 2020 +0100
@@ -0,0 +1,47 @@
+// hmi_tree.ysl2
+
+
+// HMI Tree computed from VARIABLES.CSV in svghmi.py
+const "hmitree", "ns:GetHMITree()";
+
+
+// HMI Tree Index
+const "_indexed_hmitree" apply "$hmitree", mode="index";
+const "indexed_hmitree", "exsl:node-set($_indexed_hmitree)";
+
+template "*", mode="index" {
+ param "index", "0";
+ param "parentpath", "''";
+ const "content" {
+ const "path"
+ choose {
+ when "local-name() = 'HMI_ROOT'" > «$parentpath»
+ otherwise > «$parentpath»/«@name»
+ }
+ choose {
+ when "not(local-name() = $categories/noindex)" {
+ xsl:copy {
+ attrib "index" > «$index»
+ attrib "hmipath" > «$path»
+ foreach "@*" xsl:copy;
+ }
+ apply "*[1]", mode="index"{
+ with "index", "$index + 1";
+ with "parentpath" > «$path»
+ }
+ }
+ otherwise {
+ apply "*[1]", mode="index"{
+ with "index", "$index";
+ with "parentpath" > «$path»
+ }
+ }
+ }
+ }
+
+ copy "$content";
+ apply "following-sibling::*[1]", mode="index" {
+ with "index", "$index + count(exsl:node-set($content)/*)";
+ with "parentpath" > «$parentpath»
+ }
+}