6 Replies Latest reply on Jan 10, 2013 7:46 AM by elDeako

    Auto Capture Layer Names

    elDeako

      I am trying to capture the layer names from an indesign document. The idea behind the script (when finished) is to create a seperate PDF off each layer in the document and naming that document based on the layer name. My script so far can capture the first and last layer name but I cannot get the layers.nextItem to work. I keep getting an Invalid Parameter.

       

      Please can you advise me on what  am doing wrong - Thanks

       

       

      var myDoc = app.activeDocument;

      var myLayers = myDoc.layers.firstItem();

       

      // Box shows first Layer Name

      alert (myLayers.name);

       

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

            

         myLayers = myDoc.layers.lastItem();

      // Box shows last layer name but I would like the .lastItem to actually work with .nextItem    

         alert (myLayers.name);

      }

        • 1. Re: Auto Capture Layer Names
          Laubender Adobe Community Professional & MVP

          @elDeako – see the following snippets and read the annotations:

           

          //The active document:
          var myDoc = app.activeDocument;
          
          //The layers collection of the active document:
          var myLayers = myDoc.layers;
          
          //Loop through the layers collection of the active document:
          for(var i = 0; i < myLayers.length; i++) {
          
              //alert for the name of the layer the loop is currently visiting:
              alert(myLayers[i].name);
          
              };
          

           

           

          If you only want to read out all the names of the layer in one go:

           

          alert("Layer names of active document:"+"\r"+app.activeDocument.layers.everyItem().name.join("\r"));
          

           

           

          Uwe

          • 2. Re: Auto Capture Layer Names
            elDeako Level 1

            Thanks Uwe, I really appreciate your help.

            • 3. Re: Auto Capture Layer Names
              [Jongware] Most Valuable Participant

              The reason you could not get nextItem to work is because in your script you wrote lastItem, not nextItem

               

              nextItem returns the "next" item relative to an item you have to supply as its argument.

               

              So, if your first layer is myLayers, the 'next' layer would be "myDoc.layers.nextItem(myLayers)":

               

              var myDoc = app.activeDocument;
              var myLayers = myDoc.layers.firstItem();
              
              // Box shows first Layer Name
              alert (myLayers.name);
              
              for(var i = 0; i < myDoc.layers.length; i++)
              {
                 myLayers = myDoc.layers.nextItem(myLayers);
                 alert (myLayers.name);
              }
              

               

              But this shows an error message! Why? Because of the way you set up the loop. 'myLayers' is initialized with 'the first layer', then you call 'nextItem' for each of the layers. With three layers:

               

              myLayers = "A" -> nextItem makes mylayers "B", alert shows "B"

              myLayers = "B" -> nextItem makes mylayers "C", alert shows "C"

              myLayers = "C" -> nextItem sets mylayers to null, calling the alert pops up an error because 'null' is not a valid layer

               

              When using this loop, you would never see an alert for layer "A" -- you only do so because you actually did so before the loop. So a better script would be this:

               

              var myDoc = app.activeDocument;
              var myLayers = myDoc.layers.firstItem();
              for(var i = 0; i < myDoc.layers.length; i++)
              {
                 alert (myLayers.name);
                 myLayers = myDoc.layers.nextItem(myLayers);
              }
              

               

              You don't do stuff outside of the loop, and you still get one alert for each layer.

               

              But in fact there is no reason to use 'firstItem', 'nextItem', and 'lastItem' for this task. "Layers" are a simple array, ranging from 0 to (layers.length-1). You already know the 'relative' position of each layer -- it's the index number, and you iterate from first to last. So an even better loop to process each separate layer is this:

               

              var myDoc = app.activeDocument;
              for(var i = 0; i < myDoc.layers.length; i++)
              {
                 alert (myDoc.layers[i].name);
              }
              

               


               

              'firstItem' and its cousins  are useful functions when you don't know the absolute positions of items, only a relative one. I don't have a good example of correct usage at hand, I steer well away from using these functions, because they work extremely slow. Every call to one of these functions makes your script examine the entire list of objects (in the case of your layers, it only works because that's not a very long list).

              As Uwe shows, it's worth trying 'everyItem' -- but you only need to if you are sure InDesign doesn't already have the objects in an array, ready for you to loop over.

               

              Message was edited by: [Jongware] Hah! All said and done I end up with the *exact same* 'better script' Uwe already showed you!

              1 person found this helpful
              • 4. Re: Auto Capture Layer Names
                elDeako Level 1

                Thanks Jongware, I really appreciate the explanation. I am really just starting to learn about scripting and am grateful for every bit of help as it is a bit of a steep learning curve for me.

                • 5. Re: Auto Capture Layer Names
                  Laubender Adobe Community Professional & MVP

                  @elDeako – you can do you a big favor and "invest" in some books on ExtendScript with InDesign.

                   

                  I recommend reading and working with:
                  "InDesign Automation using XML & JavaScript" by Grant Gamble.

                   

                  It comes along with a lot of exercises and example files you can download…

                   

                  For  DOM documentation download the CHM files provided by Jongware:

                   

                  http://www.jongware.com/idjshelp.html

                   

                  That will give you a very good start learning scripting…

                   

                  Uwe

                  1 person found this helpful
                  • 6. Re: Auto Capture Layer Names
                    elDeako Level 1

                    Thanks Uwe, I will definately invest in the book and have already bookmarked th Link.

                    Thanks again for the help from both of you.