6 Replies Latest reply on Feb 18, 2014 8:38 AM by Trevorׅ

    [AS][CS6]Apply different styles in one text frame

    jaguar 0006 Level 1

      Hello,

       

      Currently, I have an AppleScript to fill a single text frame with a series of strings:

       

      tell MyTextFrame to set (contents of parent story) to MyText1& MyText2&MyText3&MyText4

       

      I would like to apply a different style (MyStyle1 to MyStyle4) to each of these strings (MyText1 to MyText4).

      Accuracy: MyTexti strings can contain a word or a paragraph or more, so I cannot apply a style to a paragraph, for example.

       

      Thomas

        • 1. Re: [AS][CS6]Apply different styles in one text frame
          Laubender Adobe Community Professional & MVP

          @Thomas – since you know the length of each of your strings, you could apply either local formatting for the different ranges of characters or you could apply character styles.

           

          I'm more into ExtendScript than into AppleScript, so my solution presented here is in ExtendScript.

           

          Here an example with formatting the individual strings with character styles.

          As base it is using an twodimensional array where all the relevant information is stored.

           

          A loop through that array will apply the contents and the formatting on the fly.

          I commented nearly every line of code, because I cannot know if you are doing ExtendScript.

          But I'm sure you could adapt its principles to AppleScipt.

           

          Note: counting in ExtendScript will begin with 0, not 1.

           

          //Variable for the active document:
          var myDoc = app.documents[0];
          
          //Add a text frame to page one
          
          //First define position and size
          //Change [0,0,100,100] to your own numbers for defining position and size
          var myGeoBounds = [0,0,100,100]; 
          var myTextFrame = myDoc.pages[0].textFrames.add({geometricBounds:myGeoBounds});
          
          //Define an twodimensional array (an array of arrays)
          //Where the first entry is your string
          //Where the second entry is the name of your character style 
          //you want to apply to that particular string
          
          var myArray =   [ 
                                  ["MyText1","charStyle1"],
                                  ["MyText2"],
                                  ["MyText3"],
                                  ["MyText4","charStyle4"]
                                  ];
          
          //Loop through that array from back to forth.
          //So that new text can be added always at insertion point 1:
          
          for(var n=myArray.length-1;n>=0;n--){
              
              //Some variables we need later:
              var myCurrentCharStyle;
              var myTextToFormat;
              
              //Three cases:
              
              //Case 1:
              //If there is no character style name defined in the array, apply the character style "[None]"
              
              if(myArray[n].length == 1){myCurrentCharStyle = myDoc.characterStyles[0]};
              
              //Case 2:
              //If there is a character style name defined in the array, 
              //but this character style is not present in the document
              //add a new one named to the contents of the array:
              
              if(myArray[n].length == 2 && !myDoc.characterStyles.itemByName(myArray[n][1]).isValid){
                  myCurrentCharStyle = myDoc.characterStyles.add({name:myArray[n][1]});
                  };
              
              //Case 3:
              //If there is a character style name defined in the array,
              //and a character style with that name is already present in the document, use that one:
              
              if(myArray[n].length == 2 && myDoc.characterStyles.itemByName(myArray[n][1]).isValid){
                  myCurrentCharStyle = myDoc.characterStyles.itemByName(myArray[n][1]);
                  };
              
              //The following line writes the current state to the Javascript Console of the ESTK (ExtendScript Toolkit app)
              //Shows the number of the loop (it will count from back to forth, in ExtendScript count begins with 0), 
              //the current contents of the array and the current character style as an object declaration
          
          //YOU CAN REMOVE OR COMMENT OUT THIS LINE:
              
              $.writeln(n+"\t"+myArray[n]+"\t"+myCurrentCharStyle);
              
              //NOW the real action takes place:
              
              //Add the contents of the string to the first insertion point of the text frame:
              myTextFrame.insertionPoints[0].contents = myArray[n][0];
              
              //Define the range of characters you want to format according to the length of the
              //string in the array:
              myTextToFormat = myTextFrame.texts[0].characters.itemByRange(0,myArray[n][0].length-1);
              
              //Apply the character style to that range of characters:
              myTextToFormat.appliedCharacterStyle = myCurrentCharStyle;
              
              //In case you want to apply the "[None]" character style, 
              //set back the formatting of the default one.
              //That's the one already applied or 
              //the one that is applied to insertion point one in a new text frame
              
              myTextToFormat.clearOverrides(OverrideType.CHARACTER_ONLY);
              
              };
          

           

           

          Uwe

          1 person found this helpful
          • 2. Re: [AS][CS6]Apply different styles in one text frame
            jaguar 0006 Level 1

            Hello,

             

            Thank you for this very detailed and complete answer.

            If I can find how to apply, in an AppleScript, a style between a character n and a character p of a text frame, then I could apply your method.

            And I dont know how to do this!

             

            And I do not know either, in an AppleScript, how to test if a style already exists in the document.

             

            Thomas

            • 3. Re: [AS][CS6]Apply different styles in one text frame
              Laubender Adobe Community Professional & MVP

              @Thomas – sorry, as I said, I cannot assist very much in writing AppleScript…

               

              Don't know if something like the


              itemByRange( startPositionAsIndexNumber , endPositionAsIndexNumber )-method

               

              is available.

               

              Uwe

              • 4. Re: [AS][CS6]Apply different styles in one text frame
                Trevorׅ Adobe Community Professional

                See the syntax below

                take note that whereas js items start a 0 as start at 1 so you have to adjust that in Uwe's script

                 

                tell application "Adobe InDesign CS6"

                    set myDocument to active document

                    set myPage to page 1 of myDocument

                    set myTextFrame to text frame 1 of myPage

                    tell parent story of myTextFrame

                        set myText to object reference of text from character 1 to character -2 of paragraph 1

                        tell myText

                            apply character style using character style "myCharStyle" of myDocument

                        end tell

                    end tell

                end tell

                 

                look at examples in the manual https://www.adobe.com/content/dam/Adobe/en/devnet/indesign/cs55-docs/InDesignScripting/InD esign-ScriptingGuide-AS.pdf

                A very useful reference guide indeed

                 

                Trevor

                • 5. Re: [AS][CS6]Apply different styles in one text frame
                  jaguar 0006 Level 1

                  Thank you very much for your answer that solves my problem and for the very useful reference guide.

                  My problem is actually explained on page 108 of this manual.

                  • 6. Re: [AS][CS6]Apply different styles in one text frame
                    Trevorׅ Adobe Community Professional

                    Hi Thomas,

                     

                    Glad I helped.

                     

                    I like Uwe have much more experience with JS than Applescript.

                    I found this quite useful link http://www.yourscriptdoctor.com/automating-indesign-cs6/applescript-vs-javascript

                     

                    The adobe scripting manuals are quite good but they do have some strange or outdated methods as they try to keep the script example as similar as possible as to when they were first written, possibly for cs1 even though the scripting DOM has changed radically since then.

                     

                    Checking the validity of an object is much better than a try catch method.  The above link shows how to check if an object is valid in both JS and AS scripts.

                     

                    if (exists myObject) then ....

                     

                    --AppleScript:
                    set docRef to getDocRef()
                    (*Returns reference to active document*)
                    on getDocRef()
                      tell application "Adobe InDesign CS6"
                        if (exists document 1) then
                          return document 1
                        else
                          return missing value
                        end if
                      end tell
                    end getDocRef
                    
                    //JavaScript:
                    var docRef = getDocRef();
                    /*Returns reference to active document*/function getDocRef(){
                      if (app.documents.item(0).isValid) {
                        return app.documents.item(0);
                      } else {
                        return null;
                      }
                    }
                    1 person found this helpful