7 Replies Latest reply on Apr 28, 2015 7:04 AM by duder54538470

    Memory issues on a loop over all characters of a document

    duder54538470

      Hi all,

       

      I'm trying to implement a custom export to HTML of some of the contents of a document.

      I have a loop that checks if any character has a particular style (bold, italic...) and apply the correspondent inline tag (<strong>, <i>).

      This loop takes too long and makes inDesign to stop working. If i'm not mistaken, it's a memory leak issue. I've searched these forums and other places and found no solution to my problem.

      From what I read here, it looks like each one of those memory problems always needs it's particular solution. Hopefully you will be able to help me with this one.

       

      This is my code:

       

      main();
      function main() {
        //Some code
        var txtFrames = //an array containing all TextFrame objects in the document
        var txtFramesLength = txtFrames.length;
        for (i = 0; i<txtFramesLength; i++) {
          var parLength = txtFrames[i].paragraphs.length;
          for (j = 0; j<parLength; j++)  {
            var contentsWithCharStyle = applyCharStyle(txtFrames[i].paragraphs[j]);
            file.writeln('<p>' + contentsWithCharStyle + '</p>');
          }
        }
        var charStyleName = '';
        var charContents = '';
        function applyCharStyle(paragraph) {
          var chars = paragraph.characters;
          var result = '';
          for (k = 0, kLength = chars.length; k<kLength; k++) {
            charStyleName = chars[k].appliedCharacterStyle.name;
            charContents = chars[k].contents;
            if (charStyleName == '_03-Bold') {
              result += '<strong>' + charContents + '</strong>';
            } else if (charStyleName == '_02-Regular-Italic') {
              result += '<i>' + charContents + '</i>';
            } else if (charStyleName == '_04-Bold-Italic') {
              result += '<strong><i>' + charContents + '</i></strong>';
            } else {
              result += charContents;
            }
          }
          result = result.replace(/<\/strong><strong>/g, '');
          result = result.replace(/<\/i><i>/g, '');
          return result;
        }
      }
      
      
      
      

       

      So the issue comes from the repeated calls to applyCharStyle. Retrieving chars[k].appliedCharacterStyle and chars[k].contents are the particular operations making everything to slow down.

      I guess those properties are staying somewhere in memory every time.

       

      Thanks in advance for your help and time. .appliedCharacterStyle appl dfdwyCharStyleapplyCharStyleapplyCharStyle

        • 1. Re: Memory issues on a loop over all characters of a document
          cchimi Level 2

          Is there a reason not to use find to get an array of all characters in a particular style, and then loop through that?

          • 2. Re: Memory issues on a loop over all characters of a document
            Vamitul Level 4

            You could just use a series of find/change greps:

            find: (.+), applied character style: _03-Bold

            change to: <strong>$1</strong>

             

            and so on.

            or at least use textStyleRange instead of characters collection.

            • 3. Re: Memory issues on a loop over all characters of a document
              duder54538470 Level 1

              Thanks to both of you, it works fine now.

               

              Nevertheless, if possible, I would like to know what was the thing fulfilling my memory, why was it doing so and/or what has to be done to allow memory to be deallocated.

              • 4. Re: Memory issues on a loop over all characters of a document
                Vamitul Level 4

                well.. how many characters are in your document? Consider that you are iterating over all of them, and changing them. And consider that an indesign document is nothing else but a big relational database, so whenever you do something with a character, a lot of other objects get touched too (paragraphs, stories, frames etc).

                • 5. Re: Memory issues on a loop over all characters of a document
                  duder54538470 Level 1

                  The document has 3200 characters. So you say that it´s not about a memory issue, but rather the actual time it takes to perform all these operations on those objects from the database?

                   

                  The problem now is that sometimes adding those <strong> tags makes text overflow from a text frame to another and they don't get printed to the HTML file in the desired order anymore. Do you know how to avoid this overflow?

                  • 6. Re: Memory issues on a loop over all characters of a document
                    Vamitul Level 4

                    As a general rule, when using findGrep() or changeGrep() either use it in the form findGrep(true) or, if iterating through the result go from back to front as not to invalidate the references.
                    Another thing, don't use something like myTextFrame.contents, but rather myTextFrame.parentStory.contents, so you get the whole story.
                    I can't help more without seeing your code.

                    • 7. Re: Memory issues on a loop over all characters of a document
                      duder54538470 Level 1

                      I tried using the story instead of frames, but then the story doesn't list contents in the order I need. Before looping through the text frames I give them a particular order based on their geometric positions, and I can't do that with stories.

                       

                      changeGrep(true) didn't change anything but i'll remember the advice.

                       

                      My code looks like:

                       

                      main();
                      function main() {
                      
                        app.findGrepPreferences = NothingEnum.nothing;
                        app.changeGrepPreferences = NothingEnum.nothing;
                        app.findTextPreferences = NothingEnum.nothing;
                        app.changeTextPreferences = NothingEnum.nothing;
                        app.findGrepPreferences.appliedCharacterStyle = app.activeDocument.characterStyleGroups.itemByName('_Frutiger-Serif-LT-Pro').characterStyles.itemByName('_06-Bold');
                        app.findGrepPreferences.findWhat = '(.+)';
                        app.changeGrepPreferences.changeTo = '<strong>$1</strong>';
                        app.activeDocument.changeGrep();
                        app.findGrepPreferences.appliedCharacterStyle = app.activeDocument.characterStyleGroups.itemByName('_Frutiger-Serif-LT-Pro').characterStyles.itemByName('_05-Regular-Italic');
                        app.findGrepPreferences.findWhat = '(.+)';
                        app.changeGrepPreferences.changeTo = '<i>$1</i>';
                        app.activeDocument.changeGrep();
                        app.findGrepPreferences.appliedCharacterStyle = app.activeDocument.characterStyleGroups.itemByName('_Frutiger-Serif-LT-Pro').characterStyles.itemByName('_07-Bold-Italic');
                        app.findGrepPreferences.findWhat = '(.+)';
                        app.changeGrepPreferences.changeTo = '<strong><i>$1</i></strong>';
                        app.activeDocument.changeGrep();
                      
                        var txtFrames = //an array containing all TextFrame objects in the document
                        var txtFramesLength = txtFrames.length;
                        for (i = 0; i<txtFramesLength; i++) {
                          var parLength = txtFrames[i].paragraphs.length;
                          for (j = 0; j<parLength; j++)  {
                            file.writeln('<p>' + txtFrames[i].paragraphs[j].contents + '</p>');
                          }
                        }
                      

                       

                      If I use the document's stories instead of TextFrames, it fixes the overflown text issue but it isn't ordered as I would like it to be so I can't make it this way.

                       

                      Isn't it weird that there is no way to do it the way i was trying to do it at the beginning? I can't be the only one who ever needed to loop through the contents of all chars of a document, and it feels weird if indesign can't make it without crashing or taking minutes to loop over 3000 chars.