22 Replies Latest reply on Nov 3, 2010 9:17 AM by JGL79

    Square area percent of page report

    aus-enfatico Level 1

      Sure this is not the first time someone has looked for a way to do this, but I can't find a solution.

       

      Script to find the square inch area of the each object in the whole document > make a new layer > place a tag on each object stating that object's square area > also generate the percentage of that object's area compared to the page size.

       

      I'm a novice and have hobbled together a few scripts that I've found but can't connect them up. So far I've adjusted a script to return geometric bounds of a selected object. And I modified another script that generates labels on a separate layer (the labels display various attributes of each object, color space, name, link etc).

       

      It seems that inserting my get geometric bounds script should be inserted into the labels script with the parts concerning object attributes but I can't see how (again major Novice).

       

      Haven't figured out how to get the document bounds (though that seems fairly obvious) and how to translate my geometric bounds into inches and find the % of page. I did find an almost perfect script (at the bottom) but it is for Illustrator and doesn't work off the same structure.

       

      My code below. Anything from a point in the right direction to a rewrite would be amazing! Though I really want to understand how so I can contribute, teaching myself but practical applications is not always the best place to learn.

       

      Script #1: Code for geometric bounds (where can I insert this into script #2 to apply square inches and % of page to picture/text labels)

      Object.prototype.height = function() {   var bds = this.geometricBounds; //not using visible bounds, can't see how that would help here but maybe I'm wrong   return [ b[3]-b[1] , b[2]-b[0] ]; }

       

      Script #2: Code for labels (need to convert area from points to inches and find % of page)

      var myScriptVer = "2.1"; var myInfoTitle = "Image Info"; var myInfoColor = [0,15,100,0]; var yPos = 100; var xPos = 100; //getting document length and measurements but not sure that is passing anywhere if(app.documents.length != 0){      var myDocument = app.activeDocument;      var myOrgDocHUnits = myDocument.viewPreferences.horizontalMeasurementUnits;      var myOrgDocVUnits = myDocument.viewPreferences.verticalMeasurementUnits;      var myOrgDocOrigin = myDocument.viewPreferences.rulerOrigin;      myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.millimeters;      myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.millimeters;      myDocument.viewPreferences.rulerOrigin = RulerOrigin.spreadOrigin;      var myLinks = myDocument.links;      if(myLinks.length != 0){           var myDialog = app.dialogs.add({name:"Contact Sheet Labels"+ myScriptVer});           with(myDialog){                with(dialogColumns.add()){                     with (dialogRows.add()){                          with(borderPanels.add()){                               with(dialogColumns.add()){                                    with (dialogRows.add()){                                         staticTexts.add({staticLabel:"Loose Proof Label Displays:"});                                    }                                    with(borderPanels.add()){                                         with(dialogColumns.add()){                                              with (dialogRows.add()){                                              staticTexts.add({staticLabel:"Link Info:\t"});                                              }                                         }                                         with(dialogColumns.add()){                                              with (dialogRows.add()){                                                   var myNameOpt = checkboxControls.add({staticLabel:"File Name\t", checkedState:true});                                              }                                              with (dialogRows.add()){                                                   var myPathOpt = checkboxControls.add({staticLabel:"File Path", checkedState:true});                                              }                                         }                                         with(dialogColumns.add()){                                              with (dialogRows.add()){                                                   var myTypeOpt = checkboxControls.add({staticLabel:"File Type\t\t", checkedState:false});                                              }                                              with (dialogRows.add()){                                                   var myStatusOpt = checkboxControls.add({staticLabel:"Link Status", checkedState:false});                                              }                                         }                                    }                                    with(borderPanels.add()){                                         with(dialogColumns.add()){                                              with (dialogRows.add()){                                              staticTexts.add({staticLabel:"Image Info:\t"});                                              }                                         }                                         with(dialogColumns.add()){                                              with (dialogRows.add()){                                                   var myActResOpt = checkboxControls.add({staticLabel:"Actual PPI\t", checkedState:true});                                              }                                              with (dialogRows.add()){                                                   var myEffResOpt = checkboxControls.add({staticLabel:"Effective PPI", checkedState:false});                                              }                                         }                                         with(dialogColumns.add()){                                              with (dialogRows.add()){                                                   var myScaleOpt = checkboxControls.add({staticLabel:"Scale Percentage\t", checkedState:false});                                              }                                              with (dialogRows.add()){                                                   var myColSpaceOpt = checkboxControls.add({staticLabel:"Color Space", checkedState:true});                                              }                                         }                                    }                               }                          }                     }                     with (dialogRows.add()){                          with(borderPanels.add()){                               with(dialogColumns.add()){                                    with (dialogRows.add()){                                         var myLabelOpt = checkboxControls.add({staticLabel:"Printable Labels", checkedState:true});                                    }                               }                          }                     }                     with (dialogRows.add()){                          staticTexts.add({staticLabel:"Contact Sheet Labels"});                     }                }           }           var myResult = myDialog.show({name:"SplitOptions"});           if(myResult == true){                //Clear previous layer, color, and styles                for(i = 0;i < myDocument.layers.length;i++){                     var myLayer = myDocument.layers[i];                     if(myLayer.name == myInfoTitle){                          myLayer.remove();                     }                }                for(i = 0;i < myDocument.colors.length;i++){                     var myColor = myDocument.colors[i];                     if(myColor.name == myInfoTitle){                          myColor.remove();                     }                }                               for(i = 0;i < myDocument.paragraphStyles.length;i++){                     var myPStyle = myDocument.paragraphStyles[i];                     if(myPStyle.name == myInfoTitle){                          myPStyle.remove();                     }                }                for(i = 0;i < myDocument.characterStyles.length;i++){                     var myCStyle = myDocument.characterStyles[i];                     if(myCStyle.name == myInfoTitle){                          myCStyle.remove();                     }                }                //Create the link info layer                var myLinkInfoLayer = myDocument.layers.add();                myLinkInfoLayer.name = myInfoTitle;                //Create the link info color                var myLinkInfoColor = myDocument.colors.add();                myLinkInfoColor.name = myInfoTitle;                myLinkInfoColor.colorValue = myInfoColor;                //Create the link info Character Style                var myLinkInfoCStyle = myDocument.characterStyles.add();                myLinkInfoCStyle.name = myInfoTitle;                try{                     myLinkInfoCStyle.fontStyle = "Semibold";                }                catch(e){}                //Create the link info Paragraph Style                var myLinkInfoPStyle = myDocument.paragraphStyles.add();                myLinkInfoPStyle.name = myInfoTitle;                try{                     myLinkInfoPStyle.paragraphDirection = ParagraphDirection.leftToRightDirection;                }                catch(e){}                myLinkInfoPStyle.justification = Justification.leftAlign;                try{                     myLinkInfoPStyle.appliedFont = "Myriad Pro";                     myLinkInfoPStyle.fontStyle = "Regular";                }                catch(e){}                myLinkInfoPStyle.pointSize = 6;                myLinkInfoPStyle.leading = 6;                myLinkInfoPStyle.appliedLanguage = "English: USA";                myLinkInfoPStyle.hyphenation = false;                myLinkInfoPStyle.leftIndent = "8mm";                myLinkInfoPStyle.firstLineIndent = "-8mm";                var myLink, myLinkPos, myLinkName, myLinkPath, myLinkType, myLinkStat, myLinkInfoStr, myLinkParent, myLinkSpread, myLinkStatus, myLinkInfoFrame;                                     for(l = 0;l < myLinks.length;l++){                     myLink = myLinks[l];                     var myD = myLink.linkXmp;                     if(myLink.parent.parent.itemLayer.visible == true){                          myLinkPos = myLink.parent.parent.geometricBounds;                          myLinkName = "";                          myLinkPath = "";                          myLinkType = "";                          myLinkStat = "";                          myLinkInfoStr = "";                                               myLinkParent = myLink.parent;                          do{                               if(myLinkParent.constructor.name != "Character"){                                    myLinkParent = myLinkParent.parent;                               }                               else{                                    if(app.version.split(".")[0] >= 4){                                         myLinkParent = myLinkParent.parentTextFrames[0];                                    }                                    else{                                         myLinkParent = myLinkParent.parentTextFrame;                                    }                                                        }                          }while((myLinkParent.constructor.name != "Spread")&&(myLinkParent.constructor.name != "MasterSpread"))                          if(myLinkParent.constructor.name == "Spread"){                               myLinkSpread = myDocument.spreads[myLinkParent.index];                          }                          else{                               myLinkSpread = myDocument.masterSpreads[myLinkParent.index];                          }                                               if(myNameOpt.checkedState){                               if((myPathOpt.checkedState == false) && (myTypeOpt.checkedState == false) && (myStatusOpt.checkedState == false)){                                    myLinkInfoStr = myLinkInfoStr + myLink.name;                               }                               else{                                    myLinkInfoStr = myLinkInfoStr + "Name:\t" + myLink.name;                               }                          }                          if(myPathOpt.checkedState){                               myLinkInfoStr = myLinkInfoStr + "\rPath:\t" + myLink.filePath;                          }                          if(myTypeOpt.checkedState){                               myLinkInfoStr = myLinkInfoStr + "\rType:\t" + myLink.linkType;                          }                          if(myStatusOpt.checkedState){                               myLinkStatus = "";                               switch(myLink.status){                                    case LinkStatus.normal:                                         myLinkStatus = "OK";                                         break;                                    case LinkStatus.linkOutOfDate:                                         myLinkStatus = "Modified";                                         break;                                    case LinkStatus.linkMissing:                                         myLinkStatus = "Missing";                                         break;                                    case LinkStatus.linkEmbedded:                                         myLinkStatus = "Embedded";                                         break;                                                   }                               myLinkInfoStr = myLinkInfoStr + "\rStatus:\t" + myLinkStatus;                          }                          if(myScaleOpt.checkedState){                               myLinkInfoStr = myLinkInfoStr + "\rScaling:\tX="+myLink.parent.horizontalScale+"%, Y=" + myLink.parent.verticalScale+"%";                          }                          try{                               if(myActResOpt.checkedState){                                    myLinkInfoStr = myLinkInfoStr + "\rAct.Res:\t" + myLink.parent.actualPpi[0]+" x "+myLink.parent.actualPpi[1]+" ppi";                               }                               if(myEffResOpt.checkedState){                                    myLinkInfoStr = myLinkInfoStr + "\rEffc.Res:\t" + myLink.parent.effectivePpi[0]+" x "+myLink.parent.effectivePpi[0]+" ppi";                               }                               if(myColSpaceOpt.checkedState){                                    myLinkInfoStr = myLinkInfoStr + "\rCol.Sp:\t" + myLink.parent.space;                               }                          }                          catch(e){}                                               myLinkInfoFrame = myLinkSpread.textFrames.add();                          myLinkInfoFrame.geometricBounds = [myLinkPos[0],myLinkPos[1],myLinkPos[0]+10,myLinkPos[1]+50];                          myLinkInfoFrame.textFramePreferences.insetSpacing = ["0.5mm","0.5mm","0.5mm","0.5mm"];                          myLinkInfoFrame.textFramePreferences.ignoreWrap = true;                          myLinkInfoFrame.fillColor = myInfoTitle;                          myLinkInfoFrame.fillTint = 15;                          myLinkInfoFrame.strokeColor = myInfoTitle;                          myLinkInfoFrame.strokeWeight = .5;                          if(myLabelOpt.checkedState){                               myLinkInfoFrame.nonprinting = false;                          }                          else{                               myLinkInfoFrame.nonprinting = true;                          }                          myLinkInfoFrame.contents = myLinkInfoStr;                          for(p = 0;p < myLinkInfoFrame.parentStory.paragraphs.length;p++){                               myLinkInfoFrame.parentStory.paragraphs[p].appliedParagraphS tyle = myInfoTitle;                               myLinkInfoFrame.parentStory.paragraphs[p].words[0].appliedC haracterStyle = myInfoTitle;                          }                          myLinkInfoFrame.fit(FitOptions.frameToContent);                     }                }           }      }      myDocument.viewPreferences.horizontalMeasurementUnits = myOrgDocHUnits;      myDocument.viewPreferences.verticalMeasurementUnits = myOrgDocVUnits;      myDocument.viewPreferences.rulerOrigin = myOrgDocOrigin; }

       

       

       

      Script #3: Code object area labels, but for Illustrator (basically what I want)

       

        • 1. Re: Square area percent of page report
          aus-enfatico Level 1

          Follow up: Sorry tried to insert code in the box but obviously got it wrong. Here is the Illustrator code (didn't fit)

           

          if ( app.documents.length > 0 && app.activeDocument.selection.length > 0 ) {
               //Declare the variables.
               var myDocument=app.activeDocument;
               var pathRef=docRef.selection[0];
               var pathRefArea=pathRef.area;
               var myReturn="\r";
               //Convert pathRefArea to other units of measure. Store them in a text variable named areaMessage.
               var areaMessage="Square Points: "+Math.round(pathRefArea*100)/100+myReturn
               +"Square Picas: "+(Math.round((pathRefArea/144)*100))/100+myReturn
               +"Square Inches: "+(Math.round((pathRefArea/5184)*100))/100+myReturn
               +"Square Millimeters: "+(Math.round((pathRefArea/8.037)*100))/100+myReturn
               +"Square Centimeters: "+(Math.round((pathRefArea/803.520)*100))/100
               //Display areaMessage in an alert.
               alert (areaMessage);
               
               //Create a textFrame and set its contents to areaMessage.
               var areaLabel = docRef.textFrames.add();
               areaLabel.contents = areaMessage;
               for(i=0;i<areaLabel.paragraphs.length;i++){
                    areaLabel.paragraphs[i].justification=Justification.CENTER;
               }
               
               //Position areaLabel at the center of the selected path.
               areaLabel.top = pathRef.top-pathRef.height/2+areaLabel.height/2;
               areaLabel.left = pathRef.left+pathRef.width/2-areaLabel.width/2;
          
               //Create a temporary textFrame named squarePoints to hold just the value of pathRef's area in square points.
               var squarePoints = docRef.textFrames.add();
               squarePoints.contents = Math.round(pathRefArea*100)/100;
               //Deselect pathRef. Select squarePoints. Redraw. Cut squarePoints to the clipboard.
               pathRef.selected=false;
               squarePoints.selected=true;
               redraw();
               app.cut();
          }
          
          
          

          • 2. Re: Square area percent of page report
            Peter Kahrel Adobe Community Professional & MVP

            > Code object area labels, but for Illustrator (basically what I want)

             

            Is there no Illustrator scripting forum?

             

            Peter

            • 3. Re: Square area percent of page report
              aus-enfatico Level 1

              Maybe I wasn't clear

               

              The question is about InDesign.

              The Illustrator script is what I want for InDesign. Please read the whole post.

               

              Thanks

              • 4. Re: Square area percent of page report
                Peter Kahrel Adobe Community Professional & MVP

                You mentioned a layer -- it wasn't clear to me what you want with it.Combining bits of different scripts is always difficult. Better to start from scratch, rather than accommodating one part of a script to another. What I would do in your case is this:

                 

                - set your document to inches so that you don't need to do all those calculations (first store the current values, restore them later);

                - calculate the page area;

                - calculate the selected object's area;

                - set the object's area (as a percentage of the page area) as the object's label.

                 

                This script does that with all page items in a document. It doesn't check any errors, so make sure all your work is saved.

                 

                // reference to the document
                doc = app.documents[0];
                // store the doc's view preferences
                view_prefs = doc.viewPreferences.properties;
                // set measurement units to inches
                doc.viewPreferences.verticalMeasurementUnits = doc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.inches;
                // calculate page area
                p_area = doc.documentPreferences.pageWidth * doc.documentPreferences.pageHeight;

                // reference to the document's page items
                all_objects = doc.pageItems.everyItem().getElements();
                // process them in turn
                for (i = 0; i < all_objects.length; i++)
                    {
                    // calculate an object's page area
                    o_area = object_area (all_objects[i]);
                    // calculate its percentage of the page area
                    pct = (o_area * 100) / p_area;
                    // add this as a string to the object's label
                    all_objects[i].label = String (pct);
                    }

                // restore the doc's view preferences
                doc.viewPreferences.properties = view_prefs;

                function object_area (obj)
                    {
                    var gb = obj.geometricBounds;
                    var width = gb[3]-gb[1];
                    var height = gb[2]-gb[0];
                    return width * height
                    }

                You mentioned something about a layer, but it wasn't clear to me what you want with that.

                 

                Peter

                1 person found this helpful
                • 5. Re: Square area percent of page report
                  [Jongware] Most Valuable Participant

                  Read all, including that 500-line sample script? I think not. Oh, and you are the first one ever to request the relative size of an object, when compared to its page, in inches and on a new layer.

                   

                  Rather than plough through that immensely long example and trying to fathom what's going on, I just read your question and wrote this. There are a couple of points you might want to find out more about, such as your 'height' prototype (you were about halfway there). Stuff like document page size can be found in the OMV Help, as well as in numerous samples in Adobe's own Scripting Guide.

                   

                  There is no need to recalculate units between points and inches -- in InDesign, you get what you asked for, or rather, what you already have. So if your current document settings are set to inches, the values ID returns are also in inches.

                  (It gets complicated if you work in points and want to see results in inches, but ever so slightly: points to inches is divide by 72.)

                   

                  Before I forget, here's a working script. Select an object on your page and run it to see that it works; read to see how it works

                   

                  if (app.selection.length != 1) exit(0);
                  bounds = app.selection[0].geometricBounds;
                  width = bounds[3] - bounds[1];
                  height = bounds[2] - bounds[0];
                  object_area = width * height;
                  page_area = app.activeDocument.documentPreferences.pageWidth * app.activeDocument.documentPreferences.pageHeight;
                  try {
                   app.activeDocument.layers.add({name:"Hey, a new layer"});
                  } catch (_)
                  {
                  }
                  thatNewLayer = app.activeDocument.layers.item("Hey, a new layer");
                  frame = app.activeDocument.textFrames.add(thatNewLayer, {geometricBounds:[0,0,"5mm","20mm"]});
                  frame.move (app.selection[0].parent);
                  frame.move ([app.selection[0].geometricBounds[1],app.selection[0].geometricBounds[0]]);
                  frame.contents = String(Math.round(object_area*10)/10)+" / "+String(Math.round((object_area*1000)/page_area)/10)+"%";
                  
                  1 person found this helpful
                  • 6. Re: Square area percent of page report
                    aus-enfatico Level 1

                    First off, thank you both! I realize it was a very long post, but I thought more info than less might be better

                     

                    I have a few follow up questions so I can understand better what is going on.

                     


                    As I read Peter's script it makes a lot of sense (thank you for the comments in the script). When I run it I think I see where I didn't explain well. The labels are supposed to be visual labels over each object. Maybe I'm TOTALLY missing the how it works but it seems that this is setting the object's label (as you said above) but not displaying that on a layer.

                     

                    Jongware's script does display on a layer, but only for the selected item.

                     

                    With both your advice and scripts (a much better starting point for me) I'm going to try to understand and write the exact solution I need.

                    I'll post my script, or attempt, along with a pic of the result in layout.

                     

                    Thank you both so much for your help.

                    • 7. Re: Square area percent of page report
                      aus-enfatico Level 1

                      So I understand that Peter is putting the object area and the % of the area into a string called pct.

                      And that Jongware is writing the contents calculation inside the string.

                       

                      So my first thought was to reference the string name in the frame contents (leaving out the stuff about new layer and frame creation)

                       

                      all_objects = doc.pageItems.everyItem().getElements();
                      // process them in turn
                      for (i = 0; i < all_objects.length; i++)
                          {
                          // calculate an object's page area
                          o_area = object_area (all_objects[i]);
                          // calculate its percentage of the page area
                          pct = (o_area * 100) / p_area;
                          // add this as a string to the object's label
                          all_objects[i].label = String (pct);
                          }
                      
                      frame.contents = String(pct);
                      
                      

                       

                      I'm obviously missing something here.

                       

                      So next I tried leaving the string alone and just passing the object area into it. Complete try below. I understand that the function is defining object area and that the for loop should be getting the object area for all objects in the document. I get errors in the function though. Do I need to store the object area in a string within the loop and call to it later in frame contents, or is this missing the forest for the trees.

                       

                      // reference to the document
                      doc = app.documents[0];
                      // store the doc's view preferences
                      view_prefs = doc.viewPreferences.properties;
                      // set measurement units to inches
                      doc.viewPreferences.verticalMeasurementUnits = doc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.inches;
                      // calculate page area
                      p_area = doc.documentPreferences.pageWidth * doc.documentPreferences.pageHeight;
                      
                      
                      all_objects = doc.pageItems.everyItem().getElements();
                      for (i = 0; i < all_objects.length; i++);
                          {
                           object_area = object_area (all_objects[i]);
                           }
                      
                      try {
                       app.activeDocument.layers.add({name:"Object Percent of Page"});
                      } catch (_)
                      {
                      }
                      thatNewLayer = app.activeDocument.layers.item("Object Percent of Page");
                      frame = app.activeDocument.textFrames.add(thatNewLayer, {geometricBounds:[0,0,"5mm","20mm"]});
                      frame.move (app.selection[0].parent);
                      frame.move ([app.selection[0].geometricBounds[1],app.selection[0].geometricBounds[0]]);
                      frame.fillColor = [10,10,100,10];
                      frame.fillTint = 50;
                      frame.contents = String(Math.round(object_area*10)/10)+" / "+String(Math.round((object_area*1000)/p_area)/10)+"%";
                      
                      
                      function object_area (obj)
                           {
                           var gb = obj.geometricBounds;
                           var width = gb[3]-gb[1];
                           var height = gb[2]-gb[0];
                           return width * height;
                           }
                      
                      • 8. Re: Square area percent of page report
                        aus-enfatico Level 1

                        Sorry, forgot to include the screen shot of the intended result. I guess to simplify Jongware's script

                        is perfect, I just want it to loop through all objects in the whole document (my attempt in above post).

                         

                         

                        Picture 1.png

                        • 9. Re: Square area percent of page report
                          [Jongware] Most Valuable Participant

                          A couple of errors ...

                           

                          object_area = object_area (all_objects[i])

                           

                          object_area is a function but you get its value and assign it to .. a variable with the same name. Better to use Peter's example, and give the variable another name -- why not "o_area"?

                           

                          The for.. loop gathers all data -> right. But then you end the for..loop (with the next } ) so you don't do anything with the value you got. See Peter's sample: in his loop, he calculates the area and then puts it into each object's label. It's at that point exactly where you want my stuff to kick in, and make a small text frame on top of the object with the area as its contents.

                           

                          Similar to Peter's, let me show you how to write a function to create the new frame.

                          First off, the stuff to create a new layer is only needed once, so you can move these lines

                           

                          try {
                           app.activeDocument.layers.add({name:"Object Percent of Page"});
                          } catch (_)
                          {
                          }
                          thatNewLayer = app.activeDocument.layers.item("Object Percent of Page");

                           

                          all the way to the top in your script. After asserting there is a layer called "Object Percent (etc.)", there is no need to try to re-create it for every next object. Since the variable 'thatNewLayer' gets declared outside all functions, it's therefore global, and can be used inside functions as well as outside.

                          For a description of the try..catch construction, google for "javascript try catch". (Suffice to say that if the first half fails, code in the next half will be called.)

                           

                          So, you need a function that takes

                          1. a reference to an object, so the new frame can be created on top of it, and

                          2. a value to write in to that.

                           

                          For functions, it's "best practice" to declare as much variables as possible locally, using the 'var' keyword, so they won't interfere with global variables with the same name. The rest is virtually unchanged -- app.selection[0], which acts on your current selected object, is replaced with the object that you'll have to feed it when calling.

                          Oh -- I see only one local variable is needed: "frame" is only used inside this function. All other variables are either the function arguments (forObject and value) or global ones declared earlier (thatNewLayer and p_area).

                           

                          function createTextFrame (forObject, value)
                          {
                               var frame;
                               frame = app.activeDocument.textFrames.add(thatNewLayer, {geometricBounds:[0,0,"5mm","20mm"]});
                               frame.move (forObject.parent);
                               frame.move ([forObject.geometricBounds[1],forObject.geometricBounds[0]]);
                               frame.fillColor = [10,10,100,10];
                               frame.fillTint = 50;
                               frame.contents = String(Math.round(value*10)/10)+" / "+String(Math.round((value*1000)/p_area)/10)+"%";
                          }
                          
                          

                           

                          -- and you call the function right after calculating the object area, like this

                           

                          createTextFrame(all_objects[i], o_area);

                           

                          inside the loop.

                           

                          Hope it helps!

                          • 10. Re: Square area percent of page report
                            aus-enfatico Level 1

                            Brilliant!

                             

                            Thank you for taking the time to explain everything so detailed. I read it a few times to make sure that I understood. I knew better with placing the new layer in the loop, that was dumb of me.

                             

                            This works perfectly.

                             

                            // reference to the document
                            doc = app.documents[0];
                            // store the doc's view preferences
                            view_prefs = doc.viewPreferences.properties;
                            // set measurement units to inches
                            doc.viewPreferences.verticalMeasurementUnits = doc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.inches;
                            // calculate page area
                            p_area = doc.documentPreferences.pageWidth * doc.documentPreferences.pageHeight;
                            
                            //create new layer
                            try {
                             app.activeDocument.layers.add({name:"Object Percent of Page"});
                            } 
                            catch (_)
                            {
                            }
                            thatNewLayer = app.activeDocument.layers.item("Object Percent of Page");
                            
                            // reference to the document's page items
                            all_objects = doc.pageItems.everyItem().getElements();
                            
                            
                            // process them in turn
                            for (i = 0; i < all_objects.length; i++)
                                {
                                // calculate an object's page area
                                o_area = object_area (all_objects[i]);
                                 createTextFrame(all_objects[i], o_area);
                            
                                 function createTextFrame (forObject, value)
                                           {
                                           var frame;
                                           frame = app.activeDocument.textFrames.add(thatNewLayer, {geometricBounds:[0,0,"5mm","20mm"]});
                                           frame.move (forObject.parent);
                                           frame.move ([forObject.geometricBounds[1],forObject.geometricBounds[0]]);
                                           //frame.fillColor = [10,10,100,10];
                                           //frame.fillTint = 50;
                                           frame.contents = String(Math.round(value*10)/10)+" / "+String(Math.round((value*1000)/p_area)/10)+"%";
                                           }
                                }
                            // restore the doc's view preferences
                            doc.viewPreferences.properties = view_prefs;
                            
                            function object_area (obj)
                                {
                                var gb = obj.geometricBounds;
                                var width = gb[3]-gb[1];
                                var height = gb[2]-gb[0];
                                return width * height
                                }
                            

                             

                             

                            Two follow up questions so that I understand even more.

                            1. The function object_area (obj) at the end of the deocument defines what object_area does earlier in the script. Why does this not get placed earlier, wouldn't the loop need this definition?
                            2. My frame.fillColor is causing the error "expected swatch". While this isn't a critical need for the functionality of the script, it makes it easier to read the labels. I'm confused by this because this way worked before...so I'm going to try defining a swatch by name and go from there. Left it commented out in the script above.

                             

                            Thanks again, you both have helped make a lot of smiles here today!

                            • 11. Re: Square area percent of page report
                              aus-enfatico Level 1

                              So I tried adding

                               

                               

                              //label fill color
                              var frameColor = [0,15,100,0];
                              

                              To the top so it would be a global variable for each frame label. The tried calling it just above frame contents. But getting the error "expected swatch".

                               

                              frame.fillColor = frameColor;
                                   frame.contents = String(Math.round(value*10)/10)+"squ IN: "+ String(Math.round((value*1000)/p_area)/10)+"% of Total Page";
                                   }
                              

                               

                               

                              Should frameColor not be a Global variable?

                              • 12. Re: Square area percent of page report
                                Peter Kahrel Adobe Community Professional & MVP

                                You want to get that function out of the for-loop and place it separately, e.g. at the end of the script:

                                 

                                for (i = 0; i < all_objects.length; i++)
                                    {
                                    o_area = object_area (all_objects[i]);
                                    createTextFrame(all_objects[i], o_area);
                                    }

                                // more script..

                                // maybe more script

                                 

                                function createTextFrame (forObject, value)
                                   {
                                   var frame;
                                   frame = app.activeDocument.textFrames.add(thatNewLayer, {geometricBounds:[0,0,"5mm","20mm"]});
                                   frame.move (forObject.parent);
                                   frame.move ([forObject.geometricBounds[1],forObject.geometricBounds[0]]);

                                   // colour: see below

                                   frame.fillColor = colour;
                                   frame.fillTint = 50;
                                   frame.contents = String(Math.round(value*10)/10)+" / "+String(Math.round((value*1000)/p_area)/10)+"%";
                                   }

                                 


                                As to colour, you define that at the beginning of the script. Where Jongware checks/created the layer would be a good place, and the check looks the same:

                                 

                                try
                                    {
                                    app.activeDocument.colors.add ({name: "pct_colour", space: ColorSpace.cmyk, colorValue: [10,10,100,10]})
                                    }
                                catch (_) {} // not interested in errors

                                 

                                You would then later assign that colour to a text frame:

                                 

                                frame.fillColor = app.activeDocument.swatches.item ("pct_colour");

                                 

                                Peter

                                • 13. Re: Square area percent of page report
                                  aus-enfatico Level 1

                                  Thank you, you're both awesome!

                                   

                                  One more question (I debated starting a new post but thought it was so relvant to this one it probably belonged here):

                                   

                                  I'd like to add the link name to the frame label. I thought if I followed the same logic of referencing all links in the document and then setting a loop to capture them all that I could reference it later in the frame.contents before the math string.

                                   

                                  I'm sure that I have a few things wrong and I can't figure out  how to write the function to add the link names to the text frame. Putting it inside the createTextFrame function seems illogical, but with writing it into that function I'm at a loss.

                                   

                                  I searched the Forums and turned up some interesting bits about extracting file names as a starting point (Peter, I think my all_links reference is from one of your posts). I also tried (but abondoned) referencing XMP.

                                   

                                  // reference to the document's page items
                                  all_objects = doc.pageItems.everyItem().getElements();
                                  
                                  //try 02 to reference all links
                                  all_links = app.activeDocument.allGraphics;
                                       for (i = 0; i < all_links.length; i++)
                                            {
                                       frame.contents = String(all_links[i].itemLink.filePath).name;
                                       }
                                       
                                  
                                  // process each object in turn
                                  for (i = 0; i < all_objects.length; i++)
                                      {
                                      // calculate an object's page area
                                      o_area = object_area (all_objects[i]);
                                       createTextFrame(all_objects[i], o_area);
                                  
                                       function createTextFrame (forObject, value, myObject)
                                                 {
                                                 var frame;
                                  
                                  /* frame code */
                                                 frame.contents = all_links, String(Math.round(value*10)/10)+"squ IN: "+ String(Math.round((value*1000)/p_area)/10)+"% of Total Page";
                                                 }
                                      }
                                  

                                   

                                  The rest of the script works perfectly and I understand the part about the fill color now, create a new color and name it while setting the value, then reference it inside the frame variable. Maybe I should do the same with the link name?

                                   

                                  Thanks again

                                  • 14. Re: Square area percent of page report
                                    aus-enfatico Level 1

                                    Tried switching from all ojects to just the links, but I think I've got it wrong at the frame.contents point. Help?

                                     

                                    //new reference to all links
                                    all_objects = app.activeDocument.allGraphics;
                                    
                                    
                                    //all_links = doc.pageItems[0].graphics[0].itemLink.filePath.name; 
                                         
                                    
                                    // process them in turn
                                    for (i = 0; i < all_objects.length; i++)
                                        {
                                        // calculate an object's page area
                                        o_area = object_area (all_objects[i]);
                                         createTextFrame(all_objects[i], o_area);
                                         
                                         /*try 02
                                         all_links = app.activeDocument.allGraphics;
                                         for (i = 0; i < all_links.length; i++) */
                                    
                                         function createTextFrame (forObject, value, myObject)
                                                   {
                                                   var frame;
                                    
                                                   frame = app.activeDocument.textFrames.add(thatNewLayer, {geometricBounds:[0,0,"5mm","45mm"]});
                                                   frame.move (forObject.parent);
                                                   frame.move ([forObject.geometricBounds[1],forObject.geometricBounds[0]]);
                                                   //label fill color & tint
                                                   frame.fillColor = app.activeDocument.swatches.item ("pct_color");
                                                   frame.fillTint = 50;
                                                   frame.textFramePreferences.ignoreWrap = false;
                                                   frame.contents = String(all_links[i].itemLink.filePath).name, String(Math.round(value*10)/10)+"squ IN: "+ String(Math.round((value*1000)/p_area)/10)+"% of Total Page";
                                                   }
                                        }
                                    
                                    • 15. Re: Square area percent of page report
                                      [Jongware] Most Valuable Participant

                                      That function should not be declared inside the for loop. Always put all your functions outside everything else to make them globally available.

                                       

                                      (.. I think that's all, without running the script ..)

                                       

                                      [Add] Well, apart from this: the function is already called with your active object, so it's kinda "neat" if you also use

                                       

                                      frame.contents = forObject.itemLink.filePath, [etc.]

                                       

                                      I see you cast the filePath to a String -- according to my JS Help, it's already a string, and it doesn't have a .name property.

                                       

                                      Again, that ought to be all ...

                                      • 16. Re: Square area percent of page report
                                        aus-enfatico Level 1

                                        Mmm, seems I'm still not understanding function placement with loops. I visited W3C to read up on it, but I think I also need more practice to make hte connection.

                                         

                                        I placed the reference outside then tried calling to the string inside the for loop. I think I'm going wrong at the second declaration under the for loop. If so, where does that belong, or is it redundent?

                                         

                                        // reference to the document's page items
                                        all_objects = doc.pageItems.everyItem().getElements();
                                        
                                        // reference all graphics
                                        all_links = app.activeDocument.allGraphics;
                                        
                                        // process them in turn
                                        for (i = 0; i < all_objects.length; i++)
                                        
                                        /*this is where I think I'm going wrong*/
                                         (i = 0; i < all_links.length; i++);
                                            {
                                        // calculate an object's page area
                                            o_area = object_area (all_objects[i]);
                                        
                                         
                                             createTextFrame(all_objects[i], o_area);
                                             function createTextFrame (forObject, value, myObject)
                                                       {
                                                       var frame;
                                                       //var myLink = myObject.graphics.item(0).itemLink;
                                        
                                                       frame = app.activeDocument.textFrames.add(thatNewLayer, {geometricBounds:[0,0,"5mm","45mm"]});
                                                       frame.move (forObject.parent);
                                                       frame.move ([forObject.geometricBounds[1],forObject.geometricBounds[0]]);
                                                  //label fill color
                                                  frame.fillColor = app.activeDocument.swatches.item ("pct_color");
                                                  frame.fillTint = 50;
                                                  frame.textFramePreferences.ignoreWrap = false;
                                                       //frame.contents = myLink.name;
                                        /*I added the name String but not sure it's right*/
                                                  frame.contents = String(all_links[i].itemLink.filePath).name)+String(Math.round(value*10)/10)+"squ IN: "+ String(Math.round((value*1000)/p_area)/10)+"% of Total Page";
                                                  }
                                            }
                                        
                                        • 17. Re: Square area percent of page report
                                          aus-enfatico Level 1

                                          Okay, tried changing everything to only get the links but I error out at

                                          all_links = doc.allGraphics.getElements();
                                          

                                          so, not getting far.

                                           

                                          Total script below. I'll keep reading and working tomorrow, eyes hurt for now.

                                          // reference to the document's page items
                                          /*all_objects = doc.pageItems.everyItem().getElements();*/
                                          
                                          // reference all graphics
                                          all_links = doc.allGraphics.getElements();
                                          
                                          
                                          
                                          // process them in turn
                                          /*for (i = 0; i < all_objects.length; i++)*/
                                          for (i = 0; i < all_links.length; i++);
                                              {
                                          // calculate an object's page area
                                              o_area = object_area (all_links[i]);
                                          
                                           
                                               createTextFrame(all_links[i], o_area);
                                          
                                               function createTextFrame (forObject, value, myObject)
                                                         {
                                                         var frame;
                                                         //var myLink = myObject.graphics.item(0).itemLink;
                                          
                                                         frame = app.activeDocument.textFrames.add(thatNewLayer, {geometricBounds:[0,0,"5mm","45mm"]});
                                                         frame.move (forObject.parent);
                                                         frame.move ([forObject.geometricBounds[1],forObject.geometricBounds[0]]);
                                                         //label fill color
                                                         frame.fillColor = app.activeDocument.swatches.item ("pct_color");
                                                         frame.fillTint = 50;
                                                         frame.textFramePreferences.ignoreWrap = false;
                                                         //frame.contents = myLink.name;
                                          /*tried adding string for link names here*/
                                                         frame.contents = String((all_links[i].itemLink.filePath).name)+String(Math.round(value*10)/10)+"squ IN: "+ String(Math.round((value*1000)/p_area)/10)+"% of Total Page";
                                                         }
                                              }
                                          // restore the doc's view preferences
                                          doc.viewPreferences.properties = view_prefs;
                                          
                                          function object_area (obj)
                                              {
                                              var gb = obj.geometricBounds;
                                              var width = gb[3]-gb[1];
                                              var height = gb[2]-gb[0];
                                              return width * height
                                              }
                                          

                                           

                                          Really interested in where I'm going wrong. Thanks!

                                          • 18. Re: Square area percent of page report
                                            aus-enfatico Level 1

                                            Jongware, thanks for the added info.

                                             

                                            I didn't see it before I added those posts. I'll back track and see if I can get it right from your advice. Thanks!

                                            • 19. Re: Square area percent of page report
                                              JGL79 Level 1

                                              Hello,

                                               

                                              This "square area percent page report" is so very close to what I need for my project. The only difference is that instead of a percentage of each object in relation to the page, I need the actual size in square millimeters of each object on each page. My task is two draw boxes around every object. Copy and paste the height and width in a spreadsheet that multiplies the two measurements to give me the area. Of course I have to do this literally thousands of times! Do you know of a script that can assist me with this task? I appreciate any direction you can give.  Thank you.

                                              • 20. Re: Square area percent of page report
                                                [Jongware] Most Valuable Participant

                                                Mmm.

                                                 

                                                Peter's "object_area" function returns the actual object area, but it's in inches, rather than mm. You can work around that using the definition of one inch ("One Inch Equals 25.4 mm" -- it's official!), using

                                                 

                                                area_in_mm = object_area (all_objects[i]) * 25.4 * 25.4;

                                                 

                                                or -- easier -- just set the measurements to millimeters, near the top of his script! (All measurements "inside" a script are automatically converted to 'the active' units.)

                                                 

                                                But I don't get this

                                                 

                                                My task is two draw boxes around every object

                                                 

                                                or this

                                                 

                                                Copy and paste the height and width in a spreadsheet that multiplies the two measurements to give me the area

                                                 

                                                The scripts above don't draw the boxes; they use what's already there on the page. (And why "two"?)

                                                And InDesign is horrible in copying information out of it into a spreadsheet. A typical solution would be to write the measurements into a simple text file, and import that into any other program to process.

                                                • 22. Re: Square area percent of page report
                                                  JGL79 Level 1

                                                  The boxes are really frames. Every image on a page has a frame around it. The dimensions of this frame (width and height) gives me a very simple approximation of how much space the image takes up on the page. Because selecting the frame doesnt give me square area (only width and height) I multiply the two to give me the square area. It would save me a step and cut my time in half if I already had the square area of the object to copy and paste into my list. If InDesign just gave me the square area I wouldn't have this problem. Hope that makes more sense.