21 Replies Latest reply on Sep 12, 2016 12:08 AM by Obi-wan Kenobi

    Returning a conditional text value.

    Trevorׅ Adobe Community Professional

      Hi,

       

      Can somebody tell me how to get the conditional text name (if there is) of the insertion point.

       

      Something like.

       

      CondintionalTextName=insertionpoint.conditional.name

       

      but written in Java Script instead of Gibberish!

        • 1. Re: Returning a conditional text value.
          Marc Autret Level 4

          Hi Trevor,

           

          Probably sth like:

           

          ConditionalTextName=insertionpoint.appliedConditions[0].name;
          

           

          Note that appliedConditions is an array, because multiple conditions can be applied to the same text.

           

          EDIT—To avoid errors with non-conditional text:

          var conds = myText.appliedConditions;
          var condName = conds.length ? conds[0].name : '[No Condition]';
          

           

          @+

          Marc

          • 2. Re: Returning a conditional text value.
            Trevorׅ Adobe Community Professional

            Hi Marc,

             

            Thanks for your answer, sorry for the long delay in my response .  I had a couple of things to iron out (like how to return all the conditions for all the selected texts and other simple issues that I'm too embarrassed to write) and I have been exceptinaly busy with other things.

            This is the code that I came up with based on your answer.

            try {
            var cl=app.selection[0];
            var w = new Window ("dialog","");
            array = [];
            for (var j = 0; cl.length>j; j++){
                var conds=app.selection[0].characters[j].appliedConditions;
                var curletter=app.selection[0].characters[j].contents;
                
            for (var i = 0; conds.length > (i); i++) {
             
            array.push ("Letter "+(j+1)+" \""+curletter+"\""+"\tCondition "+i+" name is \t"+conds[i].name+" ");}
             if (conds.length==0) {
             var condName = conds.length ? conds[0].name : '[No Condition]';
             array.push ("Letter "+(j+1)+" \""+curletter+"\""+"\tCondition "+i+" name is \t"+condName)
            }
            }
            if (j==0){var i=0;}
            array.push ("\r\tSelected text \""+app.selection[0].characters.itemByRange(0,-1).contents+"\"");
            array.push ("\tIn total "+j+ " characters");
             alert_scroll ("Conditional Texts Names of Selectect Characters", array,);
            function alert_scroll (title, input) // string, string/array
            {
            // if input is an array, convert it to a string
            if (input instanceof Array)
            input = input.join ("\r");
            var w = new Window ("dialog", title);
            var list = w.add ("edittext", undefined, input, {multiline: true, scrolling: true});
            // the list should not be bigger than the maximum possible height of the window
            list.maximumSize.height = w.maximumSize.height - 300;
            list.minimumSize.width = 450;
            w.add ("button", undefined, "Close", {name: "ok"});
            w.show ();    
            }}
            catch (cl)
            {
                alert("First Select Text!");
            }
            

            It produces the following result:

            ScreenShot053.jpg

            I would like to know two more things about conditionals texts.


            1) I would like to add a line at the bottom stating how many DIFFERENT conditions are used throughout all the selected texts. In the above example including [no condition] a total of 8 conditions are used 1) AppleScript 2) blue 3) Green 4) Nikud 5) Red 6) Violet 7) Yellow 8) No condition


            2) To apply the "Red" condition to the selected text I would use

            app.selection[0].applyConditions ( app.activeDocument.conditions.item("Red", true), true);
            
            

            I can't figure out how to make the selection have no conditions

            app.selection[0].applyConditions ( app.activeDocument.conditions.item("[Unconditional]", true), true); Does not work.


            Any Ideas?

            • 3. Re: Returning a conditional text value.
              tobias.wantzen Level 1

              Trevor, I don't know, if it helps after such a long time ...

               

              app.selection[0].applyConditions ( [], true );
              

               

              Tobias

              1 person found this helpful
              • 4. Re: Returning a conditional text value.
                Trevorׅ Adobe Community Professional

                Tobias ,thanks

                 

                I appreciate a thought regardless of the time passed.

                 

                I did figure out some time ago that app.selection[0].applyConditions ( ["none"], true ); works but I guess the  app.selection[0].applyConditions ( [], true ); is shorter

                 

                I do have another question.

                 

                How does one make the a condition is removed from a selection.

                 

                For example:

                 

                A selection has any combination of the conditions "Bold" "Red" "Apple" and "Fred"

                I want to remove from my selection the "Red" condition but keep any other conditions there.

                I do not want to affect the "Red" condition that is outside my selection.

                 

                any ideas

                 

                Trevor

                • 5. Re: Returning a conditional text value.
                  tobias.wantzen Level 1

                  Trevor!

                  ~ Trevor ~ wrote:

                   

                  I did figure out some time ago that app.selection[0].applyConditions ( ["none"], true ); works but I guess the  app.selection[0].applyConditions ( [], true ); is shorter

                  The best of it: It's language independant!

                   

                  ~ Trevor ~ wrote:

                   

                  How does one make the a condition is removed from a selection.

                  Thank'd be nice to know, if someone has a better method. Up to now I'd use something like:

                   

                  #target InDesign
                  
                  var theSelection = app.selection[0]
                  theSelection.applyConditions(removeCondition(theSelection.appliedConditions, 'Red'), true);
                  
                  function removeCondition (condObject, condName) {
                      newCondObject = [];
                      for (var i = 0; i < condObject.length; i++) {
                          if (condObject[i].name != condName ) newCondObject.push(condObject[i]);
                      }
                      return newCondObject;
                  }
                  

                   

                  Tobias

                  • 6. Re: Returning a conditional text value.
                    tobias.wantzen Level 1

                    Sorry, this is a bit more logical:

                     

                    #target InDesign
                    
                    var theSelection = app.selection[0];
                    removeCondition(theSelection, 'Red');
                        
                    function removeCondition (condObject, condName) {
                        condObject = theSelection.appliedConditions;
                        newCondObject = [];
                        for (var i = 0; i < condObject.length; i++) {
                            if (condObject[i].name != condName ) newCondObject.push(condObject[i]);
                        }
                        theSelection.applyConditions(newCondObject, true);
                        return null;
                    }
                    

                     

                    Tobias

                    • 7. Re: Returning a conditional text value.
                      Trevorׅ Adobe Community Professional

                      Thanks

                       

                      This method is only efective if the entire selection should become the same

                      See the screenshot

                       

                      (1) the original line

                      (2) the line after selecting the whole line and running the script

                      (3) & (4) after running the script on partial selections

                       

                      ScreenShot026.png

                      to loop though each character is not practical.

                      A solution might be to use menu action calls, i.e. check if the condition exist in the selection (using grep preference) then if found apply the "Red" condition twice through menu call.

                      I shall give this a go but was hoping for a better solution

                       

                      Regards

                       

                      Trevor

                      • 8. Re: Returning a conditional text value.
                        tobias.wantzen Level 1

                        You can a grep to find all occurences and run my script snippet on every found character.

                         

                        Tobias

                        • 9. Re: Returning a conditional text value.
                          Trevorׅ Adobe Community Professional

                          No luck so far

                          1) Can't search for presence of a particular condition can only search for an entire array of conditions

                          in other word if I search for "Red" I will only find text which has just the "Red" condition applied to it but if it also has the "Apple" condition applied to it the it won't find it.

                           

                          2) Don't now how to invoke a particular condition with a menu action. Oh well

                           

                          By the way "None" it not necessarily a localized name see Marc's comment here http://forums.adobe.com/message/4455559#4455559

                           

                          But [] is shorter

                          • 10. Re: Returning a conditional text value.
                            tobias.wantzen Level 1

                            Hi Trevor,

                             

                            indeed, the InDesign search fails on this demand. Hm.

                             

                            Alternatively you have to build your own search function for conditions (sorry, a bit in a hurry):

                             

                            #target InDesign
                            
                            var theDoc = app.activeDocument;
                            var theSelection = app.selection[0];
                            var allRanges = theSelection.textStyleRanges;
                                
                            // collect conditioned ranges
                            var conditionedRanges = [];
                            for (m=0;m<allRanges.length;m++) {
                                if ( allRanges[m].appliedConditions.length > 0 ) {
                                    conditionedRanges.push(allRanges[m]);
                                }
                            }
                              
                            // remove single condition
                            for (n=0;n<conditionedRanges.length;n++) {
                                removeCondition(conditionedRanges[n], 'Red');
                            }
                            
                               
                            function removeCondition (selectedObject, condName) {
                                var condObject = selectedObject.appliedConditions;
                                newCondObject = [];
                                for (var i = 0; i < condObject.length; i++) {
                                    if (condObject[i].name != condName ) newCondObject.push(condObject[i]);
                                }
                                selectedObject.applyConditions(newCondObject, true);
                                return null;
                            }
                            

                            I think the textStyleRanges are the best choice for this demand, because they contain the larged cluster of characters with similar formating.

                             

                            Tobias

                            • 11. Re: Returning a conditional text value.
                              Trevorׅ Adobe Community Professional

                              Hi Tobias,

                               

                              I deleted the last post that I wrote because the changes I made in your code were rubbish

                               

                              Bellow is the "correct" code

                              Has 2 changes from yours besides the doscript.

                              your script didn't work because changes to text objects must me made in reverse order (change #1 VERY IMPORTANT)

                              I also added a check that only if the text range had a "Red" condition the conditions are applied (less changes to the document)

                               

                              Once again thanks for all your efforts and I'll let you know if I get a better way.

                               

                              Trevor

                               

                               

                              #target InDesign
                              app.scriptPreferences.enableRedraw =0; 
                              app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "Remove Red Condition");
                              
                              function main(){
                              var     theDoc = app.activeDocument;
                              var theSelection = app.selection[0];
                              var allRanges=[];
                              var allRanges = theSelection.textStyleRanges;
                              
                              // collect conditioned ranges
                              conditionedRanges = [];
                              for (var m=0;m<allRanges.length;m++) {
                                  if (allRanges[m].appliedConditions.length > 0 ) {
                                      conditionedRanges.push(allRanges[m]);
                                  }
                              }
                              
                              // remove single condition
                              for (var n=conditionedRanges.length-1;n>=0; n--) // Have to go backwards!!!
                              {
                               removeCondition(conditionedRanges[n], 'Red')
                               } 
                               }
                              
                              
                              function removeCondition (selectedObject, condName) {
                              var    hasRedCondition=0;
                              var    condObject = selectedObject.appliedConditions;
                              var    newCondObject = [];
                                  for (var i = 0; i < condObject.length; i++)
                              
                               {      
                                   (condObject[i].name != condName) ? newCondObject.push(condObject[i]) : hasRedCondition=1;
                                  }
                              
                              if (hasRedCondition==1) selectedObject.applyConditions(newCondObject, true) // This way the condtions are only changed if there is a  "Red" condtion
                              
                                  return null;
                              }
                              
                              • 12. Re: Returning a conditional text value.
                                tobias.wantzen Level 1

                                Hi Trevor,

                                 

                                I gave you no bullet proof rock solid script, but only some quick thoughts for a solution. I like your changes. (Personally I'd change a bit more ... see below ...) I'm glad you now found your way through the conditions jungle.

                                 

                                In my eyes scripting conditions is a bit tricky and not as self explanatory. The fact that you could not find a text, that has multiple conditions applied,  via a single condition search in an easy way makes it even more tricky. (I'd say, that's worth a feature request ...)

                                 

                                I optimized your code a bit:

                                 

                                #target InDesign
                                app.scriptPreferences.enableRedraw = 0;
                                app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "Remove Red Condition");
                                
                                function main() {
                                    var theCondition = 'Red';
                                    var theSelection = app.selection[0];
                                
                                    var allRanges = [];
                                    var theRange = '';
                                    var allRanges = theSelection.textStyleRanges;
                                
                                    for ( var m = 0; m < allRanges.length; m++ ) {
                                        theRange = allRanges[m];
                                        if ( theRange.appliedConditions.length > 0 ) {
                                            for ( var n = theRange.length-1; n >= 0; n-- ) {  
                                                removeCondition(theRange, theCondition);  // remove condition
                                            } 
                                        }
                                    }
                                }
                                
                                function removeCondition ( selectedObject, condName ) {
                                    var hasCondition = false;
                                    var condObject = selectedObject.appliedConditions;
                                    var newCondObject = [];
                                    for ( var i = 0; i < condObject.length; i++ ) {      
                                        (condObject[i].name != condName) ? newCondObject.push(condObject[i]) : hasCondition = true;
                                    }
                                    if ( hasCondition ) selectedObject.applyConditions( newCondObject, true );  // condtions are only changed if there is a "Red" condtion
                                    return null;
                                }
                                

                                Some more ideas for you:

                                • To increase readability take some parts of the for - if - for - construction in main() and build further functions with them.
                                • You can extend the script's functionality by adding a drop down dialog window so the user can choose the condition by name.
                                • You can widen the selection part with some checks to focus the functionality on selections that make sense in this context (character, paragraph, text, ...).

                                 

                                Tobias

                                • 13. Re: Returning a conditional text value.
                                  Trevorׅ Adobe Community Professional

                                  Very good Tobias

                                   

                                  One a page document with a lot of conditions applied your optimized code took about 5.5 seconds as apposed to the about 17.5 that my one took!!

                                   

                                  Note

                                   

                                  Still not bulletproof

                                   

                                  The line in the optimized code

                                   

                                   

                                      for ( var m = 0; m < allRanges.length; m++ ) {
                                  

                                   

                                  need to be changed to

                                   

                                            for ( var m =  allRanges.length-1 ; m >=0; m-- ) {
                                  

                                   

                                  without the change does not work properly

                                   

                                  Please edit your code post above and I will delete this note on changing the code.


                                   

                                  tobias.wantzen wrote:

                                   

                                  • You can extend the script's functionality by adding a drop down dialog window so the user can choose the condition by name.

                                   

                                  The purpose ot the script is to be able to delete a condition as a function within another script without a user interface.

                                   

                                  For a user to perform the task he just goes to the conditional text panel and unticks the Red condition Easy and Instant!

                                   

                                  That's why I thought to use menu action, but it doesn't seem possible I would like to be proven wrong on this point !!

                                  My Idea to use a search was silly as the condition can be taken off the whole selection.

                                   

                                  Your right about the feature request it is really dumb that one can't search for a particlar condition that is part of an array of conditions.

                                   

                                  Trevor

                                  • 14. Re: Returning a conditional text value.
                                    tobias.wantzen Level 1

                                    5.5 to 17.5 sec.? Nice improvement.

                                     

                                    Corrected Script:

                                     

                                    #target InDesign
                                    app.scriptPreferences.enableRedraw = 0;
                                    app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "Remove Red Condition");
                                    
                                    function main() {
                                        var theCondition = 'Red';
                                        var theSelection = app.selection[0];
                                      
                                        var allRanges = [];
                                        var theRange = '';
                                        var allRanges = theSelection.textStyleRanges;
                                    
                                        for ( var m = allRanges.length-1; m >= 0; m-- ) {
                                            theRange = allRanges[m];
                                            if ( theRange.appliedConditions.length > 0 ) {
                                                for ( var n = theRange.length-1; n >= 0; n-- ) {  
                                                    removeCondition(theRange, theCondition);  // remove condition
                                                } 
                                            }
                                        }
                                    }
                                       
                                    function removeCondition ( selectedObject, condName ) {
                                        var hasCondition = false;
                                        var condObject = selectedObject.appliedConditions;
                                        var newCondObject = [];
                                        for ( var i = 0; i < condObject.length; i++ ) {      
                                            (condObject[i].name != condName) ? newCondObject.push(condObject[i]) : hasCondition = true;
                                        }
                                        if ( hasCondition ) selectedObject.applyConditions( newCondObject, true );  // condtions are only changed if there is a "Red" condtion
                                        return null;
                                    }
                                    

                                    (I can only edit my post so long as no one has answered to it ...)

                                     

                                    I didn't get the point of your menu action suggestion: What do you want to achieve with it? Can you verbose your idea?

                                     

                                    Tobias

                                    1 person found this helpful
                                    • 15. Re: Returning a conditional text value.
                                      Trevorׅ Adobe Community Professional

                                      Sorry, I didn't know that limitation to the Edit, I see there is some logic to that.

                                       

                                      You meant to say

                                           "17.5 to 5.5 sec.? Nice improvement"

                                      Sure is.

                                       

                                      Regarding the menu actions I meant as follows

                                       

                                      app.menuActions.item("$ID/#CondTextUI_PanelName").invoke();
                                      

                                       

                                      opens the menu panel

                                      ScreenShot028.png

                                      The text is already selected

                                      ScreenShot029.png

                                      If one clicks on the box to the left of the word Red then the Red condition will be applied to the entire selection (providing it wasn't already applied to the whole selection)

                                      ScreenShot030.png

                                      Now that it has been applied to the whole selection if one clicks on that box a second time it gets rid of the Red condition from the selection

                                      ScreenShot031.png

                                      note the Red / Cyan by the letters E25 has now gone.

                                       

                                      The problem is that I don't think there's a way of invoking this clicking action with a menuaction.

                                       

                                      In other words there does not seem to be away of simulating the clicking of the box to the left of the word Red.

                                      No equivalent of

                                      app.menuActions.item("$ID/#CondText_Item_Red").invoke();
                                      

                                       

                                      If there was the the scipt could be speed up very considerably.

                                       

                                      Hope it's clear what I meant

                                       

                                      Trevor

                                      • 16. Re: Returning a conditional text value.
                                        tobias.wantzen Level 1

                                        Hi Trevor,

                                         

                                        maybe this is a job for UI scripting of MacOS. But in my knowledge you could only do this with AppleScript:

                                        http://www.mactech.com/articles/mactech/Vol.21/21.06/UserInterfaceScripting/index.html

                                        http://www.macosxautomation.com/applescript/uiscripting/index.html

                                         

                                        You could try to work out the correct AppleScript code and integrate it into JS.

                                         

                                        You can doScript that like:

                                        var chs="tell application \"finder\"\r"; 
                                        chs+="activate\r" 
                                        chs+="set myPath to (choose file with prompt \"Choose\")\r"; 
                                        chs+="set myPath to POSIX path of myPath as text\r" 
                                        chs+="return myPath\r" 
                                        chs+="end tell"; 
                                        var myResults = app.doScript(chs,ScriptLanguage.APPLESCRIPT_LANGUA GE); 
                                        alert( myResults );
                                        

                                         

                                        But personally I'd avoid using UI scripting. It's not platform independant and I'm not sure, if it's even quicker ...

                                         

                                        Tobias

                                        • 17. Re: Returning a conditional text value.
                                          Trevorׅ Adobe Community Professional

                                          Having a windows system I also avoid Apple Script

                                           

                                          Thanks for all your effort, best left as is.

                                           

                                          Trevor

                                          • 18. Re: Returning a conditional text value.
                                            Trevorׅ Adobe Community Professional

                                            Well Tobias I did warn you last week

                                             

                                            Trevor wrote:

                                             

                                            You shall be hearing from me soon !

                                             

                                            I used Marc's script (slightly adapted) http://forums.adobe.com/message/4502873#4502873 for this problem and came up with Interesting results.

                                             

                                            On a real life 36 page document with 4 conditions not including unconditional, with approximately 180 occurrences of "Red" and a total of about 420 conditional occurrences in total your script took approximately  3037.674 Seconds, Just over 50 minutes.  The following script to approximately  .53 of a second.

                                             

                                            That's an increase in speed of about 5730 times !!! not bad

                                             

                                            The weakness of your script is that it if affected by all changes in formats i.e. bold, italics, font and any thing else.  That slows it down considerably.

                                             

                                            My script also has an Archimedes heal.  If there are more than about 13 different conditions it starts getting significantly slower at a square rate.

                                             

                                            On one page tests the difference is much smaller but still very significant (depending on the contents of the page)

                                             

                                            Regards

                                             

                                            Trevor

                                             

                                            #target indesign
                                            app.scriptPreferences.enableRedraw =0;
                                            startTime = new Date().getTime();
                                            
                                            app.doScript("TrevorsBasedOnMarcs()", ScriptLanguage.javascript, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "Remove Condtion by Grep");
                                            alert ((new Date().getTime()-startTime)/1000+" seconds");
                                            
                                            function TrevorsBasedOnMarcs ()
                                            {
                                             try {
                                                  var theCondition = [(app.activeDocument.conditions.item("Red"))];
                                                  var theSelection = app.selection[0];
                                                  var myOtherConditions =[]
                                                  var myConditions=app.activeDocument.conditions; 
                                                  var m=0
                                                  for(var n=0;n<myConditions.length;n++) 
                                                  { 
                                                    if (myConditions[n]!=theCondition)
                                                        {
                                                            myOtherConditions[m]=myConditions[n];
                                                            m++
                                                         }
                                                   }
                                                var myConditionCombos=[];
                                                grepFindCondition=[];
                                                (myConditionCombos= arrayParts(myOtherConditions));
                                                app.findGrepPreferences = app.changeGrepPreferences = null;
                                                app.findGrepPreferences.appliedConditions=theCondition;
                                                app.changeGrepPreferences.appliedConditions=[];
                                                try {theSelection.changeGrep()} catch (noFind) {}
                                                for (var x=0; x<myConditionCombos.length;x++)
                                                {
                                                  try
                                                   {
                                                    app.findGrepPreferences.appliedConditions= (myConditionCombos[x].concat (theCondition));
                                                    app.changeGrepPreferences.appliedConditions=myConditionCombos[x];
                                                    theSelection.changeGrep();
                                                    } catch(noFind) {}
                                                }
                                              } catch (noConds) {}
                                            }
                                            
                                            
                                            function arrayParts(/*arr*/a, r,i,j,t,s,p) // by Marc Auret
                                            // -------------------------------------
                                            // Note: a is supposed to contain unique items
                                            // [if necessary, apply a makeUnique routine first]
                                            {
                                                if(! (i = Math.pow(2,a.length)-1) ){ return null; }
                                                (r=[]).toString = function(){return this.join('\t');};
                                            
                                                while(i--)
                                                    {
                                                    r[i] = t = [];
                                                    s = (1+i).toString(2);
                                                    p = (j=s.length) - 1;
                                                    while( j-- ) '1'==s[j] && t[t.length]=a[p-j];
                                                    }
                                                return  r;
                                            }
                                            
                                            • 19. Re: Returning a conditional text value.
                                              Obi-wan Kenobi Adobe Community Professional

                                              Hi Trevor,

                                               

                                              Very nice!

                                               

                                              I'm working a lot with Conditions!

                                               

                                              This amazing script is totally beyond my current [JS] understanding but I'm studying it with a great interest!

                                               

                                              How could it be modified to deal with the "entire document", not only a text selection?

                                               

                                              Thank you in advance !

                                               

                                              (^/)

                                               

                                              • 20. Re: Returning a conditional text value.
                                                tobias.wantzen Level 1

                                                Obi-wan,

                                                 

                                                change line 12 to

                                                    var theSelection = app.activeDocument;
                                                

                                                 

                                                Tobias

                                                • 21. Re: Returning a conditional text value.
                                                  Obi-wan Kenobi Adobe Community Professional

                                                  Oups! Of course! 

                                                   

                                                  Thanks a lot Tobias!

                                                   

                                                  (^/)