1 Reply Latest reply on Sep 27, 2012 7:23 AM by wokoman1234

    Need some help with anchored objects

    wokoman1234

      Hi there,

       

      I'm using fairly standard documents, containing the usual textflows and a variety of styles. I also have on a regular base grouped and anchored objects, containing an image and some optional captions in the form of textboxes. These documents are provided to me for translation, so not much options to work on the source content. In order to simplify workflows I want to establish an XML workflow without depending too much on IDML as only option since I also want to use the XML for other purposes.

       

      I managed to get quite far with information I found on the site but am stuck to get the final bits and pieces running. I'm perfectly able to tag all elements and paragraphs on the non anchored stuff , but fail to work it out the way I want with the textboxes in the anchored groups, as they are not taggable as long as they are anchored and grouped.

       

      The patch I do now is to copy all anchored grous to a seperate layer, so the content can be ungrouped and tagged. This allows me to get all content on the page in an XML structure, but of course I now have tagged duplicated info on a new layer, and the original untagged anchors on my original layer. It's workable but leaves me with too much manual cleanup afterwards.

       

      My ultimate aim would be to get something as below, but anything more simple or elegant would be an option too of course

       

      For each anchored object on the page (ok) -> Release the object (ok) -> ungroup the elements (ok) -> Tag all elements of the group using the paragraphStyle, and add them to a parent element <group> (ok but maybe this can be simplified) -> Regroup all elements (ok) -> anchor back to original position (some help needed here) -> next anchored object

       

      but I have to admit I reached the limits of my extendScript know-how...

       

      This is what I have, the TODO blocks is where I struggle. If anyone can fix or point me in the right direction already for any one of these I would be very gratefull

       

      ----------------------------------------------------------

       

       

      function Duplicate_Grouped_Anchors(){
      
      var myDoc = app.activeDocument;
      var myItems = myDoc.allPageItems;
      var foundGroupedItems = Array();
      
      // loop through the page and find all inline objects (images) that are grouped / anchored and add them to the array
      
      for(var i = 0; i < myItems.length; i++){
          if(myItems[i].constructor.name=="Group" && myItems[i].parent instanceof Character){foundGroupedItems.push(myItems[i]);}
      }
      
      // If we have some anchores let's start the magic...
      
      if(foundGroupedItems.length > 0){
      
      // create a new layer if it's not there yet where we can duplicate the anchored objects
      try{var myDestLayer = myDoc.layers.add({name:"anchored"});} catch(myError){myDestLayer = myDoc.layers.item("anchored");}
      
      // and loop through all the anchored objects...                
      
      for(var i = 0; i < foundGroupedItems.length; i++){
      
      // for every object we copy the content on the same position on the new layer
      
      var newDuplicate = foundGroupedItems[i].duplicate(myDestLayer);
      newDuplicate.geometricBounds = foundGroupedItems[i].geometricBounds;
      try {newDuplicate.graphics[0].geometricBounds = foundGroupedItems[i].graphics[0].geometricBounds;}catch(myError){}
      
      // then we store all groupitems in an array and create a group parent tag, this will be added on top of the structure
      
      var mgi = newDuplicate.pageItems.everyItem().getElements();
      var lmgi = mgi.length;
      
      // add group tag
      try{myDoc.xmlTags.add("group");}catch(myError){exit}
      
      // define new parent tag for all elements in group
      var newParent = myDoc.xmlElements[0].xmlElements.add({markupTag:"group"});
      
      // ungroup so all can be tagged
      try {newDuplicate.ungroup()} catch (myError){};
      
      // And we loop through all the items.
      for(y=0; y<lmgi; y++)
      {
      
      // If it's an image we fit the content to the frame and add an image tag
      
      if( mgi[y].constructor.name == "Rectangle")
               {
                     var tfg = mgi[y].allGraphics;
                     var tfglg = tfg.length;
                     // loop through all the graphics
                     for(j=0; j<tfglg; j++)
                           {
                                  // TODO : Fix fit option, should become exact same position as on original layer
                                  tfg[j].fit(FitOptions.CONTENT_TO_FRAME);
                                  //Add tag to element
                                  try{myDoc.xmlTags.add("Image");}catch(myError){exit}
                                  try{myDoc.xmlElements[0].xmlElements.add({markupTag:"Image", xmlContent:tfg[j]})}catch(myError){exit}
      
                                  // TODO : Below works but might be not error proof enough ?
      
                                  var lastElement = myDoc.xmlElements.item(0).xmlElements.lastItem();
                                  try{lastElement.move(LocationOptions.AT_BEGINNING, newParent);}catch(myError){exit} 
                           }
              }
      
       // If it's a Textframe we tag the content according the Paragraph Style used
      
           if(mgi[y].constructor.name == "TextFrame")
                {
                     var pgfs = mgi[y].paragraphs;
                     var lpgfs = pgfs.length;
                      for(j=0; j<lpgfs; j++)
                           {
                                 var myParagraphStyle = pgfs[j].appliedParagraphStyle;
                                 var myParagraphStyleName = myParagraphStyle.name;
                                 var myXMLTagName = cleanTag(myParagraphStyleName);
      
                                 try{myDoc.xmlTags.add(myXMLTagName);}catch(myError){exit}
                                 try{myDoc.xmlElements[0].xmlElements.add({markupTag:myXMLTagName, xmlContent:pgfs[j]})}catch(myError){exit}
      
                                 var lastElement = myDoc.xmlElements.item(0).xmlElements.lastItem();
                                 try{lastElement.move(LocationOptions.AT_BEGINNING, newParent);}catch(myError){exit}
                            }   
      
                }
        }
      
       myDoc.groups.add(mgi) ;
      
      // TODO : copy the grouped object back to main layer, anchored onto original location
      }
      }
      }
      
      
      function cleanTag(s){
      // Get rid of characters XML doesn't really like
      
          var myXMLTagName = s.replace(/\ /gi, "_")
          myXMLTagName = myXMLTagName.replace(/\[/gi, "")
          myXMLTagName = myXMLTagName.replace(/\]/gi, "")
          myXMLTagName = myXMLTagName.replace(/\./gi, "")
          myXMLTagName = myXMLTagName.replace(/\!/gi, "")
          myXMLTagName = myXMLTagName.replace(/\+/gi, "")
          myXMLTagName = myXMLTagName.replace(/\|/gi, "");
      
      return myXMLTagName;
      
      }
      
      

       

       

      Message was edited by: wokoman1234 -> added some script to make the request easier to digest

        • 1. Re: Need some help with anchored objects
          wokoman1234 Level 1

          Ok, fixed it myself in the meantime, might not be the most optimised solution but it does the trick. Just in case someone would be intrested I'll post the solution. To recap, the script will go through all anchored objecst, release and ungroup all elements in the anchor, add a tag to all elements, group it again and place it nicely back where it was found originally...

           

           

           

          function tagAnchors(){
          
          var myDoc = app.activeDocument;
          var myItems = myDoc.allPageItems;
          
          // loop through all pageitems
          for(var i = 0; i < myItems.length; i++){
          
              // and check if the item is a grouped anchor -- these are annoying cause you can't tag them
              if(myItems[i].constructor.name=="Group" && myItems[i].parent instanceof Character)
              {
                     var myGroup = myItems[i];
          
                    var mgi = myGroup.pageItems.everyItem().getElements();
                    var lmgi = mgi.length;
          
          
                      // remember where we found it
                      var myIP=myGroup.parent.paragraphs.item(0).insertionPoints.item(0) ;
          
                      // create a parent tag to store all the elements from the group. Not needed but makes result cleaner to use
                      try{myDoc.xmlTags.add("Group");}catch(myError){exit}
                      var newParent = myDoc.xmlElements[0].xmlElements.add({markupTag:"Group"});
          
                     // As you can only releqse custom anchors we alter the anchor position, then we release the anchor, and ungroup the whole thing
                      with (myGroup)
                      {
                          anchoredObjectSettings.anchoredPosition = AnchorPosition.anchored;
                          anchoredObjectSettings.releaseAnchoredObject();
                          ungroup();
                       }  
          
          //======================================================
          // Tag all elements in the collection, images get an image tag, paragraphs get
          // their a paragraphStyle tag    
          //======================================================
          
          // loop through all elements
          
          for(y=0; y<lmgi; y++)
          {
          
          // If it's an image we fit the content to the frame and add an image tag
          
          if( mgi[y].constructor.name == "Rectangle")
                   {
                         var tfg = mgi[y].allGraphics;
                         var tfglg = tfg.length;
                              for(j=0; j<tfglg; j++)
                               {
                                      // add image tag
                                      try{myDoc.xmlTags.add("Image");}catch(myError){exit}
                                      try{myDoc.xmlElements[0].xmlElements.add({markupTag:"Image", xmlContent:tfg[j]})}catch(myError){exit}
          
                                      // make element child of group element
          
                                      var lastElement = myDoc.xmlElements.item(0).xmlElements.lastItem();
                                      try{lastElement.move(LocationOptions.AT_BEGINNING, newParent);}catch(myError){exit}
                               }
                  }
          
          // If it's a Textframe we tag the content according the Paragraph Style used
          
               if(mgi[y].constructor.name == "TextFrame")
                    {
                         var pgfs = mgi[y].paragraphs;
                         var myID = "id" + mgi[y].id;
                         var lpgfs = pgfs.length;
                          for(j=0; j<lpgfs; j++)
                               {
                                     var myParagraphStyle = pgfs[j].appliedParagraphStyle;
                                     var myParagraphStyleName = myParagraphStyle.name;
                                     var myXMLTagName = cleanTag(myParagraphStyleName);
          
                                     try{myDoc.xmlTags.add(myXMLTagName);}catch(myError){exit}
                                     try{myDoc.xmlElements[0].xmlElements.add({markupTag:myXMLTagName, xmlContent:pgfs[j]})}catch(myError){exit}
                                     var lastElement = myDoc.xmlElements.item(0).xmlElements.lastItem();
                                     try{lastElement.move(LocationOptions.AT_BEGINNING, newParent);}catch(myError){exit}
                                }  
                    }
            }
          
          //======================================================
          // end of tagging
          //======================================================
          
          // group all elements again
          var myNewGroup = myDoc.groups.add(mgi) ;  
          
          // anchor the new group again
          myNewGroup.anchoredObjectSettings.insertAnchoredObject(myIP, AnchorPosition.INLINE_POSITION);
          
          }
          }
          }
          
          function cleanTag(s){
          
              var myXMLTagName = s.replace(/\ /gi, "_")
              myXMLTagName = myXMLTagName.replace(/\[/gi, "")
              myXMLTagName = myXMLTagName.replace(/\]/gi, "")
              myXMLTagName = myXMLTagName.replace(/\./gi, "")
              myXMLTagName = myXMLTagName.replace(/\!/gi, "")
              myXMLTagName = myXMLTagName.replace(/\+/gi, "")
              myXMLTagName = myXMLTagName.replace(/\|/gi, "");
          
          return myXMLTagName;
          }