8 Replies Latest reply on Feb 3, 2017 3:10 PM by laindustria

    Speed up text script execution

    laindustria Level 1

      Hi again.

      I'm working with a long Story (of 24 A3 pages) that I have to fit in its corresponding text containers by adjusting the leading of some paragraphs.

      Doing this by loopings like


      for (var i=0; i<myStory.paragraphs.length; i++)
          if(myStory.paragraphs[i].appliedParagraphStyle.name == "myStyle")
              myStory.paragraphs[i].leading = myLeading;


      is extremely slow. And assuming that I have to insert this code into another loop,... No way.

      I have found that adjusting the all Story leading by


      myStory.leading = myLeading,


      is almost instantly. But I don't want to work in all paragraphs.

      So I decided to apply the myStory.leading = myLeading first and then restoring the leading of the paragraphs that don't have "mySyle" by loops again.

      But the fact that I have to use the loops, makes the code slow again.

      Does any one how to solve this problem or suggest another algorithm to accelerate the process?


      I found that changing the app.scriptPreferences.userInteractionLevel property helps sometimes, but not now. May be there are another properties to manipulate to get better process execution time.


      Thanks very much.

        • 1. Re: Speed up text script execution
          Laubender Adobe Community Professional & MVP

          Did you try with Text Find/Replace ?

          Maybe that's faster…



          • 2. Re: Speed up text script execution
            laindustria Level 1

            Sorry, but how it would be the code for changing the leading of some paragraphs that way?

            • 3. Re: Speed up text script execution
              Laubender Adobe Community Professional & MVP


              I think you have three options here:


              1. Change the value of leading of the applied paragraph style "myStyle"

              That would be the most effective way. But would be document wide.


              Something like this:

              app.documents[0].paragraphStyles.itemByName("myStyle").leading = myLeading;


              2. If you want to override the applied paragraph style's formatting with a new leading value, you could restrict the scope of your Find/Replace to e.g. the story of some selected text and do it like that:


              var doc = app.documents[0];
              // The paragraph style we like to find:
              var paraStyleToFind = doc.paragraphStyles.itemByName("myStyle");
              // The value you like to change:
              var myLeadingToChange = Leading.AUTO;
              // Define the principle scope of find/replace, e.g. selected text or the document or a specific story
              var myScope = app.selection[0].parentStory;
              // Restrict or widen your scope: 
              app.findChangeTextOptions.properties =
                  includeFootnotes : true ,
                  includeHiddenLayers : true ,
                  includeMasterPages : true
                      others as well, see DOM documentation e.g. for InDesign CS6
              // First set all needed properties application wide:
              // Clear the Find/Change dialog first:
              app.findTextPreferences = null;
              app.changeTextPreferences = null;
              // What we like to find by formatting:
              app.findTextPreferences.properties =
                  appliedParagraphStyle : paraStyleToFind
              // What we like to change by formatting:
              app.changeTextPreferences.properties =
                  leading : myLeadingToChange
              // Change the text in the range of the defined scope:
              // Clear the Find/Change dialog at the end:
              app.findTextPreferences = null;
              app.changeTextPreferences = null;


              3. But perhaps—depending on your situation—the best thing you could do is to add a new paragraph style that is based on the one you are looking for, changing the leading there and apply the new paragraph style to the text you are looking for. You could do this with a scripting pattern as shown with option 2 above.


              There are plenty of examples for Text- or Grep Find/Change in the InDesign scripting forum. Perhaps more with Grep Find/Change than on Text Find/Change. But the used patterns basically are the same. See also the DOM documentation for InDesign for specific properties and methods.


              For the latest InDesign version see here:

              InDesign ExtendScript API (12.0)


              For CS6 and older versions see here:

              Indesign JavaScript Help



              1 person found this helpful
              • 4. Re: Speed up text script execution
                Peter Kahrel Adobe Community Professional & MVP

                In your code, for every paragraph you make inDesign recompute the collection of paragraphs:

                1. for (var i=0; i<myStory.paragraphs.length; i++)

                2. if(myStory.paragraphs[i]...

                3. myStory.paragraphs[i]...


                which is time-consuming. You can speed up your script considerably (the bigger the story, the bigger the gain) by computing the story's paragraph once, creating an array of paragraphs. Those are the paragraphs you'll then work on:


                myParagraphs = myStory.paragraphs.everyItem().getElements();
                for (var i = myParagraphs.length-1; i >= 0; i--)  
                  if(myParagraphs[i].appliedParagraphStyle.name == "myStyle")
                    myParagraphs[i].leading = myLeading;


                And by iterating through the array starting at the end you compute the length of the array only once.



                2 people found this helpful
                • 5. Re: Speed up text script execution
                  Marc Autret Level 5

                  Hi all,


                  Regarding performance Uwe Laubender's first suggestion is by far the best option when the style can be rewritten without side-effects over the document. Otherwise you can use the find/change approach as suggested.


                  If your conditions are more complicated and require additional “per paragraph” tests, I guess the process can't be done faster than the way Peter has shown (i.e. the old good getElements() trick that leads to resolve the underlying text ranges into an array, and so on). The task might be long though, if many many paragraphs have to be treated.


                  Going back to Uwe's #1 method I see a variant in case you need to preserve the original style as it is outside of the story. And that's an interesting problem in itself… to which I didn't find a perfect solution so far :-( The idea is to create a temporary ghost document just to load the target story alone in order to rewrite myTargetStyle properties, including a new name. It is then possible to reinject the result into the original document without interfering with existing styles. However, default settings and/or [Basic Paragraph] settings and/or style hierarchy are not so easy to manage from the temporary document, so when the text goes back some style override flags may appear within the story. Visible changes look fine anyway, at least in my tests. This alternative method could surely be improved as to provide a perfect job. And it is really fast too.


                  First draft:


                  // YOUR SETTINGS
                  // ---
                  const TARGET_STYLE = 'MyStyle';
                  const NEW_STYLE_PROPS = {
                      name: TARGET_STYLE + '_Fixed',
                      leading: 12,
                      // etc.
                  // Provide your story here:
                  // ---
                  var myStory = app.selection[0].parentStory;
                  // Only applies style fix to myStory.
                  // ---
                  const LO_BEG = +LocationOptions.AT_BEGINNING;
                  var ip = myStory.insertionPoints[0],
                      tDoc = app.documents.add(false),
                      tSto = myStory.move(LO_BEG,tDoc.textFrames.add().parentStory);
                  tDoc.paragraphStyles.itemByName(TARGET_STYLE).properties = NEW_STYLE_PROPS;
                  tSto.duplicate(LocationOptions.AT_BEGINNING, ip);




                  1 person found this helpful
                  • 6. Re: Speed up text script execution
                    Laubender Adobe Community Professional & MVP

                    However, default settings and/or [Basic Paragraph] settings and/or style hierarchy are not so easy to manage from the temporary document, so when the text goes back some style override flags may appear within the story.

                    Hm, yes.
                    With some cases we already have seen here around in the forums where the definition of the [Basic Paragraph] is different from the active document and a new one created, there is indeed a challenge.


                    Just a thought:

                    Would it help to make a duplicate of the active document, remove all page items, remove all styles as far as possible—the ones named in "[…]" cannot be removed—and then move the story over to that document?



                    • 7. Re: Speed up text script execution
                      laindustria Level 1

                      Hi, Uwe.

                      I have 192 text columns (or text containers) and I have to adjust the leading of each of them in order to fit in its corresponding container. The idea is avoid split paragraphs between two containers. There are near 5 paragraphs styles besides inline images.

                      So. I am working with options 2 and 3.

                      I can manage GREP styles as designer but not as programmer yet. I'm working with it.

                      Thanks for your help.

                      • 8. Re: Speed up text script execution
                        laindustria Level 1

                        Hi, Peter.

                        I didn't know that issue of recomputing, although I actually am working with a code similar to yours.

                        I saw the time consuming problem is equally due to the iterations and to the displaying mode. So avoiding the loop iterations is a priority in itselfThanks.