svghmi/gen_index_xhtml.ysl2
author Edouard Tisserant
Mon, 07 Oct 2019 12:02:45 +0200
branchsvghmi
changeset 2791 d022523cb621
parent 2790 8fab1886ebec
child 2792 0c0d3895b036
permissions -rw-r--r--
SVGHMI: now generating JS object describing widgets and pointing to SVG elements
include yslt_noindent.yml2

// overrides yslt's output function to set CDATA
decl output(method, cdata-section-elements="script");
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"
            xmlns:xhtml="http://www.w3.org/1999/xhtml"

            /* 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">
     */
    const "geometry", "ns:GetSVGGeometry()";
    const "hmitree", "ns:GetHMITree()";

    const "_categories" {
        noindex > HMI_ROOT
        noindex > HMI_LABEL
        noindex > HMI_CLASS
        noindex > HMI_PLC_STATUS
        noindex > HMI_CURRENT_PAGE
    }
    const "categories", "exsl:node-set($_categories)";
    //const "indexed_hmitree", "$hmitree[not(local-name() = $categories/noindex/text())]";
    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;
                    }
                    /* no node expected below value nodes */
                }
                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»
        }
    }

    /* Identity template :
     *  - copy every attributes 
     *  - copy every sub-elements
     */
    template "@* | node()", mode="identity_svg" {
      /* use real xsl:copy instead copy-of alias from yslt.yml2 */
      xsl:copy apply "@* | node()", mode="identity_svg";
    }

    const "mark" > =HMI=\n

    /* copy root node and add geometry as comment for a test */
    template "/" 
      html xmlns="http://www.w3.org/1999/xhtml" {
          head;
          body style="margin:0;" {
              xsl:copy {
                  comment {
                      apply "$geometry", mode="testgeo";
                  }
                  comment {
                      apply "$hmitree", mode="testtree";
                  }
                  comment {
                      apply "$indexed_hmitree", mode="testtree";
                  }
                  apply "@* | node()", mode="identity_svg";
              }
              script{
                  /* TODO : paste hmitree hash stored in hmi tree root node */

                  /* TODO re-enable
                  ||
                  function evaluate_js_from_descriptions() {
                      var Page;
                      var Input;
                      var Display;
                      var res = [];
                  ||
                  const "midmark" > \n«$mark»
                  apply """//*[contains(child::svg:desc, $midmark) or \
                               starts-with(child::svg:desc, $mark)]""",2 
                        mode="code_from_descs";
                  ||
                      return res;
                  }
                  ||
                  */

                  /*TODO add :
                    - pages content
                      + with ref to elt ?
                    - widgets parameters
                  */

                  | var subscriptions = {

                  const "svg","/"; /* foreach loses document root */
                  foreach "$indexed_hmitree/*" {
                      | «@index»: {
                      |     name: "«@name»",
                      |     hmipath: "«@hmipath»"
                      |     ids: [
                      const "hmipath","@hmipath";
                      foreach "$svg//*[substring-after(@inkscape:label,'@') = $hmipath]" {
                      |         "«@id»"`if "position()!=last()" > ,`
                      }
                      |     ]
                      | }`if "position()!=last()" > ,`
                  }

                  | }

                  include text svghmi.js
              }
          }
    }

    template "*", mode="code_from_descs" {
        ||
        {
            var path, role, name, priv;
            var id = "«@id»";
        ||

        /* if label is used, use it as default name */
        if "@inkscape:label"
            |> name = "«@inkscape:label»";

        | /* -------------- */

        // this breaks indent, but fixing indent could break string literals
        value "substring-after(svg:desc, $mark)";
        // nobody reads generated code anyhow...

        ||

            /* -------------- */
            res.push({
                path:path,
                role:role,
                name:name,
                priv:priv
            })
        }
        ||
    }


    template "bbox", mode="testgeo"{
        | ID: «@Id» x: «@x» y: «@y» w: «@w» h: «@h»
    }

    template "*", mode="testtree"{
        param "indent", "''";
        > «$indent» «local-name()» 
        foreach "@*" > «local-name()»=«.» 
        > \n
        apply "*", mode="testtree" {
            with "indent" value "concat($indent,'>')"
        };
    }
}