6

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.

  • Your first assumption is wrong: text or file (probably you really mean xor). It's much more complicated. You can check the content of the clipboard with the Apple (Xcode) app "Clipboard Viewer". It's available in Auxiliary Tools for Xcode 7. – klanomath Apr 26 '17 at 3:54
  • One could also easily create an Automator service (assigned to a keyboard shortcut via the Keyboard system preference pane) that receives the selected text in any application and then runs the actions Set Computer Volume and Speak Text, with no need to copy the selected text to the clipboard. (Of course, you may have good reasons for using your AppleScript instead!) – Big Mac Apr 27 '17 at 21:19
  • @BigMac 1. My AppleScript code allows me to stop the Speech with the same keystroke that I use to start the Speech. 2. My code does not actually affect the system volume; it defines the volume of the Speech process as a percentage of the current system volume level. 3. Triggering a systemwide Service by keyboard shortcut is unreliable. See: Keyboard shortcut for service only works after I manually run the service. FastScripts.app, OTOH, is reliable. But, FastScripts, of course, can only trigger .scpt files, not Automator Service files. – rubik's sphere Apr 27 '17 at 22:12
  • 1
    @BigMac (1/2) The heart of my code is the genius solution provided by jackjr300 here: AppleScript: Is it possible to check if Speech is currently running?. To set the volume of the Speech, as a percentage of the current system volume (I chose 35%), see: How to change volume of “say” in AppleScript?. I discovered a command-line bug, so see here for a workaround: – rubik's sphere Apr 28 '17 at 0:21
  • 1
    (2/2) How to get around “say” command bug when setting volume? Finally, the answer by @user3439894 to this very post makes the script speak the filename of a selected file: AppleScript: How to check if the clipboard consists of a file (instead of text)? Put this all together, and you'll have created my current AppleScript file. – rubik's sphere Apr 28 '17 at 0:22
3

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.

  • Do you also know how to get just the filename (not the full path) as text, of a file that's on the clipboard? If the if condition is met: if ((clipboard info) as string) contains "«class furl»" then I would like my script to say the filename of the clipboard file. – rubik's sphere Apr 27 '17 at 6:38
  • Let me know if you think that the question in my above comment warrants a dedicated post. – rubik's sphere Apr 27 '17 at 6:39
  • @rubik's sphere, I've updated the answer to handle the condition set in your comment. By the way, if you want the fully qualified pathname you'll need to use Cocoa-AppleScript and NSPasteboard, which I'm not up on as regular AppleScript. – user3439894 Apr 27 '17 at 11:30
  • Another narrow question would be best, @rubik'ssphere . Linking the two here in comments would be nice as well. I'll edit the question you posted here down to make it clearer the topic here. – bmike Apr 27 '17 at 11:30
  • To the down-voter, please explain a legitimate reason for it, does this not answer the question asked? Do you have a better answer instead of an unwarranted down-vote!? – user3439894 Apr 27 '17 at 13:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .