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