11 Replies Latest reply on Aug 18, 2009 5:53 AM by Harbs.

    How to keep track of script-created objects for later deletion?

    bensays

      I'm creating a script which:

       

      1 puts some rectangles on each spread of a document

      2 exports the document to PDF

      3 deletes the created recangles (so that the file returns to the pre-script-state)

       

      As the number of created rectangles in step 1 is dynamic, I tried to put them into an array, so that in step3, I could loop the array and call remove() on every element. This did not work (syntax errors).

       

      How can I make this work? Do I need to cast the objects from the array to type rectangle? Or can I give a special attribute to the rectangles on creation, so that in step 3 I can find them using something like myDocument.findByClassName("myTemporaryScriptObject")?

       

      Or can I just call undo() N times in step 3, where N is the number of operations the script has done (excluding the PDF-export)?

       

      Thanks for your help!

      ben

        • 1. Re: How to keep track of script-created objects for later deletion?
          Bob Stucky Adobe Employee

          Could you post the parts of your code relevant to the creation and deletion of the rects?

           

          You should be able to do what you want to do without any trouble.

           

          Bob

          • 2. Re: How to keep track of script-created objects for later deletion?
            Thomas B. Nielsen Level 3

            Push you objects into an array, as you might allready do, then loop backwards through the array.

             

            for (i= myarray.length-1; i >= 0; i--) {

                 myarray[i].remove();

            }

            • 3. Re: How to keep track of script-created objects for later deletion?
              [Jongware] Most Valuable Participant

              Is there any system overhead in removing first-to-last? If not (or not much):

               

              while (myArray.length)

                myArray[0].remove();

               

              saves wear and tear on your fingers

              (And it looks a bit more logical.)

              • 4. Re: How to keep track of script-created objects for later deletion?
                Peter Kahrel Adobe Community Professional & MVP

                Even more wear and tear can be saved:

                 

                myArray = [];

                 

                (Besides, remove() is not an array method...)

                 

                Peter

                • 5. Re: How to keep track of script-created objects for later deletion?
                  SuperMacGuy Level 2

                  Do you even need to keep track? When I do things like this, I open the file, export/print etc., then just close the document without saving. If  you're not doing other things with the file you can close it, or do a revert (might be time intensive or relink images etc).

                   

                  Also, you could add a unique script label to each item as it's created, then do a mass-removal of all items tagged with the label, at the end of the script or function.

                  • 6. Re: How to keep track of script-created objects for later deletion?
                    [Jongware] Most Valuable Participant

                    Sorry, Peter, the intention was not to empty an array. It should remove previously added page items -- and what can be added, can be removed.

                    • 7. Re: How to keep track of script-created objects for later deletion?
                      bensays Level 1

                      Thank you for your answers so far! When I posted the original question, I didn't have the code at hand. Now I do - it's for InDesign CS3:

                       


                      var myDocument = app.documents.item(0);
                      var borders = new Array();
                      var masks = new Array();

                       

                      for(var spreadCounter = 0; spreadCounter < myDocument.spreads.length; spreadCounter++)
                      {
                          var mySpread = myDocument.spreads.item(spreadCounter);

                       

                          // create a thin black border
                          var currentBorder = mySpread.rectangles.add();
                          currentBorder.geometricBounds = getSpreadBounds(mySpread);
                          currentBorder.strokeWeight = 1;
                          currentBorder.strokeColor = myDocument.swatches.item("Black");
                          currentBorder.fillColor = myDocument.swatches.item("None");   
                          borders[borders.length] = currentBorder;

                       

                          // create a whitely stroked rectangle to cover the bleeding
                          var currentMask = mySpread.rectangles.add();
                          currentMask.geometricBounds = getSpreadBounds(mySpread);
                          currentMask.strokeWeight = 100;
                          currentMask.strokeAlignment = StrokeAlignment.OUTSIDE_ALIGNMENT;
                          currentMask.strokeColor = myDocument.swatches.item("Paper");
                          currentMask.fillColor = myDocument.swatches.item("None");
                          masks[masks.length] = currentMask;
                      }

                       

                       

                      // step 2

                      ...

                       

                       

                       

                      // step 3

                       

                      // this raises no error, but it does not remove the rectangles either.

                      borders = [];
                      masks = [];

                       

                       

                      // this works!!
                      for(var i=borders.length-1;i>=0;i--)
                          borders[i].remove();
                         
                      for(var i=masks.length-1;i>=0;i--)
                          masks[i].remove();

                       

                      As borders and masks are always of the same quantity, I can of course use only one loop.

                       

                      Now my questions: SuperMacGuy, could you please tell me how to assing labels and how to fetch all objects with a certain label? Couldn't find this anywhere and it seems quite useful.

                       

                      Also, why didn't unsetting the array ("borders = []") work? I guess it just cleared the array without calling ::remove() on the objects, right? So basically, the array doesn't really contain the objects but just pointers/references to them?

                       

                      thanks for your help!

                      • 8. Re: How to keep track of script-created objects for later deletion?
                        [Jongware] Most Valuable Participant

                        It's a bit different than in real OOP languages, where you write your own constructor (which creates a new object) and destructor (to clean up after itself on deletion). It does indeed seem arrays (and variables too) are pointers to real objects. You can do things such as

                         

                        someArray = aFrame.paragraphs;

                         

                        then work on someArray, and see the original paragraphs on your screen changing immediately. I've been stung a few times by that, when I expected a copy of an object and got a reference to the real thing -- so I learned to watch out for that.

                         

                        A minor point:

                         

                        masks[masks.length] = currentMask;

                         

                        could be replaced with

                         

                        masks.push (currentMask);

                         

                        -- although, well, it really does the same thing. I guess this is just a question of style

                         

                        [Edit] Just got to reading your Label question. Almost every single InDesign object -- including the Application itself -- can be assigned a label, and that's nothing more than a string of characters you might find useful. The Scripting engine itself is (likely) optimized to using labels, and can locate them very fast. Assigning a label to just about anything is as easy as

                         

                        myObject.label = "Something useful";

                         

                        Suppose you mark one of your rectangles with this label and run the script. Then, in the User Interface, you can open the Script Label panel and when you select the rectangle, you will see this string in the panel. You can even change it to something else; and ID will save it along with the document.

                         

                        ID doesn't mind if you give the same label to more than one single object; that's what SuperMacGuy does. I hope SuperMacGuy can come up with an example of how to do this in JavaScript in one swoop; I've seen examples in Applescript that can do something like this (apologies for syntax etc.)

                         

                        remove every rectangle whose label is "delete me"

                        • 9. Re: How to keep track of script-created objects for later deletion?
                          Peter Kahrel Adobe Community Professional & MVP

                          >remove every rectangle whose label is "delete me"

                           

                          in JS would be simply app.documents[0].rectangles.item ("delete me").remove()

                           

                          I'm still puzzled by the remove() method applied to arrays. I can't get that to work: the ESTK stops with an error. myArray[0] works fine.

                           

                          Peter

                          • 10. Re: How to keep track of script-created objects for later deletion?
                            SuperMacGuy Level 2

                            Thanks Jong and Peter for filling it on the script labels. I don't work with JS at all so I can't help with that syntax; but looks like the answer from Peter does the trick.

                             

                            Just for reference for any future AppleScripters:

                            set theNewFrame to make new text frame with properties {geometric bounds:{1,2,3,4}, label:"some label"}

                            and

                            tell document 1

                            delete (every page item whose label is "some label")

                            ...

                            • 11. Re: How to keep track of script-created objects for later deletion?
                              Harbs. Level 6

                              It's really much better practice to use custom labels (i.e. 

                              pageItem.insertLabel("myLabel","myValue") ) rather than standard 

                              labels. This is especially true for page items which might be 

                              controlled by APID (which uses the standard script labels to control 

                              item events).

                               

                              Harbs