Edouard@2878: // inline_svg.ysl2 Edouard@2878: // Edouard@2878: // Produce Inline SVG element of resulting XHTML page. Edouard@2779: edouard@2937: // Since stylesheet output namespace is xhtml, templates that output svg have to be explicitely declared as such edouard@2937: in xsl decl svgtmpl(match, xmlns="http://www.w3.org/2000/svg") alias template; edouard@2937: in xsl decl svgfunc(name, xmlns="http://www.w3.org/2000/svg") alias template; edouard@2937: edouard@2937: Edouard@2878: // Identity template : Edouard@2878: // - copy every attributes Edouard@2878: // - copy every sub-elements Edouard@2878: template "@* | node()", mode="inline_svg" { Edouard@2878: // use real xsl:copy instead copy-of alias from yslt.yml2 Edouard@2878: if "not(@id = $discardable_elements/@id)" Edouard@2878: xsl:copy apply "@* | node()", mode="inline_svg"; Edouard@2878: } Edouard@2792: Edouard@2878: // replaces inkscape's height and width hints. forces fit Edouard@2878: template "svg:svg/@width", mode="inline_svg"; Edouard@2878: template "svg:svg/@height", mode="inline_svg"; Edouard@2878: svgtmpl "svg:svg", mode="inline_svg" svg { Edouard@2878: attrib "preserveAspectRatio" > none Edouard@2878: attrib "height" > 100vh Edouard@2878: attrib "width" > 100vw Edouard@2878: apply "@* | node()", mode="inline_svg"; Edouard@2878: } Edouard@2878: // ensure that coordinate in CSV file generated by inkscape are in default reference frame Edouard@2878: template "svg:svg[@viewBox!=concat('0 0 ', @width, ' ', @height)]", mode="inline_svg" { Edouard@2878: error > ViewBox settings other than X=0, Y=0 and Scale=1 are not supported Edouard@2878: } Edouard@2878: // ensure that coordinate in CSV file generated by inkscape match svg default unit Edouard@2878: template "sodipodi:namedview[@units!='px' or @inkscape:document-units!='px']", mode="inline_svg" { Edouard@2878: error > All units must be set to "px" in Inkscape's document properties Edouard@2878: } Edouard@2792: edouard@2941: ////// Clone unlinking edouard@2941: // Edouard@2878: // svg:use (inkscape's clones) inside a widgets are Edouard@2878: // replaced by real elements they refer in order to : Edouard@2878: // - allow finding "needle" element in "meter" widget, Edouard@2878: // even if "needle" is in a group refered by a svg use. Edouard@2878: // - if "needle" is visible through a svg:use for Edouard@2878: // each instance of the widget, then needle would show Edouard@2878: // the same position in all instances Edouard@2878: // Edouard@2878: // For now, clone unlinkink applies to descendants of all widget except HMI:Page Edouard@2878: // TODO: narrow application of clone unlinking to active elements, Edouard@2878: // while keeping static decoration cloned Edouard@2967: const "to_unlink", "$hmi_elements[not(@id = $hmi_pages)]/descendant-or-self::svg:use"; Edouard@2878: svgtmpl "svg:use", mode="inline_svg" Edouard@2878: { Edouard@2878: choose { Edouard@2878: when "@id = $to_unlink/@id" Edouard@2878: call "unlink_clone"; Edouard@2878: otherwise Edouard@2878: xsl:copy apply "@* | node()", mode="inline_svg"; Edouard@2878: } Edouard@2878: } Edouard@2877: Edouard@2878: // to unlink a clone, an group containing a copy of target element is created Edouard@2878: // that way, style and transforms can be preserved Edouard@2878: const "_excluded_use_attrs" { Edouard@2878: name > href Edouard@2878: name > width Edouard@2878: name > height Edouard@2878: name > x Edouard@2878: name > y Edouard@2878: } Edouard@2878: const "excluded_use_attrs","exsl:node-set($_excluded_use_attrs)"; Edouard@2794: Edouard@2878: svgfunc "unlink_clone"{ Edouard@2878: g{ Edouard@2878: // include non excluded attributes Edouard@2878: foreach "@*[not(local-name() = $excluded_use_attrs/name)]" Edouard@2878: attrib "{name()}" > «.» Edouard@2853: Edouard@2878: const "targetid","substring-after(@xlink:href,'#')"; Edouard@2878: apply "//svg:*[@id = $targetid]", mode="unlink_clone"{ Edouard@2878: with "seed","@id"; Edouard@2854: } Edouard@2854: } Edouard@2878: } Edouard@2854: Edouard@2878: // clone unlinking is really similar to deep-copy Edouard@2878: // all nodes are sytematically copied Edouard@2878: svgtmpl "@id", mode="unlink_clone" { Edouard@2878: param "seed"; Edouard@2878: attrib "id" > «$seed»_«.» Edouard@2878: } Edouard@2854: Edouard@2878: svgtmpl "@*", mode="unlink_clone" xsl:copy; Edouard@2854: Edouard@2878: // copying widgets would have unwanted effect Edouard@2878: // instead widget is refered through a svg:use. Edouard@2878: svgtmpl "svg:*", mode="unlink_clone" { Edouard@2878: param "seed"; Edouard@2878: choose { Edouard@2878: // node recursive copy ends when finding a widget Edouard@2878: when "@id = $hmi_elements/@id" { Edouard@2878: // place a clone instead of copying Edouard@2878: use{ Edouard@2878: attrib "xlink:href" > «concat('#',@id)» Edouard@2878: } Edouard@2878: } Edouard@2878: otherwise { Edouard@2878: xsl:copy apply "@* | node()", mode="unlink_clone" { Edouard@2878: with "seed","$seed"; Edouard@2854: } Edouard@2854: } Edouard@2854: } Edouard@2878: } Edouard@2854: Edouard@2878: const "result_svg" apply "/", mode="inline_svg"; Edouard@2878: const "result_svg_ns", "exsl:node-set($result_svg)"; Edouard@2854: edouard@2941: emit "preamble:inline-svg" { edouard@2941: | let id = document.getElementById.bind(document); edouard@2941: | var svg_root = id("«$svg/@id»"); edouard@2941: } edouard@2941: edouard@2941: emit "debug:clone-unlinking" { edouard@2941: | edouard@2904: | Unlinked : Edouard@2878: foreach "$to_unlink"{ Edouard@2878: | «@id» Edouard@2808: } Edouard@2753: }