diff -r 577118ebd179 -r c89fc366bebd svghmi/hmi_tree.ysl2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svghmi/hmi_tree.ysl2 Thu Sep 02 21:36:29 2021 +0200 @@ -0,0 +1,129 @@ +// hmi_tree.ysl2 + + +// HMI Tree computed from VARIABLES.CSV in svghmi.py +const "hmitree", "ns:GetHMITree()"; + +const "_categories" { + noindex > HMI_PLC_STATUS + noindex > HMI_CURRENT_PAGE +} +const "categories", "exsl:node-set($_categories)"; + +// HMI Tree Index +const "_indexed_hmitree" apply "$hmitree", mode="index"; +const "indexed_hmitree", "exsl:node-set($_indexed_hmitree)"; + +emit "preamble:hmi-tree" { + | var hmi_hash = [«$hmitree/@hash»]; + | + | var heartbeat_index = «$indexed_hmitree/*[@hmipath = '/HEARTBEAT']/@index»; + | + | var hmitree_types = [ + + foreach "$indexed_hmitree/*" + | /* «@index» */ "«substring(local-name(), 5)»"`if "position()!=last()" > ,` + + | ]; + | + | var hmitree_paths = [ + + foreach "$indexed_hmitree/*" + | /* «@index» */ "«@hmipath»"`if "position()!=last()" > ,` + + | ]; + | +} + +template "*", mode="index" { + param "index", "0"; + param "parentpath", "''"; + const "content" { + const "path" + choose { + when "count(ancestor::*)=0" > / + when "count(ancestor::*)=1" > /«@name» + 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 parse_labels.ysl2 + +const "_parsed_widgets" { + widget type="VarInitPersistent" { + arg value="0"; + path value="lang"; + } + apply "$hmi_elements", mode="parselabel"; +} + +const "parsed_widgets","exsl:node-set($_parsed_widgets)"; + +def "func:widget" { + param "id"; + result "$parsed_widgets/widget[@id = $id]"; +} + +def "func:is_descendant_path" { + param "descend"; + param "ancest"; + // TODO : use HMI tree to answer more accurately + result "string-length($ancest) > 0 and starts-with($descend,$ancest)"; +} + +def "func:same_class_paths" { + param "a"; + param "b"; + const "class_a", "$indexed_hmitree/*[@hmipath = $a]/@class"; + const "class_b", "$indexed_hmitree/*[@hmipath = $b]/@class"; + result "$class_a and $class_b and $class_a = $class_b"; +} + +// Debug data +template "*", mode="testtree"{ + param "indent", "''"; + > «$indent» «local-name()» + foreach "@*" > «local-name()»="«.»" + > \n + apply "*", mode="testtree" { + with "indent" value "concat($indent,'>')" + }; +} + +emit "debug:hmi-tree" { + | Raw HMI tree + apply "$hmitree", mode="testtree"; + | + | Indexed HMI tree + apply "$indexed_hmitree", mode="testtree"; + | + | Parsed Widgets + copy "_parsed_widgets"; + apply "$parsed_widgets", mode="testtree"; +}