I’m revising an AppleScript that displays the Safari Export as PDF dialog. Except as noted below, this script works exactly as I want and is generally reliable:
--set filename
set {year:y, month:m, day:d, hours:h, minutes:min, seconds:s} to (current date)
set theDate to ((y * 10000) + ((m as integer) * 100) + d) as text
set theTime to text 2 thru -1 of ((1000000 + (h * 10000) + (min * 100) + s) as text)
set fileName to "Safari (" & theDate & " " & theTime & ")"
--confirm Safari is open with URL
tell application "Safari" to set theURL to URL of front document
if theURL is missing value then display dialog "The frontmost Safari window could not be found or did not return a URL." buttons {"OK"} cancel button 1 default button 1
--I normally run this script by way of FastScripts with Safari active
--as a result, the following is normally not necessary and is for testing only
tell application "System Events" to tell process "Safari"
set frontmost to true
delay 1
end tell
--confirm "Export as "PDF dialog is available then display
set repeatNumber to 6
tell application "System Events" to tell process "Safari"
repeat with i from 1 to repeatNumber
set menuAvailable to enabled of menu item "Export as PDF…" of menu "File" of menu bar 1
if menuAvailable is true then
exit repeat
else if i = repeatNumber then
display dialog "The \"Export as PDF\" menu item was not available." buttons {"OK"} cancel button 1 default button 1
else
delay 0.5
end if
end repeat
click menu item "Export as PDF…" of menu "File" of menu bar 1
delay 1 --a smaller number doesn't work for me
keystroke fileName
delay 0.5
end tell
The following is a screenshot of the dialog after the script is run:
I would like to reduce the 1-second delay at the end of the script but don’t know how to do that. If I simply reduce the delay to a 0.5 second, the script doesn’t work reliably.
Instead of using a delay, can the script test for the existence of the dialog in a repeat loop before the keystroke fileName code line? Or, as an alternative, would it be more reliable to directly address the Save As entry to insert the file name?
BTW, there is occasionally a significant and unpredictable delay from the time a web page appears loaded and the point at which the Export as PDF menu item becomes available. So, testing for this menu item seems unavoidable. I thought testing for when the web page loading is complete as suggested by akim might be a better approach. Akims’s script worked well but did not reliably indicate when the Export as PDF menu item is available.
In Japanese environment, input method switching happens, so I needed to add one return, but other than that it worked perfectly as is.
macOS26.4.1
safari 26.4 (21624.1.16.11.4)
----[ADD]Retrieve the localized names used in the UI
tell application "Safari"
set strFile to (localized string ("83.title") from table ("MainMenu")) as text
set strExportPDF to (localized string ("1059.title") from table ("MainMenu")) as text
end tell
--set filename
set {year:y, month:m, day:d, hours:h, minutes:min, seconds:s} to (current date)
set theDate to ((y * 10000) + ((m as integer) * 100) + d) as text
set theTime to text 2 thru -1 of ((1000000 + (h * 10000) + (min * 100) + s) as text)
set fileName to "Safari (" & theDate & " " & theTime & ")"
--confirm Safari is open with URL
tell application "Safari" to set theURL to URL of front document
if theURL is missing value then display dialog "The frontmost Safari window could not be found or did not return a URL." buttons {"OK"} cancel button 1 default button 1
--I normally run this script by way of FastScripts with Safari active
--as a result, the following is normally not necessary and is for testing only
tell application "System Events" to tell process "Safari"
set frontmost to true
delay 1
end tell
--confirm "Export as "PDF dialog is available then display
set repeatNumber to 6
tell application "System Events" to tell process "Safari"
repeat with i from 1 to repeatNumber
----[ADD] localized names
set menuAvailable to enabled of menu item strExportPDF of menu strFile of menu bar 1
if menuAvailable is true then
exit repeat
else if i = repeatNumber then
display dialog "The \"Export as PDF\" menu item was not available." buttons {"OK"} cancel button 1 default button 1
else
delay 0.5
end if
end repeat
click menu item strExportPDF of menu strFile of menu bar 1
delay 1 --a smaller number doesn't work for me
keystroke fileName
----[ADD] using localized imput method return is required here.
keystroke return
delay 0.5
end tell
The usual way is to wait for the appearance of the sheet with a loop and instead of the keystroke you could set the value of the text field
--set filename
set {year:y, month:m, day:d, hours:h, minutes:min, seconds:s} to (current date)
set theDate to ((y * 10000) + ((m as integer) * 100) + d) as text
set theTime to text 2 thru -1 of ((1000000 + (h * 10000) + (min * 100) + s) as text)
set fileName to "Safari (" & theDate & " " & theTime & ")"
--confirm Safari is open with URL
tell application "Safari" to set theURL to URL of front document
if theURL is missing value then display dialog "The frontmost Safari window could not be found or did not return a URL." buttons {"OK"} cancel button 1 default button 1
--I normally run this script by way of FastScripts with Safari active
--as a result, the following is normally not necessary and is for testing only
tell application "System Events" to tell process "Safari"
set frontmost to true
delay 1
end tell
--confirm "Export as "PDF dialog is available then display
set repeatNumber to 6
tell application "System Events" to tell process "Safari"
repeat with i from 1 to repeatNumber
set menuAvailable to enabled of menu item "Export as PDF…" of menu "File" of menu bar 1
if menuAvailable is true then
exit repeat
else if i = repeatNumber then
display dialog "The \"Export as PDF\" menu item was not available." buttons {"OK"} cancel button 1 default button 1
else
delay 0.5
end if
end repeat
click menu item "Export as PDF…" of menu "File" of menu bar 1
repeat until exists sheet 1 of window 1
delay 0.2
end repeat
tell sheet 1 of window 1
set value of text field 1 of splitter group 1 to fileName
end tell
end tell
I tested your suggestion with the macrumors.com and apnews.com sites–both of which are often problematic-- and your suggestion displays the dialog but as often as not does not insert the file name. For example:
Agree with you that GUI scripting in general and with Preview is horrible. I wrote one of these in 2021 that would open the Export panel, select PDF/A, apply a PDF/A custom tag, and export the PDF. It worked on every version of Preview until now with Tahoe 26.4.1 because Apple changed the internal GUI layout.
Seems like the free, third-party Coherent PDF (cpdf) command line tool combined with the date(1) tool could be used in a script to replace Peavine’s GUI scripting solution.
Interesting, I wasn’t aware of that tool. Can Coherent PDF create PDF from a web page? I went through the info on their website briefly but couldn’t seem to find anything related to this functionality.