Skip to main content
September 25, 2012
Question

Need some help with anchored objects

  • September 25, 2012
  • 1 reply
  • 1414 views

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.constructor.name=="Group" && myItems.parent instanceof Character){foundGroupedItems.push(myItems);}

}

// 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.duplicate(myDestLayer);

newDuplicate.geometricBounds = foundGroupedItems.geometricBounds;

try {newDuplicate.graphics[0].geometricBounds = foundGroupedItems.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.constructor.name == "Rectangle")

         {

               var tfg = mgi.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.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})}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.constructor.name == "TextFrame")

          {

               var pgfs = mgi.paragraphs;

               var lpgfs = pgfs.length;

                for(j=0; j<lpgfs; j++)

                     {

                           var myParagraphStyle = pgfs.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})}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

This topic has been closed for replies.

1 reply

September 27, 2012

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.constructor.name=="Group" && myItems.parent instanceof Character)

    {

           var myGroup = myItems;

          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.constructor.name == "Rectangle")

         {

               var tfg = mgi.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})}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.constructor.name == "TextFrame")

          {

               var pgfs = mgi.paragraphs;

               var myID = "id" + mgi.id;

               var lpgfs = pgfs.length;

                for(j=0; j<lpgfs; j++)

                     {

                           var myParagraphStyle = pgfs.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})}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;

}