20 Replies Latest reply on Sep 12, 2016 7:19 AM by Skemicle

    Script that can delete objects by coordinates

    Dimitra.p

      I have a long document and I need to remove some text frames that appear on every page. Those frames share the same y coordinate and some others that share the same x coordinate. Is there a script that can locate those text frames and delete them throughout the document?

      I'm on Windows so no applescript

        • 1. Re: Script that can delete objects by coordinates
          Vamitul Level 4

          Most likely you won't find a out-of-the-box solution, but it is a very simple script that you can try and build by yourself.

          • 2. Re: Script that can delete objects by coordinates
            Kai Rübsamen Level 4

            Hi Dimitra,

             

            here is the idea. If you have any problems with the script, you will surely get help

             

            1. Collect all textframes in you document

            2. Loop backwards through all your textframes

            3. Compare the x OR y coordinates of the current object with your specified value

            3 a. If you have no result, the values should maybe rounded before comparison

            4. Delete the object

             

            best

            Kai

            1 person found this helpful
            • 3. Re: Script that can delete objects by coordinates
              Skemicle Level 3

              Kai Rübsamen wrote:

               

              2. Loop backwards through all your textframes

              I have wrote a script for this but my script doesn't loop backwards.. what is the reason for looping backwards rather than just looping in order of the textFrames?

              • 4. Re: Script that can delete objects by coordinates
                Kai Rübsamen Level 4

                In this case there is no particular reason! Both will work. If I remove or duplicate things, I do it always backwards.

                • 5. Re: Script that can delete objects by coordinates
                  Dimitra.p Level 1

                  Would you be so kind as to share the script you wrote? I am a beginner and have difficulty on how to go about it.

                  • 6. Re: Script that can delete objects by coordinates
                    Skemicle Level 3

                    I will not provide my script just yet. Since you imply that you are trying to learn to script I will explain how to go about this process following 's steps above steps above:

                    Kai Rübsamen wrote:

                    1. Collect all textframes in you document

                    app.activeDocument.textFrames; // This will tell InDesign to find all text frames within the active document.

                    Kai Rübsamen wrote:

                    2. Loop backwards through all your textframes

                    for(c=app.activeDocument.textFrames.length - 1; c < 0; c--){

                         /*

                         script to be looped will go withing the for loop braces: "{}".

                         the for loop says that c is equal to the number of text frames within the active document minus 1.

                         the second part of the for loop says to loop as long as c is greater than 0.

                         and the final part of the script says to take one away from c after each loop.

                         */

                    }

                    Kai Rübsamen wrote:

                    3. Compare the x OR y coordinates of the current object with your specified value

                    if(app.activeDocument.textFrames[c].geometricBounds[0] == VALUE){

                         /*

                         the IF() line tests if the y axis is a certain value; where "VALUE" is replaced with the desired y value to remove text frames.

                         To test the x axis use app.activeDocument.textFrames[c].geometricBounds[1].

                         any script within the IF() braces "{}" will only be executed if the condition is true.

                         The IF() function should be placed within the FOR() loop braces "{}"

                         */

                    }

                    Kai Rübsamen wrote:

                    3 a. If you have no result, the values should maybe rounded before comparison

                    //to round a number you will need to use the round function:

                    eg -- Math.round(app.activeDocument.textFrames[c].geometricBounds[0] / .125) * .125 //Will round the y axis to the nearest 1/8 unit

                    Kai Rübsamen wrote:

                    4. Delete the object

                    app.activeDocument.textFrames[c].remove(); // Will remove the text frame.. should be placed within the IF() function braces"{}".

                    1 person found this helpful
                    • 7. Re: Script that can delete objects by coordinates
                      Dimitra.p Level 1
                      app.activeDocument.textFrames;
                      for(c=app.activeDocument.textFrames.length - 1; c < 0; c--){
                      if(app.activeDocument.textFrames[c].geometricBounds[0] == -11,5){
                      Math.round(app.activeDocument.textFrames[c].geometricBounds[0] / .125)
                      app.activeDocument.textFrames[c].remove();
                      }
                      }
                      

                       

                      Does this look right? It doesn't seem to do anything... Does it matter that the document is a book with facing pages?

                      • 8. Re: Script that can delete objects by coordinates
                        Loic.Aigon Adobe Community Professional

                        Yeah you did it ! Now we can start really helping you

                         

                        app.activeDocument.textFrames; is a reference that you will recall later so you may want to store into a variable:

                         

                        var doc = app.activeDocument;

                        var myTextFrames = doc.textFrames;

                         

                        When you do loop, it's always a good habit not to check the "array" length every round. So you may want to store it inside another variable:

                         

                        var n = myTextFrames.length - 1 ; //-1 if decremental loop

                         

                        When you build a loop, the direction (incrementtal or decremental impact how you build the loop.

                        In your case you try to loop backward but the exit condition states that the loop as to go through as long as the length is lesser than 0 which is not from the beginning. So your loop never runs actually.

                        When you go backwards, your exit condition is that your index is greater or equals 0;

                         

                        for ( i = n; i>=0 ; i-- ) {

                        myTextFrames[i] //reference to the text frame of rank i

                        }

                         

                        Now geometricBounds is an array of four reals as you saw. If you are expecting a very same position, you could store the array and compare to the geometric bounds of the object:

                         

                        for ( i = n; i>=0 ; i-- ) {

                             if ( myTextFrames[i].geometricBounds == [0,0,10, 100] )  myTextFrames[i].remove();

                        }

                         

                        but chances are high that an user might have moved things a little so the comparison might not work. So and that will be your very last step, it's generally better to define a virtual surrounding box (i.e. an array of 4 reals) that is bigger than teh box dimension. Then you can check if the geometricbounds stand inside that virtual box giving you a bit of margin. Then you can safely remove the object.

                         

                        Keep up the good work. You have done the toughest part…start coding

                         

                        Loic

                         

                        1 person found this helpful
                        • 9. Re: Script that can delete objects by coordinates
                          Marc Autret Level 4

                          Hi Loic,

                           

                          Just a note. You can't compare arrays using code like [1,2,3,4]==[1,2,3,4] (result is false) unless you have prototyped the '==' operator.

                           

                          This can be done this way:

                          Array.prototype['=='] = function(a){ return this.toSource() == a.toSource() };

                           

                          @+

                          Marc

                          • 10. Re: Script that can delete objects by coordinates
                            Loic.Aigon Adobe Community Professional

                            Hi @Marc,

                             

                            Oh ok, I guess I never got into that pitfall because I never had to do such comparisons but it's interesting to know

                            Plus, your code will be a perfect snippet to put aside for further use.

                             

                            Given the lack of experienceof our friend, let's offer her another form of comparison

                            var a = [1,2,3,4];

                            var b = [1,2,3,4];

                            if ( a[0]==b[0]

                            && a[1]==b[1]

                            && a[2]==b[2]

                            && a[3]==b[3] ) { alert("a & b equal); }

                             

                            Loic

                            • 11. Re: Script that can delete objects by coordinates
                              Kai Rübsamen Level 4

                              Loic, the question is, how to find x- and y-positions, not to compare the whole bounds ;-)

                               

                              Besides the wrong loop, the op use a comma in his value, instead of a point, so 11,5 should bei 11.5

                              • 12. Re: Script that can delete objects by coordinates
                                Loic.Aigon Adobe Community Professional

                                Ahh it's me being too generous

                                • 13. Re: Script that can delete objects by coordinates
                                  Dimitra.p Level 1
                                  app.activeDocument.textFrames;
                                  var doc = app.activeDocument;
                                  var myTextFrames = doc.textFrames;
                                  var n = myTextFrames.length - 1 ; //-1 if decremental loop
                                  for ( i = n; i>=0 ; i-- ) {
                                  myTextFrames[i]
                                  }
                                  for ( i = n; i>=0 ; i-- ) {
                                       if ( myTextFrames[i].geometricBounds == [170,-11.5,117,4.1] )  myTextFrames[i].remove();
                                  }
                                  

                                   

                                  Still doesn't work .

                                  • 14. Re: Script that can delete objects by coordinates
                                    Peter Kahrel Adobe Community Professional & MVP

                                    Dimitra,

                                     

                                    You check if the geometricBounds of your text frame are [170,-11.5,117,4.1]. But it's likely that the bounds are something different. Print the frame's g.bounds (select the frame and do $.writeln(app.selection[0].geometricBounds) and check the result. InDesign's measurements have 12 decimals, so what is displayed in the InDesign's panels as e.g. 170, might infact be 170.000000000001, and that's not the same as 170. So to check whether two frames are in the same position, you need to build in some allowance, e.g. by rounding the numbers or chopping off some decimals.

                                     

                                    On a different note, lines 5-7 appear not to do anything, you might as well leave them out.

                                     

                                    Peter

                                    1 person found this helpful
                                    • 15. Re: Script that can delete objects by coordinates
                                      Kai Rübsamen Level 4

                                      O.k., so let’s go one step backwards!

                                       

                                      The goal is to find textframes on a specific x or y position. So you need first: all text frames in your document. Since you cannot simply call textframes, you must call the containers as well. Als Loic said, it is always a good idea to store such things in a variable.

                                       

                                      Bildschirmfoto 2016-09-09 um 10.41.59.png

                                      var curDoc = app.activeDocument;
                                      var allTextFrames = curDoc.textFrames;
                                      

                                       

                                      While you can count your textframes, you can loop through every individual textframe with it’s index. And because you want to delete frames, it may a good idea to loop from the end. Since this so called index starts with '0' instead of '1', we need one loop less than the length of your textframes.

                                       

                                      var nTextFrames = allTextFrames.length-1;
                                      
                                      for (var i = nTextFrames; i >= 0; i--) {
                                          var curTextFrame = allTextFrames[i];
                                          // do something
                                      }
                                      
                                      1 person found this helpful
                                      • 16. Re: Script that can delete objects by coordinates
                                        Dimitra.p Level 1
                                        var curDoc = app.activeDocument;  
                                        var allTextFrames = curDoc.textFrames;  
                                        var n = myTextFrames.length - 1 ; //-1 if decremental loop
                                            var nTextFrames = allTextFrames.length-1;  
                                            for (var i = nTextFrames; i >= 0; i--) {  
                                                var curTextFrame = allTextFrames[i];  
                                               myTextFrames[i].remove(); // do something  
                                            }  
                                        
                                        

                                        And where do I input the coordinates x, y in that code?

                                        • 17. Re: Script that can delete objects by coordinates
                                          Kai Rübsamen Level 4

                                          Now to the second part:

                                           

                                          If you have your current text frame, you can read the geometric Bounds. Since you want to find only frames with specific x or y coordinates, you need only y1 and x1. And since the values could have a lot of decimals, it is a good idea to round the values, as Peter mentioned.

                                           

                                          Bildschirmfoto 2016-09-09 um 10.56.39.png

                                          var curDoc = app.activeDocument;
                                          var allTextFrames = curDoc.textFrames;
                                          
                                          var yValue = 11.5;
                                          var xValue = 20;
                                          
                                          var nTextFrames = allTextFrames.length-1;
                                          
                                          for (var i = nTextFrames; i >= 0; i--) {
                                            var curTextFrame = allTextFrames[i];
                                            var gB = curTextFrame.geometricBounds;
                                            var y1 = gB[0].toFixed(2);
                                            var x1 = gB[1].toFixed(2);
                                            
                                            if (y1 == yValue) {
                                              curTextFrame.remove();
                                            }
                                            if (x1 == xValue) {
                                              curTextFrame.remove();
                                            }
                                          }
                                          
                                          1 person found this helpful
                                          • 18. Re: Script that can delete objects by coordinates
                                            Dimitra.p Level 1

                                            !!! It finally works!!! I won't have to delete 1,4000 text frames by hand!!


                                            I only managed to get it to work when I only use the x or only the y coordinate otherwise it removes all text boxes on the same y and all on the same x without them sharing both x&y but still, this works just fine.

                                             

                                            var curDoc = app.activeDocument;
                                            var allTextFrames = curDoc.textFrames;
                                            var yValue = -11.5;
                                            // var xValue = 170;
                                            var nTextFrames = allTextFrames.length-1;
                                            for (var i = nTextFrames; i >= 0; i--) {
                                            var curTextFrame = allTextFrames[i];
                                            var gB = curTextFrame.geometricBounds;
                                            var y1 = gB[0].toFixed(2);
                                            //  var x1 = gB[1].toFixed(2);
                                            if (y1 == yValue) {
                                              curTextFrame.remove();
                                            }
                                            //  if (x1 == xValue) {
                                            //  curTextFrame.remove();
                                            //  }
                                            }
                                            

                                             

                                            Thank you all!

                                            • 19. Re: Script that can delete objects by coordinates
                                              Kai Rübsamen Level 4

                                              Hopefully you understand, that a lot of people try to give you an entry to scripting .

                                               

                                              I would assume, that this version, works with both cases?

                                               

                                              var curDoc = app.activeDocument;
                                              var allTextFrames = curDoc.textFrames;
                                              
                                              var yValue = 11.5;
                                              var xValue = 20;
                                              
                                              var nTextFrames = allTextFrames.length-1;
                                              var i, curTextFrame, gB, y1, x1;
                                              
                                              for (i = nTextFrames; i >= 0; i--) {
                                                curTextFrame = allTextFrames[i];
                                                gB = curTextFrame.geometricBounds;
                                                y1 = gB[0].toFixed(2);
                                                x1 = gB[1].toFixed(2);
                                                
                                                if (y1 == yValue && x1 != xValue) {
                                                  curTextFrame.remove();
                                                }
                                                  else if (x1 == xValue && y1 != yValue) {
                                                    curTextFrame.remove();
                                                }
                                              }
                                              
                                              • 20. Re: Script that can delete objects by coordinates
                                                Skemicle Level 3

                                                Since you have a working script I will now provide my script. The main difference with the scripts here and mine is that my script uses a text frame selection for the x and y coordinates and also provides a simple dialog to choose whether to use the x or y axis. Obi-wan Kenobi has gotten me really into adding UIs.

                                                 

                                                /*

                                                scripted by Skemicle

                                                4:05 PM 9/6/2016

                                                */

                                                if(parseFloat(app.version) < 6){

                                                    dialog();

                                                }else{

                                                    app.doScript(dialog, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Delete Cooresponding Text Frames");

                                                }

                                                function dialog(){

                                                    if(app.selection.length != 1){

                                                        alert("Please, select a single text frame and retry");

                                                        exit();

                                                    }else{

                                                        with(new Window('dialog {orientation:"column", alignChildren:"right"}', "Delete Corresponding Text Frames")){

                                                            add('staticText', undefined, "Delete textFrames that share the same:")

                                                            with(add('group {orientation:"row"}')){

                                                                var ycoord = add('radiobutton {value:true, text:"Y Coordinate"}');

                                                                add('radiobutton {value:false, text:"X Coordinate"}');

                                                            }with(add('group')){

                                                                add('button', undefined, "OK");

                                                                add('button', undefined, "Cancel");

                                                            }if(show() != 1){

                                                                exit();

                                                            }else{

                                                                main(ycoord);

                                                            }

                                                        }

                                                    }

                                                }

                                                function main(ycoord){

                                                    var x=0;

                                                    var doc = app.activeDocument;

                                                    var sel = app.selection[0];

                                                    var selgb0 = Math.round(sel.geometricBounds[0] / .0125) * .0125;

                                                    var selgb1 = Math.round(sel.geometricBounds[1] / .0125) * .0125;

                                                    var textFrames = doc.textFrames;

                                                    if(ycoord.value == true){

                                                        for(c=0;c<textFrames.length;c++){

                                                            if(Math.round(textFrames[c].geometricBounds[0] / .0125) * .0125 == selgb0){

                                                                textFrames[c].remove();

                                                                x++;

                                                                c--;

                                                            }

                                                        }

                                                    }else{

                                                        for(c=0;c<textFrames.length;c++){

                                                            if(Math.round(textFrames[c].geometricBounds[1] / .0125) * .0125 == selgb1){

                                                                textFrames[c].remove();

                                                                x++;

                                                                c--;

                                                            }

                                                        }

                                                    }alert(x + " Items have been removed.");

                                                }

                                                1 person found this helpful