def append_childs(source_node, destination_node): """Recursive function to discover node structure from a story to another. """ for elt in source_node.iterchildren(): if not elt.tag == "XMLElement": append_childs(elt, destination_node) if elt.get("Self") == source_node.get("Self"): continue if not elt.get("MarkupTag"): continue elt = XMLElement(elt) new_destination_node = elt.to_xml_structure_element() destination_node.append(new_destination_node) if elt.get("XMLContent"): xml_content_value = elt.get("XMLContent") story_name = "Stories/Story_%s.xml" % xml_content_value story = Story(self, name=story_name) try: new_source_node = story.get_element_by_id( elt.get("Self")) # The story does not exists. except KeyError: continue else: append_childs(new_source_node, new_destination_node) else: append_childs(elt, new_destination_node)
def append_childs(source_node, destination_node): """Recursive function to discover node structure from a story to another. """ for elt in source_node.iterchildren(): if not elt.tag == "XMLElement": append_childs(elt, destination_node) if elt.get("Self") == source_node.get("Self"): continue if not elt.get("MarkupTag"): continue elt = XMLElement(elt) new_destination_node = elt.to_xml_structure_element() destination_node.append(new_destination_node) if elt.get("XMLContent"): xml_content_value = elt.get("XMLContent") story_name = "Stories/Story_%s.xml" % xml_content_value story = Story(self, name=story_name) try: new_source_node = story.get_element_by_id(elt.get("Self")) # The story does not exists. except KeyError: continue else: append_childs(new_source_node, new_destination_node) else: append_childs(elt, new_destination_node)
def add_story_with_content(self, story_id, xml_element_id, xml_element_tag): Story.create(self, story_id, xml_element_id, xml_element_tag, self.working_copy_path) self.designmap.add_stories([story_id]) self.designmap.synchronize() self.init_lazy_references() return self
def test_get_element_by_id(self): idml_file = IDMLPackage(os.path.join(IDMLFILES_DIR, "4-pages.idml"), mode="r") stories = idml_file.stories story = Story(idml_file, stories[1]) # u11b elem = story.get_element_by_id("di2i3i2") self.assertEqual(elem.get("MarkupTag"), "XMLTag/content") elem = story.get_element_by_id("di2i3i2", tag="*") self.assertEqual(elem.get("MarkupTag"), "XMLTag/content")
def get_story_object_by_xpath(self, xpath): xml_element = self.xml_structure.xpath(xpath)[0] def get_story_name(xml_element): ref = xml_element.get("XMLContent") if ref: return ref else: parent = xml_element.getparent() if parent is not None: return get_story_name(xml_element.getparent()) else: return BACKINGSTORY story_name = get_story_name(xml_element) # Some XMLElement store a reference which is not a Story. # In that case, the Story is the parent's Story. if (story_name not in self.story_ids) and (story_name is not BACKINGSTORY): xpath = self.xml_structure_tree.getpath(xml_element.getparent()) story = self.get_story_object_by_xpath(xpath) else: if story_name == BACKINGSTORY: story = BackingStory(self) else: story = Story( self, "%s/Story_%s.xml" % (STORIES_DIRNAME, story_name)) story.working_copy_path = self.working_copy_path return story
def test_create(self): from tempfile import mkdtemp idml_working_copy = mkdtemp() story = Story.create(None, "my_story_id", "my_xml_element_id", "my_xml_element_tag", idml_working_copy) self.assertEqual(story.name, 'Stories/Story_my_story_id.xml') self.assertEqual(story.tostring(), b"""<?xml version='1.0' encoding='UTF-8' standalone='yes'?> <idPkg:Story xmlns:idPkg="http://ns.adobe.com/AdobeInDesign/idml/1.0/packaging" DOMVersion="7.5"> <Story Self="my_story_id" AppliedTOCStyle="n" TrackChanges="false" StoryTitle="$ID/" AppliedNamedGrid="n"> <StoryPreference OpticalMarginAlignment="false" OpticalMarginSize="12" FrameType="TextFrameType" StoryOrientation="Horizontal" StoryDirection="LeftToRightDirection"/> <InCopyExportOption IncludeGraphicProxies="true" IncludeAllResources="false"/> <XMLElement Self="my_xml_element_id" MarkupTag="XMLTag/my_xml_element_tag" XMLContent="my_story_id"/> </Story> </idPkg:Story> """) shutil.rmtree(idml_working_copy)
def _add_stories_from_idml(self, idml_package, at, only): """Add all idml_package stories and insert `only' refence at `at' position in self. What we have: ============= o The Story file in self containing "at" (/Root/article[3] marked by (A)) [1]: <XMLElement Self="di2" MarkupTag="XMLTag/Root"> <XMLElement Self="di2i3" MarkupTag="XMLTag/article" XMLContent="u102"/> <XMLElement Self="di2i4" MarkupTag="XMLTag/article" XMLContent="udb"/> <XMLElement Self="di2i5" MarkupTag="XMLTag/article" XMLContent="udd"/> (A) <XMLElement Self="di2i6" MarkupTag="XMLTag/advertise" XMLContent="udf"/> </XMLElement> o The idml_package Story file containing "only" (/Root/module[1] marked by (B)) [2]: <XMLElement Self="prefixeddi2" MarkupTag="XMLTag/Root"> <XMLElement Self="prefixeddi2i3" MarkupTag="XMLTag/module" XMLContent="prefixedu102"/> (B) </XMLElement> What we want: ============= o if XMLContent is not related to a story file, we create it and insert `only' XML content: <XMLElement Self="di2i5" MarkupTag="XMLTag/article" XMLContent="udd"> <XMLElement Self="prefixeddi2i3" MarkupTag="XMLTag/module" XMLContent="prefixedu102"/> (A) </XMLElement> o The Story_udd.xml is created. o The Spread page item 'udd' is updated. o The designmap.xml file is updated. """ xml_element_src_id = idml_package.xml_structure.xpath(only)[0].get("Self") story_src_filename = idml_package.get_story_by_xpath(only) story_src = Story(idml_package, story_src_filename) story_src_elt = story_src.get_element_by_id(xml_element_src_id).element xml_element_dest = self.xml_structure.xpath(at)[0] xml_element_dest_id = xml_element_dest.get("Self") content_ref = xml_element_dest.get("XMLContent") # We don't want to lose the XMLContent referencing the spread page item. # Neither we want to wipe the page item out from the spread. # To keep the document valid, the solution is to create a proxy story. if content_ref and (content_ref not in self.story_ids): self.add_story_with_content(content_ref, xml_element_dest_id, xml_element_dest.tag) self.xml_element_leaf_to_node(at, content_ref) xml_element_dest = self.xml_structure.xpath(at)[0] story_dest_filename = self.get_story_by_xpath(at) story_dest = Story(self, story_dest_filename, self.working_copy_path) story_dest_elt = story_dest.get_element_by_id(xml_element_dest_id) story_src_elt_copy = copy.copy(story_src_elt) if story_src_elt_copy.get("XMLContent"): for child in story_src_elt_copy.iterchildren(): story_src_elt_copy.remove(child) story_dest_elt.append(story_src_elt_copy) story_dest.synchronize() # Add Story files. # `Stories' directory may not be present in the destination package. stories_dirname = os.path.join(self.working_copy_path, STORIES_DIRNAME) if not os.path.exists(stories_dirname): os.mkdir(stories_dirname) for filename in idml_package.stories_for_node(only): story_cp = open(os.path.join(self.working_copy_path, filename), mode="wb+") story_cp.write(idml_package.open(filename, mode="r").read()) story_cp.close() # Update designmap.xml. self.designmap.add_stories(idml_package.story_ids_for_node(only)) self.designmap.synchronize() # BackingStory.xml ?? self.init_lazy_references()
def _add_stories_from_idml(self, idml_package, at, only): """Add all idml_package stories and insert `only' refence at `at' position in self. What we have: ============= o The Story file in self containing "at" (/Root/article[3] marked by (A)) [1]: <XMLElement Self="di2" MarkupTag="XMLTag/Root"> <XMLElement Self="di2i3" MarkupTag="XMLTag/article" XMLContent="u102"/> <XMLElement Self="di2i4" MarkupTag="XMLTag/article" XMLContent="udb"/> <XMLElement Self="di2i5" MarkupTag="XMLTag/article" XMLContent="udd"/> (A) <XMLElement Self="di2i6" MarkupTag="XMLTag/advertise" XMLContent="udf"/> </XMLElement> o The idml_package Story file containing "only" (/Root/module[1] marked by (B)) [2]: <XMLElement Self="prefixeddi2" MarkupTag="XMLTag/Root"> <XMLElement Self="prefixeddi2i3" MarkupTag="XMLTag/module" XMLContent="prefixedu102"/> (B) </XMLElement> What we want: ============= o if XMLContent is not related to a story file, we create it and insert `only' XML content: <XMLElement Self="di2i5" MarkupTag="XMLTag/article" XMLContent="udd"> <XMLElement Self="prefixeddi2i3" MarkupTag="XMLTag/module" XMLContent="prefixedu102"/> (A) </XMLElement> o The Story_udd.xml is created. o The Spread page item 'udd' is updated. o The designmap.xml file is updated. """ xml_element_src_id = idml_package.xml_structure.xpath(only)[0].get( "Self") story_src_filename = idml_package.get_story_by_xpath(only) story_src = Story(idml_package, story_src_filename) story_src_elt = story_src.get_element_by_id(xml_element_src_id).element xml_element_dest = self.xml_structure.xpath(at)[0] xml_element_dest_id = xml_element_dest.get("Self") content_ref = xml_element_dest.get("XMLContent") # We don't want to lose the XMLContent referencing the spread page item. # Neither we want to wipe the page item out from the spread. # To keep the document valid, the solution is to create a proxy story. if content_ref and (content_ref not in self.story_ids): self.add_story_with_content(content_ref, xml_element_dest_id, xml_element_dest.tag) self.xml_element_leaf_to_node(at, content_ref) xml_element_dest = self.xml_structure.xpath(at)[0] story_dest_filename = self.get_story_by_xpath(at) story_dest = Story(self, story_dest_filename, self.working_copy_path) story_dest_elt = story_dest.get_element_by_id(xml_element_dest_id) story_src_elt_copy = copy.copy(story_src_elt) if story_src_elt_copy.get("XMLContent"): for child in story_src_elt_copy.iterchildren(): story_src_elt_copy.remove(child) story_dest_elt.append(story_src_elt_copy) story_dest.synchronize() # Add Story files. # `Stories' directory may not be present in the destination package. stories_dirname = os.path.join(self.working_copy_path, STORIES_DIRNAME) if not os.path.exists(stories_dirname): os.mkdir(stories_dirname) for filename in idml_package.stories_for_node(only): story_cp = open(os.path.join(self.working_copy_path, filename), mode="w+") story_cp.write(idml_package.open(filename, mode="r").read()) story_cp.close() # Update designmap.xml. self.designmap.add_stories(idml_package.story_ids_for_node(only)) self.designmap.synchronize() # BackingStory.xml ?? self.init_lazy_references()
def test_pages(self): idml_file = IDMLPackage(os.path.join(IDMLFILES_DIR, "4-pages.idml"), mode="r") stories = idml_file.stories story = Story(idml_file, stories[0]) self.assertEqual(story.node.tag, "Story")