7 Replies Latest reply on Jun 21, 2010 10:03 PM by SB Masthan

    JS CS3: Help to reduce running time of my script

    SB Masthan Level 1



      We have developed a script to find similiar words/characters at the end/start of 3 or more continous lines. The script has been developed by following steps:


      1. Get all lines of the document;

      2. Get first 2 characters of first line and compare with next two lines' first 2 characters.

      3. If matches, then give a no break before the word to flow.


      The same procedure for find end characters of the lines.


      As our documents has more than 300 pages, the script runs too long time (about 15 minutes) per document.


      Could any suggest to reduce the time of script running?


      My basic sript is:


      for (k=0; k<myStory.paragraphs.item(i).lines.length; k++) {

      var myParaText =  myStory.paragraphs.item(i);

      var myChar2Fa = myParaText.lines[k].characters.itemByRange(0,1).texts[0].contents;
      var myChar2Fb = myParaText.lines[k+1].characters.itemByRange(0,1).texts[0].contents;
      var myChar2Fc = myParaText.lines[k+2].characters.itemByRange(0,1).texts[0].contents;

      if (myChar2Fa== myChar2Fb && myChar2Fa== myChar2Fc) {


      Kindly suggest.




        • 1. Re: JS CS3: Help to reduce running time of my script
          Harbs. Level 6

          try: ...lines[k].words[-1].content



          • 2. Re: JS CS3: Help to reduce running time of my script
            Peter Kahrel Adobe Community Professional & MVP

            Big gains can usually be achieved by working with arrays rather than collections. In your script, for instance, work with an array rather than with the story.paragraphs object. When you compare words in paragraphs, it's usually quicker to work with the paragraph's contents rather than with the paragraphs word objects.


            You could recast your script along these lines:




            myParagraphs = myStory.paragraphs.everyItem().getElements();
            for (i = 0; i < myParagraphs.length; i++)
               myLines = myParagraphs[i].lines.everyItem().contents;
               for (j = 0; j < myLines.length; j++)
                  // do things


            The first line creates an array of all paragraphs in the story; the third line creates an array of strings, each string representing the contents of one line. Whether this works in your script I don't know, maybe not. But that first line will probably already make a difference.


            But do you really want to do this? Won't you end up with badly spaced paragraphs? Don't get me wrong, but this looks like another example of the distribution of space being sacrificed for some "rules", other examples of which are "you can't break the last lword of a paragraph", "paragraphs mustn't end in short lines", "never leave a single line at the foot or the top of a page", etc. etc.



            1 person found this helpful
            • 3. Re: JS CS3: Help to reduce running time of my script
              [Jongware] Most Valuable Participant

              Every interaction with the Object model costs -- in this case, asking ID for paragraphs.item(i).line, itemByrange(), etc. Avoid this by storing as much as possible direct references into variables.


              Every interaction with the document text itself also costs -- you will see the script runs much faster if you only count the number of occurrences. (But this cannot be avoided.)


              That said, your way of retrieving the first 2 characters per line is rather clumsy ... My version still takes the odd minute or so, for a 300 page test document, but I think it's mainly because ID has to re-flow each paragraph it changes.



              myStory = app.selection[0].parentStory;
              ln = myStory.lines;
              n_ln = ln.length;
              for (i=0; i<n_ln-2; i++)
               if (ln[i].length > 1 &&
                ln[i].contents.substring(0,2) == ln[i+1].contents.substring(0,2) &&
                ln[i].contents.substring(0,2) == ln[i+2].contents.substring(0,2))


              I'm not convinced this does what you intend: avoiding three consecutive lines to start with the same two characters. First of all, to be sure you'd need to run it again, since reflowing the text may move another word to the front of the line with those same characters.

              Second: the [-1] is a special index in InDesign. It does not point to the item before the current (as it would if -1 was treated the same as 0, 1, and 100), but instead it counts backwards from the end of the indexed item -- in this case, the No Break is applied to the last character of the 3rd line. I bet you wanted to apply it to the last character of the 2nd line (which, if so, is easy fixed).

              • 5. Re: JS CS3: Help to reduce running time of my script
                Harbs. Level 6



                In my experience, this rule does not hold true with Text objects. It seems that resolving Text objects using collections is actually less expensive than resolving them directly!


                The "myLines" line on the other hand, would make a big difference, but he's going to have reflow when he inserts the no-breaks. That means he will have to get the reference again when that happens...



                • 6. Re: JS CS3: Help to reduce running time of my script
                  Peter Kahrel Adobe Community Professional & MVP



                  You're right, and I had wanted to mention (but forgot to) that it turns out that sometimes collections process quicker than arrays. It's also true that applying nobreaks causes the paragraph to reflow, and if the paragraph composer is used, you can get reflows before and after the line that's being processed. I just wanted to give a general approach to speeding up scripts.



                  • 7. Re: JS CS3: Help to reduce running time of my script
                    SB Masthan Level 1

                    Hi Jongware, Peter, and Harb,


                    I applied with Jongware's code and it saves a huge time. Also I have learnt a new thing from your comments.


                    Thanks a lot for all of your help.