14 Replies Latest reply on May 23, 2010 2:38 PM by Harbs.

    How to limit a GREP search to selected text

    Tom Tomasko Level 1

      Hello,

       

      I have a GREP  script that searches for gaps in a series of end note numbers. This aids a proofreader in quickly finding out if a number has been inadvertently left out.

       

      However, in any one document the series of numbers may repeat themselves because the document contains more than one chapter.

       

      So I figure I could write the script to search a series of numbers in only the selected text, say a whole chapter. But, in looking at the properties for findGrepPreferences I do not see any that limit a search to a selection. The GREP dialog box however does allow for a search of All Documents, Document, Story, To End of Story and Selection.

       

      Where can I find those properties?

       

      Tom

        • 1. Re: How to limit a GREP search to selected text
          Tom Tomasko Level 1

          Forgot. I am using CS3.


          • 2. Re: How to limit a GREP search to selected text
            Peter Kahrel Adobe Community Professional & MVP

            >in looking at the properties for findGrepPreferences I do not see any  that limit a search to a selection

             

            app.selection[0].findGrep();

             

            In a script you have many more possibilities for the search scope than you have in the interface:

             

            myWord.findGrep ();

            myParagraph.findGrep();

             

            etc. etc.

             

            You could probably also search sections, though I've never tried that.

             

            Peter

            • 3. Re: How to limit a GREP search to selected text
              [Jongware] Most Valuable Participant

              (Sort of tested in CS4 [*]) If your chapters always begin with the same paragraph style, you could search for that style first. That will give you a list of "chapter starts". Then, you can use itemByRange to create a range from the start of one chapter to the start of the next one, and search in that range only.

              The only chapter where it won't work is the last one -- you'll have to 'manually' create a range from the start of that chapter to the end of the story.

               

               

              [*] I did the paragraph style searching, and then created a range using

               

              myRange = chapterlist[i].parent.characters.itemByRange (chapterlist[i].characters[0].index, chapterlist[i+1].characters[0].index);

              templist = myRange.findText();

              -- but no matter how I tried, the length of 'templist' was always 1 (even though the item I was searching for occurred multiple times in each chapter). Weird, but when I changed findText to changeText, it still changed all occurrences per chapter.
              You'll have to try and see if you can get it to work ...

              • 4. Re: How to limit a GREP search to selected text
                Tom Tomasko Level 1

                Peter and Jongware,

                 

                Thanks for the advice. I do not think I could use the trick that Jongware suggests because it implies that end note numbers would start over for each chapter. But a book could be in sections, each section comprising several chapters. Or, more likely, somebody forgot to use an object style for opening a chapter.

                 

                So what I need is a way for a user to select the content they wish to investigate. Using the app.selection[0].findGrep() does that trick.

                 

                However, what would be even better is that the user does not have to select text (things can go wrong in the flick of a wrist!) but instead select start and ending pages from a drop down menu in a dialog.

                 

                But I've run into a problem that I cannot figure out. Below is the code:

                 

                var myDoc = app.activeDocument;
                var firstPage = myDoc.pages[0];
                var lastPage = myDoc.pages[15];
                var myRange = myDoc.pages.itemByRange(firstPage,lastPage).textFrames.everyItem().texts.everyItem();
                //array below is all one to three digit words.
                var someNumbers1 = theGrepFinder(myDoc,"\\d{1,3}");
                //var someNumbers2 = theGrepFinder(myDoc,"\\d{1,3}",myRange);

                 

                function theGrepFinder(docRef,grepFindIt,theRange){
                    app.findGrepPreferences = NothingEnum.NOTHING;
                    app.changeGrepPreferences = NothingEnum.NOTHING;
                    app.findGrepPreferences.findWhat = grepFindIt;
                    var arrGrepFindIt = app.selection[0].findGrep();//use with someNumbers1
                    //var arrGrepFindIt = theRange.findGrep();//use with someNumbers2
                    return arrGrepFindIt;
                }//end theGrepFinder

                 

                There are two alternate vars here. The first (someNumbers1) calls up the function when text for the first 16 pages is selected. This works fine.

                 

                The second (someNumbers2) calls up the function when a range of pages is defined, again pages 1-16, But I get a different kind of array when I do this. It will make me have to dive deep into the array for the Position property. As I also have to filter all the found numbers for only those that are superscripted, then sort them numerically, then find duplicate and missing numbers, I'd rather not mess with all the neat code I have written that already does this.

                 

                I'll post two pictures of the data browser window for the arrays I get for someNumbers1 and someNumbers2. I know you two experts will see right away what I am talking about. What I'd like is that someNumbers2 looks like someNumbers1.

                 

                Thanks,

                 

                Tom

                 

                Picture 3.png

                 

                 

                Picture 4.png

                • 5. Re: How to limit a GREP search to selected text
                  Harbs. Level 6

                  You are doing the find on a Text object-array. It's a funny InDesign scripting object. I've never tried finding text on such an object, but I would tend to avoid that.

                   

                  The way I'd handle this would be to loop through all the appropriate text and do a separate findGrep() on each one. You then concat() the results, and continue as you would have otherwise...

                   

                  Harbs

                  • 6. Re: How to limit a GREP search to selected text
                    Tom Tomasko Level 1

                    Harbs,

                     

                    I just tried what you suggested but the following fails:

                     

                    var myDoc = app.activeDocument;
                    var firstPage = myDoc.pages[0];
                    var lastPage = myDoc.pages[3];
                    var myRange = myDoc.spreads.everyItem().pages.itemByRange(firstPage,lastPage).textFrames;
                    var arrNumbers = [];
                    for(var i = 0; myRange.length > i; i++){
                        var foundNumbers = theGrepFinder("\\d{1,3}",myRange[i]);
                        arrNumbers.concat(foundNumbers);
                        }//end for i

                     

                    function theGrepFinder(grepFindIt,theRange){
                        app.findGrepPreferences = NothingEnum.NOTHING;
                        app.changeGrepPreferences = NothingEnum.NOTHING;
                        app.findGrepPreferences.findWhat = grepFindIt;
                        var arrGrepFindIt = theRange.findGrep();
                        return arrGrepFindIt;
                    }//end theGrepFinder

                     

                    Why does the above fail?

                     

                    Tom

                    • 7. Re: How to limit a GREP search to selected text
                      Tom Tomasko Level 1

                      Another possible way to search through just certain pages of text is to write a script to select a range of pages and then let theGrepFinder function search through that.

                       

                      But this also fails:

                       

                      var myDoc = app.activeDocument;
                      var firstPage = myDoc.pages[0];
                      var lastPage = myDoc.pages[3];
                      var myRange = myDoc.pages.itemByRange(firstPage,lastPage).textFrames;
                      app.select(myRange,SelectionOptions.REPLACE_WITH);

                       

                      I get an error message "cannot determine the spread this object is on." Don't know how to decipher that.

                       

                      Tom

                      • 8. Re: How to limit a GREP search to selected text
                        Harbs. Level 6

                        Try something like this:

                         

                        var pages = myDoc.pages.itemByRange(firstPage,lastPage).getElements();
                        var myRange = [];
                        for(var i=0;i<pages.length;i++){
                            myRange = myRange.concat(pages[i].textFrames.everyItem().getElements());
                        }

                         

                        Harbs

                        • 9. Re: How to limit a GREP search to selected text
                          Tom Tomasko Level 1

                          Harbs,

                           

                          The following works, but only if the firstPage and lastPage values are the same, that is the search takes place on one page. But as soon as I try two or more pages, it errors out, i.e., "cannot determine the spread this object is on."

                           

                          var myDoc = app.activeDocument;
                          var firstPage = myDoc.pages[0];
                          var lastPage = myDoc.pages[0];
                          var pages = myDoc.pages.itemByRange(firstPage,lastPage).getElements();
                          var myRange = [];
                          for(var i=0;i<pages.length;i++){
                              myRange = myRange.concat(pages[i].textFrames.everyItem().getElements());
                          }
                          app.select(myRange,SelectionOptions.REPLACE_WITH);
                          var someNumbers = theGrepFinder("\\d{1,3}",myRange);

                           

                          function theGrepFinder(grepFindIt,theRange){
                              app.findGrepPreferences = NothingEnum.NOTHING;
                              app.changeGrepPreferences = NothingEnum.NOTHING;
                              app.findGrepPreferences.findWhat = grepFindIt;
                              var arrGrepFindIt = app.selection[0].findGrep();
                              return arrGrepFindIt;
                          }//end theGrepFinder

                          • 10. Re: How to limit a GREP search to selected text
                            Harbs. Level 6

                            Just forget the itemByRange(). It's probably more trouble than it's worth...

                             

                             

                            var startIndex = 10;//wherever you want to start

                            var endIndex = 20;//wherever you want to end

                             

                            for(var i=startIndex;i<endIndex;i++){
                                myRange = myRange.concat(doc.pages.item(i).textFrames.everyItem().getElements());
                            }

                             

                            Harbs

                            • 11. Re: How to limit a GREP search to selected text
                              Harbs. Level 6

                              I just noticed:


                              app.select(myRange,SelectionOptions.REPLACE_WITH);

                               

                              Why in the world are you selecting the text?!?!

                               

                              Just use myRange[i].findGrep()...

                               

                              Harbs

                              • 12. Re: How to limit a GREP search to selected text
                                Tom Tomasko Level 1

                                Harbs,

                                 

                                You questioned why I use app.select(). It is the only thing that has partially worked so far,but only for one page. If I try to select more than two pages I get an error saying that the spread cannot be determined.

                                 

                                Trying your latest solution, the one that avoids itemByRange, I get a familiar error as well: "theRange.findGrep() is not a function."

                                 

                                var myDoc = app.activeDocument;
                                var firstPage = 2;
                                var lastPage = 4;
                                var myRange = [];
                                for(var i=firstPage;i<lastPage;i++){
                                    myRange = myRange.concat(myDoc.pages.item(i).textFrames.everyItem().getElements());
                                }
                                var someNumbers = theGrepFinder("\\d{1,3}",myRange);

                                 

                                function theGrepFinder(grepFindIt,theRange){
                                    app.findGrepPreferences = NothingEnum.NOTHING;
                                    app.changeGrepPreferences = NothingEnum.NOTHING;
                                    app.findGrepPreferences.findWhat = grepFindIt;
                                    var arrGrepFindIt = theRange.findGrep();
                                    return arrGrepFindIt;
                                }//end theGrepFinder

                                • 13. Re: How to limit a GREP search to selected text
                                  Harbs. Level 6

                                  You need to loop through theRange:

                                   

                                  finds=[];
                                  for(i=0;i<theRange.length;i++){
                                    finds = finds.concat(theRange[i].findGrep());
                                  }
                                  

                                   

                                  I'll just write the whole thing out...

                                   

                                  This should work (untested):

                                   

                                  var myDoc = app.activeDocument;
                                  var firstPage = 2;
                                  var lastPage = 4;
                                  var myRange = [];
                                  for(var i=firstPage;i<lastPage;i++){
                                      myRange = myRange.concat(myDoc.pages.item(i).textFrames.everyItem().getElements());
                                  }
                                  var someNumbers = theGrepFinder("\\d{1,3}",myRange);
                                  
                                  function theGrepFinder(grepFindIt,theRange){
                                      app.findGrepPreferences = NothingEnum.NOTHING;
                                      app.changeGrepPreferences = NothingEnum.NOTHING;
                                      app.findGrepPreferences.findWhat = grepFindIt;
                                      var retVal=[];
                                      for(var i=0;i<theRange.length;i++){
                                          retVal =retVal .concat(theRange[i].findGrep());
                                      }    
                                  return retVal;
                                  }//end theGrepFinder
                                  

                                   

                                  Harbs

                                  • 14. Re: How to limit a GREP search to selected text
                                    Tom Tomasko Level 1

                                    Thanks very much Harbs for taking the time out on this lovely Sunday (here anyway) to help me with this!

                                     

                                    It did not occur to me to do the looping inside theGrepFinder function.

                                     

                                    Now I gotta get outside(!) before building the dialog box I indicated above. I won't have to bug anybody about that.

                                     

                                    Thanks!

                                     

                                    Tom