1 2 Previous Next 48 Replies Latest reply on Nov 7, 2016 1:32 PM by Wosven

    Create an array of arrays from a .txt file!

    Obi-wan Kenobi Adobe Community Professional

      Hi all scripters,

       

      The beginning is a .txt file containing data as:

       

      text_1;text_12

      text_2;text_23

      text_3;text_39

       

      I'm able to get an array as:

       

      [text_1;text_12, text_2;text_23, text_3;text_39, …]

       

      But I need that:

       

      [ ["text_1","text_12"], ["text_2","text_23"], ["text_3","text_39"], …]

       

      I've absolutely no idea about the way to get this array of arrays!!

       

      Thanks for your ideas!

       

      (^/)

        • 1. Re: Create an array of arrays from a .txt file!
          Laubender Adobe Community Professional & MVP

          Hi Obi-wan,

          one split() and one loop with another split() can get you there.

          Depending on the line separator—\n or \r—that could be:

           

          var array1 = string.split("\r");
          var array2 = [];
          
          for(var n=0;n<array1.length;n++)
          {
              array2[array2.length++] = array1[n].split(";")
          };
          

           

          Regards,
          Uwe

          • 2. Re: Create an array of arrays from a .txt file!
            Obi-wan Kenobi Adobe Community Professional

            Hi Uwe,

             

            It seemed interesting but I can't make it work in my script.

             

            The deal: I have 4 Layers [Layer_1, Layer_2, Layer_3 and Layer_4] and I want to change their name but not necessarily for all!

            So I have a list (.txt file):

             

            Layer_1;Layer_12

            Layer_2;Layer_23

             

            To validate the code, I've temporarily pasted this list directly into the .jsx:

             

            myList = ["Layer_1;Layer_12","Layer_2;Layer_23"];
            
            
            var myLayers = app.activeDocument.layers;
            
            
            for (var L = 0; L < myLayers.length; L++) {
                    var myLayerName_0 = myLayers[L].name;
                    var mLength_0 = myLayerName_0.length;
            
            
                    for (var N = 0; N < myList.length; N++) {
                            var mList_0 = myList[N];
                            myConcordance = mList_0.slice(0,mLength_0);
                            myLayerName_1 = mList_0.slice(mLength_0+1,mList_0.length);
                                
                                if ( myLayerName_0 == myConcordance ) var myLayerName_0 = myLayerName_1;
            
            
                    } 
            }
            

             

            The writing seems logical but nothing happens in the Layers panel! 

             

            Tired! Thanks in advance! 

             

            (^/)

            • 3. Re: Create an array of arrays from a .txt file!
              Laubender Adobe Community Professional & MVP

              Hi Obi-wan,

               

              before talking about your code, I want to talk about the separator string—";"—you are using with your list:


              It should be one, that is not used in the listed names of layers. And that could become quite difficult since it seems like every possible character is allowed for forming a name of a layer. Even a tabulator character could be used in a layer name: "\t”. It could not be typed in, but it could be copy/pasted to the Name input field.


              So the question boils down to:
              What is a good separator string for a concordance list, old name|separator|new name for renaming layers?

               

              How about:
              "\u0016"

               

              That is used as a special character for tables with InDesign.

              I tried to copy/paste it to the Name input field of the Layers panel, but it was stripped out while pasting.

               

              Still one could assign a name using "\u0016" as part of a string to a layer's name by scripting:

               

              app.documents[0].layers[0].name = "N"+"\u0016"+"N";
              

               

              Screenshot after running this line:

               

              SpecialCharacter-used-with-LayerName.png

               

              So it's not 100% save to use a delimiter like that.
              Does someone has a better idea?

               

              Hm.

              Would a Windows user be able to insert "\u0016" to the Name edit field using the keyboard by pressing Alt+0016 ?

              Or Alt 022 or Alt 22 ?
              Cannot test this, currently I'm on Mac OSX.

               

              Regards,
              Uwe

              • 4. Re: Create an array of arrays from a .txt file!
                Obi-wan Kenobi Adobe Community Professional

                Hi Uwe,

                 

                A little misunderstanding between us! 

                 

                I've ";" in my .txt file because it's an export from Excel in .txt with as horizontal separator = ";".

                 

                The user wants to change layer names! So he creates a concordances table in Excel.

                First column = actual layer name

                2nd column = new layer name.

                 

                The next step of my writing will be to extract this list directly from the .txt file [I've already written the code].

                Just have to insert it when I'll be able to manipulate its contents! Not yet apparently! 

                 

                (^/)

                • 5. Re: Create an array of arrays from a .txt file!
                  Laubender Adobe Community Professional & MVP

                  I don't think, I misunderstood.
                  I spoke a bit in general terms about compiling a concordances table.


                  If your customer isn't using the horizontal separator ";" in a layer name, all is starting ok.

                   

                  But sometimes a list is compiled by reading out a lot of documents by scripting where you cannot check individually what's in a layer's name. And then my notes on what would be the best delimiter would become relevant very soon.

                   

                  Best regards,
                  Uwe

                  • 6. Re: Create an array of arrays from a .txt file!
                    Laubender Adobe Community Professional & MVP

                    Back to your essential coding problems.

                    Here an example that could work for you:

                     

                    /**
                    * @@@BUILDINFO@@@ RenamingLayers-Using-ConcordanceList.jsx !Version! Sat Nov 05 2016 15:05:59 GMT+0100
                    */
                    
                    // Uwe Laubender
                    
                    // Make sure, that the separatorString cannot be used in a regular layer name
                    // "oldName;newName" would perhaps not work, because ; could be part of oldName ( or newName ).
                    // I've seen a lot when it comes to naming layers with customer documents.
                    
                    // This could be a candidate:
                    var notUsedCharacterInNames = "\u0016";
                    
                    // But for the sake of Obi-wan's example we use the following one:
                    notUsedCharacterInNames = ";";
                    
                    // Scheme: oldName+separatorString+newName
                    var listArray =
                        [
                            "Layer_1"+notUsedCharacterInNames+"Layer_12",
                            "Layer_2"+notUsedCharacterInNames+"Layer_12" // I did this by purpose
                        ];
                    
                    var myDoc = app.documents[0];
                    
                    
                    // Execute function:
                    renameLayersFromList(myDoc , listArray , notUsedCharacterInNames);
                    
                    
                    // Arguments of function:
                    
                    // 1. doc  [object Document]
                    
                    // 2. listArray  [object Array] of concordance strings in the form:
                    // oldString+separatorString+newString
                    
                    // 3. notUsedCharacterInNames  [object String],
                    // the separator string from item 2, that has dual use in the function below:
                    // A. To split() the entry in the provided list to new and old
                    // B. To check in the layer names array of the document if the new name is already in use
                    
                    function renameLayersFromList(doc , listArray , notUsedCharacterInNames)
                    {
                    
                        // Loop through the listArray:
                        for(var n=0;n<listArray.length;n++)
                        {
                            // Implemented for preventing errors with the naming process.
                            // Note: Names of layers must be unique.
                            var error = false;
                           
                            // Split the incoming item of the listArray:
                            var splitArray = listArray[n].split(notUsedCharacterInNames);
                           
                            // No error checking here on the result, but maybe should be done.
                            // The provided list could be malformed.
                            var oldName = splitArray[0];
                            var newName = splitArray[1];
                    
                            // Before renaming we should check two things:
                    
                            // 1. Does the old name listed correspond with a valid layer name?
                            if(!doc.layers.itemByName(oldName).isValid){error = true};
                    
                            // 2. Is the new name in conflict with an already existing layer name?
                            if(app.documents[0].layers.everyItem().name.join(notUsedCharacterInNames).match(newName)){error = true};
                    
                            // If an error ocsurred, we loop on.
                            // You could also track the error and write a detailed report.
                            if(error){continue};
                    
                            // No errors? Fine. Do the renaming:
                            doc.layers.itemByName(oldName).name = newName;
                           
                        }
                    
                    } // function renameLayersFromList()
                    

                     

                    Have a nice weekend, Obi-wan!
                    Uwe

                    • 7. Re: Create an array of arrays from a .txt file!
                      Wosven Level 1

                      Hi,

                       

                      You forget somewhere in your script to modifiy the layer name.

                      Here another attempt with 2 arrays : old names = oNames and new names = nNames

                       

                      (function () {
                      
                          if (app.locale.toString() == "FRENCH_LOCALE") {
                      
                              var infos = {
                                  findFile:"Choisir le fichier contenant la liste de noms."
                              };
                          } else {
                      
                              var infos = {
                                  nodoc:"Select the text file for layer names."
                              };
                          }
                      
                          var txtList = "layer_names.txt", oNames = [], nNames = [];
                          var myListFile = File(myFindFile(txtList));
                          // datas
                          var testNames = listNames();
                      
                          if (testNames && oNames.length == nNames.length) {
                          //    alert(oNames + "\n" + nNames);
                      
                              var myLayers = app.activeDocument.layers;
                              for (var L = 0; L < myLayers.length; L++) {
                                  var testN = false;
                                  for (var n = 0; n < oNames.length && !testN; n++) {
                      
                                      if (myLayers[L].name == oNames[n]) {
                                          myLayers[L].name = nNames[n];
                                          // ensure old name doesn't conflict with same new name :
                                          oNames[n] = "";
                                          testN = true;
                                      }
                                  } // for n
                              } // for L
                          }
                      
                          function listNames() {
                              // Open the file for reading
                              myListFile.open("r");
                              var text = myListFile.read();
                              var lines = text.split("\n");
                      
                              if (lines.length > 0) {
                      
                                  for (var y =0; y < lines.length; y++) {
                      
                                      var l = lines[y];
                                      if (l.length != 0) {
                      
                                          if (l[0] !== "") {
                                              var names = l.split(";");
                                              if (names.length == 2) {
                                                  oNames.push(names[0]);
                                                  nNames.push(names[1]);
                                              }
                                          }
                                      } // l.length
                                  } // for
                                  return true;
                              } // lines.length
                              return false;
                          }
                      
                          //////// FUNCTIONS ////////////
                          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(infos.findFile);
                              }
                              // else alert("ok");
                              return myFilePath;
                          }
                          function myGetScriptPath() {
                              try {
                                  myFile = app.activeScript;
                              }
                              catch(myError){
                                  myFile = myError.fileName;
                              }
                              return myFile;
                          }
                      }());
                      

                       

                      I hope this helped,

                      Swo.

                      • 8. Re: Create an array of arrays from a .txt file!
                        Obi-wan Kenobi Adobe Community Professional

                        Uwe,

                         

                        Nice learning for me WE! 

                         

                        See you soon! … and have a nice WE too!

                         

                        (^/)

                         

                        [ I've tested your code! Cool! Now, just need to study, understand and be able to replicate it in other situations! Thanks a lot! ]

                        • 9. Re: Create an array of arrays from a .txt file!
                          Obi-wan Kenobi Adobe Community Professional

                          Wow!  Another code and more work for my saturday!

                           

                          I'm going to work on it too and I'll give you comments soon!

                           

                          Thanks a lot!

                           

                          … and have a nice WE too! 

                           

                          (^/)

                          • 10. Re: Create an array of arrays from a .txt file!
                            Peter Kahrel Adobe Community Professional & MVP

                            Michel -- Maybe you should tell us what you want to achieve. Rename layers, using the text file, so that Layer_1 is renamed Layer_12, etc.?

                            • 11. Re: Create an array of arrays from a .txt file!
                              Obi-wan Kenobi Adobe Community Professional

                              Hi Peter,

                               

                              The idea is, using a list of concordances, as: old layer name / new layer name, joined as a .txt file [the list could be done in Excel and exported as I said], to change the layer names in ID using this list.

                              Some layer names have to be changed (concordance in the .txt file) but certains not.

                               

                              I've already manipulated external lists as apply a char style to a list of words or make an index from a list of words.

                              I've never done it in this kind of situation.

                               

                              In fact, I'm really interested by the way we could play it. I've actually 3 scripts, mine doesn't work!

                              Uwe's one seems to work fine! As I said, the most important for me is to study and understand codes and truly be able to replicate them.

                              I don't search somebody to write scripts for me! I just would like help to tell me why I'm wrong and learn more in right directions!

                               

                              [JS] is really awesome and I think we are very lucky to have here true JS masters!

                               

                              (^/)

                              • 12. Re: Create an array of arrays from a .txt file!
                                Wosven Level 1

                                I made a typo :

                                please correct line 11 :

                                nodoc:"Select the text file for layer names." 

                                should be :

                                findFile:"Select the text file for layer names." 

                                 

                                and line 28 would be better checking for existing layer:

                                if (myLayers[L].name == oNames[n] && !app.activeDocument.layers.itemByName(nNames[n]).isValid) {

                                • 13. Re: Create an array of arrays from a .txt file!
                                  Peter Kahrel Adobe Community Professional & MVP

                                  Ok, then here's yet another one. The code you wrote and showed above (in comment 2) is very verbose. All you need is this:

                                   

                                  myList = ["Layer_1;Layer_12","Layer_2;Layer_23"];
                                  myLayers = app.activeDocument.layers;
                                  for (L = 0; L < myLayers.length; L++) {
                                    parts = myList[L].split (';');
                                    myLayers.item(parts[0]).name = myLayers.parts[1];
                                  }
                                  

                                   

                                  Peter

                                  • 14. Re: Create an array of arrays from a .txt file!
                                    Obi-wan Kenobi Adobe Community Professional

                                    Hi Peter,

                                     

                                    I've an error on "parts"! 

                                     

                                    Capture d’écran 2016-11-06 à 11.03.25.png

                                     

                                    (^/)

                                    • 15. Re: Create an array of arrays from a .txt file!
                                      Laubender Adobe Community Professional & MVP

                                      Yes Peter,

                                      but I think there should be some error handling.

                                       

                                      Maybe "Layer_12" is already used as name in the stack of layers, so "Layer_1" cannot be renamed?

                                       

                                      Regards,
                                      Uwe

                                      • 16. Re: Create an array of arrays from a .txt file!
                                        Obi-wan Kenobi Adobe Community Professional

                                        I think we need a double loop as I did!

                                         

                                        Actually, as I've corrected and inserted an "if", the code corrects first, the top layer, then next in the Layers panel.

                                         

                                        (^/)

                                        • 17. Re: Create an array of arrays from a .txt file!
                                          Peter Kahrel Adobe Community Professional & MVP

                                          No, you don't need nested loops. Line 5 in my code should be as follows:

                                           

                                          myLayers.item(parts[0]).name = parts[1];

                                           

                                          And sure, error handling should be handled, but all that error-handling obscures the basics of what you're trying to illustrate.

                                           

                                          P.

                                          • 18. Re: Create an array of arrays from a .txt file!
                                            Wosven Level 1

                                            Hi,

                                            Here my “obscure” version with error-handling and a final pop-up listing which layer was renamed.

                                             

                                            I hope I'll be able to write as fine scripts as you do Peter,

                                            Swo

                                             

                                            //DESCRIPTION:Rename layers from text file
                                            /*
                                            Text file should contains 2 columns (old name;new name), line by line
                                            separator is ";", can be changed at line 27
                                            If script is unable to find layer_names.txt, it asks for a file.
                                            
                                            No check for forbidden characters in names:
                                            you need to check the text file before running the script.
                                            */
                                            
                                            
                                            (function () {
                                            
                                                if (app.locale.toString() == "FRENCH_LOCALE") {
                                            
                                                    var infos = {
                                                        findFile:"Choisir le fichier contenant la liste de noms :",
                                                        msg:" calque(s) renommé(s) :"
                                                    };
                                                } else {
                                            
                                                    var infos = {
                                                        findFile:"Select the text file for layer names:",
                                                        msg:" layer(s) renamed:"
                                                    };
                                                }
                                            
                                                // Modify text file's name and separator (sepa) if needed
                                                var txtList = "layer_names.txt",
                                                    sepa= ";";
                                               
                                                var oNames = [], nNames = [], rNames = [];
                                                var myListFile = File(myFindFile(txtList));
                                                // datas
                                                var testNames = listNames();
                                            
                                                if (testNames && oNames.length == nNames.length) {
                                            
                                                    var myLayers = app.activeDocument.layers, c = 0;
                                                   
                                                    for (var L = 0; L < myLayers.length; L++) {
                                                        var testN = false;
                                                        for (var n = 0; n < oNames.length && !testN; n++) {
                                            
                                                            if (myLayers[L].name == oNames[n] && !app.activeDocument.layers.itemByName(nNames[n]).isValid) {
                                                                myLayers[L].name = nNames[n];
                                                                // list renamed layers
                                                                rNames.push(oNames[n] + " => " + nNames[n]);
                                                                // ensure old name doesn't conflict with same new name :
                                                                oNames[n] = "";
                                                                testN = true;
                                                                c++;
                                                            }
                                                        } // for n
                                                    } // for L
                                                    alert(c + infos.msg + "\n" + rNames.join("\n"));
                                                }
                                            
                                                function listNames() {
                                                    // Open the file for reading
                                                    myListFile.open("r");
                                                    var text = myListFile.read();
                                                    var lines = text.split("\n");
                                            
                                                    if (lines.length > 0) {
                                            
                                                        for (var y =0; y < lines.length; y++) {
                                            
                                                            var l = lines[y];
                                                            if (l.length != 0) {
                                            
                                                                if (l[0] !== "") {
                                                                    var names = l.split(sepa);
                                                                    if (names.length == 2) {
                                                                        oNames.push(names[0]);
                                                                        nNames.push(names[1]);
                                                                    }
                                                                }
                                                            } // l.length
                                                        } // for
                                                        return true;
                                                    } // lines.length
                                                    return false;
                                                }
                                            
                                                //////// FUNCTIONS ////////////
                                                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(infos.findFile);
                                                    }
                                                    // else alert("ok");
                                                    return myFilePath;
                                                }
                                                function myGetScriptPath() {
                                                    try {
                                                        myFile = app.activeScript;
                                                    }
                                                    catch(myError){
                                                        myFile = myError.fileName;
                                                    }
                                                    return myFile;
                                                }
                                            }());
                                            
                                            • 19. Re: Create an array of arrays from a .txt file!
                                              Laubender Adobe Community Professional & MVP

                                              Hi Obi-wan,

                                               

                                              About error handling:
                                              What could go wrong?

                                               

                                              Customer errors:

                                              1. The layer name provided as "old name" does not match existing names.

                                              2. The layer name provided as "old name" is provided more than one time.

                                              3. The "new name" is provided more than one time in the provided list.

                                               

                                              To tackle issue 1 and 2 the incoming list has to be pre-processed and should be matched against the existing names.
                                              Same with issue 3, pre-process the incoming list. Write an error report and contact the customer before proceeding.

                                               

                                              Structure problem (no customer error):

                                              3. The "new name" is already in use with a layer that the loop did not come accross yet.

                                               

                                              How to tackle the structure problem?
                                              Before doing anything according to the provided list, rename all layers with e.g. a numbering scheme.

                                               

                                              doc.layers[n].name = n+uniqueSeparator+doc.layers[n].name;
                                              


                                              Then you could start renaming using the provided list.

                                              Log all layers that are not renamed according to the list.

                                              Remove the numbering scheme for all layers not provided by the list.

                                               

                                              Below an example.

                                              "Layer_3", "Background_1 and "Background_2" should not be renamed and therefore are not provided by the list:

                                               

                                              var notUsedCharacterInNames = ";"
                                              var listArray = 
                                                  [
                                                      "Layer_1"+notUsedCharacterInNames+"Layer_5",
                                                      "Layer_2"+notUsedCharacterInNames+"Layer_4",
                                                      "Layer_4"+notUsedCharacterInNames+"Layer_2",
                                                      "Layer_5"+notUsedCharacterInNames+"Layer_1"
                                                  ];
                                              

                                              1-BeforeRenaming.png

                                               

                                              After renaming:

                                              2-AfterRenaming.png

                                               

                                              Regards,

                                              Uwe

                                              • 20. Re: Create an array of arrays from a .txt file!
                                                Wosven Level 1

                                                @Uwe: Thanks for this interesting exemple where renaming "somethings" doesn't always means completely differents names.

                                                 

                                                 

                                                @Obi:

                                                About your first question: going from text file to [["oName 1", "nName 1"], ["oName 2", "nName 2"], ...]

                                                it would be a function with only one array for names (allNames):

                                                function oneListNames() {
                                                    // Open the file for reading
                                                    myListFile.open("r");
                                                    var text = myListFile.read();
                                                    var lines = text.split("\n");
                                                
                                                    if (lines.length > 0) {
                                                
                                                        for (var y =0; y < lines.length; y++) {
                                                
                                                            var l = lines[y];
                                                            if (l.length != 0) {
                                                
                                                                if (l[0] !== "" && l[1] !== "") {
                                                                    var names = l.split(";");
                                                                    if (names.length > 1) {
                                                                        allNames.push([names[0], names[1]]);
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        return true;
                                                    }
                                                    return false;
                                                }
                                                

                                                 

                                                 

                                                Swo

                                                • 21. Re: Create an array of arrays from a .txt file!
                                                  Obi-wan Kenobi Adobe Community Professional

                                                  Peter,

                                                   

                                                  I totally like your code!

                                                  I didn't know the "parts" syntax and the way you thought the loop is great!

                                                  … but I've an error even if the script correctly renames the layers! …

                                                  Do I need to write a try…catch to delete it?

                                                   

                                                  Capture d’écran 2016-11-06 à 17.55.13.png

                                                  • 22. Re: Create an array of arrays from a .txt file!
                                                    Obi-wan Kenobi Adobe Community Professional

                                                    Uwe and Swo,

                                                     

                                                    Very cool answers for me! Thanks a lot!

                                                     

                                                    It's a very good learning for me to study how you think and how you write your own code!

                                                     

                                                    I'm going to study more all about "array" and "error" use.

                                                     

                                                    @Swo, I'm very interested by your approach about the external .txt file call! I'm going to study it too!

                                                     

                                                    Maybe more questions on this point later!

                                                     

                                                    (^/) 

                                                    • 23. Re: Create an array of arrays from a .txt file!
                                                      Peter Kahrel Adobe Community Professional & MVP

                                                      Ugh... In line 4, 'myLayers.length' should be 'myList.length'.

                                                       

                                                      P.

                                                      • 24. Re: Create an array of arrays from a .txt file!
                                                        Obi-wan Kenobi Adobe Community Professional

                                                        Yeap!

                                                         

                                                        myList = ["Layer_1;Layer_12","Layer_2;Layer_23"];  
                                                        myLayers = app.activeDocument.layers;  
                                                        for (L = 0; L < myList.length; L++) {  
                                                            parts = myList[L].split (';');
                                                            myLayers.item(parts[0]).name = parts[1];
                                                        }
                                                        

                                                         

                                                        Previously, I've corrected as:

                                                         

                                                        myList = ["Layer_1;Layer_12","Layer_2;Layer_23"];  
                                                        myLayers = app.activeDocument.layers;  
                                                        for (L = 0; L < myLayers.length; L++) {  
                                                                try 
                                                                {
                                                                    parts = myList[L].split (';');
                                                                    myLayers.item(parts[0]).name = parts[1];
                                                                }
                                                                catch(myError){}  
                                                        }
                                                        

                                                         

                                                        … and I've no error!

                                                         

                                                        So, my big questions:

                                                        In a script writing, is it dangerous to systematically "mask" real errors with a try…catch (as I did)?

                                                        and:

                                                        do I need to systematically find why there's an error and where it is to avoid awful problems in the future?

                                                         

                                                        (^/) 

                                                        • 25. Re: Create an array of arrays from a .txt file!
                                                          Wosven Level 1

                                                          As you said : using

                                                          catch(myError){}  

                                                          doesn't mean there isn't any error, but that you "mask" them.

                                                          There's a possible error if the new name is already used for a layer.

                                                           

                                                          I usually don't hide error messages, but I try to thinks or test untill there's no more errors.

                                                          Uwe showed me in his example that I missed some possible errors.

                                                           

                                                          When you'll test yours scripts with users, they'll find new errors you didn't thought about :S

                                                          (That's the way when working with creative people)

                                                           

                                                          If you hide errors, how about in six month, or a year later... You'll use this script, and won't understand why it doesn't produce any result

                                                          ...because you'll have forgotten about hiding errors.

                                                           

                                                          If you don't have yet a solution, at least add an alert. Later, when you'll have more time, you'll be able to debug or complete the script.

                                                          I use this as a reminder, and because users feel betrayed or frightened (sort of) when you give a script that "doesn't work" or give cryptic error messages (inDesign error messages).

                                                           

                                                          Just my 2 cents about this,

                                                          Swo.

                                                          • 26. Re: Create an array of arrays from a .txt file!
                                                            Laubender Adobe Community Professional & MVP

                                                            Hi Obi-wan,

                                                            and be aware, that a provided list should always be prepocessed.
                                                            Otherwise some strange things could happen. :-)

                                                             

                                                            A "normal" user cannot:

                                                            1. Use a name with an empty string.

                                                            A script can set it. A list can provide it.

                                                             

                                                            doc.activeLayer.name = "";
                                                            

                                                             

                                                            1-Layer-Name-EmptyString.png

                                                             

                                                            Here the UI is not sure what to tell:

                                                            2-Layer-Name-EmptyString.png

                                                             

                                                             

                                                            2. Use names with white space only.

                                                            A script can set it. A list can provide it.

                                                             

                                                            doc.activeLayer.name = "          ";
                                                            

                                                             

                                                            2-Layer-Name-WhitespaceOnly.png

                                                             

                                                            1-Layer-Name-WhitespaceOnly.png

                                                             

                                                             

                                                             

                                                            3. Use names with trailing white space.

                                                            A script can set it. A list can provide it.

                                                             

                                                            doc.activeLayer.name = "    trailing white space      ";
                                                            

                                                             

                                                            2-Layer-Name-TrailingWhiteSpace.png

                                                            1-Layer-Name-TrailingWhiteSpace.png

                                                             

                                                            Hm:

                                                            "Ils doivent envisager qu’une grande responsabilité est la suite inséparable d’un grand pouvoir."
                                                            And also: "With Great Power Comes Great Responsibility".

                                                             

                                                            Regards,
                                                            Uwe

                                                            • 27. Re: Create an array of arrays from a .txt file!
                                                              Obi-wan Kenobi Adobe Community Professional

                                                              Uwe and Swo,

                                                               

                                                              I agree with both of you! 

                                                               

                                                              Uwe is totally right!  "With Great Power Comes Great Responsibility!"

                                                               

                                                              My Master Yoda would have said:

                                                               

                                                              "Powerful the Force is! Powerful Javascript and Grep are also!

                                                              Easy is to go to the dark side and errors make!

                                                              The errors we must tame!"

                                                               

                                                              (^/) 

                                                               

                                                              I think the user has to first control his list quality! [as Uwe enumerated greatly!]

                                                              An alert [Ok to continue, Cancel to abort] could tell him: "Your list must be as …!"

                                                               

                                                              Imho, the real problem the script could encounter is when a layer name already exists, as:

                                                               

                                                              Capture d’écran 2016-11-06 à 21.13.59.png

                                                              The concordances list is:

                                                               

                                                              Layer_1;Layer_8

                                                              Layer_2;Layer_9

                                                               

                                                              As you can see, there's a problem with Layer_8!

                                                               

                                                              So, as Uwe did, I've taken his code and inserted a double if:

                                                               

                                                              myList = ["Layer_1;Layer_8","Layer_2;Layer_9"];  
                                                              myLayers = app.activeDocument.layers;  
                                                              for ( L = 0; L < myList.length; L++ ) {
                                                                  var error = false;  
                                                                  parts = myList[L].split (';');
                                                                  if ( myLayers.everyItem().name.join(";").match(parts[1]) ){ error = true };  
                                                                      if( error ){
                                                                          alert ( "This layer name '" + parts[1] + "' already exist! \rThe script is going to abort! Correct it!\r(^/)  ;-)" ); 
                                                                          exit(); 
                                                                      }
                                                                  myLayers.item(parts[0]).name = parts[1];
                                                              }
                                                              

                                                               

                                                              Thanks for your comments! [I go on to study!]

                                                               

                                                              (/^)

                                                              • 28. Re: Create an array of arrays from a .txt file!
                                                                Obi-wan Kenobi Adobe Community Professional

                                                                Uwe,

                                                                 

                                                                I need to study more what you wrote in post#19!

                                                                 

                                                                My way above is not really cool! 

                                                                 

                                                                (^/)

                                                                • 29. Re: Create an array of arrays from a .txt file!
                                                                  Obi-wan Kenobi Adobe Community Professional

                                                                  That seems to be an interesting, surely bad written, approach:

                                                                   

                                                                  app.doScript(main, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Rename Layers By List! …");
                                                                  
                                                                  
                                                                  function main ()      
                                                                  {
                                                                      var myLayers = app.activeDocument.layers,
                                                                      P = myLayers.length,
                                                                      myList = ["Layer_3;Layer_2","Layer_2;Layer_8","Layer_8;Layer_1","Layer_1;Layer_4","Layer_4;Layer_7","Layer_7;Layer_5","Layer_6;Layer_6","Layer_5;Layer_3"],
                                                                      N = myList.length;
                                                                          while ( N-- ) myList[N] = myList[N]  + " ";
                                                                          for ( N = 0; N < myList.length; N++ ) {
                                                                          parts = myList[N].split (';');
                                                                          myLayers.item(parts[0]).name = parts[1];
                                                                          }
                                                                          while ( P-- && myLayers[P].name.slice(-1) == "x" ) myLayers[P].name = myLayers[P].name.slice(0,-1);
                                                                  }
                                                                  

                                                                   

                                                                  Before/After:

                                                                   

                                                                  Capture d’écran 2016-11-06 à 22.38.31.png   Capture d’écran 2016-11-06 à 22.38.46.png

                                                                   

                                                                  Of course, if bad list! … So, I suppose by default the list is correct! 

                                                                   

                                                                  Thanks for your comments!

                                                                   

                                                                  (^/)

                                                                  • 30. Re: Create an array of arrays from a .txt file!
                                                                    Wosven Level 1

                                                                    Obi-wan,

                                                                    I really like :

                                                                    "Powerful the Force is! Powerful Javascript and Grep are also!

                                                                    Easy is to go to the dark side and errors make!

                                                                    The errors we must tame!"

                                                                    And I would add :

                                                                    "And great scripts must have!"

                                                                     

                                                                    An alert ([Ok to continue, Cancel to abort] could tell him: "Your list must be as …!") would teach us users to be carefull with the text file content.

                                                                    Too many can be anoying too...

                                                                     

                                                                     

                                                                     

                                                                    Perhaps you can play with a "while" (be carefull, those are tricky), to rename the layer adding a +" 2", +" 3" or +" copy 1", +" copy 2"... in the name.

                                                                     

                                                                    if (myLayers[L].name == oNames[n] && !app.activeDocument.layers.itemByName(nNames[n]).isValid) {
                                                                        // renaming, etc.
                                                                        ...
                                                                    }
                                                                    

                                                                     

                                                                    This part would change for:

                                                                     

                                                                    if (myLayers[L].name == oNames[n]) {
                                                                        // "a" will increase until there's no more layer with the same name
                                                                        var a = "2";
                                                                        // testName will change value until it's an unique layer name
                                                                        var testName = nNames[n];
                                                                        while (app.activeDocument.layers.itemByName(testName).isValid) {
                                                                            testName = nNames[n] + " " + a;
                                                                            a++;
                                                                        }
                                                                        myLayers[L].name = testName;
                                                                        // list renamed layers
                                                                        rNames.push(oNames[n] + " => " + testName);
                                                                        // ensure old name doesn't conflict with same new name :
                                                                        oNames[n] = "";
                                                                        testN = true;
                                                                        c++;
                                                                    }
                                                                    

                                                                     

                                                                    This feels more like a puzzle now

                                                                     

                                                                    Have fun,

                                                                    Swo

                                                                    • 31. Re: Create an array of arrays from a .txt file!
                                                                      Obi-wan Kenobi Adobe Community Professional

                                                                      Swo,

                                                                       

                                                                      Right!  A puzzle now! 

                                                                       

                                                                      Could you post your last version! Thanks!

                                                                       

                                                                      (^/)

                                                                      • 32. Re: Create an array of arrays from a .txt file!
                                                                        Wosven Level 1

                                                                        Hu...

                                                                        Are you adding spaces to new names ?

                                                                        while ( N-- ) myList[N] = myList[N]  + " ";  
                                                                        

                                                                         

                                                                        If thoses layers are renamed and you add invisible spaces in those new names, and those new layers names are part of a more complexe script used later, it will fail.

                                                                         

                                                                        Swo

                                                                        • 33. Re: Create an array of arrays from a .txt file!
                                                                          Wosven Level 1

                                                                          Here it is:

                                                                           

                                                                          //DESCRIPTION:Rename layers from text file
                                                                          /*
                                                                          Text file should contains 2 columns (old name;new name), line by line
                                                                          separator is ";", can be changed at line 27
                                                                          If script is unable to find layer_names.txt, it asks for a file.
                                                                          
                                                                          No check for forbidden characters in names: 
                                                                          you need to check the text file before running the script.
                                                                          */
                                                                          
                                                                          
                                                                          (function () {
                                                                          
                                                                              if (app.locale.toString() == "FRENCH_LOCALE") {
                                                                          
                                                                                  var infos = {
                                                                                      findFile:"Choisir le fichier contenant la liste de noms :",
                                                                                      msg:" calque(s) renommé(s) :"
                                                                                  };
                                                                              } else {
                                                                          
                                                                                  var infos = {
                                                                                      findFile:"Select the text file for layer names:",
                                                                                      msg:" layer(s) renamed:"
                                                                                  };
                                                                              }
                                                                          
                                                                              // Modify text file's name and separator (sepa) if needed
                                                                              var txtList = "layer_names.txt", 
                                                                                  sepa= ";";
                                                                              
                                                                              var oNames = [], nNames = [], rNames = [];
                                                                              var myListFile = File(myFindFile(txtList));
                                                                              // datas
                                                                              var testNames = listNames();
                                                                          
                                                                              if (testNames && oNames.length == nNames.length) {
                                                                          
                                                                                  var myLayers = app.activeDocument.layers, c = 0;
                                                                                  
                                                                                  for (var L = 0; L < myLayers.length; L++) {
                                                                                      var testN = false;
                                                                                      for (var n = 0; n < oNames.length && !testN; n++) {
                                                                          
                                                                                          if (myLayers[L].name == oNames[n]) {
                                                                                              // "a" will increase until there's no more layer with the same name
                                                                                              var a = "2";
                                                                                              // testName will change value until it's an unique layer name
                                                                                              var testName = nNames[n];
                                                                                              while (app.activeDocument.layers.itemByName(testName).isValid) {
                                                                                                  testName = nNames[n] + " copy " + a;
                                                                                                  a++;
                                                                                              }
                                                                                              myLayers[L].name = testName;
                                                                                              // list renamed layers
                                                                                              rNames.push(oNames[n] + " => " + testName);
                                                                                              // ensure old name doesn't conflict with same new name :
                                                                                              oNames[n] = "";
                                                                                              testN = true;
                                                                                              c++;
                                                                                          }
                                                                                      } // for n
                                                                                  } // for L
                                                                                  alert(c + infos.msg + "\n" + rNames.join("\n"));
                                                                              }
                                                                          
                                                                              function listNames() {
                                                                                  // Open the file for reading
                                                                                  myListFile.open("r");
                                                                                  var text = myListFile.read();
                                                                                  var lines = text.split("\n");
                                                                          
                                                                                  if (lines.length > 0) {
                                                                          
                                                                                      for (var y =0; y < lines.length; y++) {
                                                                          
                                                                                          var l = lines[y];
                                                                                          if (l.length != 0) {
                                                                          
                                                                                              if (l[0] !== "") {
                                                                                                  var names = l.split(sepa);
                                                                                                  if (names.length == 2) {
                                                                                                      oNames.push(names[0]);
                                                                                                      nNames.push(names[1]);
                                                                                                  }
                                                                                              }
                                                                                          } // l.length
                                                                                      } // for
                                                                                      return true;
                                                                                  } // lines.length
                                                                                  return false;
                                                                              }
                                                                          
                                                                              //////// FUNCTIONS ////////////
                                                                              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(infos.findFile);
                                                                                  }
                                                                                  // else alert("ok");
                                                                                  return myFilePath;
                                                                              }
                                                                              function myGetScriptPath() {
                                                                                  try {
                                                                                      myFile = app.activeScript;
                                                                                  }
                                                                                  catch(myError){
                                                                                      myFile = myError.fileName;
                                                                                  }
                                                                                  return myFile;
                                                                              }
                                                                          }());
                                                                          
                                                                          • 34. Re: Create an array of arrays from a .txt file!
                                                                            Obi-wan Kenobi Adobe Community Professional

                                                                            Yes! but I remove them at the end [code line 15]! [new script version, previous is wrong!]

                                                                             

                                                                            app.doScript(main, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Rename Layers By List! …");
                                                                            
                                                                            
                                                                            function main ()      
                                                                            {
                                                                                var myLayers = app.activeDocument.layers,
                                                                                P = myLayers.length,
                                                                                myList = ["Layer_3;Layer_2","Layer_2;Layer_8","Layer_8;Layer_1","Layer_1;Layer_4","Layer_4;Layer_7","Layer_7;Layer_5","Layer_6;Layer_6","Layer_5;Layer_3"],
                                                                                N = myList.length;
                                                                                    while ( N-- ) myList[N] = myList[N]  + " ";
                                                                                    for ( N = 0; N < myList.length; N++ ) {
                                                                                    parts = myList[N].split (';');
                                                                                    myLayers.item(parts[0]).name = parts[1];
                                                                                    }
                                                                                    while ( P-- ) if ( myLayers[P].name.slice(-1) == " " )  myLayers[P].name = myLayers[P].name.slice(0,-1);
                                                                            }
                                                                            

                                                                             

                                                                            I've added 2 new layers (9 & 10) not included in the list.

                                                                             

                                                                            Capture d’écran 2016-11-06 à 23.29.25.png   Capture d’écran 2016-11-06 à 23.29.35.png

                                                                             

                                                                            (^/)  Thanks for your script last version [post#33]! 

                                                                            • 35. Re: Create an array of arrays from a .txt file!
                                                                              Peter Kahrel Adobe Community Professional & MVP

                                                                              while-loops are used when you don't know how many items you're processing. If you do know the number of items (e.g. in an array), then use a for-loop because for-loops execute quicker than while-loops. What you're up to with those two while loops is beyond me, but never mind.

                                                                               

                                                                              What you do in that last while-loop (which should really be a for-loop), this:

                                                                               

                                                                              if ( myLayers[P].name.slice(-1) == " " )  myLayers[P].name = myLayers[P].name.slice(0,-1);

                                                                               

                                                                              can be done as follows, which is probably quicker:

                                                                               

                                                                              myLayers[P].name = myLayers[P].name.replace(/ $/,'');

                                                                               

                                                                              Peter

                                                                              • 36. Re: Create an array of arrays from a .txt file!
                                                                                Obi-wan Kenobi Adobe Community Professional

                                                                                Thanks Peter!

                                                                                 

                                                                                // ID is close for me at the moment! I can't test!

                                                                                 

                                                                                If I want to add a space at the end of the layers name, can I use this:

                                                                                 

                                                                                myLayers[P].name = myLayers[P].name.replace(/$/,' ');

                                                                                 

                                                                                (^/)

                                                                                • 37. Re: Create an array of arrays from a .txt file!
                                                                                  Peter Kahrel Adobe Community Professional & MVP

                                                                                  Yes, you can. If only InDesign's grep could do things like that.

                                                                                  • 38. Re: Create an array of arrays from a .txt file!
                                                                                    Obi-wan Kenobi Adobe Community Professional

                                                                                    Aha! So not this! …

                                                                                     

                                                                                    (^/)

                                                                                    • 39. Re: Create an array of arrays from a .txt file!
                                                                                      Wosven Level 1

                                                                                      Ok, sorry, I didn't saw the line.

                                                                                      Won't you get an error if there's another layer with the same name ?

                                                                                      Didn't you forget the space before $ ?

                                                                                       

                                                                                       

                                                                                      myLayers[P].name = myLayers[P].name.replace(/ $/,'');

                                                                                       

                                                                                      Swo

                                                                                       

                                                                                      (hightlight syntax is messy with this line)

                                                                                      1 2 Previous Next