Skip navigation
mcs_dean
Currently Being Moderated

Selecting Symbols on page by name

Nov 26, 2011 4:43 PM

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.

 
Replies
  • Currently Being Moderated
    Nov 26, 2011 10:10 PM   in reply to mcs_dean

    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
                                  }
              }
    
     
    |
    Mark as:
  • Currently Being Moderated
    May 31, 2012 5:37 AM   in reply to CarlosCanto

    there is a much simpler solution. why not use .getByName() method? check out page 208 208 http://www.adobe.com/content/dam/Adobe/en/devnet/pdf/illustrator/scrip ting/illustrator_scripting_reference_javascript_cs5.pdf

     
    |
    Mark as:
  • Currently Being Moderated
    May 31, 2012 7:15 AM   in reply to hilukasz

    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…

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 7, 2012 2:26 PM   in reply to CarlosCanto

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 7, 2012 5:35 PM   in reply to W_J_T

    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....

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 7, 2012 5:06 PM   in reply to Muppet Mark

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

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 8, 2012 1:46 PM   in reply to hilukasz

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 8, 2012 1:56 PM   in reply to W_J_T

    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 )

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 8, 2012 2:01 PM   in reply to Muppet Mark

    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;
    }

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 8, 2012 2:16 PM   in reply to Muppet Mark

    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!

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 8, 2012 2:37 PM   in reply to W_J_T

    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…

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 8, 2012 2:46 PM   in reply to Muppet Mark

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Jun 8, 2012 6:57 PM   in reply to W_J_T

    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.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points