# HG changeset patch # User Edouard Tisserant # Date 1584447361 -3600 # Node ID bec552270ad11c71c1a5c8ea7c896d20d6e734b8 # Parent 682bce95379598f67df85b861c1da940e3271b09 SVGHMI: added inline_svg.ysl2 diff -r 682bce953795 -r bec552270ad1 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Tue Mar 17 11:24:07 2020 +0100 +++ b/svghmi/gen_index_xhtml.xslt Tue Mar 17 13:16:01 2020 +0100 @@ -521,6 +521,13 @@ + + + + + + + Made with SVGHMI. https://beremiz.org @@ -553,6 +560,15 @@ + + + debug_unlink: + + + + + + Unlinked : diff -r 682bce953795 -r bec552270ad1 svghmi/gen_index_xhtml.ysl2 --- a/svghmi/gen_index_xhtml.ysl2 Tue Mar 17 11:24:07 2020 +0100 +++ b/svghmi/gen_index_xhtml.ysl2 Tue Mar 17 13:16:01 2020 +0100 @@ -45,117 +45,7 @@ include detachable_pages.ysl2 - //////////////// Inline SVG - - // Identity template : - // - copy every attributes - // - copy every sub-elements - template "@* | node()", mode="inline_svg" { - // use real xsl:copy instead copy-of alias from yslt.yml2 - if "not(@id = $discardable_elements/@id)" - xsl:copy apply "@* | node()", mode="inline_svg"; - } - - // replaces inkscape's height and width hints. forces fit - template "svg:svg/@width", mode="inline_svg"; - template "svg:svg/@height", mode="inline_svg"; - svgtmpl "svg:svg", mode="inline_svg" svg { - attrib "preserveAspectRatio" > none - attrib "height" > 100vh - attrib "width" > 100vw - apply "@* | node()", mode="inline_svg"; - } - // ensure that coordinate in CSV file generated by inkscape are in default reference frame - template "svg:svg[@viewBox!=concat('0 0 ', @width, ' ', @height)]", mode="inline_svg" { - error > ViewBox settings other than X=0, Y=0 and Scale=1 are not supported - } - // ensure that coordinate in CSV file generated by inkscape match svg default unit - template "sodipodi:namedview[@units!='px' or @inkscape:document-units!='px']", mode="inline_svg" { - error > All units must be set to "px" in Inkscape's document properties - } - - - //////////////// Clone Unlinking - - // svg:use (inkscape's clones) inside a widgets are - // replaced by real elements they refer in order to : - // - allow finding "needle" element in "meter" widget, - // even if "needle" is in a group refered by a svg use. - // - if "needle" is visible through a svg:use for - // each instance of the widget, then needle would show - // the same position in all instances - // - // For now, clone unlinkink applies to descendants of all widget except HMI:Page - // TODO: narrow application of clone unlinking to active elements, - // while keeping static decoration cloned - const "to_unlink", "$hmi_elements[not(@id = $hmi_pages)]//svg:use"; - svgtmpl "svg:use", mode="inline_svg" - { - choose { - when "@id = $to_unlink/@id" - call "unlink_clone"; - otherwise - xsl:copy apply "@* | node()", mode="inline_svg"; - } - } - - // to unlink a clone, an group containing a copy of target element is created - // that way, style and transforms can be preserved - const "_excluded_use_attrs" { - name > href - name > width - name > height - name > x - name > y - } - const "excluded_use_attrs","exsl:node-set($_excluded_use_attrs)"; - - svgfunc "unlink_clone"{ - g{ - // include non excluded attributes - foreach "@*[not(local-name() = $excluded_use_attrs/name)]" - attrib "{name()}" > «.» - - const "targetid","substring-after(@xlink:href,'#')"; - apply "//svg:*[@id = $targetid]", mode="unlink_clone"{ - with "seed","@id"; - } - } - } - - // clone unlinking is really similar to deep-copy - // all nodes are sytematically copied - svgtmpl "@id", mode="unlink_clone" { - param "seed"; - attrib "id" > «$seed»_«.» - } - - svgtmpl "@*", mode="unlink_clone" xsl:copy; - - // copying widgets would have unwanted effect - // instead widget is refered through a svg:use. - svgtmpl "svg:*", mode="unlink_clone" { - param "seed"; - choose { - // node recursive copy ends when finding a widget - when "@id = $hmi_elements/@id" { - // place a clone instead of copying - use{ - attrib "xlink:href" > «concat('#',@id)» - } - } - otherwise { - xsl:copy apply "@* | node()", mode="unlink_clone" { - with "seed","$seed"; - } - } - } - } - - /*const "mark" > =HMI=\n*/ - - const "result_svg" apply "/", mode="inline_svg"; - const "result_svg_ns", "exsl:node-set($result_svg)"; + include inline_svg.ysl2 template "/" { comment > Made with SVGHMI. https://beremiz.org @@ -164,13 +54,6 @@ // '&bug' is a workaround for pyPEG that choke on yml2 python results not parsing to a single call !"&bug {"+"\n".join(["comment {\n| \n| %s:\n call \"%s\";\n| \n}"%(n,n) for n in debug_output_calls]) +"}"! - comment { - | Unlinked : - foreach "$to_unlink"{ - | «@id» - } - } - /**/ html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" { diff -r 682bce953795 -r bec552270ad1 svghmi/inline_svg.ysl2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svghmi/inline_svg.ysl2 Tue Mar 17 13:16:01 2020 +0100 @@ -0,0 +1,120 @@ +// inline_svg.ysl2 +// +// Produce Inline SVG element of resulting XHTML page. + +// Identity template : +// - copy every attributes +// - copy every sub-elements +template "@* | node()", mode="inline_svg" { + // use real xsl:copy instead copy-of alias from yslt.yml2 + if "not(@id = $discardable_elements/@id)" + xsl:copy apply "@* | node()", mode="inline_svg"; +} + +// replaces inkscape's height and width hints. forces fit +template "svg:svg/@width", mode="inline_svg"; +template "svg:svg/@height", mode="inline_svg"; +svgtmpl "svg:svg", mode="inline_svg" svg { + attrib "preserveAspectRatio" > none + attrib "height" > 100vh + attrib "width" > 100vw + apply "@* | node()", mode="inline_svg"; +} +// ensure that coordinate in CSV file generated by inkscape are in default reference frame +template "svg:svg[@viewBox!=concat('0 0 ', @width, ' ', @height)]", mode="inline_svg" { + error > ViewBox settings other than X=0, Y=0 and Scale=1 are not supported +} +// ensure that coordinate in CSV file generated by inkscape match svg default unit +template "sodipodi:namedview[@units!='px' or @inkscape:document-units!='px']", mode="inline_svg" { + error > All units must be set to "px" in Inkscape's document properties +} + + +//////////////// Clone Unlinking + +// svg:use (inkscape's clones) inside a widgets are +// replaced by real elements they refer in order to : +// - allow finding "needle" element in "meter" widget, +// even if "needle" is in a group refered by a svg use. +// - if "needle" is visible through a svg:use for +// each instance of the widget, then needle would show +// the same position in all instances +// +// For now, clone unlinkink applies to descendants of all widget except HMI:Page +// TODO: narrow application of clone unlinking to active elements, +// while keeping static decoration cloned +const "to_unlink", "$hmi_elements[not(@id = $hmi_pages)]//svg:use"; +svgtmpl "svg:use", mode="inline_svg" +{ + choose { + when "@id = $to_unlink/@id" + call "unlink_clone"; + otherwise + xsl:copy apply "@* | node()", mode="inline_svg"; + } +} + +// to unlink a clone, an group containing a copy of target element is created +// that way, style and transforms can be preserved +const "_excluded_use_attrs" { + name > href + name > width + name > height + name > x + name > y +} +const "excluded_use_attrs","exsl:node-set($_excluded_use_attrs)"; + +svgfunc "unlink_clone"{ + g{ + // include non excluded attributes + foreach "@*[not(local-name() = $excluded_use_attrs/name)]" + attrib "{name()}" > «.» + + const "targetid","substring-after(@xlink:href,'#')"; + apply "//svg:*[@id = $targetid]", mode="unlink_clone"{ + with "seed","@id"; + } + } +} + +// clone unlinking is really similar to deep-copy +// all nodes are sytematically copied +svgtmpl "@id", mode="unlink_clone" { + param "seed"; + attrib "id" > «$seed»_«.» +} + +svgtmpl "@*", mode="unlink_clone" xsl:copy; + +// copying widgets would have unwanted effect +// instead widget is refered through a svg:use. +svgtmpl "svg:*", mode="unlink_clone" { + param "seed"; + choose { + // node recursive copy ends when finding a widget + when "@id = $hmi_elements/@id" { + // place a clone instead of copying + use{ + attrib "xlink:href" > «concat('#',@id)» + } + } + otherwise { + xsl:copy apply "@* | node()", mode="unlink_clone" { + with "seed","$seed"; + } + } + } +} + +/*const "mark" > =HMI=\n*/ + +const "result_svg" apply "/", mode="inline_svg"; +const "result_svg_ns", "exsl:node-set($result_svg)"; + +function "debug_unlink" { + foreach "$to_unlink"{ + | «@id» + } +} +!debug_output_calls.append("debug_unlink")