21 Replies Latest reply on Jul 31, 2014 1:30 PM by Teetan VK

    Why mFound = mTarget.findGrep() not work on cs5.5?

    Teetan VK Level 1

      Hi, everyone

       

      I got this script:

       

      app.doScript('main()', ScriptLanguage.JAVASCRIPT, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "grow numbers on masters"); 

      function main() { 

        catchOption = app.findChangeGrepOptions.includeMasterPages; 

        app.findChangeGrepOptions.includeMasterPages = true; 

        app.findGrepPreferences = changeGrepPreferences = null; 

        app.findGrepPreferences.findWhat = "\\b20\\d+\\b"; 

       

      var 

        mTarget = app.documents.everyItem().masterSpreads.everyItem().textFrames.everyItem(), 

        mFound = mTarget.findGrep(), 

        mConFound = [], 

        len = mFound.length; 

       

        if (len && mFound[0].constructor.name == "Array") 

             while (len-->0) 

                  mConFound = mConFound.concat(mFound[len]); 

       

        len = mConFound.length; 

        while (len-->0) { 

             mConFound[len].contents = String(Number(mConFound[len].contents) + 1); 

        } 

        app.findChangeGrepOptions.includeMasterPages = catchOption; 

      }

       

      it works very fine in the cs6, but not work in cs5.5

       

      I don't know why

       

      and you?

       

      Teetan

        • 1. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
          Jump_Over Level 5

          Hi Teetan,

          it works very fine in the cs6, but not work in cs5.5

           

          What "not work" does mean?

          • does not find any occurence?
          • does return an error?
          • does not work "undo"?

           

          Jarek

          • 2. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
            Teetan VK Level 1

            Hi, Jarek

             

            it seems like cs5.5 not support mTarget

             

            I don't know, but the error source is mTarget

             

            Teetan

            • 3. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
              Jump_Over Level 5

              It works on CS 5 on my side, so would be strange if only CS5.5 is a problem.

              Check a "small" details on your side, pls.

               

              Jarek

              • 4. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                Laubender Adobe Community Professional & MVP

                Hi, Teetan!
                I tested on a simple example with my InDesign CS5.5 on Mac OSX 10.7.5. The script is working…

                 

                Uwe

                • 5. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                  Teetan VK Level 1

                  Hi, Jarek

                   

                  tonight I will check

                   

                  because, only my company has cs5.5 version

                   

                  my be cs5.0

                   

                  I am not sure

                   

                  but relly got an error about mTarget

                   

                  Teetan

                  • 6. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                    Laubender Adobe Community Professional & MVP

                    However, as I already said somewhere else, it is only working on first level text frames.
                    Will "fail" silently, if the text frames are nested. "Fail" is the wrong expression here, because the script will target only first level text frames.

                     

                    @Teetan – Could you provide the *exact* error message here?
                    Also a simple IDML and/or InDesign file zipped for download where the script is missing?
                    (Might be a link to a Dropbox account or a similar service.)

                     

                    Uwe

                    • 7. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                      Teetan VK Level 1

                      Hi Jarek

                       

                      the error screen shot

                       

                      script error.jpg

                      • 8. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                        Teetan VK Level 1

                        I don't how to attatch a file

                        • 10. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                          Laubender Adobe Community Professional & MVP

                          We cannot attach files here in this forum.

                          Just use a hosting service like "Dropbox" and post the link…

                           

                          Uwe

                          • 11. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                            Jump_Over Level 5

                            Hi,

                             

                            It tells - "there is no textFrame on any master Spread of opened doc"

                             

                            Try reach your goal using InDesign interface. If you are seeing same error doing a job manually - well, script is not any magic...

                             

                            Jarek

                            • 12. Re: Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                              Laubender Adobe Community Professional & MVP

                              @Jarek – well, I did not read the whole error message, silly me ;-)  You are obviously right!
                              @Teetan – if there is a text frame on the master spread, the the script cannot reach it. As I already said, it could be locked, it could be nested into other objects (e.g. pasted inside a rectangle).

                               

                              You could write a if-clause to see, if your mTarget contains any text frames at all…

                               

                              But I cannot know, what is going on before looking into that InDesign CS5.5 document.

                               

                              What does the following code reveal?

                               

                              alert(app.documents.everyItem().masterSpreads.everyItem().textFrames.everyItem().getElements().length);
                              

                               

                              Uwe

                              • 13. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                Teetan VK Level 1

                                can you give me a temp mail address?

                                • 14. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                  Teetan VK Level 1

                                  Hi,

                                   

                                  Jarek, Uwe

                                   

                                  I know what's going on

                                   

                                  if the master has too many frame object, the script must give you an error

                                   

                                  you can try by you self

                                   

                                  Teetan

                                  • 15. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                    Teetan VK Level 1

                                    and make sure each text frame must has text inside, else, you will receive an error

                                    • 16. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                      Peter Kahrel Adobe Community Professional & MVP

                                      "Object contains no text for find/change" means that you're trying a findGrep() on an empty text frame. Avoid empty frames likes this or something similar:

                                       

                                      var frames = app.documents[0].masterSpreads.everyItem().getElements();

                                      var found = [];

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

                                         if (frames[i].contents.length > 0)

                                            found = found.concat (frames[i].findGrep());

                                         }

                                      }

                                       

                                      And here's an alternative:

                                       

                                      app.findChangeGrepOptions.includeMasterPages = true;

                                      var found = app.documents[0].findGrep();

                                      var arr = [];

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

                                         if (found[i].parent instanceof MasterSpread) {

                                            arr.push (found[i]);

                                         }

                                      }

                                       

                                      Peter

                                      • 17. Re: Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                        Laubender Adobe Community Professional & MVP

                                        @Peter – thank you for chiming in :-)

                                        Ah. I see.

                                        Btw. your first line is missing textFrames.everyItem() . And a additional closing bracket.  A typo, I guess:

                                         

                                        var frames = app.documents[0].masterSpreads.everyItem().textFrames.everyItem().getElements();
                                        var found = [];
                                        for (var i = frames.length-1; i >= 0; i--) {
                                           if (frames[i].contents.length > 0)
                                              found = found.concat (frames[i].findGrep());
                                           }
                                        

                                         

                                         

                                        I want to expand your code a bit, the idea for looking after contents and its length, to all page items to catch also the text frames or textPaths that are nested (not including text in object states of MSOs, that are not the active one):

                                         

                                        app.findChangeGrepOptions.includeMasterPages = true;
                                        app.findGrepPreferences = changeGrepPreferences = null;
                                        app.findGrepPreferences.findWhat = "\\b20\\d+\\b";
                                        
                                        var allDocuments = app.documents.everyItem().getElements();
                                        
                                        for(var d=0;d<allDocuments.length;d++){
                                            var docMasterSpreads = allDocuments[d].masterSpreads.everyItem().getElements();
                                            for(var m=0;m<docMasterSpreads.length;m++){
                                               
                                                var myTargetArray = docMasterSpreads[m].allPageItems;
                                                var found = [];
                                        
                                                for (var i = myTargetArray.length-1; i >= 0; i--) {
                                        
                                                    if (myTargetArray[i].hasOwnProperty("contents") && myTargetArray[i].contents.length > 0){
                                                        found = found.concat (myTargetArray[i].findGrep());
                                                        };
                                                    };
                                        
                                                for(var n=0;n<found.length;n++){
                                                    found[n].contents = String(Number(found[n].contents) + 1);
                                                    };
                                               
                                                };
                                            };
                                        

                                         

                                        I'm using the allPageItems array and filter all objects that have a property "contents" and all text objects with contents.length greater than 0.

                                        So far that will work…

                                         

                                        Flattening an array of arrays would also be an option to minimize the number of for-loops. So we could begin the code with a target like that:

                                         

                                        var myArrayOfArrays = app.documents.everyItem().masterSpreads.everyItem().allPageItems;
                                        

                                         

                                        I've seen some promising functions for flattening an array of arrays with arbitrary depth on stackoverflow.com :-)

                                        However, Adobe's implementation of ECMAScript does not include some of the newer methods available for flattening an array.
                                        Flattening an array was also discussed here in this forum, I think. Have to look it up.


                                        But this discussion is worth an extra thread…

                                         

                                        Uwe

                                         

                                        PS. Something OT about editing forum posts here:

                                        During editing this very message I was thrown out of the forum (automatically logged out?). I could recover my already typed post. But only as I switched over to the "Advanced Editor" feature of the forum. And I think the recreation of my post was only possible, because I had used the "Advanced Editor" feature in the moment I was logged out…

                                        • 18. Re: Re: Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                          Laubender Adobe Community Professional & MVP

                                          Ah, another idea on flattening: Since the depth of myArrayOfArrays could be known, flattening that array should be possible with a for-loop. That would avoid writing a recursive function (not my favourite thing to do). Have to think that over a bit…

                                           

                                          The depth should be the length of the array myArrayOfArrays.

                                           

                                          So flattening would work like this:

                                           

                                          app.findChangeGrepOptions.includeMasterPages = true; 
                                          app.findGrepPreferences = changeGrepPreferences = null; 
                                          app.findGrepPreferences.findWhat = "\\b20\\d+\\b";
                                          
                                          var myArrayOfArrays = app.documents.everyItem().masterSpreads.everyItem().allPageItems;
                                          var myFlattenedArray = [];
                                          
                                          for(var n=0;n<myArrayOfArrays.length;n++){
                                              myFlattenedArray = myFlattenedArray.concat(myArrayOfArrays[n]);
                                              };
                                          
                                          var myPageItemsArray = myFlattenedArray;
                                          var found = [];
                                          
                                          for (var i = myPageItemsArray.length-1; i >= 0; i--) {
                                          
                                              if (myPageItemsArray[i].hasOwnProperty("contents") && myPageItemsArray[i].contents.length > 0){
                                                  found = found.concat (myPageItemsArray[i].findGrep());
                                                  }; 
                                              };
                                          
                                          for(var n=0;n<found.length;n++){
                                              found[n].contents = String(Number(found[n].contents) + 1);
                                              };
                                          

                                           

                                           

                                          Uwe

                                          • 19. Re: Re: Re: Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                            Peter Kahrel Adobe Community Professional & MVP

                                            Hi Uwe,

                                             

                                            Thanks for pointing out the typos and omissions.

                                             

                                            app.documents.everyItem().masterSpreads.everyItem().allPageItems

                                             

                                            creates a simple array of arrays: [array1, array2, array3, . . .], so that's easy to flatten using concat. Flattening arrays with any depth of nesting isn't too complicated: it follows the same idea as traversing any kind of structure such as subdirectories, indexes, xml trees:

                                             

                                            function flatten (inArray, outArray) {
                                                for (var i = 0; i < inArray.length; i++) {
                                                    if (inArray[i] instanceof Array) {
                                                        flatten (inArray[i], outArray);
                                                    } else {
                                                        outArray.push (inArray[i]);
                                                    }
                                                }
                                                return outArray;
                                            }
                                            

                                             

                                            Call the function like this:

                                             

                                            myArray = [1,2,[3,4,['a','b','c'],5],6,7];

                                            flattened = flatten (myArray, []);

                                             

                                            Your approach of looking only in master pages may be quicker in long documents, but it's much more complicated than my second approach, which simply finds everything and then filters out what's not on a master page.

                                             

                                            Peter

                                            • 20. Re: Re: Re: Re: Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                              Laubender Adobe Community Professional & MVP

                                              Hi Peter,

                                              yes, that array flattener looks quite easy to me…

                                               

                                              Here another solution, that builds on the fact, that GREP is unable to find anything in locked objects.
                                              Of course only valuable, if we are aloud to lock/unlock pageItems at will.

                                               

                                              The scope is all open documents, not an individual array or collection of page items.
                                              Empty text frames are no problem with that.

                                               

                                              var myDocuments = app.documents.everyItem();
                                              var myLayers = myDocuments.layers.everyItem();
                                              
                                              //Locked text frames on master spreads are not touched.
                                              //If you want to unlock them you have to add something like this:
                                              
                                              //Unlock ALL page items in every document on spreads and master spreads (optional):
                                              myDocuments.pageItems.everyItem().locked = false;
                                              
                                              var myPageItemsOnNormalSpreads = myDocuments.spreads.everyItem().pageItems.everyItem();
                                              
                                              //Unlock the layers (optional)
                                              myLayers.locked = false;
                                              
                                              //Lock all first level page items on normal spreads
                                              //That leaves the page items on master spreads unlocked:
                                              myPageItemsOnNormalSpreads.locked = true;
                                              
                                              //Now for the GREP part:
                                              app.findChangeGrepOptions.includeMasterPages = true;
                                              app.findGrepPreferences = changeGrepPreferences = null;
                                              app.findGrepPreferences.findWhat = "\\b20\\d+\\b";
                                              
                                              //Do the search on "all open document" level
                                              //That will return an array of arrays:
                                              var myTarget = myDocuments.findGrep();
                                              
                                              //Flattening the myTarget array:
                                              var flattenedFoundArray = [];
                                              
                                              for(var n=0;n<myTarget.length;n++){
                                                  flattenedFoundArray = flattenedFoundArray.concat(myTarget[n]);
                                                  };
                                              
                                              //Change contents of found texts in flattened array:
                                              for(var n=flattenedFoundArray.length-1;n>=0;n--){
                                                  flattenedFoundArray[n].contents = String(Number(flattenedFoundArray[n].contents) + 1);
                                                  };
                                              
                                              //Unlock all objects on normal spreads:
                                              myPageItemsOnNormalSpreads.locked = false;
                                              
                                              //Reset GREP find and change prefs:
                                              app.findGrepPreferences = changeGrepPreferences = null;
                                              

                                               

                                              Is it faster? Did no tests for speed yet…

                                              One advantage: GREP will find and change also text in none-active states of MSOs (MultiStateObjects). Opposed to the allPageItems-method, that can only see the pageItems in the active state of a MSO. Note: All states of all Buttons can be searched and changed with both methods.

                                               

                                              Uwe

                                              • 21. Re: Why mFound = mTarget.findGrep() not work on cs5.5?
                                                Teetan VK Level 1

                                                Hi, all guys

                                                 

                                                Sorry, last two days I am on my trip to Macau

                                                 

                                                So I reply late

                                                 

                                                Thank you all guys

                                                 

                                                Thank you for your help, appreciate

                                                 

                                                especially thank you Laubender, your idea incredibly perfect,

                                                 

                                                thank you

                                                 

                                                Teetan