10 Replies Latest reply on Mar 12, 2015 1:32 AM by Luca Bisin

    Change case on multiple documents

    Luca Bisin

      Hi there!

      I'm very newbie to scripting and I have the following script which finds "AllCaps" format text and change it to real uppercase. I'm working with ID CS 6 on Windows XP.

      The script works on a single document if there's one open, otherwise it asks for a folder and process all the INDD files in that folder.

      This is what I have:

       

      if(app.documents.length != 0){
          processDocument(app.activeDocument);
          alert("Done!");
          }
      else {
          _folder = Folder('~/Desktop').selectDlg("Select folder");
          if(_folder == null) exit();
          _files = _folder.getFiles("*.indd");
          if(_files.length == 0){
                  alert("No INDD files in the selected folder!");            
              }
          else {
              for (i=0; i<_files.length; i++){
              app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
              _inddFile = _files[i]
              doc = app.open(_inddFile);
              app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;      
              processDocument(doc);
              app.activeDocument.close(SaveOptions.yes);
              } 
          alert("Done!");
          }
      }
      
      function processDocument(doc) {    
          app.findGrepPreferences = app.changeGrepPreferences = null;
          app.findGrepPreferences.capitalization = Capitalization.allCaps;
          app.findGrepPreferences.appliedCharacterStyle = 'Red';
          var _results = doc.findGrep();
          app.findGrepPreferences = app.changeGrepPreferences = null;    
          _length = _results.length;
          for (i=0; i<_length; i++) {
              _results[i].texts[0].changecase(ChangecaseMode.uppercase);
              _results[i].texts[0].capitalization = Capitalization.normal;
              _results[i].texts[0].appliedCharacterStyle = 'Blue';
          }
      }
      

       

      The script works well on a single document, but for some reason it doesn't work on multiple documents. I'm trying the script on 4 files with this content (colors are added to the text only to help verify the results):

       

       

      Every time only the first or the first two documents are processed correctly, the others are not processed at all. But I'm getting no error message. Where's the problem?

      Any help would be greatly appreciated!

       

      Luca

        • 1. Re: Change case on multiple documents
          nicolaik Level 1

          I am on 5.5 and a mac, so it might be different

           

          app.findGrepPreferences.appliedCharacterStyle = 'Red';


          The character style has to be an object. I think you need to use itemByName('Red')  or iterate through character styles on each document and reference the one which matches by name


          Edit


          Sorry, I was wrong, it does accept string. Please ignore


          Edit 2


          It works fine for me. The only way I can recreate your problem is when the character style 'Red' is not present in the other files.

          • 2. Re: Change case on multiple documents
            Luca Bisin Level 1

            Hi nicolaik,

             

            To be more clear: character styles play no role for me, I added them only to color the text in order to help verifying the results of the script: it is faster to see if the text has changed form red to blue, than if the text has changed from all caps format to real uppercase.

             

            So the processDocument function could be like this:

             

            function processDocument(doc) {     
                app.findGrepPreferences = app.changeGrepPreferences = null; 
                app.findGrepPreferences.capitalization = Capitalization.allCaps; 
                var _results = doc.findGrep(); 
                app.findGrepPreferences = app.changeGrepPreferences = null;     
                _length = _results.length; 
                for (i=0; i<_length; i++) { 
                    _results[i].texts[0].changecase(ChangecaseMode.uppercase); 
                    _results[i].texts[0].capitalization = Capitalization.normal; 
                } 
            } 
            

             

            I've tried the script on Mac CS 6 and on Win CS 5.5 and it doesn't work for me.

             

            I guess the problem has something to do with the "_results" array: it seems like the script doesn't re-populate the array (or doesn't execute the grep search) after the first document in the folder, so the for loop in the function is not executed.

            • 3. Re: Change case on multiple documents
              Vamitul Level 4

              Script looks fine to me, but you should make a habit of using findGrep(true) so it searches from the back.

              Do the third and fourth documents have the character style 'Red' and 'Blue' in them? I understand you only added them for visual input, but since you did, the script will look for them.


              • 4. Re: Change case on multiple documents
                Jump_Over Level 5

                Hi,

                 

                Watch variable names' conflict (doc - doc)

                Try to differ variable names. Basically the good practice is to declare var names if no need to set them as global.

                Watch ";" at the end of lines (line #15)

                 

                Code logic seems good for me

                 

                Jarek

                • 5. Re: Change case on multiple documents
                  nicolaik Level 1

                  I tried to re-create your problem again and I do have something similar. I know it can't be right, but mine started working when I changed variable i in the second for. I can see they have different scope, but somehow it made difference. Could you try it by any chance?

                   

                  #target indesign
                  if(app.documents.length != 0){ 
                      processDocument(); 
                      alert("Done!"); 
                      } 
                  else { 
                      _folder = Folder('~/Desktop').selectDlg("Select folder"); 
                      if(_folder == null) exit(); 
                      _files = _folder.getFiles("*.indd"); 
                      if(_files.length == 0){ 
                              alert("No INDD files in the selected folder!");             
                          } 
                      else { 
                          for (i=0; i<_files.length; i++){ 
                          app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT; 
                          _inddFile = _files[i] ;
                          doc = app.open(_inddFile); 
                          app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;       
                          processDocument(doc); 
                          app.activeDocument.close(SaveOptions.yes); 
                          }  
                      alert("Done!"); 
                      } 
                  } 
                  
                  function processDocument() {     
                      app.findGrepPreferences = app.changeGrepPreferences = null; 
                      app.findGrepPreferences.capitalization = Capitalization.allCaps; 
                      app.findGrepPreferences.appliedCharacterStyle = "Red"; 
                      var _results = app.activeDocument.findGrep(); 
                      $.write(_results);
                      app.findGrepPreferences = app.changeGrepPreferences = null;     
                      _length = _results.length; 
                      $.write(_length);
                      for (s=0; s<_length; s++) { 
                          _results[s].texts[0].changecase(ChangecaseMode.uppercase); 
                          _results[s].texts[0].capitalization = Capitalization.normal; 
                          _results[s].texts[0].appliedCharacterStyle = 'Blue'; 
                      } 
                  }
                  
                  
                  • 6. Re: Change case on multiple documents
                    Vamitul Level 4

                    nicolaik good catch.. since the variables are not declared through var, they become globals and mess up the loops.

                    using

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

                    and

                    for (var i=0; i<_length; i++) {
                    

                    will fix the problems

                    • 7. Re: Change case on multiple documents
                      Luca Bisin Level 1

                      Great! It works!

                      Thank you all for your help!

                       

                      @nicolaik: would you (or someone else) be so kind to explain me what the lines 31 and 34 in your code do? What is the "$" sign for?

                      • 8. Re: Change case on multiple documents
                        nicolaik Level 1

                        My bad, I forgot to delete them. I was dumping the variables trying to track the problem. This is for debugging only.

                         

                        $.write() will evaluate and output the result in your Console, if you are using ESTK. This would be the same as using alert(), but without a popup dialogue. Vanila JavaScript uses console.log() for the same purpose.

                        • 9. Re: Change case on multiple documents
                          nicolaik Level 1

                          Vamitul - many thanks for the explanation, I learned something useful. This will probably resolve half of my own bugs .

                          • 10. Re: Change case on multiple documents
                            Luca Bisin Level 1

                            Thank you so much!