Wed, 13 Dec 2006

AppleScript Tutorial

David LeBer

A Tutorial Through Script Samples

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.

Beep

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

The Finder

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

Simple Variables

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

Coercion

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

More Complex Data Structures

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

Object Hiearchy

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

Giving Feedback

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?

Conditionals

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

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

Scripting Applications

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

Shell Scripts

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/"

Folder Actions

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

The End

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).

[/AppleScript] Static link

Content Image

Recent Articles:

Get notified when there are new articles.

News + Opinion

We're not the only ones with bandwidth and a need to share. Here are some of our favorite technical resources on the web.

MacJournals

We've been lifetime subscribers to MDJ for, like, ever. Insightful, biting and timely. Well worth the cash.

Versiontracker

Need software? Versiontracker will help you find it.

MacMinute

High on news, low on press releases. I like the layout too.

Daring Fireball

Great layout, like the writing style. Gruber writes for MacJournals too.

Mac OS X Labs

Need to learn about the deeper levels of Mac OS X? Mac OS X Labs can help.

MacWindows

Heterogeneous, Heterogeneous, Heterogeneous!