11 Replies Latest reply on Dec 31, 2013 6:12 AM by Scorpio17523

    How to make my script ignore pages 1 and 2?

    Scorpio17523

      Hi all. I'm a complete beginnger at all of this so thank you in advance for all you're help, I really appreciated it.

       

      I have a JavaScript that I've been working on, and with help from people on here it's working really well. I uses a combination of GREP expressions and checks the entire document and then applies pre-made Character Style that have been set up in the InDesign Templates. (By the way I'm using CS6).

       

      My latest problem is that I don't want this to affect page 1 or 2 as the templates are layed out in spreads so these are the front and back cover.

       

      Is there a way I can get the script to ignore page 1 and 2?

       

      If not, I thought another way round would be to only have the script run on highlighted text, but I'd prefere to just ignore pages 1 and 2.

       

      Any and all help would be greatly appreciated.

       

      Thanks again,

       

      Scorpio

        • 1. Re: How to make my script ignore pages 1 and 2?
          Kai Rübsamen Adobe Community Professional

          I’m not sure, if this can be done easier: As far as I know, it is not possible to search for specific pages? So I would loop through all pages (start at page 3) and then loop through every text frame on the current page.

           

          var curDoc = app.activeDocument;

          var allPages = curDoc.pages;

           

           

          // loop through pages

          for ( var i = 2; i < allPages.length; i++ ) {

           

              var curPage = allPages[i];

              var tfs = curPage.textFrames;

           

              app.findGrepPreferences = app.changeGrepPreferences = null;

              app.findGrepPreferences.findWhat = "~M";

           

              // loop through textframes on current page

              for ( var t = 0; t < tfs.length; t++ ) {

                  var tf = tfs[t];

                  if ( tf.contents != "" )  {

                      var found = tf.findGrep();

                      if (found.length > 0) {

                          for ( var f = 0; f < found.length; f++ ) {

                              var curFound = found[f];

                              var curLine = curFound.lines[0];

                              curLine.fillColor = curDoc.swatches[4];

                          } // for

                      } // if

                  } // if

              } // for

          } // allPages

          • 2. Re: How to make my script ignore pages 1 and 2?
            Marc Autret Level 4

            Hi Scorpio17523 and Kai,

             

            > As far as I know, it is not possible to search for specific pages?

             

            My guess is that you can, in fact, use Pages.itemByRange(2,-1)... in order to reach a valid plural specifier that holds a findGrep (or changeGrep) method—like TextFrame or Paragraph. This is a powerful way to run a GREP query in a single command.

             

            Say you want to apply some character style (MyCharStyle) to every word that begin with a 'A' or 'a', considering all textframes except those of page 1 and 2 (i.e. index 0 and 1). This can be done in a single pass without any loop, as shown below:

             

            // Your settings
            // ---
            var GREP_PATTERN = '\\<[aA][\\l\\u]+';
            var CHAR_STYLE_NAME = 'MyCharStyle';
            
            // Variables
            // ---
            var doc = app.activeDocument,
                cStyle = doc.characterStyles.itemByName(CHAR_STYLE_NAME),
                target = doc.pages.itemByRange(2,-1).textFrames.everyItem().paragraphs.everyItem(),
                nr;
            
            // Set GREP, and run!
            // ---
            app.findGrepPreferences = app.changeGrepPreferences = null;
            app.findGrepPreferences.findWhat = GREP_PATTERN;
            app.changeGrepPreferences.appliedCharacterStyle = cStyle;
            
            nr = target.changeGrep().length;
              
            alert( nr + " expressions have been changed." );
            

             

            The important part is:

             

            target = doc.pages.itemByRange(2,-1).textFrames.everyItem().paragraphs.everyItem()

             

            This allows to filter page indices 0 and 1 inside the specifier. As a result, target is a 'plural' Paragraph object which represents every desired text and can then invoke its changeGrep() method.

             

            Note that we could as well invoke changeGrep() from a plural TextFrame—i.e.: ...textFrames.everyItem()—but the GREP command will lead to a runtime error if some textframe of the collection is empty. That issue does not occur if one extends the specifier to ...paragraphs.everyItem()—unless all the frames are empty!

             

            Hope that helps.

             

            @+

            Marc

            • 3. Re: How to make my script ignore pages 1 and 2?
              Laubender Adobe Community Professional & MVP

              @Marc – cool trick.

               

              But this is only working for the top level text frames. Text frames that are nested or anchored in the top level text frames will not be searched.

               

              I suggest rather "to flip the problem around" by the following method:

              Lock all objects you don't want to be searched.

               

              Either for ranges of spreads or ranges of pages.

               

              Here an example:

              In a 10 pages document, we like to search/replace only on page 3

               

              //"Hiding" objects from the GREP search/replace:
              
              //Lock all objects on all pages:
              app.documents[0].pageItems.everyItem().locked = true;
              
              //Unlock the page items on a specific page or a page range:
              //In this case page 3 (with index 2):
              app.documents[0].pages.itemByRange(2,2).pageItems.everyItem().locked = false;
              
              //Do your GREP search/replace on the whole document:
              app.findGrepPreferences.findWhat = "a";
              app.changeGrepPreferences.changeTo = "b";
              app.documents[0].changeGrep();
              
              //unlock all objects on all pages:
              app.documents[0].pageItems.everyItem().locked = false;
              

               

              Of course this method should be refined, if we have some objects deliberately locked at the starting point.

              (And they should be locked after running the script).

               

              Uwe

              • 4. Re: How to make my script ignore pages 1 and 2?
                Laubender Adobe Community Professional & MVP

                I just want to add: As a side effect when using this method all objects on the pasteboard of page 3 are out of the game, GREP search will not touch them.

                 

                Uwe

                • 5. Re: How to make my script ignore pages 1 and 2?
                  Scorpio17523 Level 1

                  That worked great! Of course I've changed it because I want it to search everything except page 1 and 2 (index 0,1) so I adjusted it to lock (0,1) run my script and then unlock them.

                   

                  Works perfectly!

                   

                  Thanks

                  • 7. Re: How to make my script ignore pages 1 and 2?
                    Laubender Adobe Community Professional & MVP

                    @Scorpio17523 – About objects on the pasteboard?

                     

                    With targeting spreads you not only target all page items that are positioned on the pages of a spread, but also all page items on the pasteboard of these spreads.

                     

                    With targeting pages, you only target all page items positioned on the pages.

                     

                    An here the ( not rethorical!) question:

                    what is considered to be positioned on a specific page, if objects overlap to other pages?


                    Not a trivial one, if we have to work on double sided documents and only want to target a specific page on a spread.

                     

                    Do some experiments with selected page items to find out to what page they belong:

                     

                    alert(app.selection[0].parentPage.documentOffset);
                    

                     

                    alert(app.selection[0].parentPage.name);
                    

                     

                    Do it with objects partly inside the bleed or partly inside the slug area.

                    Also with objects with their geometric center exactly between two pages.

                     

                    The thing gets interesting, if you move pages a bit with the Page Tool.

                     

                    Uwe

                    • 8. Re: How to make my script ignore pages 1 and 2?
                      Kai Rübsamen Adobe Community Professional

                      Hi Marc,

                       

                      I tried itemByRange but did fail, because I did not use everyItem() then. I’m impressed that in this case no loop is needed. Thanks

                       

                      > but the GREP command will lead to a runtime error if some textframe of the collection is empty.

                       

                      Yes. It seems that in this case one loop is necessary?

                       

                      var target = doc.pages.itemByRange(2,-1).textFrames.everyItem().getElements();
                      …
                      for ( var i = 0; i < target.length; i++ ) {
                        if ( target[i].contents != "" ) {
                          target[i].changeGrep();
                        }
                      }
                      

                      best

                      Kai

                       


                      • 9. Re: How to make my script ignore pages 1 and 2?
                        Laubender Adobe Community Professional & MVP

                        @Scorpio17523 – A little off-topic here, but just to illustrate the problem, what object is positioned where, see the following screenshot of a double sided document (pages 2-3):

                         

                        SelectedObjectOnPage3.png

                         

                        Uwe

                        • 10. Re: How to make my script ignore pages 1 and 2?
                          Marc Autret Level 4

                          @Uwe

                           

                          Good points. The method I suggest only works in simple layouts and doesn't deal with anchored/inline/nested/extra frames. Anyway I think it's a good thing to keep in mind the underlying principle: as far as one can use plural specifiers instead of looping in arrays, that solution will remain the most effective.

                           

                          @Kai

                           

                          Empty frames might still be skipped using ...paragraphs.everyItem() or perhaps ...lines.everyItem(). Of course we can always imagine cases in which this fails too, but in practice such cases should be detected upstream, IMHO.

                           

                          Marc

                          • 11. Re: How to make my script ignore pages 1 and 2?
                            Scorpio17523 Level 1

                            @Everyone

                             

                            You have all helped me so much with these examples and explinations. I deffinately have enough here to keep me busy for a while.

                             

                            Many thanks again.

                             

                            Scorpio