8 Replies Latest reply on Apr 29, 2010 11:40 PM by Kasyan Servetsky

    Newbie question on FindChangeByList script (REVISED)

    JoJo Jenkins Level 1

      Hi...I'm using FindChangeByList (the Javascript version) and I have a question. The default behavior of this script seems to be the following:

       

      1. If text is selected, then run the script on the text

       

      2. Otherwise, run the script on the entire document.

       

      By looking at the script (which I'm pasting below), I can see that the script is intentionally set up this way. I'm totally new to scritping, but by reading the remarks I think these are the relevent lines:

       

      //Something was selected, but it wasn't a text object, so search the document.
           myFindChangeByList(app.documents.item(0));
      

       

      and

       

      //Nothing was selected, so simply search the document.
         myFindChangeByList(app.documents.item(0));
      

       

      MY GOAL:  I want to prevent the script running on my entire document by mistake if I mistakenly don't have the Text tool active.

       

      I have a feeling that would be very easy to write, but since I know nothing about scripting, I appeal to this forum. Thanks.

       

      If you need it, the entire script is pasted below. (It's also a standard sample script built into CS4).

       

      //FindChangeByList.jsx
      //An InDesign CS4 JavaScript
      /*  
      @@@BUILDINFO@@@ "FindChangeByList.jsx" 2.0.0.0 10-January-2008
      */
      //Loads a series of tab-delimited strings from a text file, then performs a series
      //of find/change operations based on the strings read from the file.
      //
      //The data file is tab-delimited, with carriage returns separating records.
      //
      //The format of each record in the file is:
      //findType<tab>findProperties<tab>changeProperties<tab>findChangeOptions<tab>description
      //
      //Where:
      //<tab> is a tab character
      //findType is "text", "grep", or "glyph" (this sets the type of find/change operation to use).
      //findProperties is a properties record (as text) of the find preferences.
      //changeProperties is a properties record (as text) of the change preferences.
      //findChangeOptions is a properties record (as text) of the find/change options.
      //description is a description of the find/change operation
      //
      //Very simple example:
      //text {findWhat:"--"} {changeTo:"^_"} {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:false} Find all double dashes and replace with an em dash.
      //
      //More complex example:
      //text {findWhat:"^9^9.^9^9"} {appliedCharacterStyle:"price"} {include footnotes:true, include master pages:true, include hidden layers:true, whole word:false} Find $10.00 to $99.99 and apply the character style "price".
      //
      //All InDesign search metacharacters are allowed in the "findWhat" and "changeTo" properties for findTextPreferences and changeTextPreferences.
      //
      //If you enter backslashes in the findWhat property of the findGrepPreferences object, they must be "escaped"
      //as shown in the example below:
      //
      //{findWhat:"\\s+"}
      //
      //For more on InDesign scripting, go to http://www.adobe.com/products/indesign/scripting/index.html
      //or visit the InDesign Scripting User to User forum at http://www.adobeforums.com
      //
      main();
      function main(){
       var myObject;
       //Make certain that user interaction (display of dialogs, etc.) is turned on.
       app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
       if(app.documents.length > 0){
        if(app.selection.length > 0){
         switch(app.selection[0].constructor.name){
          case "InsertionPoint":
          case "Character":
          case "Word":
          case "TextStyleRange":
          case "Line":
          case "Paragraph":
          case "TextColumn":
          case "Text":
          case "Cell":
          case "Column":
          case "Row":
          case "Table":
           myDisplayDialog();
           break;
          default:
           //Something was selected, but it wasn't a text object, so search the document.
           myFindChangeByList(app.documents.item(0));
         }
        }
        else{
         //Nothing was selected, so simply search the document.
         myFindChangeByList(app.documents.item(0));
        }
       }
       else{
        alert("No documents are open. Please open a document and try again.");
       }
      }
      function myDisplayDialog(){
       var myObject;
       var myDialog = app.dialogs.add({name:"FindChangeByList"});
       with(myDialog.dialogColumns.add()){
        with(dialogRows.add()){
         with(dialogColumns.add()){
          staticTexts.add({staticLabel:"Search Range:"});
         }
         var myRangeButtons = radiobuttonGroups.add();
         with(myRangeButtons){
          radiobuttonControls.add({staticLabel:"Document"});
          radiobuttonControls.add({staticLabel:"Selected Story", checkedState:true});
          if(app.selection[0].contents != ""){
           radiobuttonControls.add({staticLabel:"Selection", checkedState:true});
          }
         }   
        }
       }
       var myResult = myDialog.show();
       if(myResult == true){
        switch(myRangeButtons.selectedButton){
         case 0:
          myObject = app.documents.item(0);
          break;
         case 1:
          myObject = app.selection[0].parentStory;
          break;
         case 2:
          myObject = app.selection[0];
          break;
        }
        myDialog.destroy();
        myFindChangeByList(myObject);
       }
       else{
        myDialog.destroy();
       }
      }
      function myFindChangeByList(myObject){
       var myScriptFileName, myFindChangeFile, myFindChangeFileName, myScriptFile, myResult;
       var myFindChangeArray, myFindPreferences, myChangePreferences, myFindLimit, myStory;
       var myStartCharacter, myEndCharacter;
       var myFindChangeFile = myFindFile("/FindChangeSupport/FindChangeList.txt")
       if(myFindChangeFile != null){
        myFindChangeFile = File(myFindChangeFile);
        var myResult = myFindChangeFile.open("r", undefined, undefined);
        if(myResult == true){
         //Loop through the find/change operations.
         do{
          myLine = myFindChangeFile.readln();
          //Ignore comment lines and blank lines.
          if((myLine.substring(0,4)=="text")||(myLine.substring(0,4)=="grep")||(myLine.substring(0,5)=="glyph")){
           myFindChangeArray = myLine.split("\t");
           //The first field in the line is the findType string.
           myFindType = myFindChangeArray[0];
           //The second field in the line is the FindPreferences string.
           myFindPreferences = myFindChangeArray[1];
           //The second field in the line is the ChangePreferences string.
           myChangePreferences = myFindChangeArray[2];
           //The fourth field is the range--used only by text find/change.
           myFindChangeOptions = myFindChangeArray[3];
           switch(myFindType){
            case "text":
             myFindText(myObject, myFindPreferences, myChangePreferences, myFindChangeOptions);
             break;
            case "grep":
             myFindGrep(myObject, myFindPreferences, myChangePreferences, myFindChangeOptions);
             break;
            case "glyph":
             myFindGlyph(myObject, myFindPreferences, myChangePreferences, myFindChangeOptions);
             break;
           }
          }
         } while(myFindChangeFile.eof == false);
         myFindChangeFile.close();
        }
       }
      }
      function myFindText(myObject, myFindPreferences, myChangePreferences, myFindChangeOptions){
       //Reset the find/change preferences before each search.
       app.changeTextPreferences = NothingEnum.nothing;
       app.findTextPreferences = NothingEnum.nothing;
       var myString = "app.findTextPreferences.properties = "+ myFindPreferences + ";";
       myString += "app.changeTextPreferences.properties = " + myChangePreferences + ";";
       myString += "app.findChangeTextOptions.properties = " + myFindChangeOptions + ";";
       app.doScript(myString, ScriptLanguage.javascript);
       myFoundItems = myObject.changeText();
       //Reset the find/change preferences after each search.
       app.changeTextPreferences = NothingEnum.nothing;
       app.findTextPreferences = NothingEnum.nothing;
      }
      function myFindGrep(myObject, myFindPreferences, myChangePreferences, myFindChangeOptions){
       //Reset the find/change grep preferences before each search.
       app.changeGrepPreferences = NothingEnum.nothing;
       app.findGrepPreferences = NothingEnum.nothing;
       var myString = "app.findGrepPreferences.properties = "+ myFindPreferences + ";";
       myString += "app.changeGrepPreferences.properties = " + myChangePreferences + ";";
       myString += "app.findChangeGrepOptions.properties = " + myFindChangeOptions + ";";
       app.doScript(myString, ScriptLanguage.javascript);
       var myFoundItems = myObject.changeGrep();
       //Reset the find/change grep preferences after each search.
       app.changeGrepPreferences = NothingEnum.nothing;
       app.findGrepPreferences = NothingEnum.nothing;
      }
      function myFindGlyph(myObject, myFindPreferences, myChangePreferences, myFindChangeOptions){
       //Reset the find/change glyph preferences before each search.
       app.changeGlyphPreferences = NothingEnum.nothing;
       app.findGlyphPreferences = NothingEnum.nothing;
       var myString = "app.findGlyphPreferences.properties = "+ myFindPreferences + ";";
       myString += "app.changeGlyphPreferences.properties = " + myChangePreferences + ";";
       myString += "app.findChangeGlyphOptions.properties = " + myFindChangeOptions + ";";
       app.doScript(myString, ScriptLanguage.javascript);
       var myFoundItems = myObject.changeGlyph();
       //Reset the find/change glyph preferences after each search.
       app.changeGlyphPreferences = NothingEnum.nothing;
       app.findGlyphPreferences = NothingEnum.nothing;
      }
      function myFindFile(myFilePath){
       var myScriptFile = myGetScriptPath();
       var myScriptFile = File(myScriptFile);
       var myScriptFolder = myScriptFile.path;
       myFilePath = myScriptFolder + myFilePath;
       if(File(myFilePath).exists == false){
        //Display a dialog.
        myFilePath = File.openDialog("Choose the file containing your find/change list");
       }
       return myFilePath;
      }
      function myGetScriptPath(){
       try{
        myFile = app.activeScript;
       }
       catch(myError){
        myFile = myError.fileName;
       }
       return myFile;
      }
      

       

      Message was edited by: JoJo Jenkins. Proper script formatting was used and the question was revised and made more concise.

        • 1. Re: Newbie question on FindChangeByList script (REVISED)
          ArcRaj Level 1

          Hai All,

           

          Is it possible to read the contents in Excel file for Find and Change list like TXT file below?

           

          Thanks,

           

          ArcRaj

          • 2. Re: Newbie question on FindChangeByList script (REVISED)
            John Hawkinson Level 5

            It's mighty difficult. You should be able to export your Excel file to a text file. Or to a CSV file and modify the script to read that. What's your goal? Why is that a potentially helpful workflow for you?

            • 3. Re: Newbie question on FindChangeByList script (REVISED)
              ArcRaj Level 1

              Hai Hawkinson,

               

              Thanks for the response, I feel that it'll comfortable to fix the each item in Find and Change details in the Excel cells instead of giving tabbed contents.

               

              Thanks,

               

              ArcRaj

              • 4. Re: Newbie question on FindChangeByList script (REVISED)
                ArcRaj Level 1

                Pl. respond, I'm again explaining below:

                 

                Currently, we are following the pattern like below:

                 

                grep {findWhat:"  +"} {changeTo:" "} {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:false} Find all double spaces and replace with single spaces.

                 

                instead can we follow simply like [SPACE]+ in the first cell and [SPACE] in the next cell in the Excel file? This is not big deal, but while accessing the Excel files directly we can do many things like accessing the values in the Excel cells and creating the InDesign templates based on that.

                • 5. Re: Newbie question on FindChangeByList script (REVISED)
                  [Jongware] Most Valuable Participant

                  Are you thinking of using Adobe Extendscript to process Microsoft Excel files from within InDesign? Because that's not gonna work. Use Microsoft's scripting language (VBA) to process Excel, from within Excel. And I am 100% sure Adobe's FindChangeList simply won't do anything when you try to run it in Excel.

                   

                  As soon as you import an Excel file into InDesign, it stops being an Excel file, and it's a regular InDesign table, so that's no solution either.

                  • 6. Re: Newbie question on FindChangeByList script (REVISED)
                    John Hawkinson Level 5

                    As I said on March 30, a reasonable workflow is for you to save your Excel worksheet as a CSV file, which you can then read in Adobe Javascript. If you really want to, you can write some VBscript to tell Excel to do that, and execute it from Javascript in InDesign. But since exporting to CSV takes only a few seconds, unless you have to productionize this hundreds of times, I would just do that part by hand.

                     

                    If this doesn't work for you, please tell us more about your workflow.

                    • 7. Re: Newbie question on FindChangeByList script (REVISED)
                      JoJo Jenkins Level 1

                      I'm a little confused. None of the replies to my original post for this thread seem to relate to my question. See the first post in this thread. Sorry. Thanks.

                      • 8. Re: Newbie question on FindChangeByList script (REVISED)
                        Kasyan Servetsky Level 5

                        You can't check which instrument is active in InDesign by script (although you can select it, but it's not useful in your case).

                        I suggest you  the following approach: check if a single object is selected and if it's a text frame — if so, make a search without showing the dialog.

                        Notice that use

                        myFindChangeByList(app.selection[0].parentStory.texts[0]);

                        instead of

                        myFindChangeByList(app.selection[0]);

                        this allows me to process threaded and overset text.

                         

                        function main(){
                             var myObject;
                             //Make certain that user interaction (display of dialogs, etc.) is turned on.
                             app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
                             if(app.documents.length > 0){
                                  if(app.selection.length == 1 && app.selection[0].constructor.name == "TextFrame"){
                                       myFindChangeByList(app.selection[0].parentStory.texts[0]);
                                  }
                                  else if(app.selection.length > 0){
                                       switch(app.selection[0].constructor.name){
                                            case "InsertionPoint":
                                            case "Character":
                                            case "Word":
                                            case "TextStyleRange":
                                            case "Line":
                                            case "Paragraph":
                                            case "TextColumn":
                                            case "Text":
                                            case "Cell":
                                            case "Column":
                                            case "Row":
                                            case "Table":
                                                 myDisplayDialog();
                                                 break;
                                            default:
                                                 //Something was selected, but it wasn't a text object, so search the document.
                                                 myFindChangeByList(app.documents.item(0));
                                       }
                                  }
                                  else{
                                       //Nothing was selected, so simply search the document.
                                       myFindChangeByList(app.documents.item(0));
                                  }
                             }
                             else{
                                  alert("No documents are open. Please open a document and try again.");
                             }
                        }