Hi there
I am frequently wanting to open a PDF, which is already open in Preview, to open in Acrobat for some advanced editing. Is this something that is easily scriptable? Or is there a solution which would avoid scripting?
Many thanks for any suggestions.
Try this, Preview is not scriptable.
The script takes the name of the window and searches the file with Spotlight
activate application "Preview"
tell application "System Events" to tell process "Preview" to set theImage to name of window 1
set Imagepath to POSIX file (do shell script "/usr/bin/mdfind 'kMDItemFSName = \"" & theImage & "\"'") as alias
tell application "Adobe Acrobat Professional"
activate
open Imagepath
end tell
Thanks, Stefan
I got an Applescript error due to the fact that the Preview window always includes a “(page 1 of 4)” or the like. I tweaked your suggestion to parse out the offending characters and it now seems to work. It does take some time to react though so I also added in a Quicksilver notification, so there is instant feedback that the script is running/working. Many thanks.
Here is the tweaked code:
activate application "Preview"
tell application "System Events" to tell process "Preview" to set theImage to name of window 1
set text item delimiters to "("
set split to text items of theImage
set build to ""
set delim to ""
repeat with n from 1 to (number of items in split) - 1
set build to build & delim & item n of split
set delim to "("
end repeat
set build to text 1 thru ((length of build) - 1) of build
set rpdf to offset of ".pdf" in build
if rpdf = 0 then
set build to build & ".pdf"
end if
tell application "Quicksilver" to show large type "Opening '" & build & "' in Acrobat"
set Imagepath to POSIX file (do shell script "/usr/bin/mdfind 'kMDItemFSName = \"" & build & "\"'") as alias
tell application "Adobe Acrobat Professional"
activate
open Imagepath
end tell
Stefan
I have encountered a problem with the shell script you posted. Sometimes, I have two versions of the same file in different folders. When this occurs, I get an appscript error from the shell script:
Can’t make file “Macintosh HD:Users:macminia:Foldershare:Professional:2008-07-02 Fax SRA re Practising Certificate.pdf
:Users:macminia:Documents:Faxes:2008-07-02 Fax SRA re Practising Certificate.pdf” into type alias.
Any suggestions on how I might deal with this? I suppose I could have an error routine that catches the problem and then parse/display dialog a choice of files. But I am wondering if there is a way to generate a list rather than a string from the shell script search, which would be more elegant a solution…
Many thanks for your help
Ok, I assumed that there is only one file.
Try this
activate application "Preview"
tell application "System Events" to tell process "Preview" to set theImage to name of window 1
set Imagepaths to paragraphs of (do shell script "/usr/bin/mdfind 'kMDItemFSName = \"" & theImage & "\"'")
tell application "System Events" to set myImage to (choose from list Imagepaths)
if myImage is false then return
set myImage to POSIX file (item 1 of myImage) as alias
tell application "Adobe Acrobat Professional"
open myImage
end tell
The script works faster if you define a base folder to search in
Stefan
Thanks for this. Knowing that guys like you are there is a great motivator to take on tasks like this, which are really outside my daily competence.
Having now twiddled a bit, I have found a way that works faster without the need for a shell script. It works almost instantaneously and is not fussed by multiple files. I have incorporated some basic error messaging and Growl notification:
tell application "Finder"
get name of every process
end tell
if result contains "Preview" then
activate application "Preview"
try
tell application "System Events" to tell process "Preview"
set theImage to name of window 1
set thePath to value of attribute "AXDocument" of window 1
end tell
--get file name from frontmost window
set text item delimiters to "("
set split to text items of theImage
set build1 to ""
set delim to ""
repeat with n from 1 to (number of items in split) - 1
set build1 to build1 & delim & item n of split
set delim to "("
end repeat
set build1 to text 1 thru ((length of build1) - 1) of build1
set rpdf to offset of ".pdf" in build1
if rpdf = 0 then
set build1 to build1 & ".pdf"
end if
-- get file path of file referenced in frontmost window
set text item delimiters to "/"
set split to text items of thePath
set build2 to ""
repeat with n from 4 to (number of items in split) - 1
set build2 to build2 & "/" & item n of split
end repeat
--combine file name and file path
set finalbuild to build2 & "/" & build1
set Imagepath to POSIX file finalbuild as alias
my notify(3, build1)
--open in Acrobat
tell application "Adobe Acrobat Pro"
activate
open Imagepath
end tell
on error
--if not a PDF or no file open, return error
beep
my notify(1, "")
end try
else
--if Preview not running, return error
beep
my notify(2, "")
end if
on notify(messNum, appname)
tell application "GrowlHelperApp"
-- Make a list of all the notification types
-- that this script will ever send:
set the allNotificationsList to ¬
{"NotPDF", "PreviewNotRunning", "OpeninAcrobat"}
-- Make a list of the notifications
-- that will be enabled by default.
-- Those not enabled by default can be enabled later
-- in the 'Applications' tab of the growl prefpane.
set the enabledNotificationsList to {"NotPDF", "PreviewNotRunning", "OpeninAcrobat"}
-- Register our script with growl.
-- You can optionally (as here) set a default icon
-- for this script's notifications.
register as application ¬
"PreviewAcrobat" all notifications allNotificationsList ¬
default notifications enabledNotificationsList ¬
icon of application "Preview"
--Send a Notification...
if messNum is 1 then
notify with name ¬
"NotPDF" title ¬
"Preview" description ¬
"Front File in Preview:" & return & "NOT a PDF; or" & return & "NO File Open" application name "PreviewAcrobat"
else if messNum is 2 then
notify with name ¬
"PreviewNotRunning" title ¬
"Preview" description ¬
"Preview NOT Running" application name "PreviewAcrobat"
else if messNum is 3 then
notify with name ¬
"OpeninAcrobat" title ¬
"Preview" description ¬
"Opening in Acrobat:" & return & "'" & appname & "'" application name "PreviewAcrobat"
end if
end tell
end notify
great way to get the file path.
Extracting the information could be easier
tell application "Finder"
get name of every process
end tell
if result contains "Preview" then
activate application "Preview"
tell application "System Events" to tell process "Preview"
try
set theImage to name of window 1
set thePath to value of attribute "AXDocument" of window 1
on error
set theImage to ""
end try
end tell
if theImage contains " (" then
set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "/"}
set Imagepath to "/" & text items 4 thru -1 of thePath as text
set fileName to text item -1 of thePath
set AppleScript's text item delimiters to ASTID
set Imagepath to POSIX file Imagepath as alias
my notify(3, fileName)
--open in Acrobat
tell application "Adobe Acrobat Professional"
activate
open Imagepath
end tell
else
--if not a PDF or no file open, return error
beep
my notify(1, "")
end if
else
--if Preview not running, return error
beep
my notify(2, "")
end if
on notify(messNum, appname)
.
Stefan
Much more elegant but there is a problem with taking the filename from attribute “AX Document”. In “AX Document”, spaces in the file name come through as “%20” each time so that the script systematically generates an error. Have tried to get round this using your script but with no success. I parsed the file name from the Window in my version, which avoided this issue as no roque "%20"s …
there is a perl routine to coerce a file URL with escaped characters to a path
tell application "Finder"
get name of every process
end tell
if result contains "Preview" then
activate application "Preview"
tell application "System Events" to tell process "Preview"
try
set theImage to name of window 1
set thePath to value of attribute "AXDocument" of window 1
set thePath to (do shell script "perl -e 'use URI::file; print URI->new(\"" & thePath & "\")->file;'")
on error
set theImage to ""
end try
end tell
if theImage contains " (" then
set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "/"}
set fileName to text item -1 of thePath
set AppleScript's text item delimiters to ASTID
set Imagepath to POSIX file thePath as alias
my notify(3, fileName)
--open in Acrobat
tell application "Adobe Acrobat Professional"
activate
open Imagepath
end tell
else
--if not a PDF or no file open, return error
beep
my notify(1, "")
end if
else
--if Preview not running, return error
beep
my notify(2, "")
end if
Works sweet. And fast.
Shell scripts and perl are like Chinese to me!
Many thanks.
Hope others find it helpful. Final full script:
tell application "Finder"
get name of every process
end tell
if result contains "Preview" then
activate application "Preview"
tell application "System Events" to tell process "Preview"
try
set theImage to name of window 1
set thePath to value of attribute "AXDocument" of window 1
set thePath to (do shell script "perl -e 'use URI::file; print URI->new(\"" & thePath & "\")->file;'")
on error
set theImage to ""
end try
end tell
if theImage contains " (" then
set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "/"}
set fileName to text item -1 of thePath
set AppleScript's text item delimiters to ASTID
set Imagepath to POSIX file thePath as alias
my notify(3, fileName)
--open in Acrobat
tell application "Adobe Acrobat Pro"
activate
open Imagepath
end tell
else
--if not a PDF or no file open, return error
beep
my notify(1, "")
end if
else
--if Preview not running, return error
beep
my notify(2, "")
end if
on notify(messNum, appname)
tell application "GrowlHelperApp"
-- Make a list of all the notification types
-- that this script will ever send:
set the allNotificationsList to ¬
{"NotPDF", "PreviewNotRunning", "OpeninAcrobat"}
-- Make a list of the notifications
-- that will be enabled by default.
-- Those not enabled by default can be enabled later
-- in the 'Applications' tab of the growl prefpane.
set the enabledNotificationsList to {"NotPDF", "PreviewNotRunning", "OpeninAcrobat"}
-- Register our script with growl.
-- You can optionally (as here) set a default icon
-- for this script's notifications.
register as application ¬
"PreviewAcrobat" all notifications allNotificationsList ¬
default notifications enabledNotificationsList ¬
icon of application "Preview"
--Send a Notification...
if messNum is 1 then
notify with name ¬
"NotPDF" title ¬
"Preview" description ¬
"Front File in Preview:" & return & "NOT a PDF; or" & return & "NO File Open" application name "PreviewAcrobat"
else if messNum is 2 then
notify with name ¬
"PreviewNotRunning" title ¬
"Preview" description ¬
"Preview NOT Running" application name "PreviewAcrobat"
else if messNum is 3 then
notify with name ¬
"OpeninAcrobat" title ¬
"Preview" description ¬
"Opening in Acrobat:" & return & "'" & appname & "'" application name "PreviewAcrobat"
end if
end tell
end notify
I have assigned a trigger with Quicksilver to run the script and can now quickly jump into Acrobat (NB Acrobat Pro 9 has a different name to Acrobat Pro 8 - in this version it is set to work with Acrobat 9 - change to activate and open with “Adobe Acrobat Professional” if using Acrobat 8 ).
a little note:
the close tag for applescript codes is
```