11 Replies Latest reply on Nov 10, 2018 9:10 AM by Peter Kahrel

    Delete empty graphics frames inside table

    mikefwd Level 1

      Hi all

       

      I need a script to delete all empty graphics frames inside all tables of a multi page document.

       

      The following script deletes text frames in the document but does not delete them if they are inside a table.

       

      var myGraphicFrames = app.activeDocument.rectangles; 

      for (i=myGraphicFrames.length-1; i>=0; i--) { 

          if (myGraphicFrames[i].graphics.length < 1) 

              myGraphicFrames[i].remove(); 

      }

       

       

      Anyone know how to rewrite this script so that it deletes graphic frames from within all tables as well?

      I'm a total beginner at scripting so any help would be much appreciated.

       

      Cheers

       

      Mike

        • 1. Re: Delete empty graphics frames inside table
          Manan Joshi Level 4

          Something like below should work, you need to iterate all the tables in the document and then each cell of all these tables

          var myGraphicFrames = app.activeDocument.stories.everyItem().tables.everyItem().cells.everyItem().pageItems
          for (i = 0; i < myGraphicFrames.length; i++)
          {
              if (myGraphicFrames[i].graphics.length == 0)
                  myGraphicFrames[i].remove();
          }
          

           

          -Manan

          1 person found this helpful
          • 2. Re: Delete empty graphics frames inside table
            Manan Joshi Level 4

            I just noticed that the code i gave would not work on inner tables i.e. tables within a table cell and so forth. But that can be added to it, you just need to check each cell to check for tables within it and then the process repeats itself to iterate each cell. A recursive algorithm fits the bill in this case.

             

            -Manan

            • 3. Re: Delete empty graphics frames inside table
              Peter Kahrel Adobe Community Professional & MVP

              In fact it's probably simpler to get a handle on all graphics, and delete those that are in a table:

               

              g = app.documents[0].allGraphics;
              for (i = g.length-1; i >= 0; i--) {
                if (g[i].parent.parent.parent instanceof Cell) {
                  g[i].parent.remove();
                }
              }
              

               

              Peter

              1 person found this helpful
              • 4. Re: Delete empty graphics frames inside table
                Laubender Adobe Community Professional & MVP

                Hi Peter,

                I think, only empty graphic frames in tables should be removed.

                All with graphics inside should stay.

                 

                Regards,
                Uwe

                • 5. Re: Delete empty graphics frames inside table
                  Peter Kahrel Adobe Community Professional & MVP

                  Ah, thanks Uwe, hadn't spotted that. Anyway, a bit more work but not much:

                   

                  r = app.documents[0].allPageItems;
                  for (i = r.length-1; i >= 0; i--) {
                    if (r[i] instanceof Rectangle && r[i].parent.parent instanceof Cell && r[i].graphics.length == 0) {
                      r[i].remove();
                    }
                  }
                  

                   

                  P.

                  1 person found this helpful
                  • 6. Re: Delete empty graphics frames inside table
                    Laubender Adobe Community Professional & MVP

                    Hi Peter,

                    tested your code.

                     

                    Did a try/catch around the if clause so it could run through my sample document without error message.

                     

                    Even then:

                    It will fail on group items that are empty.

                    It will remove graphic frames where graphic frames with images are pasted in.

                     

                    And of course there could be Polygons or Ovals as well.

                     

                    Before:

                     

                    Before-Running-Script-RemoveEmptyFramesInTables.PNG

                     

                    After:

                     

                    After-Running-Script-RemoveEmptyFramesInTables.PNG

                     

                    Just trying to write my own code that would

                    1. Also remove the empty frames in the anchored group of cell 1 in the nested table.

                    2. Not remove the frame with the pasted in graphic of cell 2 of the nested table.

                     

                    EDIT:

                    3. Also removes the empty graphic frame in the graphic cell of the nested table.

                    Just spotted that.

                     

                    Currently I have success with item 1. and item 3.

                    Still looking for a straight way to get around item 2.

                     

                    Regards,
                    Uwe

                    • 7. Re: Delete empty graphics frames inside table
                      Laubender Adobe Community Professional & MVP

                      https://forums.adobe.com/people/Manan+Joshi  wrote

                       

                      I just noticed that the code i gave would not work on inner tables i.e. tables within a table cell and so forth. But that can be added to it, you just need to check each cell to check for tables within it and then the process repeats itself to iterate each cell. A recursive algorithm fits the bill in this case.

                       

                      -Manan

                      Hi Manan,

                      check the allPageItems array of a cell. That would include also nested tables with their cells and inserted page items.

                       

                      Something like the code below would work.

                      Warning! It's not perfect!

                      It would also remove graphic frames where graphic frames with images are pasted inside!

                       

                      ( function()
                      {
                      
                      app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
                      
                      app.doScript
                      (
                      
                          removeEmptyFramesInTablesOfDoc,
                          ScriptLanguage.JAVASCRIPT,
                          [],
                          UndoModes.ENTIRE_SCRIPT,
                          "Remove Empty Frames in Tables of Document | SCRIPT"
                      
                      );
                      
                      function removeEmptyFramesInTablesOfDoc()
                      {
                      
                          var doc = app.documents[0];
                          var cellsArray = doc.stories.everyItem().tables.everyItem().cells.everyItem().getElements();
                          var cellsArrayLength = cellsArray.length;
                      
                          var resultsArray = [];
                          var e;
                      
                          for( var n=0;n<cellsArrayLength;n++ )
                          {
                              // allPageItems would include also nested contents, like page items in tables nested in tables:
                              var allItems = cellsArray[n].allPageItems;
                              var allItemsLength = allItems.length;
                             
                              for( var a=0; a<allItemsLength; a++ )
                              {
                                  // Perhaps also exlude other objects as well like Button, MultiStateObject …
                                  if( allItems[a].constructor.name == "Group" ){ continue };
                                  if( !allItems[a].hasOwnProperty("graphics") ){ continue };
                                 
                                  if( allItems[a].graphics.length == 0)
                                  {
                                      resultsArray[resultsArray.length++] = allItems[a];
                                  };
                              }
                          };
                      
                          for( var n=0; n<resultsArray.length; n++ )
                          {
                              // resultsArray[n].fillColor = "Magenta";
                              try{ resultsArray[n].remove() }catch(e){ /* $.writeln( n +"\t"+ e.message ) */};
                          };
                      
                      };
                      
                      }() )
                      

                       

                      Before:

                       

                      Before-Running-Script-RemoveEmptyFramesInTables.PNG

                       

                      After:

                      The pasted in graphic is still a problem!!

                      The parent frame should not be removed.

                       

                      After-Running-OwnScript-RemoveEmptyFramesInTables.PNG

                       

                      Regards,
                      Uwe

                      • 8. Re: Delete empty graphics frames inside table
                        Laubender Adobe Community Professional & MVP

                        Ah. Found a solution and changed the for loop where I remove the object to that:

                         

                        for( var n=0; n<resultsArray.length; n++ )
                        {
                            // Test for allGraphics array of individual object:
                            if( resultsArray[n].allGraphics.length > 0 ){ continue };
                            try{ resultsArray[n].remove() }catch(e){ /* $.writeln( n +"\t"+ e.message ) */};
                        };
                        

                         

                        Regards,
                        Uwe

                        • 9. Re: Delete empty graphics frames inside table
                          Peter Kahrel Adobe Community Professional & MVP

                          Interesting, different approaches.

                           

                          To find empty graphic frames of any embedded depth, keep testing its parent's constructor until it's Cell or Document. If it's Document the page item is not in a cell. Pasted graphics aren't deleted, by the way.

                           

                          function inCell (frame) {
                            var p = frame.parent;
                            while (!(p instanceof Document || p instanceof Cell)) {
                              p = p.parent;
                            }
                            return p instanceof Cell;
                          }
                          
                          
                          r = app.documents[0].allPageItems; 
                          for (i = r.length-1; i >= 0; i--) { 
                            if (r[i].hasOwnProperty('graphics') && inCell (r[i]) && r[i].graphics.length == 0) { 
                              r[i].remove(); 
                            } 
                          }
                          

                           

                          Because of JavaScript's short-circuit evaluation, you can speed up the script (any script) by rearranging the three coordinated tests. (Short-circuit evaluation means that if the first test fails, following tests aren't done.) If very few page items are in cells, then it makes sense first to test whether any page item is in a cell: if a frame is not in a cell, the two other tests are done. And if very few frames are empty, then first test whether any frame has a graphic.

                           

                          P.

                          • 10. Re: Delete empty graphics frames inside table
                            Laubender Adobe Community Professional & MVP

                            Hi Peter,

                            I would add a fourth condition just at the start of the if condition:

                             

                            if ( r[i].isValid && r[i].hasOwnProperty('graphics') && inCell (r[i]) && r[i].graphics.length == 0 )
                            { 
                                r[i].remove();
                            }
                            

                             

                            With nested structures it could be that a item does not exist anymore because the parent item was already removed.

                            Tested that with my sample and it was necessary to avoid an error message.

                             

                            Regards,
                            Uwe

                            • 11. Re: Delete empty graphics frames inside table
                              Peter Kahrel Adobe Community Professional & MVP

                              Sure. Always a wise precaution.

                               

                              P.