// detachable_elements.ysl2 // // compute what elements are required by pages // and decide where to cut when removing/attaching // pages elements on page switch // returns all directly or indirectly refered elements def "func:refered_elements" { param "elems"; const "descend", "$elems/descendant-or-self::svg:*"; const "clones", "$descend[self::svg:use]"; const "originals", "//svg:*[concat('#',@id) = $clones/@xlink:href]"; choose { when "$originals" result "$descend | func:refered_elements($originals)"; otherwise result "$descend"; } } def "func:all_related_elements" { param "page"; const "page_overlapping_geometry", "func:overlapping_geometry($page)"; const "page_overlapping_elements", "//svg:*[@id = $page_overlapping_geometry/@Id]"; const "page_sub_elements", "func:refered_elements($page | $page_overlapping_elements)"; result "$page_sub_elements"; } def "func:required_elements" { param "pages"; choose{ when "$pages"{ result """func:all_related_elements($pages[1]) | func:required_elements($pages[position()!=1])"""; }otherwise{ result "/.."; } } } const "required_elements", """//svg:defs/descendant-or-self::svg:* | func:required_elements($hmi_pages)/ancestor-or-self::svg:*"""; const "discardable_elements", "//svg:*[not(@id = $required_elements/@id)]"; def "func:sumarized_elements" { param "elements"; const "short_list", "$elements[not(ancestor::*/@id = $elements/@id)]"; const "filled_groups", """$short_list/parent::svg:*[ not(descendant::*[ not(self::svg:g) and not(@id = $discardable_elements/@id) and not(@id = $short_list/descendant-or-self::*[not(self::svg:g)]/@id) ])]"""; const "groups_to_add", "$filled_groups[not(ancestor::*/@id = $filled_groups/@id)]"; result "$groups_to_add | $short_list[not(ancestor::svg:g/@id = $filled_groups/@id)]"; } def "func:detachable_elements" { param "pages"; choose{ when "$pages"{ result """func:sumarized_elements(func:all_related_elements($pages[1])) | func:detachable_elements($pages[position()!=1])"""; }otherwise{ result "/.."; } } } // Avoid nested detachables const "_detachable_elements", "func:detachable_elements($hmi_pages)"; const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]"; function "debug_detachables" { foreach "$detachable_elements"{ | «@id» } } !debug_output_calls.append("debug_detachables")