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"
/* Our namespace to invoke python code */
xmlns:ns="beremiz"
extension-element-prefixes="ns func"
exclude-result-prefixes="ns str regexp exsl func" {
/* 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 "hmi_elements", "//*[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']";
const "default_page" choose {
when "count($hmi_pages) > 1" {
const "Home_page",
"$hmi_pages[func:parselabel(@inkscape:label)/widget/arg[1]/@value = 'Home']";
choose {
when "$Home_page" > Home
otherwise {
error "No Home page defined!";
}
}
}
when "count($hmi_pages) = 0" {
error "No page defined!";
}
otherwise > «func:parselabel($hmi_pages/@inkscape:label)/widget/arg[1]/@value»
}
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" 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 "/" {
comment > Made with SVGHMI. https://beremiz.org
html xmlns="http://www.w3.org/1999/xhtml" {
head;
body style="margin:0;" {
xsl:copy {
comment {
apply "$hmi_geometry", mode="testgeo";
}
comment {
apply "$hmitree", mode="testtree";
}
comment {
apply "$indexed_hmitree", mode="testtree";
}
apply "@* | node()", mode="identity_svg";
}
script{
call "scripts";
}
}
}
}
func:function name="func:parselabel" {
param "label";
const "description", "substring-after($label,'HMI:')";
const "_args", "substring-before($description,'@')";
const "args" choose {
when "$_args" value "$_args";
otherwise value "$description";
}
const "_type", "substring-before($args,':')";
const "type" choose {
when "$_type" value "$_type";
otherwise value "$args";
}
const "ast" if "$type" widget {
attrib "type" > «$type»
foreach "str:split(substring-after($args, ':'), ':')" {
arg {
attrib "value" > «.»
}
}
const "paths", "substring-after($description,'@')";
foreach "str:split($paths, '@')" {
path {
attrib "value" > «.»
}
}
}
func:result select="exsl:node-set($ast)"
}
function "scripts"
{
/* 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 hmi_index = {
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()" > ,`
}
| }
|
| var page_desc = {
foreach "$hmi_pages" {
const "desc", "func:parselabel(@inkscape:label)/widget";
| "«$desc/arg[1]/@value»": {
| id: "«@id»",
| widgets: [
const "page", ".";
const "p", "$hmi_geometry[@Id = $page/@id]";
foreach """$hmi_geometry[@Id != $page/@id and
@x >= $p/@x and @y >= $p/@y and
@w <= $p/@w and @h <= $p/@h]""" {
| "«@Id»"`if "position()!=last()" > ,`
}
| ]
}
| }
|
| var default_page = "«$default_page»";
include text svghmi.js
}
/*
Parses:
"HMI:WidgetType:param1:param2@path1@path2"
Into:
widget type="WidgetType" {
arg value="param1";
arg value="param2";
path value="path1";
path value="path2";
}
*/
template "*", mode="page_desc" {
}
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,'>')"
};
}
}