9 Replies Latest reply on May 17, 2009 2:45 PM by RyanPPI

    Possible JavaScript GREP Bug?

    RyanPPI

      I have run into a situation that works in inDesign's GREP dialog box (in the program itself), but does not work as a script, and I think it may be a bug.  If anyone can shed light on the situation, it would be much appreciated.

       

      Basically, I want to run a Find/Change GREP query repeatedly until no more matching text is found, and a problem arises when I try to use more than one lookbehind.

       

      The code, in its simplest form, looks like this:

       

      #target indesign
      var myFoundText;
      target = app.selection[0].parentStory;

       

      app.findGrepPreferences.findWhat = "1";
      myFoundText = app.findGrep();

       

      while (myFoundText.length != 0){
          app.findGrepPreferences.findWhat = "((?<=March )|(?<=June ))(1)(?!st)";
          app.changeGrepPreferences.changeTo = "$0st";
          target.changeGrep();
          myFoundText = app.findGrep();
          }

       

      The problem is that the script finds the '1', adds a 'st' to the end, but then gets stuck in an infinite loop (even though it should stop running after the first change operation, as the 1 no longer needs an 'st' after it) .

       

      The problem seems to be multiple lookbehinds, as the same script will NOT get stuck in an infinite loop if I only use a single lookbehind.  It appears that there is no way to script a GREP query to consider multiple different lookbehinds, although it is quite easy to do so inside the program itself.  Is this a bug, or have I missed something?

       

      Thanks,

       

      -Ryan

        • 1. Re: Possible JavaScript GREP Bug?
          Harbs. Level 6

          I don't know what's wrong at your end. It works by me...

           

          Harbs

          • 2. Re: Possible JavaScript GREP Bug?
            Peter Kahrel Adobe Community Professional & MVP

            Ryan,

             

            You needn't loop at all, a single statement works fine, as it does in the interface -- or are there special circumstances where one pass doesn't give you the correct result? This works fine for me:

             

            target = app.selection[0].parentStory;
            app.findGrepPreferences.findWhat = "((?<=March )|(?<=June ))1(?!st)";
            app.changeGrepPreferences.changeTo = "1st";
            target.changeGrep();

             

            There's no need, by the way, to create a reference to "1" by grouping it, and $0 isn't needed in the replacement.

             

            Peter

            • 3. Re: Possible JavaScript GREP Bug?
              Harbs. Level 6

              Peter,

               

              I figured that Ryan knew that, but there was more to his code which he 

              left out which did require the loop...

               

              Harbs

              • 4. Re: Possible JavaScript GREP Bug?
                RyanPPI Level 1

                Thank you for the replies.  First, yes there is a reason I need to loop the code, and the actual code is far longer than what I posted here (my years as a bug tester have taught me to 'track' weird behavior and reduce it to its simplest form).

                 

                Harbs: The code, as I posted it, does in fact work without an infinite loop.  However!  If I change the lookbehinds from months to digits (e.g. to catch '21' or '31' instead of 'March 1' or 'June 1'), the code goes into an infinite loop.  It will perform the find/change correctly, but will then be stuck.  In the case that no matches are present, it will simply get trapped in an infinite loop right away.

                 

                It seems like the while loop is not cancelled when there are no further matches; perhaps the length of myFoundItems is not zeroed when no matches are found?  If this is the case, can anyone explain what the return value of an app.findGrep() statement is when no matches are found?

                 

                -Ryan

                • 5. Re: Possible JavaScript GREP Bug?
                  Harbs. Level 6

                  Ryan,

                   

                  I need more to go on than that... Some sample code would help.

                   

                  findGrep (and changeGrep) will always return an array.

                   

                  FWIW, you don't need to do findGrep after changeGrep. changeGrep will return the finds (prior to the change).

                   

                  Harbs

                  • 6. Re: Possible JavaScript GREP Bug?
                    RyanPPI Level 1

                    Harbs,

                     

                        Sure thing.  Here is the sample code and the sample text I'm running it on:

                     

                    Code:

                    #target indesign
                    var myFoundText;

                    target = app.selection[0].parentStory;

                     

                    app.findGrepPreferences.findWhat = "21";
                    myFoundText = app.findGrep();

                     

                    while (myFoundText.length != 0){
                        app.findGrepPreferences.findWhat = "((?<=2)|(?<=3))(1)(?!st)";
                        app.changeGrepPreferences.changeTo = "$0st";
                        target.changeGrep();
                        myFoundText = app.findGrep();
                        }

                     

                    Sample Text:

                    This is June 1 and June 21.

                     

                    When I run the script, the text changes to:

                    This is June 1 and June 21st.

                     

                    But then it gets stuck in an infinite loop.  What am I doing wrong?

                     

                    Thanks again,

                     

                    -Ryan

                    • 7. Re: Possible JavaScript GREP Bug?
                      Peter Kahrel Adobe Community Professional & MVP

                      Ryan -- Your code works fine over here. It changes the text and stops, no problem.

                       

                      Peter

                      • 8. Re: Possible JavaScript GREP Bug?
                        Harbs. Level 6

                        Ryan,

                         

                        My hunch is that your problem is with the app.findGrep()

                         

                        You should probably be using target.findGrep().

                         

                        You probably have a find in another document or something.

                         

                        I'd advise stepping through the script in the ESTK to find what's 

                        wrong...

                         

                        Harbs

                        • 9. Re: Possible JavaScript GREP Bug?
                          RyanPPI Level 1

                          Harbs,

                           

                          Brilliant.  That was the problem.  I changed from app.findGrep() to target.findGrep() and the example script works like a charm.  Just updated my original (full-size) script with the lessons learned in the example, and the whole thing performs exactly as I want.

                           

                          The original script formatted all sorts of dates in a uniform way, and before now it was a 'dumb' script that ran a set number of times, just to cover any likely amount of changes it would need to make (e.g. a for loop that runs 20 times).  However, we've begun to use the script on some very slow computers, and it was really bogging them down even on stories that did not need a single change!  As well, in the rare cases that there were more changes than the max loop number, those extras would go unformatted and would need to be later corrected manually.  Now the script only runs if changes are necessary, and then runs only as many times as it needs to before stopping.  Much more efficient!

                           

                          Thank you very much for your help!

                           

                          -Ryan