14 Replies Latest reply: Jun 8, 2012 6:57 PM by hilukasz RSS

    Selecting Symbols on page by name

    mcs_dean Community Member

      Im struggling with the correct use of symbol / symbol items in applescript. I can successfully list the symbols used on the page, but I cannot select them. Any suggestions on how I can select all the items on the page that are Symbol Items of symbols named "Apples" but not oranges? After that I hope to replace the instances matching the height or width of the items whichever is greater with a 3rd item name. Any suggestions would be great. Javascript is always an option as well but I had the same difficulty.

        • 1. Re: Selecting Symbols on page by name
          CarlosCanto MVP

          here's how to do it with JS

           

          var idoc = app.activeDocument; // get active document
          
          
          for (i=0; i<idoc.symbolItems.length; i++) // loop thru all symbol items in the active document
                    {
                              var symbolitem = idoc.symbolItems[i]; // get each symbol item
                              if (symbolitem.symbol.name == "Apples") // check if it is an instance of "Apples" symbol
                                        {
                                                  symbolitem.selected = true; // if it is, then select it
                                        }
                    }
          
          • 2. Re: Selecting Symbols on page by name
            mcs_dean Community Member

            Thanks much. I was going in circles. Works like a charm.

            • 4. Re: Selecting Symbols on page by name
              Muppet Mark Community Member

              SymbolItem getByName (name: string)

              Get the first element in the collection with the provided name.

               

              The OP wanted all symbol instances of a given symbol name… each instance can have its own name too…

              • 5. Re: Selecting Symbols on page by name
                W_J_T Community Member

                Hello Everyone,

                 

                First let me start by apologizing as I am not sure if its ok to post in this thread with a very similar question that continues on this very same topic? I hope its ok, anyway, this is great to know as I too was wondering this myself just recently, then I saw this thread when it was bumped, so awesome! I am wondering however if it is possible to extend this little script to find items that their names include a certain string with in them? So instead of just selecting items named "Apples" the script would select items that have the desired string term within the name as follows:

                 

                123apple5

                apple_1, apple_2, apple_3 … apple_45, etc...

                apple

                APPLE

                Apple

                appleapple

                bigredapple

                juicyApple

                etc…

                 

                Of course these would not work:

                 

                app5le

                appl_e

                a_p_p_l_e

                etc..

                 

                So finding the string "apple" within the items name on the page, upper or lower case as long as the letters "apple" reside somewhere in the name sequentially. Hope that makes since, I was wondering if something like this would be possible?

                 

                Any feedback, advice, scripts, are welcome, thanks everyone for your time and assitance.

                • 6. Re: Selecting Symbols on page by name
                  hilukasz Community Member

                  you would run a match method on it, which returns true if it matches. the if statement checks if they method returns true and tells you what layers contain apples. It uses a regular expression to match it, kind of a shortcut so you don't have to do all the regex mess, starts with / ends with / and the i tells it to ignore case making it case insenstive:

                   

                  var doc = app.activeDocument,
                      layers = doc.layers,
                      //string to match, change apples to anything else you want
                      stringToMatch = /apple/i; 
                  
                  //iterate through all the layers
                  for(var i = 0; i < layers.length; i++){
                      // if true, continue
                      if(layers[i].name.match(stringToMatch)){
                          //return result
                          print(layers[i].name+" contains apples");
                      }
                  }
                  

                   

                  ran test on all cases you posted. seems to work well.

                   

                  returns:

                   

                  bigredapple contains apples

                  juicyApple contains apples

                  123apples5 contains apples

                  appleapples contains apples

                  APPLES contains apples

                  apple_1 contains apples

                  Tastey Apples contains apples

                  _apples contains apples

                  apples contains apples

                   

                  and if you wanted to get user input via a prompt you could use something like this:

                   

                  Array.prototype.indexOf = Array.prototype.indexOf || function(value, start) {
                    for (var i = 0, length = this.length; i < length; i++) {
                      if (this[i] == value) {
                        return i;
                      }
                    }
                    return -1;
                  }
                  
                  
                  var doc = app.activeDocument,
                      layers = doc.layers,
                      matchString = 'aPpLe';
                  
                  
                  for(var i = 0; i < layers.length; i++){
                      var string = layers[i].name.toLowerCase();
                      if (string.indexOf(matchString.toLowerCase()) != -1){
                          print(layers[i].name+" contains apples");
                      }
                  }
                  
                  

                   

                  but this should come with understanding that you are extending the array class and doing some hacky things with extendscript....

                  • 7. Re: Selecting Symbols on page by name
                    hilukasz Community Member

                    @muppet mark oh, I see. yeah, ok I read it fast and missed that part.

                    • 8. Re: Selecting Symbols on page by name
                      W_J_T Community Member

                      Thanks so much for your comment and code. Its very much appreciated.

                       

                      I must say I only started coding myself in Illustrator a few weeks ago, so far its been going great, however there is still so much that seems foreign to me. I have been perusing the illustrator javascript reference and that has been great, as well as searching and reading tons of posts in this forum which is wonderful. So many great code snippets laying around with little nuggets to learn from and so may talented Illustrator users and coders.

                       

                      I tried both your scripts in Illustrator as well as via the ExtendScript Toolkit. In Illustrator I don't seem to have anything happen, I am not familiar with the "print" method, it gives me "TypeError: print is not a function" in Illustrator, so I tried both in ExtendScript and got undefined. So I am not sure if there are things I am doing wrong trying your codes, or perhaps something else. I noticed you seem to be targeting layers in your codes which I have not really got into yet (mostly using selection, etc., thus far) I did get some output when I changed my layer name to "apple" using your codes, then it found things, but again perhaps there are things about your example that I don't understand.

                       

                      Anyway, great news however your mention of using RegEx with match got me on the right track, thanks so much for mentioning that! I was not overly familiar with RegEx, so I spent some time learning up on it, wow powerful and clean stuff that will really come in handy with all types of situations. Using RegEx, I was able to come up with the following and seems to do what I wanted and somewhat extends Carlos's original script to do what I desired.

                       

                      var doc = app.activeDocument;
                      var symbols = doc.symbolItems;
                      //
                      var promtText = "Search For Symbols\nType a string to search for symbols"
                      var findString = prompt(promtText,"");
                      stringToMatch = new RegExp(findString, 'i')
                      //
                      for (var i = 0; i < symbols.length; i++) {
                          var symbolitem = symbols[i];
                          if (symbolitem.symbol.name.match(stringToMatch)) {
                              symbolitem.selected = true;
                          }
                      }
                      

                       

                      Thanks so much everyone! If there is something I can do in my code better I am always all ears and wish to learn.

                      • 9. Re: Selecting Symbols on page by name
                        Muppet Mark Community Member

                        Swap print() for $.write() or $.writeln() when using the ESTK to debug these are the methods for getting info back to the toolkit console…

                         

                        Also be careful you set a variable symbolitem to a symbol these are 2 different things and that can become very confusing… A symbolItem ( cap I ) is in the artwork of the document where a symbol is in the document symbols collection ( used or unused )

                        • 10. Re: Selecting Symbols on page by name
                          Muppet Mark Community Member

                          Also match does not return a boolean… could be string array or null… do use test instead…

                           

                          if (stringToMatch.test(symbolitem.symbol.name) ) {
                               symbolitem.selected = true;
                          }

                          • 11. Re: Selecting Symbols on page by name
                            W_J_T Community Member

                            Thanks Muppet Mark!

                            Muppet Mark wrote:

                             

                            Swap print() for $.write() or $.writeln() when using the ESTK to debug these are the methods for getting info back to the toolkit console…

                             

                            Also be careful you set a variable symbolitem to a symbol these are 2 different things and that can become very confusing… A symbolItem ( cap I ) is in the artwork of the document where a symbol is in the document symbols collection ( used or unused )

                             

                             

                            Thanks for the heads up on the ESTK write methods for debugging.

                             

                            Also on the symbolItem, I just looked it up in the reference, I see what you mean. I was using it from Carlos's code above, but yes I understand that using reserved words can get confusing and cause issues. Thanks for letting me know, so much new stuff to learn in the reference docs.

                            Muppet Mark wrote:

                             

                            Also match does not return a boolean… could be string array or null… do use test instead…

                             

                            if (stringToMatch.test(symbolitem.symbol.name) ) {
                                 symbolitem.selected = true;
                            }

                             

                            Thanks so much for the heads up on test, works great! Thanks so much Muppet Mark for the sound advice, improvements and direction!

                            • 12. Re: Selecting Symbols on page by name
                              Muppet Mark Community Member

                              In general… I use the $.write() to console methods all the way though debugging so I know where things are up to… Just comment them out as I progress once done you can remove them all… I did start out using alert() but these things are learnt as we progress… a learning curve and its still a long way up that hill… I only debug using the ESTK so print() could be totally vaild in some other text editor app…

                              • 13. Re: Selecting Symbols on page by name
                                W_J_T Community Member

                                Thanks Muppet Mark, I have only opened the ESTK a few times, but after testing these codes, I will probably begin to utilize it further in the future. Yeah I have been using alert() also some, and ah yes the learning curve. Always something to learn no matter how much we know or dont know, but it always fun to learn even with all the challenges it brings.

                                 

                                Thanks I appreciate your guidance and feedback. Plus all the knowledge I find laying around here with all yours and others posts.

                                • 14. Re: Selecting Symbols on page by name
                                  hilukasz Community Member

                                  haha, oops you're right I forget sometimes that people don't have my functions. I have a lot of helpers, its annoying to wrote $.write everytime so i wrote a print function:

                                   

                                  function print(i) {
                                          $.write(i+"\n"); 
                                  };
                                  

                                   

                                  not too fancy.... but saves time.