// parse_labels.ysl2 // Parses: // "HMI:WidgetType|freq:param1:param2@a=path1,path1min,path1max@b=path2#a+b>3" // // Into: // widget type="WidgetType" id="blah456" { // arg value="param1"; // arg value="param2"; // path value=".path1" index=".path1" min="path1min" max="path1max" type="PAGE_LOCAL"; // path value="/path1" index="348" type="HMI_INT"; // path value="path4" index="path4" type="HMI_LOCAL"; // } // const "pathregex",!"'^(\w+=)?([^,=]+)([-.\d,]*)$'"!; const "newline" | const "twonewlines", "concat($newline,$newline)"; template "*", mode="parselabel" { 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($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($label,1,$len - 1),translate($continuation,$newline,''))"; } otherwise value "$label"; } const "id","@id"; const "declaration", "substring-after($full_decl,'HMI:')"; const "_args", "substring-before($declaration,'@')"; const "args" choose { when "$_args" value "$_args"; otherwise value "$declaration"; } const "_typefreq", "substring-before($args,':')"; const "typefreq" choose { when "$_typefreq" value "$_typefreq"; otherwise value "$args"; } const "freq", "substring-after($typefreq,'|')"; const "_type", "substring-before($typefreq,'|')"; const "type" choose { when "$_type" value "$_type"; otherwise value "$typefreq"; } if "$type" widget { attrib "id" > «$id» attrib "type" > «$type» if "$freq" { if "not(regexp:test($freq,'^[0-9]*(\.[0-9]+)?[smh]?'))" { error > Widget id:«$id» label:«$full_decl» has wrong syntax of frequency forcing «$freq» } attrib "freq" > «$freq» } foreach "str:split(substring-after($args, ':'), ':')" { arg { attrib "value" > «.» } } // 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"; } // 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 : 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[3]"; const "pathminmaxcount", "count($pathminmax)"; 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:«$full_decl» has wrong syntax of path section «$pathminmax» } } if "$indexed_hmitree" choose { when "regexp:test($path,'^\.[a-zA-Z0-9_]+$')" { attrib "type" > PAGE_LOCAL } when "regexp:test($path,'^[a-zA-Z0-9_]+$')" { attrib "type" > HMI_LOCAL } otherwise { 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:«$full_decl» path section «$pathminmax» use min and max on non mumeric value } if "count($item) = 1" { attrib "index" > «$item/@index» attrib "type" > «$pathtype» } } } } } choose{ when "$has_continuation" { const "_continuation", "substring-after($desc, $twonewlines)"; if "$_continuation" desc value "$_continuation"; } otherwise if "$desc" desc value "$desc/text()"; } } } // Templates to generate label back from parsed tree template "arg", mode="genlabel" > :«@value» template "path", mode="genlabel" { > @«@value» if "string-length(@min)>0 or string-length(@max)>0" > ,«@min»,«@max» } template "widget", mode="genlabel" { > HMI:«@type» apply "arg", mode="genlabel"; apply "path", mode="genlabel"; }