9 Replies Latest reply on Feb 2, 2017 8:35 AM by Dirk Becker

    Applescript within Javascript

    JustOneBren Level 1

      Hi all, have a question that hopefully will be easy for someone but is beyond my reach at present.

      Below is part of a script I am building and it "should" (but doesn't)

       

      // Select the text within a frame labled "Odd Page Header" in the Layers Pallette, then run the Function

          app.documents.item(0).pageItems.itemByName("Odd Page Header").texts.everyItem().select();  app.doScript(reFlow)

      // Select the text within a frame labled "Even Page Header" in the Layers Pallette, then run the Function

          app.documents.item(0).pageItems.itemByName("Even Page Header").texts.everyItem().select();  app.doScript(reFlow)

      // The Function: Normally would run a keyboard shortcut to reflow the text but has been changed to just type an "r" for testing

          function reFlow () {app.doScript('tell application "System Events" to keystroke "r" ', ScriptLanguage.APPLESCRIPT_LANGUAGE)}

      // Deselect

      // app.select(null);

       

      The problem is, instead it runs the function twice on the "Even Page Header" box (inserting "rr") and if I uncomment the "Deselect" command it doesn't work at all.

      I can see that the app.doScript has to be last to work but have no idea why or how to get around it so it works for each text frame selected.

      Have to thank Trevor for helping me on the original app.doScript to get a keystroke but expanding on it for this purpose I have hit a few problems.

       

      Any help would be appreciated, Brendan

        • 1. Re: Applescript within Javascript
          Laubender Adobe Community Professional & MVP

          Hi Brendan,

          what is the menu command you like to invoke?

          You are mentioning a keyboard shortcut for reflowing the text?

           

          Could that be this one?

           

          app.menuActions.itemByName("$ID/Recompose all stories").invoke();
          

           

          Regards,
          Uwe

           

          //EDIT

          • 2. Re: Applescript within Javascript
            Laubender Adobe Community Professional & MVP

            After testing a bit I see that even using two AppleScripts in a row is a bit strange with selections. Maybe not only with selections. I did not test this. It is as if InDesign is waiting after all script code is executed and then is doing the AppleScript part all together on the last selection.

             

            Even the code below will not work as I expected—the execution order is not in the order of the function execution, but only after the document is saved, closed, opened again and the second selection took place.

             

            Before running the snippet:

             

            BeforeScriptExecution.png

             

            The snippet that I ran from the ESTK with InDesign CC 2017 on Mac OSX 10.10.5:

             

            // Two AppleScripts:
            var scriptOne = 'tell application "System Events"\nkeystroke "scriptOne"\nend tell';
            var scriptTwo = 'tell application "System Events"\nkeystroke "scriptTwo"\nend tell';
            
            var InDesignFile = File(app.documents[0].fullName);
            
            // Execute the first function:
            one();
            
            // Save and close the document:
            app.documents[0].close(SaveOptions.YES);
            
            // Open the document immediately after closing it:
            app.open(InDesignFile);
            
            // Execute the second function:
            two();
            
            function one()
            {
            
                // Clearing the selection:
                app.documents[0].select(null);
            
                // Select the text in the text frame named "OddPageHeader":
                app.documents[0].pageItems.itemByName("OddPageHeader").texts.everyItem().select();
                app.doScript(scriptOne,ScriptLanguage.APPLESCRIPT_LANGUAGE);
            
            };
            
            function two()
            {
                // Clearing the selection:
                app.documents[0].select(null);
               
                // Select the text in the text frame named "EvenPageHeader":
                app.documents[0].pageItems.itemByName("EvenPageHeader").texts.everyItem().select();
                app.doScript (scriptTwo,ScriptLanguage.APPLESCRIPT_LANGUAGE);
            
            };
            

             

            After executing the code above:

             

            AfterScriptExecution.png

             

            The text frame named "EvenPageHeader" now has the contents that is done by the two AppleScripts combined.

             

            How can that be explained?

             

            Regards,
            Uwe

            • 3. Re: Applescript within Javascript
              JustOneBren Level 1

              Hi Uwe,

              The text reflow I am referring to is a 3rd party piece of software called "Agility" and I have set a keyboard shortcut (option r) to make it run the "Refow Story". I will check in the morning to see the exact name of the menu action and try to customise your invoke command, it seems a more direct solution than my keyboard shortcut version.

              Thank you, will let you know how I get on. Brendan

              • 4. Re: Applescript within Javascript
                JustOneBren Level 1

                Uwe,

                 

                Thought it was just me going mad, on one side I'm glad it's not but on the other side I am more of a loss than you as to why .

                Have been trying to work it out for hours and in the end had to raise it on here to check I wasn't just going around it totally the wrong way. Thanks for putting in the time to test it and I'm sorry if it gives you a few restless hours trying to wrap your head around it as it did with me. Will definitely be trying the invoke line as I said before but would be interesting to see if there are any answers to the above.

                Thanks again, Brendan

                • 5. Re: Applescript within Javascript
                  JustOneBren Level 1

                  Thank you Uwe,

                   

                  That line wored perfectly . Just changed it too "app.menuActions.itemByName("$ID/Reflow Story").invoke();" and there is no need for 'Functions' or 'doScripts', didn't realise that would work with drop down menus. It has opened up a whole new world of testing for me!

                   

                  Still stumped on the AppleScript problem so not sure at the moment wether to mark your answer correct (although it is for what I need) just in case someone has an explanation of that problem.

                   

                  Thank you again, Brendan

                  • 6. Re: Applescript within Javascript
                    Laubender Adobe Community Professional & MVP

                    Hi Brendan,

                    if we are looking at the title of this thread "AppleScript with JavaScript" the AppleScript part is not solved and is still waiting for some explanations or theories why it would be executed not immediately but altogether with the next (or perhaps last?) execution of the function providing an AppleScript (my assumptions).

                     

                    You already marked my answer with the menu action as "helpful".

                    That's enough. The real problem according to the title is not solved (if it can ever be solved).

                     

                    Note:
                    Using menu actions cannot be done with InDesign Server, because server is UI-less.

                     

                    Ah: And your problem lead my thinking to that menu command I offered in answer 1 here.

                    and at the same time it seems to be the solution to a problem I currently have with another redraw problem.

                     

                    Doing your suggestion:

                    app.menuActions.itemByName("$ID/Reflow Story").invoke();
                    

                    using a menu command for redrawing a single story would require a selected text frame or a selected text, I think.

                     

                    See this thread here if you are interested into other redrawing problems and possible solutions:

                    Updating a document's layout

                     

                    My problem discription and a solution for at least InDesign Desktop (not Server) here:

                     

                    3. Re: Updating a document's layout

                    Laubender Feb 1, 2017 (in response to frameexpert)

                     

                    Re: Updating a document's layout

                     

                    Regards,
                    Uwe

                    • 7. Re: Applescript within Javascript
                      Dirk Becker Level 4

                      In the original post you're passing the name of the javascript function reFlow to the app.doScript() call following the select().

                      Either invoke the function directly, or pass script code (javascript string holding an AppleScript) or the script file to app.doScript().

                      The use of app.doScript() within the function looks better, note the additional language parameter.

                      • 8. Re: Applescript within Javascript
                        JustOneBren Level 1

                        Hi, my original script was without the function as below and it still worked the same as my latest one, as in it would run both doScripts on the last selected object instead of one in each box.

                         

                        // Select the text within a frame labled "Odd Page Header" in the Layers Pallette, then run the doScript     app.documents.item(0).pageItems.itemByName("Odd Page Header").texts.everyItem().select()     app.doScript('tell application "System Events" to keystroke "r" ', ScriptLanguage.APPLESCRIPT_LANGUAGE) // Select the text within a frame labled "Even Page Header" in the Layers Pallette, then run the doScript     app.documents.item(0).pageItems.itemByName("Even Page Header").texts.everyItem().select()     app.doScript('tell application "System Events" to keystroke "r" ', ScriptLanguage.APPLESCRIPT_LANGUAGE)     // Deselect //~ app.select(null);

                         

                        and if you put anything (even an alert) after it doesn't run the doScript at all.

                        • 9. Re: Applescript within Javascript
                          Dirk Becker Level 4

                          Then the problem is that during script execution InDesign won't accept most user input, including those simulated keystrokes.

                          Only when the script is done, the event loop will see and apply them to the final selection - that would be your deselect.

                          You could work around by leaving script execution when you sent the key strokes.

                          To resume the script operation you could have an idle task waiting in background that would implement some reasonable delay, or checks for the result of the operation triggered by the keystroke.

                          Far too complicated and instable though as you already got the better solution by Uwe.

                          2 people found this helpful