At Your Service
If you have ever used the services available under the application menu’s Service item, you know how cool they are. Some will copy text to a new TextEdit document, or speak the selected text, or open an email with the selected file as an attachment. Others will open URL’s or search Google.
Having thought about creating my own service, I know that it’s a fairly arcane process involving object-c programming. Wouldn’t it be nice if you could use Applescript to create a service? Now, with ThisService, you can!
ThisService is a donationware program from Waffle Software that lets you create a service from an Applescript, perl script, python script, or ruby script. The program doesn’t have a lot of difficult options or other junk. Just write a script according to a specified formula (more on that in a minute) and you can create a service by giving it a name and clicking “Create Service.” It’s that simple.
Scripting From A Script
Services break down into 3 types: Those that perform an action, those that return output, and those that do both (a filter). For example, a service that takes a URL and opens it in Safari would be an action. A service that outputs your name and address (say for a letter) would be an output service. A service that takes a calculation and replaces it with the answer is a filter.
The program comes with barebones scripts for each language so that you can get started right away. I found the program quick and easy to use and immediately began cranking out scripted services using Applescript. While I’m sure it works well with the other scripting languages mentioned, I don’t “speak” any of them, and will leave it as an exercise for the reader to play with them.
Scripting Your Service
The first script I’ll share is the first one I wrote. It’s a simple action script that takes the selection and opens my Man Handler man page viewer and searches the man pages for the selection. It’s fairly straightforward:
on process(input)
tell application "Man Handler"
activate
copy word 1 of input to contents of text field 1 of front window
tell button 1 of front window to perform action
end tell
end process
Once saved, the script is loaded into ThisService:
Creating the Man Handler service
Notice that you have the option of using a reference to your script instead of the actual script. This is for debugging so that you can create the service but continue to refine the script until it works the way you want it to. At that point, you can use “Pack Up Service” to pull the actual script in and add your contact information (or other instructions) to make a zip file that you can distribute:
Packing up the Man Handler service
That’s all there is to it! A nice simple utility but as versatile as your scripting ability. Here are some examples of other scripts:
on process()
tell application "Address Book"
set theString to name of my card & return & formatted address of address of my card
quit
end tell
return theString as Unicode text
end process
This is a script that produces output only, retrieving and pasting your name and address into a document. It’s written to use “my card” from the Address Book, so it will always get the current user’s information.
The next script is an example of a filter. It takes the selection as input and returns the input in a changed fashion:
on process(input)
return "[b]" & input & "[/b]"
end process
If you use bbcode in your forum posts, here’s a quick script that will insert bold tags around the selected text.
To Serve and Protect
ThisService uses the osa command line programs to run your Applescript, so that imposes a restriction - no user interaction outside of an application tell block. That means you can’t run display dialog commands unless you wrap them in a tell block that addresses an application. This is fairly easy to get around, though - here’s a script that contains the code to address the front application:
on process(input)
set wordCount to count (words of input)
tell application "System Events" to set frontApp to name of first application process whose frontmost is true
set themessage to ("Selection contains " & wordCount & " words.") as text
set theTime to 5
tell application frontApp
set theVolume to get volume settings
if output muted of theVolume then
display dialog themessage buttons {"OK"} default button 1 ¬
giving up after theTime
else
say themessage
end if
end tell
end process
The speech command say doesn’t seem to bother the osascript command, so you can also use verbal feedback, which this script does if the sound is not muted. Otherwise, it displays a dialog box in your current application.
Another restriction is that you cannot just write your script within the implied run handler, it must be in a handler named process(). According to the author, that’s the number one thing that folks forget.
As a final postscript, I should mention that version 2.0.1 which was recently released had the problem of crashing when trying to pack up an Applescript service. The author has worked quickly to repair the problem and I’m happy to report that version 2.0.2 with the fix is available from their website now. (Even without the fix, you can still create services - just don’t use the “reference your script” option, instead use the “copy your script” option. Then get the service out of your ~/Library/Services folder and you can zip it yourself with any instructions you need to include.)
I’ve created a zip file with all the services shown here in one file. It’s available from Scriptbuilders. Now go crunch code!