4 Replies Latest reply on Mar 17, 2016 8:20 AM by kkirk69

    Accessing paragraph array by index in for loop (ID CC 2014)

    kkirk69

      Originally I wanted to search for every blank line on the page (ones that only have a return "\r") and delete the return character so the blank line would be deleted.

      Here's what I have so far:

       

            var myParagraphs = app.activeDocument.textFrames[0].paragraphs.everyItem();

            for(i=0; i<myParagraphs.length; i++){

                var myChar = myParagraphs[i].characters[0];

                if(myChar.contents == '\r'){

                   app.select(myChar);

                   app.cut();

                   }

              }

       

      This errors out (it doesn't do what I expected it to do).

      Running it in the ESTK gives the error "The object does not support the property or method '0'" at line 3.

       

      If I reference a particular character like:

      var myCharacter = app.activeDocument.textFrames[0].paragraphs[0].characters[0]

      if(myCharacter.contents == '\r'){

                app.select(myChar);

                app.cut();

           }


      I get success.


      paragraphs.everyItem() builds an array of paragraphs and I can confirm that with:

      alert(myParagraphs.contents);


      Am I referencing the array incorrectly?



        • 1. Re: Accessing paragraph array by index in for loop (ID CC 2014)
          [Jongware] Most Valuable Participant

          No

           

          The problem is that the actual object "Paragraphs" changes as soon as you remove just a single "\r" - the number of paragraphs changes! Your temp array "myParagraphs" still contains a copy of the document as they were, but as soon as you remove one return, it no longer reflects what's actually in the document.

           

          I have two different solutions for you, pick one:

           

          1. Loop backwards over the myParagraphs array instead of forwards. If you remove a return, everything forwards of it will no longer be valid - but everything backwards of it will still be valid.

          Looping backwards over such a "live" array is a trick that works with all objects. It'll come in handy on numerous occasions.

           

          2. (I think I would prefer this in this situation) No need to 'manually' loop over all paragraphs and checking its characters. Just use GREP! Search for '(?<=\r)\r+' (sans the quotes, as always) and replace with nothing. Done.

           

          Free Tip of the Day: don't set a selection and use 'app.cut()'. You can simplfy this to "myParagraphs[i].characters[0].remove();". It should be way faster than selecting, then using Cut. (And why use "cut" when you want "app.clear()"? (After checking: oops. Seems someone at Adobe forgot to include that!)

          • 2. Re: Accessing paragraph array by index in for loop (ID CC 2014)
            kkirk69 Level 1

            Thanks Jongware.

            Method 2 is most applicable for sure and works like a charm.

            I am finding however that if the first line in the frame is blank it doesn't get changed?

            Thoughts?

            ps. What does that GREP statement actually say/mean?

            • 3. Re: Accessing paragraph array by index in for loop (ID CC 2014)
              [Jongware] Most Valuable Participant

              Yes, that GREP indeed only looks for hard returns where the preceding character is also a hard return:

               

              (?<=  Lookbehind Group
              \r  Paragraph Break (Hard Return)
              )  End Lookbehind Group
              \r+  Paragraph Break (Hard Return); may occur once or more times; longest possible match will be taken


               (?<=< \r <) \r +

               

              (output from WhatTheGrep - Indesign GREP Help). Sorry, I guesstimated it as 50/50 whether it should or should not work for you. Here is a better one:

               

                  (?<![^\r])\r+

               

              This (very sneaky) expression looks for hard returns where there is not not a hard return before. It works because (1) if there is a hard return before, then "not not hard return" is true and it matches. And (2) if there is nothing before it, then there is no hard return (or any other character). In this case WhatTheGrep doesn't really make it much clearer

               

               

              (?<!  Negative Lookbehind Group
              [^  Exclusion: any character not in this group
                \r  Paragraph Break (Hard Return)
              ]  End Exclusion Group
              )  End Negative Lookbehind Group
              \r+  Paragraph Break (Hard Return); may occur once or more times; longest possible match will be taken


               (?<!<! [X \r ] <!) \r +

              • 4. Re: Accessing paragraph array by index in for loop (ID CC 2014)
                kkirk69 Level 1

                Hey no need to apologize - you put me back on the road when I had a flat!

                 

                As a casual ID user this kind of advice is invaluable.

                WhatTheGrep is a great bit of help.

                 

                 

                Thanks again.