Wed, 13 Dec 2006
This is a thin tutorial that is designed to give you a feel for the AppleScript language by demonstrating it through a slew of samples. Each snippet builds on the previous ones and demonstrates a new concept or area of the language. Play along and have fun.
Note 1: If you haven't read through the first part of the Workflow AppleScripting article we suggest you do that now.
Note 2: AppleScript uses -- for single line comments and (* and *) for multiple line comments.
Note 3: AppleScript commands cannot span multiple lines. Because of html formating issues, long lines will occasionally get split into two or more. To show this, lines that start with ← are a continuation of the line above.
This script demonstrates the internal commands built into the AppleScript language (there are many more: display dialog, chose folder, chose file, etc.) Copy this into your Script Editor and click Run the script should play your system alert sound.
--beep script beep
Scripting the Finder is a common task, this first script demonstrates the use of a Tell Block to focus the action of the script. It also demonstrates the use of objects and commands provided by a scriptable application. (Exercise: Use the Script Editor's->File->Open Dictionary... command to look at the Finder's AppleScript Dictionary)
--finder tell application "Finder" open disk "Macintosh HD" end tell
This second script does the same as the first but does it better. The first script expects to find a disk named "Macintosh HD" on your machine, this script uses one of the standard locations (startup disk) instead. This makes the script far more robust and portable. A good thing all around.
--better tell application "Finder" open startup disk end tell
Using the make new command to create a folder on the desktop (again, notice the use of a standard location desktop)
--create folder tell application "Finder" make new folder at desktop end tell
Objects (like files, folders or applications) have properties. This script shows how to create a folder with a given name.
--create a folder with a name
tell application "Finder"
make new folder at desktop with properties
← {name:"Hello there I'm a new folder"}
end tell
AppleScript has several types of variables. This script snippet shows their usage.
--variables set theWord to "Hello" -- setting a text variable's value say theWord -- accessing the variable set theNumber to 5 -- setting a number variable's value set theNumber to theNumber + 1 -- doing some math
AppleScript handles most coercion (conversion from one data type to another) for you automagicaly.
--variables set theWord to "1" --setting a text value set theWord to theWord + 2 --now its a number: result is 3 set theWord to theWord & " Monkeys" -- now its back to text: result is "3 Monkeys" set theWord to theNumber as string - forced coercion
In addition to the simple variables above AppleScript supports two more complex data structures: the lists and records. Lists are lists of objects, records are made up of name:object pairs
set theList to {1, 2, 3, 4}
set theRecord to {firstName:"David", lastName:"LeBer"}
Lists can be accessed by numeric or relative position
set theList to {1, 2, 3, 4}
set theNumber to item 1 of theList
set theNumber to the last item of theList
Records are accessed by name
set theRecord to {firstName:"David", lastName:"LeBer"}
set theLastName to lastName of theRecord
It is important when working with AppleScript that you unambiguously identify the object you want to act upon. AppleScript will not be happy with you if you don't. You need to know the object hierarchy for whatever object your are working with. For example, TextEdit has the following hierarchy TextEdit->Document->Paragraph->Word. And this is how you identify the 4th word in the second paragraph of the frontmost document in TextEdit:
--object hierarchy tell application "TextEdit" set theWord to word 4 of paragraph 2 of document 1 end tell
Although out of the box AppleScript doesn't come with rich GUI tools (you'll have to use AppleScript Studio for that) it does possess some ways of interacting with the user. display dialog is one of the most common.
--giving feedback display dialog "Hello World" --you just knew there would be a Hello World example didn't you?
Decisions, decisions. AppleScript uses if--then--else conditionals to make decisions. Notice the important end if statement.
--conditional set theColour to "blue" if theColour is equal to "blue" then say "I'm feeling sad" else if theColour is equal to "red" then say "I'm feeling mad" end if
This script demonstrates using the display dialog command along with some of its additional properties and an if statement acting on the special result variable (that always contains the result of the last action).
--getting feedback 2
display dialog "Give me an answer" default answer "" buttons
← {"OK", "Not OK", "Not even close to OK"}
if text returned of result is "" then
display dialog "you weren't listening"
end if
The choose folder (and its cousin the choose file) command can be used to prompt the user to pick a folder (or file). In this example we explicitly assign the result of the choose folder command to a variable (theFolder).
This script also demonstrates the strength of the Finder's Object Model by allowing us to filter all of the object in the chosen folder by using the whose command.
--getting feedback and finder tell application "Finder" set theFolder to choose folder "Select a Folder please" open (every file of the theFolder whose ← name starts with "New") end tell
Iteration (or looping) is a very powerful part of any programming language. AppleScript has several different types of repeat statements. This example uses the repeat with aVariable in aList form.
--iteration or looping
set theColourList to {"red", "white", "blue"}
repeat with aColour in theColourList
say aColour
end repeat
These next scripts create a new document in Adobe Indesign. The first is very simple, it asks Indesign to create a new document with its default preferences. Notice the tell block.
--scripting an Application tell application "InDesign 2.0.2" set myDocument to make new document end tell
After studying the AppleScript Dictionary for Indesign (Script Editor->File->Open Dictionary...) we discover that the document dimensions are stored in the document preferences of the document So we can modify our script to create an new document with a specific size (2 by 3 inches).
--scripting an Application tell application "InDesign 2.0.2" set myDocument to make new document tell document preferences of myDocument set page width to 3 set page height to 2 end tell end tell
Unfortunately the new document still has a the default margins. Which in our case are .5 inches. They are far to large for our new document size. Again after studying the Indesign Dictionary we discover that the margin values in the document preferences are read only. We need to adjust them in the margin preferences and they need to be set before we create the document
--scripting an Application tell application "InDesign 2.0.2" tell margin preferences set margin top to 0.1 set margin bottom to 0.1 set margin left to 0.1 set margin right to 0.1 end tell set myDocument to make new document tell document preferences of myDocument set page width to 3 set page height to 2 end tell end tell
OK, we're getting really close now. The only problem left is that the next user who uses Indesign after our script has run will find that the margins are not where they left them. Probably not a way to make friends. This is a common problem as you develop more complex scripts and it is relatively easy to fix. We will cache the values we need to change before we start, and restore them afterwards.
--scripting an Application tell application "InDesign 2.0.2" tell margin preferences set priorTop to margin top set priorBottom to margin bottom set priorLeft to margin left set priorRight to margin right set margin top to 0.1 set margin bottom to 0.1 set margin left to 0.1 set margin right to 0.1 end tell set myDocument to make new document tell document preferences of myDocument set page width to 3 set page height to 2 end tell tell margin preferences set margin top to priorTop set margin bottom to priorBottom set margin left to priorLeft set margin right to priorRight end tell end tell
OS X brings with it a very rich command line environment. AppleScript has evolved to be able to take advantage of it as this simple script demonstrates Note: Most unix shell commands do not understand Mac OS resource forks! Be careful what you choose to manipulate with them.
--do shell script do shell script "mv ~/Desktop/test.txt ~/Documents/"
OS X allows you to create very powerful watched folders by attaching AppleScripts to folders via folder actions
Copy this script into Script Editor and save it as a Compiled Script into /Library/Scripts/Folder Action Scripts/. Control click on a folder and select Configure Folder Actions... and make sure the checkbox beside Enable Folder Actions is checked
Control click on a folder and select Attach Folder Action... and navigate to /Library/Scripts/Folder Action Scripts/ and pick the script you saved.
Test by dragging something into the folder. You should hear your system alert sound when the move is finished.
--folder action on adding folder items to thisFolder after receiving addedItems beep end adding folder items to
Although not comprehensive, I think this gives a fairly good overview of the basic syntax of AppleScript. Be sure to check the resource links in the Workflow AppleScripting article for more detail. Study assignemnt: investigate the three ways to reference a file in AppleScript (hint: posix, path, alias).
Get notified when there are new articles.
We're not the only ones with bandwidth and a need to share. Here are some of our favorite technical resources on the web.
We've been lifetime subscribers to MDJ for, like, ever. Insightful, biting and timely. Well worth the cash.
Need software? Versiontracker will help you find it.
High on news, low on press releases. I like the layout too.
Great layout, like the writing style. Gruber writes for MacJournals too.
Need to learn about the deeper levels of Mac OS X? Mac OS X Labs can help.
Heterogeneous, Heterogeneous, Heterogeneous!