MacOS – AppleScript: How to check if the clipboard consists of a file (instead of text)

applescriptcopy/pastefilemacos

If my understanding is correct, there are two types of content that can be copied to the Mac global (systemwide) clipboard:

  • text

or

  • file

Even though they are two different, discrete data types, they share the very same clipboard. For example, if you have an image file on your clipboard, and then you copy a text sentence, the sentence will overwrite the image file, and vice versa. Please correct me if I am wrong.

My question is, how can I determine if the clipboard does not contain text, using AppleScript?

The context of my question is an AppleScript .scpt file that speaks the selected text in the System Voice at a specified volume. The selected text is copied to the clipboard, and then the text is spoken via the say command. The script is triggered by keystroke via FastScripts.app.

Every so often, I am given an error dialog that states, "Error Number: -1728." This error occurs when, instead of text being highlighted, I have highlighted or selected an actual file. Mac's Speech function cannot speak a file; Speech can only verbalize text.

So, I would like to create an if...then statement in my script to catch this error. Ideally, I would then like to convert the file to text, if possible in the way that TextEdit does.

Best Answer

If the Clipboard contains a file object, then clipboard info will contain, e.g., «class furl» (a file URL), along with many other classes.

The follow example code will check for the presence of «class furl» in the clipboard info:

if ((clipboard info) as string) contains "«class furl»" then
    say "the clipboard contains a file named " & (the clipboard as string)
else
    say "the clipboard does not contain a file"
end if

Update:

As I mentioned in one of my comments, there are other ways to code this, and this approach will return either an empty list or a list containing one list, which should be faster instead of the 14 that the first example returns if it contains a file. If the Clipboard does not contain a file, then the list returned is empty and it errors out, setting cbFile to false, and if not empty, setting it to true, which then is tested against in the following example.

try
    (item 1 of (clipboard info for «class furl»))
    set cbFile to true
on error
    set cbFile to false
end try
if cbFile then
    say "the clipboard contains a file named " & (the clipboard as string)
else
    say "the clipboard does not contain a file"
end if

By the way, I ran the purge command in Terminal in between testing these two examples and it felt like the second example is a bit faster, however YMMV.