You'll get your Mac news here from now on...

Help TMO Grow

Subscriber Login

Advertising Info


The Mac Observer Express Daily Newsletter


More Info

Site Navigation

Home
News
Tips
Columns & Editorials
Reviews
Reports
Archives
Search
Forums
Links
Mac Links
Software
Reports
Contact



by Stephen Swift


Repeat Yourself With AppleScript
June 12th, 2002

This marks the 9th installment of AppleScript: The Macintosh Autopilot. If you find any of this tutorial not making sense, check out the some of the earlier installments.

Download today's script files! Decompress the file, open the folder, and drop these scripts onto the script editor. And now onto today's lesson!

AppleScript is a great automation tool. Two clicks and your browser is loaded, your e-mail is downloaded, and your coffee is steaming. Being able to repeat your routine, however, is an essential component of AppleScript. You might have an excellent script that prepares your photos for the Web, but without the repeat loop, editing fifty photos is still a pain.

The Almighty Powerful Repeat Loop

repeat
--insert your command here
end repeat

That's it!?

Yes, well sort of. The above code creates an infinite loop, where the program repeats the commands inside the loop for eternity or until you force the program to stop. A useful repeat loop requires a little more code, but no matter how complex you get, it still is based on that infinite loop.

Tip: You can end an infinite loop with an if-then statement.

set x to 0
repeat
set x to (x + 1)
if x = 5 then
--after the 5th loop, x will equal 5.
exit repeat
--a command used to end repeat loops.
end if
end repeat

There are approximately five different variations on the basic repeat loop. Many of them do the same function, just in different ways. When you use repeat loops you should ask yourself:

  1. What action needs to be repeated?
  2. How do I stop the repeat loop?
  3. What variation am I most comfortable with and makes the most sense in my situation?
This will help you use repeat loops effectively and make your scripts easy to read by other people.

Repeat x many times

One of the most common loops, this variation on the repeat loop specifies a number of times the repeat loop runs. For example:

repeat 5 times
(*commands inside the loop will be repeated 5 times*)
beep
end repeat
--the computer will beep 5 times

Tip: You can replace the number with a variable. This is helpful if the number of times you need the action repeated is not constant.

Repeat Until...

In this case, the loop will repeat until a certain Boolean is true.

set x to 5
repeat until x = 0
beep
set x to (x - 1)
end repeat

The Boolean in this example is "x = 0." Originally, x is 5 so "5 = 0" is false. So is "4 = 0" and "3 = 0" and so on. When x is 0, the Boolean is true and the repeat statement does not run. In the above example, the repeat statement will run five times. Indeed, the simpler "repeat x times" loop would be easier to use in this situation. However, many different things return Booleans such as...

exists folder "Applications" of startup disk*
--useful to stop a loop when a file is added
(current date) is date "Thursday, May 30, 2002 12:00:00 AM"
--useful to stop a loop after a certain amount of time
(the clipboard) is ""
--useful to stop a script when something has been copied to the clipboard

*Must be enclosed in a tell application "Finder"/end tell statement.

Repeat While...

This variation is the opposite of Repeat Until. The repeat will run when the Boolean is true.

set x to 0
repeat while x < 5
beep
set x to (x + 1)
end repeat

Similar to Repeat Until, Repeat While also depends on Booleans. You can use a wide variety of Booleans. The Boolean in this example is x < 5. We start off with x equal to 0 and then each time we loop we add 1 to x. The loop stops when x equals 5.

Repeat with i

This is the most useful repeat loop. Instead of performing the exact same action each time, the task is changed a little bit.

set x to ""
repeat with i from 1 to 5
set x to x & (i as string)
end repeat

In this example, every time the loop repeats, the variable i is a different number. First, it is 1, then 2, then 3, etc. Run this script and then look at the result window. The string "12345" should be displayed. Each time the loop repeated, the next number was added to the string. If we had used a simple loop such as

set x to (1 as string)
--a number must be changed to a string (regular text)
set the_string to ""
repeat 5 times
set the_string to (the_string & x)
end repeat

the result would be: "11111"

Repeat with i in theList

This is very similar to the regular repeat with i loop. Instead setting i to a different number each time, we set it to an item in a list. For example:

set theList to {"I ", "Love ", "AppleScript!"}
set x to ""
repeat with i in theList
set x to (x & i)
end repeat

Each time the loop repeats, an item from theList is added to the string, x. The result is: "I Love AppleScript!"

So Many Options

As I mentioned earlier, many of these variations perform the same function. There isn't much difference between using a repeat 5 loop versus repeat until x = 5 or repeat while x < 5. They all repeat the loop five times. It depends on which is easiest for you to remember and with what you are comfortable.

Real Life Experience

Let's put our knowledge of repeat loops to use! Repeat loops are great for find and replace tasks.

Problem: There are many files with spaces in their names. These spaces must be replaced with dashes.

What actions must be performed?

  1. All the file names must be retrieved. Why not store these in a list?
  2. Each file must have its spaces replaced with dashes. A repeat loop would work fine
Because AppleScript doesn't force us to work in order, why don't we start with the find and replace task. There will be a list of files, so the perfect loop for this task would be:

repeat with i in theList

The items in theList will be file references. We need to get the name of each of these references to the files. Since a file is an object belonging to the Finder, open the Finder's dictionary. In the left frame, scroll down until you see file (it should be about half way down). Click on it, and in the right frame a list of commands will appear. Look carefully for the property name. You didn't find it. That's because the only properties there ones specific to files only. However, you do see

<Inheritance> item [r/o] -- inherits some of its properties from the item class.

This means that the same properties that work for items also work for files because a file is an item. Folders, files, and disks are all items. So now scroll up the left frame until you see item. Click on it. Now you should find the property name.

So now we can get the name of the file. Since the command we are about to use belong to the finder we have to enclose the commands in a

tell application "Finder"/end tell

statement. We will set the variable the_name to the name of the file. The code:

tell application "Finder"
set the_name to name of i
--gets the name of the file and changes it to text
end tell

Now we must look at every character in the name to determine if it needs to be changed. But first, we need to find out how many characters are in the name. To do this, we will use the code:

set num to number of characters in the_name
--num is variable equal to whatever number it was set to

We will start with creating a new variable set to a blank string. We have to look at each character individually. Then after we have sent it through the find/replace action, the script will add our character to the new word.

set new_name to ""

Now we will look at each character using the repeat loop:

repeat with char from 1 to num
--it will loop through each character of the name stopping at the last character (number num).

Now we come to our action. If the character is " " (a space) the script will replace it with "-" (a dash). If not, the script will leave the character alone.

if character char of the_name is " " then
set new_name to new_name & "-" as string
--add a dash to the new name. The as string part makes sure that the result will be text.
else
set new_name to new_name & character char of the_name as string
--adds the original character to the new name
end if

Now our find/replace loop is done. Add end repeat to your script. Now we must change the file's name. The Finder controls this. To change the name, we simply say set name to the new value. Here is the code:

tell application "Finder"
set name of i to new_name
--it is a reversal of the code we had before: set the_name to name of i
end tell

Now our loop through all the files is complete. Add end repeat to your script.

Now we have to go back to the beginning of the script and obtain a list of files that we need to change. The simplest way is to create a droplet. A droplet is a script application on which you can drop files. The script will create a list of these files and perform the required tasks on them. A droplet is created when you place your script in an on open/end open statement. For example:

on open TheList
--where theList is the list of files

--insert your action here
end open

So now place the code we created within this statement, save your script as an application (make sure to check never show startup screen) and viola! The application looks like a normal application, but it has an arrow in the icon. Drop files on the script to change their name.

The complete code:

on open theList
--where theList is the list of files
repeat with i in theList
tell application "Finder"
set the_name to name of i
--gets the name of the file and changes it to text
end tell
set num to number of characters in the_name
--num is variable equal to whatever number it was set to
set new_name to ""
repeat with char from 1 to num
--it will loop through each character of the name stopping at the last character (number num)
if character char of the_name is " " then
set new_name to new_name & "-" as string
--add a dash to the new name. The as string part makes sure that the result will be text.
else
set new_name to new_name & character char of the_name as string
--adds the original character to the new name
end if
end repeat
tell application "Finder"
set name of i to new_name
--it is a reversal of the code we had before: set the_name to name of i
end tell
end repeat
end open

The Last Word

Repeat loops are very valuable, often used, and easy to understand. I recommend memorizing the repeat with i from number to number loop. It is often the most useful and normally the best way to repeat a task.

This Lesson Covered:

  • How to use repeat loops (and how they relate to lists!)
  • The many different variations of repeat loops
  • Using the dictionary
  • How to create a find and replace script.
Next Time:
  • Learn all about sub-routines (Scary name, easy code!)
  • Review previous AppleScript knowledge
  • Try to start creating scripts on your own
More Info

Join the AppleScript gang at the Coder's Corner in The Mac Observer Forums! We discuss AppleScript related news and updates, extract really cool and useful AppleScripts, ask questions, and give answers. It's a lot of fun and a great resource for all your scripting needs! Also, if you have a befuddling AppleScript problem, please send it to Stephen@macobserver.com and I'll be more than willing to help you out!


Comments or Questions? Is this column going to slow or fast for you? Do you want to script something, but don't know how? Do you need something explained or have a question about a script?  My E-mail address, stephen@macobserver.com, is open 24 hours a day, 7 days a week.


Most Recent AppleScript Columns

Break Your Script Into Pieces with Subroutines
June 26th

Repeat Yourself With AppleScript
June 12th

AppleScript Lists
June 5th

AppleScript Archives

Back to The Mac Observer For More Mac News!



Today's Mac Headlines

[Podcast]Podcast - Apple Weekly Report #135: Apple Lawsuits, Banned iPhone Ad, Green MacBook Ad

We also offer Today's News On One Page!

Yesterday's News

 

[Podcast]Podcast - Mac Geek Gab #178: Batch Permission Changes, Encrypting Follow-up, Re-Enabling AirPort, and GigE speeds

We also offer Yesterday's News On One Page!

Mac Products Guide
New Arrivals
New and updated products added to the Guide.

Hot Deals
Great prices on hot selling Mac products from your favorite Macintosh resellers.

Special Offers
Promotions and offers direct from Macintosh developers and magazines.

Software
Browse the software section for over 17,000 Macintosh applications and software titles.

Hardware
Over 4,000 peripherals and accessories such as cameras, printers, scanners, keyboards, mice and more.

© All information presented on this site is copyrighted by The Mac Observer except where otherwise noted. No portion of this site may be copied without express written consent. Other sites are invited to link to any aspect of this site provided that all content is presented in its original form and is not placed within another .