AppleScript question

How do I get the selected text from Applescript? Not the contents of the clipboard, but the text that is currently highlighted in Safari. I thought it should be just:

    tell application "Safari"
      set output to the selection as string
    end tell

but that doesn't do it ("Can't make selection into type string.") Google is not helping me, nor is the AppleScript language guide.

Failing that, how do I copy that selected text to the Clipboard, and then get that as a string? I can't make that work either.

(As always, please only answer if you've actually tried it and seen it work. Not interested in your guesses.)

Tags: , , ,

22 Responses:

  1. fdaapproved says:

    tell application "Safari"
    do JavaScript "getSelection()+''" in document 1
    end tell

    Dumb? Yeah, but it works.

    • jwz says:

      Thanks, that works.

      Do you understand why what I was trying to do doesn't work? Or where any of that selection/clipboard crap is actually documented?

      • You've discovered a major shortcoming of the standard additions in AppleScript on the Mac. There is no generalized way of "grabbing the selection" from a given application. Note that if you browse the Standard Additions dictionary you will not find any attribute "selection" that would be have the way you're hoping.

        To the extent what you want to do works, it's been implemented explicitly by the particular application's AppleScript support, or there is some workaround such as the JavaScript interface to Safari cited above.

        The reason for the glaring lack of functionality probably goes back to the fact that "it's hard" to generalize exactly what the selection is in a particular app, and historically application cooperation has been required in "populating" the clipboard. It also doesn't help matters that Carbon and Cocoa applications both support AppleScript but have dramatically different clilpboard APIs.

        Welcome to the frustrating world of AppleScript!

        • cyeh says:

          That's the best explanation I've read so far. In short, you are at the complete mercy of the developer that wrote the AppleScript support. I would have thought that AS support would have gotten better, but from reading this, I see little has changed since 1995.

          • mattbot says:

            The language itself is quite a bit better now than in the Mac OS days and it's easy for developers to add scripting support to their apps with Cocoa. So I think it's improved at least a little.

  2. duskwuff says:

    You've got a solution above, but also note that pbcopy will give you the contents of the pasteboard Clipboard as a string.

    • jwz says:

      Yeah, I knew about that, but I wanted the selected text, not the copied text.

      • duskwuff says:

        Right - you've already got a solution for Safari above. If you wanted this to work in applications other than Safari, your best bet would probably be to trigger a Cmd-C key event:

        tell application "System Events" to keystroke "C" using command down

        • Note that to use these "system events" type script commands, you'll need to "Enable access for assistive devices" from the Universal Access control panel. The mechanism depends on the same hooks that Apple provides for these purposes.

        • mattbot says:

          That's the correct way to do it, with System Events and copying to the clipboard. Using Javascript is eaiser, more directly a solution in this case but still makes you feel dirty. It's lose-lose with Applescript.

          The problem in the original code snippet is the use of the selection property. The selection property isn't defined for Safari; it's typically used for the Finder in returning a reference to the selected file or folder in a Finder window.

          There is no proper documentation for Applescript other than the dictionary files for the applications and due to their format they don't often tell you what you'd like to know. You use a lot of trial and error in AS coding. Get the O'Reilly "AppleScript, The Definative Guide" book, it's the best one out there by far.

          Rather than coding in AS and calling on other scripting languages for special tasks you might want to code in ruby or perl or whatever and call the command line applescript interface to do copy/paste stuff. AS has problems and will only cause you pain.

          • I disagree with this because

            1. Safari is almost entirely non-scriptable, explicitly encouraging use of javascript for all useful functionality.

            2. Using the UI System Events requires activating a user-preference, so scripts that are written with those features are inherently less portable than scripts that don't resort to that level.

            • Yes better make our Applescript portable! :)

            • mattbot says:

              You can use the "System Events" keystroke command without activating the assistive devices check-box in the Universal Access pref pane. You only need it checked if you want to do mouse-like manipulations on UI widgets.

              I've gotten burned in the past trying to get AppleScript and Lingo to work together the way the docs said they would. (Granted, this was back circa Mac OS 8.5 or so.) I implicitly encourage the use of anything besides AppleScript when ever possible.

          • jwz says:

            Oh, don't worry, it's more perverse than that: I'm actually writing in Emacs-Lisp, and calling out to AppleScript to get text and URLs out of Safari.

            • mattbot says:

              The "AppleScript, The Definative Guide" book claims that there are structural and stylistic similarities between LISP and AppleScript. I can only assume he means that in the sense that 120 lbs. marathon runners and 350 lbs. couch potatoes both have skeletal systems.

              It has a jurisdiction over the GUI that no other language has but horrid implementation. I wish Apple would kill AppleScript and replace it with an open set of APIs that could bridge to some real language. This godforsaken language was almost all I had back when I was doing pre-OS X Mac admining.

        • tfofurn says:

          Hmm . . . wouldn't this have the side effect of losing the previous contents of the clipboard?

  3. kitten_moon says:

    I don't have my powerbook with me right now, but I think the "pure" AppleScript you want is something like this:

    set output to text of selection

    Intuitive, eh? That's why AppleScript is a language for "novices".

    (It also can change your script so that it no longer compiles, but that's another story.)