14 Replies Latest reply: May 8, 2012 1:38 PM by tpa_gru_flo RSS

    Iterate through selected characters

    tpa_gru_flo Community Member

      Hi guys and girls!

       

      Has anybody a code snippet to show me how to iterate through the selected text (not the frame!, not the words, only the selected chars) and make any change on the characterAttributes (size, color, etc.)?

       

       

      Deeper into it:

      In the property "app.activeDocument.selection" usually the selected objects are stored as an array. Now when I select characters in a textframe (or TextPath, whatever) there is a [Textrange] in it.

      I already tried some combinations like this snippet underneath but I still get errors, that selectedChars[i] is undefined.

       

      FYI: I'm on Illustrator CS4, Mac OS X, Javascript

       

      
      var selectedChars = app.activeDocument.selection.characters;
                              
      for (i = 0; i < selectedChars.length; i++ ){                            
           selectedChars[i].characterAttributes.fillColor = myNewCMYKColor;
      }
      
      

       

      I hope I have gathered all relevant information. If not, please do not kill me and just ask back

      So has anybody a smart hint for me?

       

      Thanks a lot in advance!

        • 1. Re: Iterate through selected characters
          CarlosCanto MVP

          select some characters before running

           

          var myNewCMYKColor = new CMYKColor;
          myNewCMYKColor.magenta = 100;
          
          app.activeDocument.selection.fillColor = myNewCMYKColor;
          
          • 2. Re: Iterate through selected characters
            tpa_gru_flo Community Member

            Hi Carlos!

             

            Thanks for your answer. That could work, but I would like to make changes on the single characters. For example I would like to change the size of each of the selected character to a random value.

             

            Here is an image to make it clearer. After the script has run the text should look like this:

             

            screenshot.png

             

            So for that I definitely need a loop (for, while), where I can access single characters. Any suggestions for my "problem"?

             

            Thanks again!

            • 3. Re: Iterate through selected characters
              Larry G. Schneider MVP

              Here's a Change Size script that I found in my collection that somebody posted severat years ago. I'm sorry I don't remember who it was to give proper credit.

               

               

              #target illustrator
              
              // change size of paragraph text
              
              //$.bp();
              
              ChangeSize();
              
              function ChangeSize()
              {
                  selectedItems = selection;
                  // check to make sure something is selected.
                  if (selectedItems.length == 0)
                  {
                      alert("Nothing is selected");
                      return;
                  }
              
                  endIndex = selectedItems.length;
              
                  for (index = 0; index < endIndex; index++)
                  {
                      pageObject = selectedItems[index];
                      pageItemType = pageObject.typename;
              
                      if (pageItemType == "TextFrame")
                      {
                          // get the paragraphs from the selection.
                          theTextRange = pageObject.textRange;
                          paraTextRange = theTextRange.paragraphs;            
                          numParagraphs = paraTextRange.length;
              
                          for (i = 0 ; i < numParagraphs ; i++)
                          {
                              aParagraph = paraTextRange[i];
              
                              charTextRange = aParagraph.characters;
                              charCount = charTextRange.length;
              
                              if (charCount > 1)
                              {
                                  end = charCount;
                                  fontSizeChanger = 14/end;
                                  currentFontSize = 18;
                                  for (j = 0 ; j < end; j++)
                                  {
                                      theChar = charTextRange[j];
                                      theChar.size = currentFontSize;   
                                      currentFontSize = currentFontSize - fontSizeChanger;
                                  }
                                 
                              }
                          }
                      }
                  }
              }
              

               

              and here's the output.

               

              Screen shot 2012-05-04 at 9.46.07 AM.png

               

              You should be able to go from there.

              • 4. Re: Iterate through selected characters
                Muppet Mark Community Member

                I doesn't behave like I would expect it to here either… I have no issues when changing characters at an individual… The issue appears to be handling selection… in text… Yes I can loop the textRange… But it will NOT allow me to change at character level… I can change the whole range or loop with the characters to the same value but but can't makes changes with each… Some thing will always error undefined

                #target illustrator
                
                var doc = app.activeDocument;
                
                var sel = doc.selection;
                
                if ( sel.typename == 'TextRange' ) {
                
                          var count = sel.characters.length;
                
                          doc.selection = null;
                
                          for ( var i = 0; i < count; i++ ) {
                
                                    $.writeln( i );
                
                                    var selCar = sel.characters[i]; // Is defined
                
                                    $.writeln( selCar.contents );
                
                                    var newSize = 24 + ( i * 3 ); // Is defined
                
                                    $.writeln( newSize );
                
                
                     //selCar.characterAttributes.size = newSIze;
                
                                    selCar.characterAttributes.size = 30;
                
                          };
                
                };
                
                

                 

                The commented out line will always error here… All the figures and letters look right in console?

                • 5. Re: Iterate through selected characters
                  CarlosCanto MVP

                  Hi Mark, it might be a bug, at first, in you code selChar is a Character, and in the documentation even though it says "textRange" objects of length 1, there's really no Character Object...but anyhow, selChar does take properties like Contents, behaving like a true textRange Object...but weird it doesn't work when you set the sizes...weird.

                   

                  then I noticed the textRange Object has a textRanges property, that did it, it holds each character as a textRange.

                   

                  here's a working sample

                   

                  randomSelectedCharacterSize.gif

                   

                  var myNewCMYKColor = new CMYKColor;
                  myNewCMYKColor.magenta = 100;
                  
                  var sel = app.activeDocument.selection;
                  var characters = sel.textRanges;
                  var fontsize = sel.characterAttributes.size;
                  
                  for (i=1; i<=characters.length; i++) {
                      var character = characters[i];
                      var randomFontSize = randomXToY (fontsize-6, fontsize+6);
                      character.characterAttributes.size = randomFontSize;
                      character.fillColor = myNewCMYKColor;
                  
                      var randomMagentaColor = randomXToY (0, 100);
                      myNewCMYKColor.magenta = randomMagentaColor;
                  }
                  
                  //function to get random number upto m, by Roshan Bhattarai
                  function randomXToY(minVal,maxVal,floatVal)
                  {
                    var randVal = minVal+(Math.random()*(maxVal-minVal));
                    return typeof floatVal=='undefined'?Math.round(randVal):randVal.toFixed(floatVal);
                  }
                  
                  • 6. Re: Iterate through selected characters
                    Larry G. Schneider MVP

                    Prefect, Carlos, for writing your next ransom note. All we need now is to randomize the font by character.

                    • 7. Re: Iterate through selected characters
                      CarlosCanto MVP

                      hahaha, that's right, let's have tpa_gru_flo write that as homework

                      • 8. Re: Iterate through selected characters
                        Larry G. Schneider MVP

                        I'm trying to get this to work. I have it in ESTK and have targeted illustrator but it keeps returning "The specified text range is invalid" for the line var character = characters[i].  I have a piece of text in the file and a selection made of the text. Any words of wisdom?

                        • 9. Re: Iterate through selected characters
                          Muppet Mark Community Member

                          Thats a good spot Carlos… I had seen that but had NOT the time to put it to any tests ( saved me a bother ) There was also a textRange.textSelection that I wasn't sure about… Text ranges and sub ranges are a little weird at times…

                          • 10. Re: Iterate through selected characters
                            CarlosCanto MVP

                            Hi Larry, are you getting that error running my script? or you're using that line in your own version?.....

                             

                            ...wait, I see what's happening, let me run a couple of tests.

                            • 11. Re: Iterate through selected characters
                              CarlosCanto MVP

                              ok, you can safely forget all I have said previously

                               

                              Larry my previous script worked only because I randomly started my selection at the second character, just a coincidence here. I was really iterating the whole textFrame, so ended up rewriting the thing....and at the end it was like Mark's...???...that's weird, how come Marks didn't work?

                               

                              Mark, I revisited your script and it does not work cos you have a typo , you have newSIze, instead of newSize, changed that and it works beautifully...so, you still need to figure out textRanges and textSelection

                               

                              here's the new version, it still needs work to make it a real Ransom Note generator

                               

                              var myNewCMYKColor = new CMYKColor;
                              myNewCMYKColor.magenta = 100;
                              
                              var sel = app.activeDocument.selection;
                              
                              var fontsize = sel.characterAttributes.size;
                              
                              for (i=0; i<sel.length; i++) {
                                  var character = sel.characters[i]; //characters[i];
                                  //alert(character);
                                  //alert("i= " + i + "\rcharacter= " + character.contents);
                                  var randomFontSize = randomXToY (fontsize-6, fontsize+6);
                                  character.characterAttributes.size = randomFontSize;
                                  character.fillColor = myNewCMYKColor;
                              
                                  var randomMagentaColor = randomXToY (0, 100);
                                  myNewCMYKColor.magenta = randomMagentaColor;
                              }
                              
                              //function to get random number upto m, by Roshan Bhattarai
                              function randomXToY(minVal,maxVal,floatVal)
                              {
                                var randVal = minVal+(Math.random()*(maxVal-minVal));
                                return typeof floatVal=='undefined'?Math.round(randVal):randVal.toFixed(floatVal);
                              }
                              
                              • 12. Re: Iterate through selected characters
                                Larry G. Schneider MVP

                                Thanks, Carlos. Works well now. I looked in my scripts and found one by James Talmadge to vary the baseline of text so may work to incorporate that as well.

                                • 13. Re: Iterate through selected characters
                                  Muppet Mark Community Member

                                  Looks like I should increase the size of my type in the ESTK I couldn't spot that… Hum a trip to spec savers or a 27" imac… I'll have a think… ( once a muppet always a… )

                                   

                                  Screen shot 2012-05-05 at 11.17.31.png

                                  • 14. Re: Iterate through selected characters
                                    tpa_gru_flo Community Member

                                    No Internet for 5 days ... puh, that was tough. And then: maintainence.... but finally online again!

                                     

                                    Guys, thank you very much. I studied the documentation PDF, but never found that way of Carlos. I already integrated the snippet into my script and it works prefectly. As soon as everythijng is optimized and finished (there will be a little bit more in it ) I will post the script for download! Maybe it's useful for somebody here

                                     

                                    Have a nice evening and once again: THANKS for your help!!!