A Simple AppleScript Example

 

Overview

The following AppleScript service script will count the number of words in the currently selected text and display the result to the user in a dialog. This is a trivial example in that it does not utilize any custom additions, nor does it deal with multiple pasteboard types. It does, however, illustrate the basic points to consider when implementing services with AppleScript.

 

A Simple Example: Count Words

The following code listing shows a complete Bellhop service script written in the AppleScript language. You can try this yourself by simply creating a Bellhop document, adding a new AppleScript service, and then pasting the following code directly into the editor window. Then all you have to do is activate the service using the Settings panel, and then you can invoke it from any services-aware application.

(* Sample AppleScript service to count the number of words in the current selection. This service might be labeled "Count Words" in the Services menu. The aPasteboard argument identifies the unique pasteboard name that is reserved for the current service transaction. You will use this name as the argument to the various methods that get and set data from the pasteboard. *) on runService (aPasteboard) (* Read the contents of the pasteboard *) set theText to readPasteboardString(aPasteboard, NSStringPboardType) (* Split the text into an array of words *) set theWords to words of theText (* And count them *) set numWords to length of theWords (* Finally, display result back to user *) display dialog "Word count: " & numWords end runService

Listing 1: Sample AppleScript service

If you are familiar with the concepts and implementation details regarding system services in Mac OS X, the above script should be straightforward. If not, you can refer to the Apple developer documentation covering System Services and the More Info section of this document.

Looking at Listing 1, the first non-comment line is

on runService(aPasteboard)

This is the entry point to your AppleScript service. Almost all of your runService() handlers will follow a similar pattern: read pasteboard data, operate on it, and write modified pasteboard data back. The only argument to this handler, aPasteboard, is the particular pasteboard that is used for this service transaction. Each service transaction is assigned a unique service pasteboard.

The following lines read the selection from the service pasteboard:

(* Read the contents of the pasteboard *) set theText to readPasteboardString(aPasteboard, NSStringPboardType)

This line uses one of the Bellhop Pasteboard subroutines to get a string from the pasteboard. Notice the use of the NSStringPboardType constant to specify string type data. This is one of the global pasteboard type constants that is made available to all Bellhop AppleScript services, and mimics the same symbolic constant as defined in the Cocoa frameworks.

Next, we examine the pasteboard data and operate on it to calculate the number of words:

(* Split the text into an array of words *) set theWords to words of theText (* And count them *) set numWords to length of theWords

This is the meat of our service.

Here we simply chunk the text into words, and then count the number of words and store them in the numWords variable.

Finally, we use AppleScript's built-in UI support to show the user how many words are in the selection:

(* Finally, display result back to user *) display dialog "Word count: " & numWords

One thing to notice in this service is that we are not sending any data back to the pasteboard. This is a read-only service in that it simply reads data from the pasteboard and acts on it, but does not send anything back to the requesting application.

And finally, to conform to valid AppleScript syntax, we close our handler definition:

end runService

It is worth pointing out that we did not have to explicitly import any of the custom Bellhop subroutines, and we are using constants that mimic those defined in the Cocoa frameworks.

That's all there is to it! When a user invokes our "Count Words " service from the Services menu (e.g. from the TextEdit application), the operating system will automatically forward the request to Bellhop, which will in turn invoke the appropriate script's runService() handler. All of your services will follow a similar pattern.