svghmi/parse_labels.ysl2
branchwxPython4
changeset 3609 51a3d6f39944
parent 3595 375626e60b63
--- a/svghmi/parse_labels.ysl2	Tue Sep 13 16:51:54 2022 +0200
+++ b/svghmi/parse_labels.ysl2	Tue Sep 13 16:53:15 2022 +0200
@@ -2,7 +2,7 @@
 
 
 //  Parses:
-//  "HMI:WidgetType|freq:param1:param2@path1,path1min,path1max@path2"
+//  "HMI:WidgetType|freq:param1:param2@a=path1,path1min,path1max@b=path2#a+b>3"
 //
 //  Into:
 //  widget type="WidgetType" id="blah456" {
@@ -13,39 +13,39 @@
 //      path value="path4" index="path4" type="HMI_LOCAL";
 //  }
 //
-const "pathregex",!"'^([^\[,]+)(\[[^\]]+\])?([-.\d,]*)$'"!;
+const "pathregex",!"'^(\w+=)?([^,=]+)([-.\d,]*)$'"!;
 
 const "newline" |
 const "twonewlines", "concat($newline,$newline)";
 
 template "*", mode="parselabel"
 {
-    const "part","@inkscape:label";
+    const "label","@inkscape:label";
     const "desc", "svg:desc";
 
     // add svg:desc field if continuation "\" marker is found at the end of label
-    const "len","string-length($part)";
-    const "has_continuation", "substring($part,$len,1)='\\'";
-    const "label" choose{
+    const "len","string-length($label)";
+    const "has_continuation", "substring($label,$len,1)='\\'";
+    const "full_decl" choose{
         when "$has_continuation" {
            const "_continuation", "substring-before($desc, $twonewlines)";
            const "continuation" choose {
                when "$_continuation" value "$_continuation";
                otherwise value "$desc";
            }
-           value "concat(substring($part,1,$len - 1),translate($continuation,$newline,''))";
+           value "concat(substring($label,1,$len - 1),translate($continuation,$newline,''))";
         }
-        otherwise value "$part";
+        otherwise value "$label";
     }
 
     const "id","@id";
 
-    const "description", "substring-after($label,'HMI:')";
+    const "declaration", "substring-after($full_decl,'HMI:')";
 
-    const "_args", "substring-before($description,'@')";
+    const "_args", "substring-before($declaration,'@')";
     const "args" choose {
         when "$_args" value "$_args";
-        otherwise value "$description";
+        otherwise value "$declaration";
     }
 
     const "_typefreq", "substring-before($args,':')";
@@ -66,37 +66,59 @@
         attrib "type" > «$type»
         if "$freq" {
             if "not(regexp:test($freq,'^[0-9]*(\.[0-9]+)?[smh]?'))" {
-                error > Widget id:«$id» label:«$label» has wrong syntax of frequency forcing «$freq»
+                error > Widget id:«$id» label:«$full_decl» has wrong syntax of frequency forcing «$freq»
             }
             attrib "freq" > «$freq»
         }
+
+        // find "#" + JS expr at the end
+        const "tail", "substring-after($declaration,'@')";
+        const "taillen","string-length($tail)";
+        const "has_enable", "contains($tail, '#')";
+        const "paths" choose{
+            when "$has_enable" {
+               value "substring-before($tail,'#')";
+            }
+            otherwise value "$tail";
+        }
+        if "$has_enable" {
+            const "enable_expr", "substring-after($tail,'#')";
+            attrib "enable_expr" value "$enable_expr";
+        }
+
         foreach "str:split(substring-after($args, ':'), ':')" {
             arg {
                 attrib "value" > «.»
             }
         }
-        const "paths", "substring-after($description,'@')";
+
+        // for stricter syntax checking, this should make error
+        // if $paths contains "@@" or ends with "@" (empty paths)
+
         foreach "str:split($paths, '@')" {
             if "string-length(.) > 0" path {
                 // 1 : global match
+                // 2 : assign=
                 // 2 : /path
-                // 3 : [accepts]
-                // 4 : min,max
+                // 3 : min,max
                 const "path_match", "regexp:match(.,$pathregex)";
+                const "pathassign", "substring-before($path_match[2],'=')";
                 const "pathminmax", "str:split($path_match[4],',')";
-                const "path", "$path_match[2]";
-                const "path_accepts", "$path_match[3]";
+                const "path", "$path_match[3]";
                 const "pathminmaxcount", "count($pathminmax)";
-                attrib "value" > «$path»
-                if "string-length($path_accepts)"
-                    attrib "accepts" > «$path_accepts»
+                if "not($path)"
+                    error > Widget id:«$id» label:«$full_decl» has wrong syntax
+
+                attrib "value" value "$path";
+                if "$pathassign"
+                    attrib "assign" value "$pathassign";
                 choose {
                     when "$pathminmaxcount = 2" {
                         attrib "min" > «$pathminmax[1]»
                         attrib "max" > «$pathminmax[2]»
                     }
                     when "$pathminmaxcount = 1 or $pathminmaxcount > 2" {
-                        error > Widget id:«$id» label:«$label» has wrong syntax of path section «$pathminmax»
+                        error > Widget id:«$id» label:«$full_decl» has wrong syntax of path section «$pathminmax»
                     }
                 }
                 if "$indexed_hmitree" choose {
@@ -110,7 +132,7 @@
                         const "item", "$indexed_hmitree/*[@hmipath = $path]";
                         const "pathtype", "local-name($item)";
                         if "$pathminmaxcount = 3 and not($pathtype = 'HMI_INT' or $pathtype = 'HMI_REAL')" {
-                            error > Widget id:«$id» label:«$label» path section «$pathminmax» use min and max on non mumeric value
+                            error > Widget id:«$id» label:«$full_decl» path section «$pathminmax» use min and max on non mumeric value
                         }
                         if "count($item) = 1" {
                             attrib "index" > «$item/@index»