DekGenius.com
[ Team LiB ] Previous Section Next Section

2.3 Internally Scriptable Application

A number of applications are internally scriptable. By this I mean that the application contains its own internal mechanism, possibly a proprietary language, for automating just that application. When such an application is developed for Mac OS, it sometimes happens that its developers would like to provide it with a means of communicating with other applications. That means Apple events, and AppleScript is a convenient way to send Apple events (convenient both for the developers and for the end user), so a typical approach is to let the internal scripting language treat text as AppleScript code. Such applications are not very good places to develop your AppleScript code, since you usually have no way to edit and test that code coherently inside the application. A typical approach is to develop the code in a dedicated script editing environment such as the Script Editor, and then copy it into the other application.

An example is Microsoft Word. Word comes with its own internal scripting language, Visual Basic for Applications (VBA), whose purpose is to automate Word itself. The Mac OS version of VBA also includes the MacScript function, which accepts a string and compiles and runs it as AppleScript on the fly. For more about using VBA in Word, see Steven Roman's Writing Word Macros (O'Reilly).

Constructing your AppleScript code in VBA is rather a trying experience, because you have to pass through VBA's rules about generating strings. Since AppleScript is a line-based language, line breaks in the code must be expressed explicitly; the way to do this in VBA is to call a function, Chr(13). The calls to this function must be concatenated with the rest of your string to form the AppleScript code. Quotation marks are also a cause of concern and possible confusion.

Figure 2-7 shows a Word document and the Macro dialog; we are about to run the CallASExample macro. Figure 2-8 shows the result of running this macro. The macro has placed the names of my disks at the insertion point. The way Word found out the names of the disks was by constructing and running some AppleScript code.

Figure 2-7. Microsoft Word
figs/as_0207.gif
Figure 2-8. Word inserts the result of an AppleScript call
figs/as_0208.gif

Here's the VBA code of the CallASExample macro:

Sub callASExample(  )
        s = "tell application ""Finder""" + Chr(13)
        s = s + "get the name of every disk" + Chr(13)
        s = s + "end tell"
        Selection.InsertAfter Text:=MacScript(s)
End Sub

The AppleScript code is assembled into the string variable s; as promised, this is a fairly hideous operation. The code is concatenated from literals representing each line, separated by the Return characters generated by calling Chr(13). In order to express the double-quoted literal "Finder" inside a VBA string literal, the double quotes must themselves be doubled, since this is how VBA "escapes" a quote character. Once the script text is assembled, it is handed to the MacScript function. This returns a string, which is yet another problem: AppleScript is capable of returning a variety of datatypes, but your script must limit itself to a result that can be expressed as a string, possibly coercing or reformatting it somehow before returning it. Finally, the VBA macro inserts that string result into the document.

A program that behaves similarly is the database application FileMaker Pro. It has internal scripting facilities, and one of the things its internal scripting language can do is take some text and execute it as AppleScript. This text can be static; alternatively, it can be the contents of a field, and since field values in FileMaker can be "calculated," the text can be dynamically constructed. Here's an example that illustrates both approaches.

Figure 2-9 shows two programs, FileMaker Pro and Mailsmith. The FileMaker window (in front) shows a database of contacts. In this window is a "To" button; pressing this has just caused Mailsmith to create a new email message (in back) using the email address from the current FileMaker record. So in this scenario FileMaker Pro is the sender and Mailsmith is the target; FileMaker tells Mailsmith to create a new email message, using the value of a field in the current record as the addressee of this new message. The idea is that AppleScript lets the two programs work together, each doing what it does best: a database program is good for storing and finding information, whereas a mail client is good for constructing and sending mail messages (see Section 1.6).

Figure 2-9. FileMaker talking to Mailsmith
figs/as_0209.gif

The FileMaker script that's triggered by pressing the "To" button consists of two text snippets executed as AppleScript. Figure 2-10 shows the first snippet, which is static and has simply been typed directly into a dialog box.

Figure 2-10. Literal script text in FileMaker
figs/as_0210.gif

Figure 2-11 shows how the second snippet is generated dynamically through a calculated field. Some literal text is combined with the value of the expansion field to construct the string that will be executed as AppleScript:

Figure 2-11. Calculated script text in FileMaker
figs/as_0211.gif
"tell application ""Mailsmith"" to tell message window 1 
to make new to_recipient at end with properties 
{address:""" & expansion & """}"

The challenges here are similar to those of the Microsoft Word example just preceding. In the AppleScript code, quotation marks must surround the string value drawn from the expansion field; to indicate these in a string literal, they have to be "escaped" by doubling them, and this happens to occur at the boundaries of two literals, necessitating the bizarre triple-double-quotes toward the end of the text.

    [ Team LiB ] Previous Section Next Section