I am writing a script to print a section of a bookdown
online book as PDF, then move to the next section, and so on.
The print part works (the key codes are from this page):
tell application "Safari"
activate
tell application "System Events"
key code 35 using command down -- activate print menu item
end tell
delay 0.5
set i to 0
repeat while i < 15
set i to i + 1
delay 0.1
tell application "System Events"
key code 48 -- press tab 15 times
end tell
end repeat
tell application "System Events"
key code 49 -- press space
end tell
set i to 0
repeat while i < 2
set i to i + 1
delay 0.1
tell application "System Events"
key code 125 -- press down key twice
end tell
end repeat
tell application "System Events"
key code 36 -- enter
end tell
set i to 0
repeat while i < 16
set i to i + 1
delay 0.1
tell application "System Events"
key code 125 -- press tab to get to "save"
end tell
end repeat
tell application "System Events"
key code 36 -- enter to cleck on save
end tell
end tell
Problem
Now that I have printed the current section and I am back on Safari, I can click manually on the right arrow and move to the next section, but I can't manage to have the script to do that.
I have tried to add the following to the script above:
tell application "System Events"
key code 124 -- right arrow to enter the next page
end tell
Or even to "reopen" Safari, but nothing happens.
tell application "Safari"
activate
tell application "System Events"
key code 124 -- right arrow to move to the next section
end tell
end tell
How can I have AppleScript "turn the page" and move to the next section?
Also, I welcome suggestions to improve the script! I wonder if it would be easy to avoid repeating "tab" 15 times. I have looked at the Accessibility Inspector and found that "PDF" in the print menu corresponds to NSPopUpButtonCell
. I have tried to use select NSPopUpButtonCell of its sheet
but it did not work.
I can click manually on the right arrow and move to the next section, but I can't manage to have the script to do that.
How can I have AppleScript "turn the page" and move to the next section?
If you are trying to programmatically click the right-arrow, as shown in the image below, then the following example AppleScript code can do that:
tell application "Safari" to ¬
tell document 1 to ¬
do JavaScript ¬
"document.getElementsByClassName('fa fa-angle-right')[0].click();"
Notes:
This requires Allow JavaScript from Apple Events to be check on the hidden Develop menu.
To unhide the hidden Develop menu:
Update to address:
Also, I welcome suggestions to improve the script! I wonder if it would be easy to avoid repeating "tab" 15 times.
Here is how I'd use the JavaScript from above and coded to avoid using the key code
and or keystroke
System Events commands, especially tabbing around the UI.
Example AppleScript code:
tell application "System Events"
tell application process "Safari"
set frontmost to true
set i to 0
repeat until (its frontmost = true)
delay 0.1
set i to i + 1
if i ≥ 20 then return
end repeat
click menu item "Print…" of ¬
menu 1 of ¬
menu bar item "File" of ¬
menu bar 1
tell its front window
set i to 0
repeat until (exists menu button "PDF" of sheet 1)
delay 0.1
set i to i + 1
if i ≥ 20 then return
end repeat
click menu button "PDF" of sheet 1
set i to 0
repeat until (exists menu item "Save as PDF" of ¬
menu 1 of menu button "PDF" of sheet 1)
delay 0.1
set i to i + 1
if i ≥ 20 then return
end repeat
click menu item "Save as PDF" of ¬
menu 1 of ¬
menu button "PDF" of ¬
sheet 1
set i to 0
repeat until (exists button "Save" of sheet 1 of sheet 1)
delay 0.1
set i to i + 1
if i ≥ 20 then return
end repeat
click button "Save" of sheet 1 of sheet 1
set i to 0
repeat while (exists sheet 1)
delay 0.1
set i to i + 1
if i ≥ 100 then return
end repeat
end tell
end tell
end tell
tell application "Safari" to ¬
tell document 1 to ¬
do JavaScript ¬
"document.getElementsByClassName('fa fa-angle-right')[0].click();"
Notes:
Since this type of AppleScript script is using UI Scripting, I have included an error handling in the form of a repeat
loop to wait up to two seconds for the target UI element
to become available to be acted upon for most of the targets, however the last repeat
loop waits longer because it has to wait until the Save as PDF to complete. A simple delay
command with an appropriate value could be used instead, but with the include delay of a tenth of a second in the repeat
loops it shouldn't have to wait any longer than need be. In other words, I'd only use simple delay
command if I want to slow the script down from going through the various events of the UI. It's doubtful that it would need to be adjusted, but obviously do so as/if necessary.
If the timeout is reached, the script aborts at that point without any error message. The single-line if i ≥ 20 then return
statements can be turned into a full if
block and include an error message via the display dialog, display alert, or display notification command as wanted.