1 2 Previous Next 41 Replies Latest reply: Jan 21, 2015 5:37 AM by Colin Flashman RSS

    cleaning up text frames

    winterm Community Member

      hello all you smart guys.

       

      I get a big complex files from another designers every month for further processing. Among other not-so-good habits, they usually do not use layers.

      To make layout a bit more organized, I move text to its own layer - simple task, have script for it. But it does the job straightforward - exactly 'as advertised' (Jongware's expression - I like it so )

       

      Unfortunately, those designers didn't bother much with 'frame content' option. They can draw a frame with a text tool, fill it with color and use it as a background for some artwork or whatever...

      my script 'text frames to separate layer' creates a mess on such pages, and locate it - not always is an easy task. Document usually has over 200 pages...

       

      So, I'm dreaming about some magic script, which is able to "prepare" text for moving, I mean, to find and process:

       

      case1: empty text frame with no fill/outline - remove (delete)

      case2: empty text frame with any fill/outline - convert to 'unassigned'

      case3: text frame with the same color applied to text and the frame itself (yes, it happens!) - well, maybe just 'select and stop'? I'm afraid it's too complicated to remove text from such a frame and then treat the frame as 'case2'?

       

      any suggestions would be greatly appreciated...

        • 1. Re: cleaning up text frames
          Colin Flashman Community Member

          not sure myself, but have you checked this thread?

           

          http://forums.adobe.com/message/3306350

          • 2. Re: cleaning up text frames
            winterm Community Member

            thank you for your reply, I see my fault now - I didn't mention, I'm on PC, ID 7.5.2 (CS5.5), so java is preferable...

             

            anyway, this one

            http://forums.adobe.com/message/2291359#2291359

            is closer to my needs, but in both threads guys are talking about "deleting empty text frames" - that's not the biggest part for me...

             

            my main problem is, that not all frames, which content marked as "text", are really text.

            What I really need is proper content marking.

             

            Let's say, you draw a box with text tool, fill it with a some color, maybe even tap spacebar inside that frame inadvertently... and use that "text frame" as a background for your artwork.

            Later you send me that file for further processing, and:

            1) if I run script "remove empty text frames", I loose your "background" (if you didnt tap spacebar or whatever in it)

            or

            2) if I run script "move text frames to  layer" - I get your "text frame" (a.k.a. "background") all over the artwork and maybe real text frames...

            You keep your text layer above images, didn't you?

             

            It's a mess...

            • 3. Re: cleaning up text frames
              Nagaraj Muthu Community Member

              you need to check with textFrame properties.......

               

              if (myTextFrame.fillColor.name == None ) {

              alert("No Colors used");

              }

              else {

              alert("Colors applied on TextFrame);

              }

               

              try this..............

              • 4. Re: cleaning up text frames
                siva prasath Community Member

                use this script it will help to remove only the empty text frame

                 

                 

                var myDocument = app.activeDocument;
                var myStories = app.activeDocument.stories.everyItem().getElements();
                for (i = myStories.length - 1; i >= 0; i--){
                    var myTextFrames = myStories[i].textContainers;
                    for (j = myTextFrames.length - 1; j >= 0; j--)    {
                var stroke = myTextFrames[j].strokeWeight;
                var color = myTextFrames[j].fillColor.name;
                //alert (color)
                     if (myTextFrames[j].contents == "" && stroke == "0" && color == "None"){
                           //alert ("yes") 
                   myTextFrames[j].remove();
                        }
                    }
                }
                
                
                • 5. Re: cleaning up text frames
                  winterm Community Member

                  nice job, thank you!

                  your script nicely removes really empty text frames, which are just trash, in fact...

                  unfortunately, after this cleaning I still can't move remaining frames to their own layer - I still must find out the way to convert empty, but filled/outlined text frames to "unassigned" first...

                  • 6. Re: cleaning up text frames
                    Laubender MVP

                    @winterm:
                    You can try this using script menu actions. This will only work, if the certain menu action is available.
                    It is not available if there is contents in the text frame (e.g. a blank character) or (much more important from a scripters point of view) if a threaded text frame is empty because it's contents cannot fit inside it and it's contents is an empty string.

                     

                    Following code will single out empty text frames, select them and invoke a script menu action to set them to "Unassigned":

                     

                    var _d = app.documents[0];
                    var _allStories = _d.stories;
                    
                    
                    for(var n=_allStories.length-1;n>=0;n--){
                        var _storyAllTextFrames = _allStories[n].textContainers;
                    
                        for(var m=_storyAllTextFrames.length-1;m>=0;m--){
                            //If the contents of a text frame is an empty string:
                            if(_storyAllTextFrames[m].contents === ""){
                                _storyAllTextFrames[m].select();
                                //Convert frame to "Unassigned":
                                try{
                                app.scriptMenuActions.itemByID(11297).invoke();
                                    }catch(e){};
                                };
                            };
                        };
                    
                    //Trick to deselect the last selection
                    //Add a new textFrame, select and remove it:
                    var _tempTextFrame = _d.textFrames.add();
                    _tempTextFrame.select();
                    _tempTextFrame.remove();
                    

                     

                    @all: If there is a better way to deselect a selection please give an example…

                     

                    Uwe

                    • 7. Re: cleaning up text frames
                      Marijan Tompa [tomaxxi] UGM-MVPs

                      Hi Winterm,

                       

                      I've corrected Uwe's script a little bit.

                      There is "contentType" property for text frame that can be changed.

                       

                      var _d = app.documents[0],
                          _allStories = _d.stories;
                      
                      for (var n = _allStories.length - 1; n >= 0; n--){
                          var _storyAllTextFrames = _allStories[n].textContainers;
                          for (var m = _storyAllTextFrames.length - 1; m >= 0; m--){
                              if (_storyAllTextFrames[m].contents === "")
                                  _storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
                          }
                      }
                      

                       

                      Uwe,

                       

                      To clear selection you can simply do this:

                       

                      app.select(null);
                      

                       

                      or a little bit more complex:

                       

                      app.select(NothingEnum.NOTHING);
                      

                       

                      Hope that helps.

                       

                      --

                      Marijan (tomaxxi)

                      http://tomaxxi.com

                      • 8. Re: cleaning up text frames
                        [Jongware] MVP

                        1. Use ContentType:

                         

                         

                        contentTypeContentType:
                        ContentType.UNASSIGNED
                        ContentType.GRAPHIC_TYPE
                        ContentType.TEXT_TYPE
                        r/wThe type of content that a frame can contain.

                         

                         

                        _storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
                        

                         

                        2. Use app.select:

                         

                        void select (selectableItems: varies[, existingSelection: SelectionOptions=SelectionOptions.REPLACE_WITH])
                        Selects the specified object(s).

                        ParameterTypeDescription
                        selectableItemsArray of Objects
                        NothingEnum
                        Object
                        SelectAll
                        The objects to select. Can accept: Object, Array of Objects, NothingEnum enumerator or SelectAll enumerator.
                        existingSelectionSelectionOptions:
                        SelectionOptions.ADD_TO
                        SelectionOptions.REMOVE_FROM
                        SelectionOptions.REPLACE_WITH
                        The selection status of the Application in relation to previously selected objects. (Optional) (default:SelectionOptions.REPLACE_WITH)

                         

                         

                        app.select(NothingEnum.NOTHING);
                        

                         

                        (Edit: Hi Marijan!)

                        • 9. Re: cleaning up text frames
                          Laubender MVP

                          Thank you, Marijan & Jongware to point to the right property "contentType" and to app.select(null).

                          I think the line:

                           

                          _storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
                          


                          needs a try-catch-wrapper:

                           

                          try{
                              _storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
                              }catch(e){};
                          

                           

                          It could be that a threaded text frame has no contents because the contents is too big to fit inside.
                          contents === "" will perfectly match such an empty text frame, but you cannot asign a new contentType to it.
                          See my screen shot:

                          ContentsOfThreadedTextFrameIsEmptyString.png

                           

                          Uwe

                          • 10. Re: cleaning up text frames
                            winterm Community Member

                            Many thanks to all you, guys, for your so elegant solutions. Reading your codes, I can see how and why it works, but couldn't write something similar for ages...

                            So far I did "field testing" for Uwe's code, and it fits perfectly my needs in "case 2". Sometimes I get shapes, copy-pasted from Illustrator, and with content type: text applied in Id... Uwe's script fixes them back to "unassigned" too! Very nice.

                            I think so far I'll add Marijan's line for clearing selection (it's not so critical for practical purposes, though. It's just elegant) and some simple alert at the end - something like "job is done"...

                            Oh, and I need another free day to study Marijan's & Jongware's solutions - it's a valuable school to me and other fresh people here at forum. Thank you!

                            • 11. Re: cleaning up text frames
                              winterm Community Member

                              Ah, and recently I realized there is just another way to deselect after the script is done...

                              Laubender, its your way - calling Menu Action item by ID!

                              I just duplicated this piece of your script:

                               

                              try{
                                          app.scriptMenuActions.itemByID(11297).invoke();
                                              }catch(e){};
                              

                              and changed ID to 278 - it stands for "Deselect All" and does the trick too

                              • 12. Re: cleaning up text frames
                                Antoys Community Member

                                Hi, im working on something right now, but i just could get a script that deletes a textframe with multiple blank character/spaces. I need help. thanks in advance..

                                • 13. Re: cleaning up text frames
                                  RobertKyle Community Member

                                  "Empty" text frame that actually contained blank spaces were giving me headaches, until one of the grep experts around here mentioned that \S is grep for "not a space". So this:

                                   

                                  app.selection[0].contents.match(/\S/); // assuming that the selection is a text frame

                                   

                                  Returns null when the frame contains only spaces. Doesn't matter how many or what kind. If the result is something other than null, the frame has actual content.

                                  • 14. Re: cleaning up text frames
                                    Colin Flashman Community Member

                                    I think this is an awesome script for removing blank textboxes, but a forum on macscripter revealed a feature that, while it would rarely be used, would not be caught in this script, and that is any instance of a blank text box with no fill or stroke BUT contained a text-wrap for whatever reason (e.g. to move an object or nudge text in a "cheat's" fashion)

                                     

                                    http://macscripter.net/viewtopic.php?id=19953

                                     

                                    I have tried changing these lines:

                                     

                                    var color = myTextFrames[j].fillColor.name;

                                    //alert (color)

                                         if (myTextFrames[j].contents == "" && stroke == "0" && color == "None"){

                                     

                                    to

                                     

                                    var color = myTextFrames[j].fillColor.name;

                                    var wrap = myTextFrames[j].TextWrapModes.name;

                                    //alert (color)

                                         if (myTextFrames[j].contents == "" && stroke == "0" && color == "None" && wrap == "None"){

                                     

                                    but it errors. can anybody point out what I've done wrong?

                                    • 15. Re: cleaning up text frames
                                      Laubender MVP

                                      @Robert – I did not test that, but there might be a special occasion like the following one:

                                       

                                      After a data merge with empty fields there is a special character inserted in the process: <FEFF>. And that character is not seen as whitespace in the GREP impementation of InDesign (UI).

                                       

                                      So I foresee a case where an otherwise empty text frame with a <FEFF> character is not considered as "empty".

                                       

                                      See the following thread in the InDesign forum:

                                       

                                      LinaD36

                                      Multiple record data merge into paragraph styles-applies the wrong style

                                       

                                      http://forums.adobe.com/thread/1341730?tstart=0

                                       

                                      And my script snippet to remove "<FEFF>" in the same thread:

                                      http://forums.adobe.com/message/5883785#5883785

                                       

                                      If you want to spot that <FEFF> character, also see:

                                       

                                      Michael Gianino

                                      Data Merge Invisibles

                                       

                                      http://forums.adobe.com/message/3614180#3614180

                                       

                                      Answer by John Hawkinson (with a script snippet to eliminate all <FEFF> characters):

                                      http://forums.adobe.com/message/3615031#3615031

                                       

                                      I tested John's snippet on some material by LinaD36 and had some problems with it.
                                      But this is another story…

                                       

                                      Conclusion of this case (so far I can see):
                                      Only a TEXT search/replace action can reliably eliminate <FEFF>.

                                       

                                      I think we have to look for <FEFF> and add it to the whitespace case…

                                       

                                      Uwe

                                      • 16. Re: cleaning up text frames
                                        Colin Flashman Community Member

                                        As I mentioned, I'm trying to improve on the script so that any text box with no fill or stroke BUT with a text-wrap doesn't get deleted. I've modded the script in the following way:

                                         

                                        var stroke = myTextFrames[j].strokeWeight;

                                        var color = myTextFrames[j].fillColor.name;

                                        var wrap = myTextFrames[j].textWrapPreferences.textWrapMode;

                                        //alert (color)

                                             if (myTextFrames[j].contents == "" && stroke == "0" && color == "None" && wrap == "None"){

                                                   //alert ("yes")

                                           myTextFrames[j].remove();

                                         

                                        but now when running the script, nothing is deleted, including the empty textboxes with no fill, stroke or textwrap. what have I missed?

                                        • 17. Re: cleaning up text frames
                                          Laubender MVP

                                          @Colin – at first glance, textWrapMode cannot be "None".

                                          That's a string.

                                          And you are asking for an enumeration.

                                           

                                          The answer in your case would be:

                                           

                                          TextWrapModes.NONE
                                          

                                           

                                          So, if you select a text frame, you could ask:

                                           

                                          var sel = app.selection[0];
                                          var wrap = sel.textWrapPreferences.textWrapMode;
                                          
                                          if(wrap === TextWrapModes.NONE){
                                              alert("textWrapMode: "+"\"NONE\"");
                                              };
                                          

                                           

                                          Did not further look into your code…

                                           

                                          Uwe

                                          • 18. Re: cleaning up text frames
                                            Colin Flashman Community Member

                                            Thank you for that Uwe. I've modded the script again but no joy. Here's what I have so far:

                                             

                                             

                                            var myStories = app.activeDocument.stories.everyItem().getElements();
                                            for (i = myStories.length - 1; i >= 0; i--){
                                                var myTextFrames = myStories[i].textContainers;
                                                for (j = myTextFrames.length - 1; j >= 0; j--)    {
                                            var stroke = myTextFrames[j].strokeWeight;
                                            var color = myTextFrames[j].fillColor.name;
                                            var wrap = myTextFrames[j].textWrapPreferences.textWrapMode;
                                            //alert (color)
                                                 if (myTextFrames[j].contents == "" && stroke == "0" && color == "None" && wrap === "TextWrapModes.NONE"){
                                                       //alert ("yes") 
                                               myTextFrames[j].remove();
                                                    }
                                                }
                                            }
                                            
                                            var _d = app.documents[0],
                                                _allStories = _d.stories;
                                            
                                            for (var n = _allStories.length - 1; n >= 0; n--){
                                                var _storyAllTextFrames = _allStories[n].textContainers;
                                                for (var m = _storyAllTextFrames.length - 1; m >= 0; m--){
                                                    if (_storyAllTextFrames[m].contents === "")
                                                        try{
                                                _storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
                                                }catch(e){};
                                                }
                                            }
                                            

                                             

                                             

                                            The original script earlier on in this thread worked in that it identified any text container that has no text, 0 stroke and None as the fill color. Anything meeting that criteria was deleted. Another sweep is done looking for any text container with no text, and that container is converted to unassigned

                                             

                                            However, the modified script should identifiy any text container that has no text, 0 stroke, None as the fill color, and no text wrap. Anything meeting that criteria should be deleted. Another sweep is done looking for any text container with no text, and that container should be converted to unassigned.

                                             

                                            Instead, all it doesn't delete anything and any text container with nothing inside it is converted to unassigned.

                                             

                                            Message was edited by: cdflash I've been using a testfile to determine if the script is working: https://dl.dropboxusercontent.com/u/55743036/empty%20textbox%20test.indd

                                            • 19. Re: cleaning up text frames
                                              Laubender MVP

                                              @Colin – don't know, if I have time to look into this more deeply today or the next days.

                                               

                                              Just looked at your if statement:

                                              You have to eliminate the quotes from TextWrapModes.NONE.

                                               

                                              TextWrapModes.NONE is no String Object. It's an Enumeration Object. If you wrap it in quotes like that: "TextWrapModes.NONE", ExtendScript will not recoginise it as an Enumerator.

                                               

                                              An Enumeration is a fixed feature baked in the DOM of InDesign.
                                              Instead of TextWrapModes.NONE you could also use it's number representation.

                                              In your case that would be the number: 1852796517

                                               

                                              So:

                                               

                                              wrap === TextWrapModes.NONE
                                              

                                               

                                              would be basically the same as:

                                               

                                              wrap === 1852796517
                                              

                                               

                                               

                                              You could look up all enumerations here (better use the chm-file representatons):

                                               

                                              http://www.jongware.com/idjshelp.html

                                               

                                              Or directly here (but it's more trouble to run a find action for a specific phrase or DOM object):

                                               

                                              http://jongware.mit.edu/idcs6js/

                                               

                                              Your specific case is here:

                                               

                                              http://jongware.mit.edu/idcs6js/pe_TextWrapModes.html

                                               

                                              Uwe

                                              • 20. Re: cleaning up text frames
                                                Laubender MVP

                                                @Colin – could you provide an IDML for download as well?

                                                 

                                                Uwe

                                                • 21. Re: cleaning up text frames
                                                  Colin Flashman Community Member

                                                  G'day there Uwe.

                                                   

                                                  That was all it was - take the quotes off of the TextWrapModes.NONE

                                                   

                                                  The revised line in the script should be:

                                                   

                                                   

                                                   
                                                  if (myTextFrames[j].contents == "" && stroke == "0" && color == "None" && wrap === TextWrapModes.NONE){
                                                  
                                                  
                                                  

                                                   

                                                  I have also added an IDML version of the file used to test this script.

                                                   

                                                  https://dl.dropboxusercontent.com/u/55743036/empty%20textbox%20test.idml

                                                   

                                                  Fixing empty textboxes has been a bugbear of mine for a while, and now the script is complete, I think I can safely move on!!!

                                                   

                                                  Thank you all for your help.

                                                   

                                                  Colin

                                                  • 22. Re: cleaning up text frames
                                                    Colin Flashman Community Member

                                                    ...the saga continues. I don't think Lord of the Rings went on for this long!

                                                     

                                                    Just found that this script - as great as it is - doesn't like text on paths. Reports an error on this line:

                                                     

                                                    Error 30476
                                                    Error String: The requested action could not be completed because the object no longer exists
                                                    
                                                    Source:   var myTextFrames=myStories[i]textContainers;
                                                    

                                                     

                                                    I've made a test script that now features text on paths.

                                                     

                                                    Also has an unwanted side effect: type on a path that is on a textbox that has no fill, stroke or textwrap will be deleted.

                                                     

                                                     

                                                    https://dl.dropboxusercontent.com/u/55743036/empty%20textbox%20test.idml

                                                     

                                                    Colly

                                                    • 23. Re: cleaning up text frames
                                                      Laubender MVP

                                                      @Colly – yeah, that's one of the pitfalls…
                                                      The textContainer class could point to textFrames and textPaths as well.

                                                       

                                                      So you have to implement another test, if a textFrame contains a textPath and if yes, if there is some contents there…

                                                       

                                                      Something around that code:

                                                       

                                                      //Naive tests, text frames could contain parts of a threaded table:
                                                      
                                                      //Case 1: No textPath on textFrame
                                                      if(
                                                          myTextFrame.contents === "" && 
                                                          myTextFrame.textPaths.length == 0
                                                          )
                                                      {
                                                          alert("Empty.");
                                                      };
                                                      
                                                      //Case 2: textPath on textFrame, check both for contents
                                                      if(
                                                          myTextFrame.contents === "" && 
                                                          myTextFrame.textPaths.length === 1 && 
                                                          myTextFrame.textPaths[0].texts[0].contents === ""
                                                          )
                                                      {
                                                          alert("Also Empty.");
                                                      };
                                                      

                                                       

                                                      Uwe

                                                      • 24. Re: cleaning up text frames
                                                        Colin Flashman Community Member

                                                        Thanks for that Uwe.

                                                         

                                                        Have amended my empty box cleaner... again! This one will catch all text frames, graphic frames or unassigned frames that are rectangles, ovals or polygons that have

                                                         

                                                        • no fill
                                                        • no stroke
                                                        • no textwrap
                                                        • no text on a path around it
                                                        • possible references to data merge fields that were empty

                                                         

                                                        and will delete them. Have made one sacrifice from the previous script - empty textboxes that were in threaded text were deleted in the old script, but in order to catch text on paths, have had to change from textContainers to textFrames as to avoid accidentally finding text that is on a path that is not a closed shape (i.e. a line). Code looks like this:

                                                         

                                                         

                                                        var myDoc = app.activeDocument;
                                                        app.findTextPreferences = app.changeTextPreferences = null; 
                                                        
                                                        app.findTextPreferences.findWhat = "<FEFF>"; 
                                                        app.changeTextPreferences.changeTo = "";
                                                        
                                                        myDoc.changeText();
                                                        
                                                        app.findTextPreferences = app.changeTextPreferences = null;
                                                        
                                                        
                                                        var myStories = app.activeDocument.stories.everyItem().getElements();
                                                        for (i = myStories.length - 1; i >= 0; i--){
                                                            var myTextFrames = myStories[i].textFrames;
                                                            for (j = myTextFrames.length - 1; j >= 0; j--)    {
                                                        var stroke = myTextFrames[j].strokeWeight;
                                                        var color = myTextFrames[j].fillColor.name;
                                                        var tpath = myTextFrames[j].textPaths.length;
                                                        var wrap = myTextFrames[j].textWrapPreferences.textWrapMode;
                                                        //alert (color)
                                                             if (myTextFrames[j].contents === "" && stroke == "0" && color == "None" && wrap === TextWrapModes.NONE && tpath == 0){
                                                                   //alert ("yes") 
                                                           myTextFrames[j].remove();
                                                                }
                                                            }
                                                        }
                                                        
                                                        var _d = app.documents[0],
                                                            _allStories = _d.stories;
                                                        
                                                        for (var n = _allStories.length - 1; n >= 0; n--){
                                                            var _storyAllTextFrames = _allStories[n].textContainers;
                                                            for (var m = _storyAllTextFrames.length - 1; m >= 0; m--){
                                                                if (_storyAllTextFrames[m].contents === "")
                                                                    try{
                                                            _storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
                                                            }catch(e){};
                                                            }
                                                        }
                                                        
                                                        var myGraphicFrames = app.activeDocument.rectangles;
                                                        for (i=myGraphicFrames.length-1; i>=0; i--) {
                                                        var stroke = myGraphicFrames[i].strokeWeight;
                                                        var color = myGraphicFrames[i].fillColor.name;
                                                        var tpath = myGraphicFrames[i].textPaths.length;
                                                        var wrap = myGraphicFrames[i].textWrapPreferences.textWrapMode;
                                                            if (myGraphicFrames[i].graphics.length < 1 && stroke == "0" && color == "None" && wrap === TextWrapModes.NONE && tpath == 0)
                                                                myGraphicFrames[i].remove();
                                                        }
                                                        
                                                        var myOvalFrames = app.activeDocument.ovals;
                                                        for (i=myOvalFrames.length-1; i>=0; i--) {
                                                        var stroke = myOvalFrames[i].strokeWeight;
                                                        var color = myOvalFrames[i].fillColor.name;
                                                        var tpath = myOvalFrames[i].textPaths.length;
                                                        var wrap = myOvalFrames[i].textWrapPreferences.textWrapMode;
                                                            if (myOvalFrames[i].graphics.length < 1 && stroke == "0" && color == "None" && wrap === TextWrapModes.NONE && tpath == 0)
                                                                myOvalFrames[i].remove();
                                                        }
                                                        
                                                        var myPolygonFrames = app.activeDocument.polygons;
                                                        for (i=myPolygonFrames.length-1; i>=0; i--) {
                                                        var stroke = myPolygonFrames[i].strokeWeight;
                                                        var color = myPolygonFrames[i].fillColor.name;
                                                        var tpath = myPolygonFrames[i].textPaths.length;
                                                        var wrap = myPolygonFrames[i].textWrapPreferences.textWrapMode;
                                                            if (myPolygonFrames[i].graphics.length < 1 && stroke == "0" && color == "None" && wrap === TextWrapModes.NONE && tpath == 0)
                                                                myPolygonFrames[i].remove();
                                                        }
                                                        

                                                         

                                                        Before I attempt to "crack the champagne" thinking that this is it... what other conditions might one find that deleting a blank box is actually catastrophic?

                                                         

                                                        Colly

                                                        • 25. Re: cleaning up text frames
                                                          Laubender MVP

                                                          @Colly – look at my screenshot in answer #9 of this thread. Yes, with threaded text frames there are constellations where the layout could change and overset text would be the result.

                                                           

                                                          Did I already mention tables, that run through more than one text frame?
                                                          Also, something one could consider; but maybe a bit nit-picking…

                                                           

                                                          Uwe

                                                          • 26. Re: cleaning up text frames
                                                            Colin Flashman Community Member

                                                            I think I might try something simpler next time... climbing Mt Everest perhaps.

                                                             

                                                            have made a testfile that I am sure covers any instance where a clear box should stay/be deleted: https://dl.dropboxusercontent.com/u/55743036/empty%20textbox%20test.idml

                                                             

                                                            the script so far leaves items mentioned by Uwe (tables that run through more than one text frame, and text boxes that have nothing in them due to overset text shifting the story onto the next textbox), and am glad to say also:

                                                             

                                                            • does not delete no fill/stroke/text items that are part of a group
                                                            • deletes no fill/stroke/text boxes that are anchored objects
                                                            • does not delete fill/stroke/text boxes that contain an anchored object.

                                                             

                                                            however, it did NOT delete graphic/unassigned rectangles/ovals/polygons that have no fill/stroke/textwrap/path on type that are anchored objects within a text frame.

                                                             

                                                            An old forum features a script from harbs (http://forums.adobe.com/message/2668865) that removes any no graphic/text anchored objects, but it's too powerful (will delete the anchored object even if it has a fill or stroke or wrap or text on path). I've since modded his script and added it to the one i've been developing. without placing the entire code, i'll just include the modded snippet:

                                                             

                                                             

                                                            var myDocument = app.activeDocument;
                                                            var inlines = myDocument.stories.everyItem().pageItems.everyItem().getElements();
                                                            while(fr=inlines.pop()){
                                                              if(fr instanceof Group){continue}
                                                              if(fr instanceof TextFrame){
                                                                if(fr.contents == "" && fr.strokeWeight == "0" && fr.fillColor.name == "None" && fr.textWrapPreferences.textWrapMode === TextWrapModes.NONE && fr.textPaths.length == 0){fr.remove()}
                                                                continue;
                                                              }
                                                              if(fr.graphics.length==0 && fr.strokeWeight == "0" && fr.fillColor.name == "None" && fr.textWrapPreferences.textWrapMode === TextWrapModes.NONE && fr.textPaths.length == 0){fr.remove()}
                                                            }
                                                            

                                                             

                                                            But as I look at this modded script, I have a feeling that if I made a copy of the script but replaced the line:

                                                             

                                                             

                                                            var inlines = myDocument.stories.everyItem().pageItems.everyItem().getElements();
                                                            

                                                             

                                                            and changed it to

                                                             

                                                             

                                                            var inlines = myDocument.stories.everyItem().getElements();
                                                            

                                                             

                                                            That resulting script would effectively do what the following portion of the script does, but with less syntax:

                                                             

                                                            var myStories = app.activeDocument.stories.everyItem().getElements();
                                                            for (i = myStories.length - 1; i >= 0; i--){
                                                                var myTextFrames = myStories[i].textFrames;
                                                                for (j = myTextFrames.length - 1; j >= 0; j--)    {
                                                            var stroke = myTextFrames[j].strokeWeight;
                                                            var color = myTextFrames[j].fillColor.name;
                                                            var tpath = myTextFrames[j].textPaths.length;
                                                            var wrap = myTextFrames[j].textWrapPreferences.textWrapMode;
                                                            //alert (color)
                                                                 if (myTextFrames[j].contents === "" && stroke == "0" && color == "None" && wrap === TextWrapModes.NONE && tpath == 0){
                                                                       //alert ("yes") 
                                                               myTextFrames[j].remove();
                                                                    }
                                                                }
                                                            }
                                                            

                                                             

                                                            is that correct?

                                                             

                                                            Colly

                                                            • 27. Re: cleaning up text frames
                                                              Laubender MVP

                                                              @Colly – I know I'm a little late for commenting your answer #26, but my answer is lengthy ;-)

                                                               

                                                              Your "condensed" version* of the script will do nothing (or at least not much), because:

                                                               

                                                              //EDIT: After re-reading the whole thread, I can see that this last snippet you posted in answer #26 is not your's. Sorry. However, I did the following test with that snippet.

                                                               

                                                              1. It does not work with the text container(s) of a particular story, but only with text frames that sit inside the text of the stories (anchored or inline text frames).

                                                               

                                                              I ran your script (slightly altered: instead of removing I did a fill with "Magenta") on the following situation:

                                                               

                                                              BeforeScript.png

                                                              After running the script:

                                                              (the Magenta filled ones would be removed)

                                                              AfterScript.png

                                                               

                                                              2. And even if this script would remove the two text frames hosting the anchored ones:

                                                              Text frames with tables that span several threaded text frames are considered empty but the one text frame that contains the start of the table.

                                                               

                                                              Let's test #2 on a small example with the following code that is running on a selection of text frames:

                                                               

                                                              //Some threaded text frames selected.
                                                              //They contain a table that spans several text containers.
                                                              
                                                              var sel = app.selection;
                                                              
                                                              //EASY TEST on emptyness with contents property:
                                                              
                                                              //Running the loop backwards in case we want to remove something
                                                              //and so mixing up the length of the
                                                              
                                                              for(var n=sel.length-1;n>=0;n--){
                                                                  if(sel[n].contents == ""){sel[n].fillColor = "Magenta"};
                                                                  };
                                                              

                                                               

                                                              Example screen shots:

                                                               

                                                              Before

                                                               

                                                              TableThreaded.png

                                                               

                                                              After running the above snippet:

                                                              The Magenta filled text frames are considered empty (as far as this script's logic is going)!

                                                              TextFramesToRemove_WRONG-ASSUMPTION.png

                                                               

                                                               

                                                              To tackle  problems #1 and also #2 we could:

                                                               

                                                              1. Work with the textContainers array of a story object.

                                                              That means we are working of an array of arrays, if the document contains more than one story.

                                                               

                                                              2. Duplicate all text frames or the parent of a text path (= a graphic line, a text frame, a spline item …) and check for emptyness of the duplicate and/or its text path.

                                                               

                                                              Background: if you duplicate a text frame containing one part of a table that is otherwise occupying a number of text frames and its contents property is suggesting it's empty, you'll get always that portion of the table, that is shown in the original text frame.

                                                               

                                                              Below a more elaborate code for detecting empty* text frames and removing them.

                                                               

                                                              However, there is one flaw in this code:

                                                              If it occurs, that a button object contains a state with empty text containers only, the whole button will or can be removed!
                                                              Depends on the number of states and if the removed object sits in an active state.

                                                               

                                                              Explanation: The Story object of the document is a deep-level object and the collection of all story objects will summerize every text frame or every text path in the document. Even in nested objects like groups, MSOs, etc. and well, also buttons.

                                                               

                                                              And there is another flaw (a tiny one), which I camouflaged with a "try/catch -> continue" scenario. Some objects might not exist anymore in the moment I want to remove them. I did not implement a optimization routine on double ID numbers of the array, that is responsible for removing the text containers or in case of text paths their parent objects.

                                                               

                                                              Warning: The script could create situations where text overflows like shown in answer #9 here.

                                                              There is no steady control of overflow during the script's action.

                                                               

                                                              Code:

                                                               

                                                              //REMOVE_EmptyTextContainers_DuplicateMethod_STORIES-TEXTCONTAINERS_v2.jsx
                                                              //Uwe Laubender
                                                              /**
                                                              * @@@BUILDINFO@@@ REMOVE_EmptyTextContainers_DuplicateMethod_STORIES-TEXTCONTAINERS_v2.jsx !Version! Sat Jan 04 2014 20:24:54 GMT+0100
                                                              */
                                                              
                                                              //THERE IS NO TEST ON EFFECTS !!
                                                              //Effects on otherwise empty objects are not visible. They need at least a stroke weight or a fill color to get in effect.
                                                              //If I'm wrong here, empty objects with visible effects are removed as well.
                                                              
                                                              //Foreseeable issues:
                                                              //BUTTONS COULD BE REMOVED, 
                                                              //if one of the states contain empty text frames only OR empty text paths on otherwise empty parent objects only!
                                                              
                                                              //MSOs WILL BE REMOVED (A MESSAGE WILL POP UP), 
                                                              //if the MSO's empty text frames are removed 
                                                              //and only one state would be left over
                                                              //however, all text frames with contents will survive!
                                                              
                                                              //WHAT IS NOT CONSIDERED EMPTY:
                                                              //1. Frames with a fillColor.name other than "None"
                                                              //2. Frames with a strokeWeight other than "0"
                                                              //3. Graphic lines with a text path with a strokeWeight other than "0"
                                                              //4. Text frames and text paths with a contents other than "".
                                                              
                                                              //ALL TEXTFRAMES OR TEXTPATHS ARE EXAMINED AS NOT THREADED.
                                                              
                                                              
                                                              app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
                                                              
                                                              app.doScript(_RemoveEmptyTextContainers, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Remove empty text containers");
                                                              
                                                              function _RemoveEmptyTextContainers(){
                                                              
                                                              var d=app.documents[0];
                                                              var counterOne = 0;
                                                              var counterTwo = 0;
                                                              
                                                              var IDsOfallTextContainers = new Array();
                                                              var IDsOfTextContainersToRemove = new Array();
                                                              
                                                              var arrayOfArraysOfTextContainers = d.stories.everyItem().textContainers;
                                                              
                                                              for(var n=0;n<arrayOfArraysOfTextContainers.length;n++){
                                                              
                                                                  var arrayOfTextContainers = arrayOfArraysOfTextContainers[n];
                                                                  for(c=0;c<arrayOfTextContainers.length;c++){
                                                              
                                                                      IDsOfallTextContainers[counterOne] = arrayOfTextContainers[c].getElements()[0].id;
                                                                      ++counterOne;
                                                              
                                                                      };
                                                                  };
                                                              
                                                              for(var n=0;n<IDsOfallTextContainers.length;n++){
                                                              
                                                                  var myOriginal = d.pageItems.itemByID(IDsOfallTextContainers[n]).getElements()[0];
                                                                 $.writeln(myOriginal);
                                                              
                                                                  //Here is more testing on "emptyness" needed:
                                                              
                                                                  //Whitespace in contents
                                                                  //. . . ???
                                                                  //Column breaks, page breaks in contents
                                                              
                                                                  //Overset text possible !!!
                                                              
                                                                  //Case 1: myOriginal is textFrame
                                                              
                                                                  if(myOriginal.constructor.name === "TextFrame"){
                                                              
                                                                      var myDup = myOriginal.duplicate();
                                                              
                                                                      if(
                                                                                myDup.contents === "" 
                                                                          && myDup.fillColor.name === "None" 
                                                                          && myDup.strokeWeight === 0 
                                                                          && myDup.textWrapPreferences.textWrapMode === TextWrapModes.NONE
                                                                          ){
                                                                          IDsOfTextContainersToRemove[counterTwo] = myOriginal.id;
                                                                          };
                                                              
                                                                      ++counterTwo;
                                                              
                                                                      myDup.remove();
                                                                      };
                                                              
                                                                  //Case 2: myOriginal is textPath
                                                                  if(myOriginal.constructor.name === "TextPath"){
                                                              
                                                                      var myDup = myOriginal.parent.duplicate();
                                                              
                                                                      if(
                                                                          myDup.textPaths[0].contents === "" 
                                                                          && myDup.constructor.name === "GraphicLine"
                                                                          && myDup.strokeWeight === 0
                                                                          && myDup.textWrapPreferences.textWrapMode === TextWrapModes.NONE
                                                                          ){
                                                                          IDsOfTextContainersToRemove[counterTwo] = myOriginal.id;
                                                                          ++counterTwo;
                                                                          };
                                                              
                                                                      if(
                                                                          myDup.textPaths[0].contents === "" 
                                                                          && myDup.constructor.name != "GraphicLine"
                                                                          && myDup.strokeWeight === 0
                                                                          && myDup.fillColor.name === "None"
                                                                          && myDup.textWrapPreferences.textWrapMode === TextWrapModes.NONE
                                                                          ){
                                                                          IDsOfTextContainersToRemove[counterTwo] = myOriginal.id;
                                                                          ++counterTwo;
                                                                          };
                                                              
                                                                      myDup.remove();
                                                              
                                                                      };
                                                              
                                                                  };
                                                              
                                                              //Array could be optimized for removing doubles in ID numbers:
                                                              
                                                              for(var n=0;n<IDsOfTextContainersToRemove.length;n++){
                                                              
                                                                      try{
                                                                      d.pageItems.itemByID(IDsOfTextContainersToRemove[n]).remove();
                                                                      }catch(e){
                                                              //~             $.writeln(e.message);
                                                                          continue;
                                                                          };
                                                              
                                                                  };
                                                              
                                                              
                                                              }; //END of function _RemoveEmptyTextContainers()
                                                              

                                                               

                                                              Uwe

                                                               

                                                              Message was edited by: Laubender

                                                              • 28. Re: cleaning up text frames
                                                                Laubender MVP

                                                                I updated the post above.

                                                                 

                                                                Uwe

                                                                • 29. Re: cleaning up text frames
                                                                  Laubender MVP

                                                                  An annotation to post #27 – the first situation where an empty text frame is anchored to an otherwise empty text frame.

                                                                   

                                                                  BeforeScript.png

                                                                   

                                                                  It's more tricky, than I first thought ;-)

                                                                   

                                                                  If the anchored text frame is removed, the host is considered empty, but might not be removed. It depends on the order of detecting empty frames and the order of removing them.

                                                                   

                                                                  So in a situation like this:

                                                                   

                                                                  AnchoredTextFrames_WithAnchoredOnes.png

                                                                   

                                                                  It might be better to do a search from a deeper level of nesting to not nested.

                                                                  A lot of effort.


                                                                  Or the user (or the script) is running the script more than once. Perhaps with in a while loop until no empty frame is found.

                                                                   

                                                                  Uwe

                                                                   

                                                                  Message was edited by: Laubender

                                                                  • 30. Re: cleaning up text frames
                                                                    Laubender MVP

                                                                    And we should think about: is it desirable to remove empty inline text frames at all?
                                                                    Text composition will be changed, if we do so.

                                                                     

                                                                    TextCompositionAndInlineTextFrames.png

                                                                     

                                                                    Uwe

                                                                     

                                                                    //EDIT: the previous version did not show inline text frames but inline rectangles

                                                                     

                                                                    Message was edited by: Laubender

                                                                    • 31. Re: cleaning up text frames
                                                                      Laubender MVP

                                                                      Here a test of anchoredness on an object by Hans-Gerd Claßen at:

                                                                       

                                                                      http://forums.adobe.com/message/4745348#4745348

                                                                       

                                                                      I just added a try/catch for objects that are not anchored at all:

                                                                       

                                                                      //NotAnchored_ANCHORED_Inline_Above_Custom_TEST-ON-SELECTION.jsx
                                                                      //Hans-Gerd Claßen
                                                                      //http://forums.adobe.com/message/4745348#4745348
                                                                      
                                                                      //TEST ON A SELECTION OF A SINGLE OBJECT:
                                                                      var myObject = app.selection[0];
                                                                      
                                                                      //Uwe Laubender
                                                                      //Try/catch added for examples that are not anchored at all:
                                                                      
                                                                      try{
                                                                      myObject.anchoredObjectSettings.anchoredPosition;
                                                                      }catch(e){
                                                                          alert("Not anchored!");
                                                                          exit();
                                                                          };
                                                                      
                                                                      var myAnchorPosition = myObject.anchoredObjectSettings.anchoredPosition;
                                                                      
                                                                      switch(myAnchorPosition)
                                                                      {
                                                                      case AnchorPosition.INLINE_POSITION:
                                                                          alert("Inline");
                                                                           // get inline settings
                                                                          break;
                                                                      
                                                                      case AnchorPosition.ABOVE_LINE:
                                                                          alert("Above");
                                                                           // get above line settings
                                                                          break;
                                                                      
                                                                      case AnchorPosition.ANCHORED:
                                                                          alert("Custom");
                                                                           // get custom settings
                                                                          break;
                                                                      
                                                                      default :     break;
                                                                      }
                                                                      

                                                                       

                                                                      To continue what I said in the post above: we could well  leave empty text frames untouched that are anchored with:

                                                                      "INLINE_POSITION" or "ABOVE_LINE"

                                                                       

                                                                      Uwe

                                                                      • 32. Re: cleaning up text frames
                                                                        Colin Flashman Community Member

                                                                        Thank you for all your efforts Uwe. I am beginning to think that I have opened Pandora's Box (or Frame) here.

                                                                         

                                                                        The concept started out simply enough, any empty text box should be deleted.

                                                                        Then it became any empty text box with no fill or stroke should be deleted.

                                                                        Then it became any empty text box with no fill or stroke or text wrap or type on a path or empty data merge legacy should be be deleted.

                                                                        Then it became any empty text box with no fill or stroke or text wrap or type on a path or empty data merge legacy or  that may/may not be an anchored object or within an anchored object or inline graphic should be be deleted.

                                                                        THEN the script... blah blah blah... and also looked for not just text frames, but graphic and unassigned frames of any shape...

                                                                         

                                                                        And now of course the use I had not considered - multi-state objects or buttons... *sigh*

                                                                         

                                                                        The list of scenarios where an empty text frame may have an alternate use is growing larger and larger. There are also scenarios where the removal of an empty text frame are subjective. An example is post 30 of this thread where empty boxes were used to indent text instead of adjusting the first line indent in the paragraph palette. In that instance I would agree that the script should leave those boxes alone, however if the script was used to tidy up a catalogue created using data merge, then I would argue that the script should remove those boxes. If a situation arose where both phenomena existed in the same file, then I put my head in my hands and cry.

                                                                         

                                                                        To that degree I'm satisfied with the script that is cobbled together at the moment: https://dl.dropboxusercontent.com/u/55743036/emptyframeremover.jsx for dealing with print purpose files, given that it successfully removes the text boxes in this test file that should be deleted with the exception of threaded text that I would like left alone: https://dl.dropboxusercontent.com/u/55743036/empty%20textbox%20test.idml . I would like to try this script on the snippets in your last posts, are you able to PM me with links to those files?

                                                                        • 33. Re: cleaning up text frames
                                                                          Laubender MVP

                                                                          @Colly – Indeed: Pandora's Box ;-)

                                                                           

                                                                          Here a link to my InDesign/IDML file:

                                                                           

                                                                          https://www.dropbox.com/s/ar7w9sja4bp9433/E2-TextFramesOfAnySort_AlsoNested.zip

                                                                           

                                                                          E2-TextFramesOfAnySort_AlsoNested.zip

                                                                           

                                                                              E2-TextFramesOfAnySort_AlsoNested.indd

                                                                              E2-TextFramesOfAnySort_AlsoNested.idml

                                                                           

                                                                          Of course, I'm not sure, if all *critical* cases are covered ;-)

                                                                           

                                                                          Uwe

                                                                          • 34. Re: cleaning up text frames
                                                                            Colin Flashman Community Member

                                                                            Thank you for your test file Uwe. I have run my cobbled together script on the file and am satisfied with the results. Buttons and MSOs were left alone; grouped objects were not touched; empty inlines within other empty inlines were deleted, and threaded text was ONLY deleted if (within the entire threaded story) there is no text... otherwise the threaded frames remain... but I can live with that. Whether it fulfils the requirements of anyone else is subjective, but for my purposes it does what it needs to do... until further texting reveals more bugs

                                                                             

                                                                            Colin

                                                                            • 35. Re: cleaning up text frames
                                                                              winterm Community Member

                                                                              @ cdflash

                                                                              @ Laubender

                                                                               

                                                                              very impressive!

                                                                              thank you both for your valuable input and... sharing.

                                                                              the thread is pretty old and was marked as answered years ago, so I just marked as helpful some of "key points"...

                                                                               

                                                                              thanks again,

                                                                              respectfully -

                                                                                        winterm

                                                                               

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

                                                                              just one small addition: for my needs it’s also safe to delete text frames, containing non-printing characters only. Maybe not a good idea always and for everyone, but I consider them as 'empty', so added at the beginning of Your script this:

                                                                               

                                                                              app.findGrepPreferences.findWhat = „\\A\\s+\\Z”;

                                                                              app.changeGrepPreferences.changeTo = „”;

                                                                              app.activeDocument.changeGrep();

                                                                              app.findGrepPreferences = app.changeGrepPreferences = null;

                                                                               

                                                                              Message was edited by: winterm

                                                                              • 36. Re: cleaning up text frames
                                                                                Laubender MVP

                                                                                @Winterm – just a small thing.
                                                                                I found it valuable to write my GREPs this way:

                                                                                 

                                                                                app.findGrepPreferences.findWhat = /\A\s+\Z/.source;
                                                                                

                                                                                 

                                                                                Don't know, if I saw it the first time with a script by John Hawkinson or Peter Kahrel…

                                                                                Very handy, you need not to escape the \ signs.

                                                                                 

                                                                                Also generally good for strings like that:

                                                                                 

                                                                                alert( /He said: "What should I say? It works…"/.source );
                                                                                

                                                                                 

                                                                                Uwe

                                                                                • 37. Re: Re: cleaning up text frames
                                                                                  Colin Flashman Community Member

                                                                                  Despite a year of having the script and looking like it was working flawlessly, I have discovered two problems with it:

                                                                                   

                                                                                  1) If there are no text boxes in the script at all, it throws up this error

                                                                                   

                                                                                  Screen Shot 2015-01-21 at 10.39.45 pm.png

                                                                                   

                                                                                  That particular piece of code has to deal with the handling of inline graphics. I think I know the cause, and that is there is no else statement in the function to say "if there is no text frames at all, then do nothing". The code currently looks like this:

                                                                                   

                                                                                  var inlines = myDocument.stories.everyItem().pageItems.everyItem().getElements();
                                                                                  while(fr=inlines.pop()){
                                                                                    if(fr instanceof Group){continue}
                                                                                    if(fr instanceof TextFrame){
                                                                                      if(fr.contents == "" && fr.strokeWeight == "0" && fr.fillColor.name == "None" && fr.textWrapPreferences.textWrapMode === TextWrapModes.NONE && fr.textPaths.length == 0){fr.remove()}
                                                                                      continue;
                                                                                    }
                                                                                    if(fr.graphics.length==0 && fr.strokeWeight == "0" && fr.fillColor.name == "None" && fr.textWrapPreferences.textWrapMode === TextWrapModes.NONE && fr.textPaths.length == 0){fr.remove()}
                                                                                  }
                                                                                  
                                                                                  

                                                                                   

                                                                                  How would I add that else statement to this function?

                                                                                   

                                                                                  2) The script will remove frames that have frames within them. Let me demonstrate. In this screen capture, there are typically three kinds of frames in InDesign - unassigned, graphic and text.

                                                                                  Screen Shot 2015-01-21 at 10.46.51 pm.png

                                                                                  However, when I paste a triangle drawn in indesign into a rectangle using "paste into", or a picture inside a frame into a frame (again using paste into), it doesn't seem to fall into any of these categories.

                                                                                  Screen Shot 2015-01-21 at 10.49.37 pm.png

                                                                                   

                                                                                  So this is fouling up a part of my script that searches for all rectangles, ovals and polygons looking for no stroke/fill/text on paths/text wrap. The function is written three times, once for rectangles, once for ovals, once for polygons. Here is the sample for rectangles:

                                                                                   

                                                                                  var myGraphicFrames = app.activeDocument.rectangles;
                                                                                  for (i=myGraphicFrames.length-1; i>=0; i--) {
                                                                                  var stroke = myGraphicFrames[i].strokeWeight;
                                                                                  var color = myGraphicFrames[i].fillColor.name;
                                                                                  var tpath = myGraphicFrames[i].textPaths.length;
                                                                                  var wrap = myGraphicFrames[i].textWrapPreferences.textWrapMode;
                                                                                      if (myGraphicFrames[i].graphics.length < 1 && stroke == "0" && color == "None" && wrap === TextWrapModes.NONE && tpath == 0)
                                                                                          myGraphicFrames[i].remove();
                                                                                  }
                                                                                  
                                                                                  

                                                                                  What am I missing that would be able to identify these frames as having content and leave them alone?

                                                                                   

                                                                                  Colin

                                                                                  • 38. Re: Re: cleaning up text frames
                                                                                    winterm Community Member

                                                                                    There is part 2 of this thread...

                                                                                    Cleaning up (not only) text frames, Pt. 2

                                                                                     

                                                                                    I believe, some problems solved there...

                                                                                    • 39. Re: cleaning up text frames
                                                                                      Colin Flashman Community Member

                                                                                      Thank you winterm, looks like you encountered exactly the same problem that I faced today. Great that there is a fix though.

                                                                                       

                                                                                      With the more minor issue of the error being thrown when there is no text boxes in the document, is there any way that this issue can be resolved? It's unlikely that the script would be run without text being in a document somewhere, but if it can be fixed, then i'd like to fix it.

                                                                                       

                                                                                      Colin

                                                                                      1 2 Previous Next