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")