13 Replies Latest reply on Apr 3, 2011 7:03 AM by Iain Robinson

    still got problems with finding next para

    Iain Robinson Level 1

      Hi all

       

      I posted a few days ago about my problems changing the current paragraph based on what style is applied to the next paragraph. Peter Kahrel and stoereee posted some code which when doctored to fit in my script did work but I couldn't follow how it was working. Consequently when I came to change it and re-use it it doesn't work (for me). The bit I used works but I can't see how the hell it does!

       

      My code for comparing one paragraph with the previous one is

       

      app.findGrepPreferences.appliedParagraphStyle="Quotes";
      app.findGrepPreferences.findWhat = "^.+$";

       

      f = app.activeDocument.findGrep();
      for (i = 0; i < f.length; i++) {
        if (f[i].parentStory.insertionPoints[f[i].index-1].appliedParagraphStyle.name=="Quotes")
            f[i].appliedParagraphStyle="Quotes subsequent";
      }

       

      I can follow what that is doing. What I'm having to do now is identify the first of a series of quotes, the last and any in the middle, and apply different styles to those three groups so I can put different amount of space before and after them. All quotes automatically come in as "Quotes" paragraph style so my intention is to;

      1. identify the first quote by finding a "Quotes" paragraph not preceded by "Quotes" && followed by "Quotes"
      2. the last quote will be a "Quotes" paragraph not followed by a "Quotes" paragraph
      3. any "Quotes" paragraphs left can then all be converted to a "Quotes middle" style

       

      To do this I really need to compare a paragraph to the next one and change the current one accordingly. Could someone please explain the methodology of using insertionPoints[-1].paragraphs[0]; rather than parentStory.insertionPoints[MyPar.index-1].paragraphs[0];, which finds the previous paragraph?? I've been banging my head against this for a couple of hours now, trying different things, and the answer is not coming to me!

       

      Apologies for the long post and thanks for any assistance.

      Iain

        • 1. Re: still got problems with finding next para
          Mayhem SWE Level 2

          Hmm. I'm just a novice when it comes to InDesign scripting, but personally I wouldn't use GREP at all for this kind of problem. In this case it seems much easier to manually examine appliedParagraphStyle using nested for-loops over either app.selection or app.activeDocument.stories depending on your preference. I don't know how large your document is or the performance effectiveness of GREP versus manual examination of appliedParagraphStyle, but either way the ease of implementation would be worth any reasonable performance penalty.

          • 2. Re: still got problems with finding next para
            Iain Robinson Level 1

            Thanks Mayhem, I'll have a look at that method. Just so you know, the documents are only likely to be 10-20 pages long - so performance isn't our primary concern. I chose Grep as the method outlined in my original post was suggested on here and I'm comfortable with Grep.

             

            Any more suggestions? Would be quite keen to get the original method working - I'm hoping I'm nearly there and just need to adjust it slightly.

             

            Iain

            • 3. Re: still got problems with finding next para
              Mayhem SWE Level 2

              GREP isn't really equipped to deal with what happens before or after a match. You have the lookbehind and lookahead syntax of course, but you cannot specify InDesign style parameters separately for them. Because it's no longer the middle of the night, and it's more fun to write scripts than doing actual work, here's a proposed manual solution:

               

              for (var story = 0; story < app.activeDocument.stories.length; story++) {
                   var current = app.activeDocument.stories[story].paragraphs;
                   for (var paragraph = 0; paragraph < current.length; paragraph++) {
                        if (current[paragraph].appliedParagraphStyle.name.indexOf("Quotes") == 0) {
                             var previous = paragraph > 0 && current[paragraph-1].appliedParagraphStyle.name.indexOf("Quotes") == 0;
                             var next = paragraph < current.length-1 && current[paragraph+1].appliedParagraphStyle.name.indexOf("Quotes") == 0;
                             if (next && !previous)
                                  current[paragraph].appliedParagraphStyle = "Quotes First";
                             else if (next && previous)
                                  current[paragraph].appliedParagraphStyle = "Quotes Middle";
                             else if (!next && previous)
                                  current[paragraph].appliedParagraphStyle = "Quotes Last";
                             else // single quote which appears by itself
                                  current[paragraph].appliedParagraphStyle = "Quotes";
                        }
                   }
              }
              

               

              Couldn't be arsed to make up a test document so I have not tested this code at all aside from making sure there are no syntax errors. The code is quite self-explanatory though, so should be a piece of cake for you to fix any mistakes and adapt for your situation!

              • 4. Re: still got problems with finding next para
                [Jongware] Most Valuable Participant

                How about this?

                 

                app.findGrepPreferences = null;
                app.findGrepPreferences.appliedParagraphStyle = "Quote";
                app.findGrepPreferences.findWhat = "(?s).+";
                list = app.activeDocument.findGrep();
                for (l=0; l<list.length; l++)
                {
                 list[l].paragraphs[0].appliedParagraphStyle = "first";
                 list[l].paragraphs[-1].appliedParagraphStyle = "last";
                }
                
                • 5. Re: still got problems with finding next para
                  Iain Robinson Level 1

                  Thanks Mayhem, that's excellent - worked perfectly. Is kind of hard to follow - you're no beginner! I'm a beginner! I especially liked the "Couldn't be arsed..." phrase - are you British?

                   

                  Jongware - thanks for your contribution. Your code uses "list" which I haven't come across before. Mayhem's deals with three types of para styles whereas yours only two. Presumably it could be made to do two but I'm going to have to crack on with this and use the one that works even though I don't fully understand how it works. I always try and describe to myself in plain English what any script is doing (especially one I have basically copied from the net) in the hope that it all sinks in. I can't do that for Mayhem's, yet.

                  • 6. Re: still got problems with finding next para
                    Mayhem SWE Level 2

                    Haha, and here I thought my script was much easier to read than arcane regular expression syntax! All it contains is an outer loop which goes through every story in the document and an inner loop which goes through every paragraph in the current story. The variable current is used as shorthand for all paragraphs in the current story but serves no real purpose aside from making the code easier to read (writing out app.activeDocument.stories[story].paragraphs[paragraph].appliedParagraphStyle every time consumes lots of screen real estate!).

                     

                    For each paragraph we check whether its style name begins with "Quotes", and if so whether the next and/or previous paragraph style names do too (but first double-checking whether we're at the first or last paragraph already, trying to inspect a paragraph that does not exist will throw an error). Then all that remains is to set the appropriate paragraph style based on simple boolean logic (I have no idea how proficient you are at programming in general or JavaScript in particular, but ! and && just means not and and respectively), if the next paragraph has also been identified as a quote but not the previous paragraph than it stands to reason that we must currently be processing the first in a series of quotes etc.

                     

                    I'm from Sweden so my English vocabulary likely consists of a wild mix of American, British, Australian etc. phrases.

                    • 7. Re: still got problems with finding next para
                      [Jongware] Most Valuable Participant

                      Heh heh -- and there I was thinking, shorter is better. Okay -- here's the breakdown.

                       

                      * My script uses a GREP expression to gather all of the consecutive paragraphs in the style "Quote" in one go. Usually, GREP defaults to not straying beyond paragraph boundaries, but the modifier "?s" makes it disregard paragraph returns (they are treated as 'normal' characters instead).

                       

                      * The "list" is nothing special -- it's just a variable! The "findGrep" command returns an array of results -- each item in the array "contains" an occurrence of the found text (which may or may not consist of more than one paragraph).

                       

                      * Looping over the list (using a for..loop on its length), we can simply address each of the "found" items. Each item can contain more than one single paragraph, and so the notation

                       

                      item.paragraphs[0]

                       

                      will address the *first* paragraph in the 'found' range; on the other hand, the notation

                       

                      item.paragraphs[-1]

                       

                      is a special one. It addresses the *last* paragraph in the 'found' range.

                       

                      So you can easily change both the first and last paragraph in a set of "Quote" paragraphs; with a little more code, you can make decisions for what to do when there is only one paragraph in the "set", or two, or more than two.

                      • 8. Re: still got problems with finding next para
                        Mayhem SWE Level 2

                        [Jongware] wrote:

                         

                        My script uses a GREP expression to gather all of the consecutive paragraphs in the style "Quote" in one go. Usually, GREP defaults to not straying beyond paragraph boundaries, but the modifier "?s" makes it disregard paragraph returns (they are treated as 'normal' characters instead).

                        Ahh, so that's what the modifier does. Quite a neat solution! One thing is missing however, the first thing the script must do is reset every paragraph using the various quote styles back to the base style. Otherwise subsequent runs of the script will produce different results with fewer and fewer "base" quotes available and you wouldn't be able to add more quotes to the document after the script had been run once.

                        • 9. Re: still got problems with finding next para
                          [Jongware] Most Valuable Participant

                          Mayhem SWE wrote:

                           

                          [Jongware] wrote:

                           

                          My script uses a GREP expression to gather all of the consecutive paragraphs in the style "Quote" in one go. Usually, GREP defaults to not straying beyond paragraph boundaries, but the modifier "?s" makes it disregard paragraph returns (they are treated as 'normal' characters instead).

                          Ahh, so that's what the modifier does. Quite a neat solution! One thing is missing however, the first thing the script must do is reset every paragraph using the various quote styles back to the base style. Otherwise subsequent runs of the script will produce different results with fewer and fewer "base" quotes available and you wouldn't be able to add more quotes to the document after the script had been run once.

                           

                          Good point ...

                           

                          ... So, step #1 should be to use regular find/change to change all "first' and "last" quote styles to plain "Quote".

                          • 10. Re: still got problems with finding next para
                            Iain Robinson Level 1

                            I've got to dash off in a minute (daughter's first concert) but I'll look at this in detail tomorrow. Descriptions in English are very helpful and I appreciate the time you've both taken. Until tomorrow...

                            • 11. Re: still got problems with finding next para
                              Iain Robinson Level 1

                              Didn't get time to look at this on Friday...

                               

                              Mayhem - Thanks for the description of what the script does. I can kind of follow it now. It's pretty involved (for me). But it works perfectly - deeper understanding will come when I try to tweak it. Should have guessed you were Swedish from your username!

                               

                               

                              Jongware - Thank you for your description of your script. I see the logic in it. Didn't notice that "list" was just a variable - doh! Thinking about how I would extend it to apply "Quotes middle" para style to the paras between first and last - as we don't know how many paras there will be I can't refer to them specifically by their index so I thought I would first make every para in the array "Quotes middle" then allow the existing code to change the first and last. I added the line  list[l].appliedParagraphStyle = "Quotes middle"; as the first line within the loop. That does it.

                               

                              Now, just out of interest (this wasn't part of the original query I think, but Mayhem's script does it and I now see the need for it), is it possible to use your method to style paras on their own (individual quotes) to a different style? Is that do-able? I can't imagine the logic that would allow *that particular method* you showed me to distinguish that (I can use Mayhem's to do it if not). Currently such paras are styled as "Quotes last", since that is the last instruction to run within the loop. We're back to the old question of looking at styling of the paras before and after again, which your script was a way of avoiding!

                               

                              thanks,

                              Iain

                              • 12. Re: still got problems with finding next para
                                [Jongware] Most Valuable Participant

                                You can check the number of paragraphs *inside* each found array item simply by checking:

                                 

                                if (list[l].paragraphs.length == 1)
                                 ... // There can be only one!
                                else
                                 ...  // There can be more than one!
                                
                                • 13. Re: still got problems with finding next para
                                  Iain Robinson Level 1

                                  Highlander!

                                   

                                  That's done it. I was coming at it from completely the wrong angle (thinking I had to look at what was before and after). This is much more elegant than that.

                                   

                                  Thanks Jongware - great service for a Sunday!