timing applescripts

when developing a script, it’s sometimes helpful to find out how long the script takes to do its thing. you can then compare different portions or versions of scripts to get the most efficient outcome. rather than sitting there with your stopwatch, you can just build a simple timer into your script.

the current date command gives you … you guessed it … the current date. the beauty of it is that it gives you the current date right down to the second and returns something like this :

date "Wednesday, 5 October 2011 8:02:08 PM"

if you get the current date at the beginning of your script, and then again at the completion, you can compare the two to get the runtime of the script :

set mgStart to current date
---------------------------------------
-- insert applescript code here --
delay 3
---------------------------------------
set mgStop to current date

display dialog "This took " & (mgStop - mgStart) & " seconds."

this will give you a dialog box something like this :

screen grab of 3 seconds dialog box

to time a script in less than seconds (milliseconds), you’d have to track down a separate scripting addition. (see update below)

for those interested in this sort of thing…
you can extract various elements from the current date — to do with as you will. here are a few, no doubt there are other coercions as well :

current date -- "Wednesday, 5 October 2011 8:02:08 PM"

date string of (current date) -- "Wednesday, 5 October 2011"
time string of (current date) -- "8:02:08 PM"

weekday of (current date) -- Wednesday
day of (current date) -- 5
month of (current date) -- October
year of (current date) -- 2011

hours of (current date) -- 20 (note: 24 hour time)
minutes of (current date) -- 2
seconds of (current date) -- 8

time of (current date) -- 72128 (seconds since midnight)
time of (current date)/60 -- 1202.1333333 (minutes since midnight)
weekday of (current date) as number -- 4
month of (current date) as number -- 10

update : 01 November : here’s a timing solution which uses the shell to measure in fractions of seconds — thanks to Alex Zavatone on the applescript-users mailing list :

set mgRightNow to "perl -e 'use Time::HiRes qw(time); print time'"
set mgStart to do shell script mgRightNow
---------------------------------------
-- insert applescript code here --
---------------------------------------
set mgStop to do shell script mgRightNow
set mgRunTime to mgStop - mgStart
display dialog "This took " & mgRunTime & " seconds." & return & "that's " & (round (mgRunTime * 1000)) & " milliseconds."

macgrunt icon

InDesign tip : #07

tip #04 showed how to use libraries to easily store text and object styles and add them to other files. here are a couple of other ways to copy styles from one file (source) to another (destination).

the standard way is to open your destination file, open the paragraph styles panel and select ‘load all styles’ from the panel’s dropdown menu :

screen grab showing paragraph styles panel dropdown list

you’ll be asked to locate the source file, then you’ll be presented with a window similar to this :

screen grab showing load all styles window

paragraph styles are marked ‘¶’, character styles are marked ‘A’. check the boxes next to the styles you want to import. any style conflicts are highlighted at right and you can choose how to deal with these. you can select a style to see the specs for the incoming and original versions at the bottom of the window. you can also do a similar thing from the object styles and table styles panels.

but you probably already knew that. here’s a trick to copy styles into multiple destination files …

NOTE: in the case of style conflicts, this method WILL use the source file’s versions and override all destination versions without warning. that’s the beauty of this method — it makes the styling in all documents identical.

open a new book file (file menu > new > book…). BEFORE importing any documents make sure you turn off the automatic pagination option for the book — otherwise all your documents will have their pages renumbered :

screen grab of book dropdown list showing book numbering options
screen grab showing auto numbering unchecked

then click the ‘+’ button to import all your files, including the source file. click the box next to the file you want to be the source. then set your synchronise options to suit your needs :

screen grab of book dropdown showing synchronise options
screen grab of synchronise options

as you can see, the synchronise book feature copies more than just styles to other files. now select the files you want to synchronise to the source (or deselect all files to synchronise the entire book). and go for it :

screen grab showing how to synchronise from dropdown menu

once you’re done you can trash your book file — it’s served its purpose.

macgrunt icon

create folders from list

a recent digital publishing workflow required the creation of over 90 folders (one for each chapter of the book) and each of these also had to include a ‘links’ folder. imagine trying to do that manually — over 90 folders.

applescript droplet icon this is a perfect job for an applescript droplet — drop a text file on the app and watch the folders appear — as if by magic :

screen grab of finder before and after text file is dropped on droplet

this workflow starts with a comma delimited list of folder names. you could also use a tab delimited list. note: this version of the script does not handle returns (line breaks) in the list. the demo list looks like this :

screen grab of comma delimited list

you can get a copy of the CreateFolders app here

screen grab of create folders script compiled in script editor

for those interested in this sort of thing…
this script shows one way to strip leading and trailing spaces from chunks of text. it uses two repeat while loops, each of which keep repeating for as long as the associated statement is true. the repeat loop ceases as soon as the statement is false, and the script moves on.

you could use the repeat until form instead :
repeat until mgThisItem does not start with ” ”

the last part of the script shows a simple, pure applescript way to create folders in the finder. the syntax is tortured and long-winded, but it works a treat. to learn how to create folders and folder hierarchies by scripting the shell, see nigel garvey’s excellent explanation at macscripter

update : if you are in the german or dutch regions you may find that your CSV files export as semi-colon separated (rather than comma separated). in which case you would replace this line :

    set text item delimiters of AppleScript to ","

with this :

    set text item delimiters of AppleScript to ";"

macgrunt icon

InDesign scripting : lesson 06

the printing script from lesson 04 and lesson 05 is very simple, but there’s still one more thing to explain about it before we move onto the next script in lesson 07. here’s the printing script again :

Screen grab of Print All Files script

when creating a script to perform a particular task, you need to consider all the possibilities that may arise when the script is run. for example, the script from lesson 03 was written to delete all the guides throughout an entire document. will it still perform this task if the guides are on a locked layer? ; if the guides themselves are locked? ; if the guides are on a master page? (in CS2 at least the answers are : yes ; yes ; and no)

sometimes it’s not a problem if your script doesn’t perform exactly as expected — it simply fails to complete the task and you have to either fix it or live with it. but sometimes it IS a problem because an error can stop a complex process mid-script. sometimes an error can even crash InDesign. sometimes you learn this the hard way.

error handling involves anticipating potential problems and building safeguards into your script. the printing script has error handling in the form of an if/then statement. the script works fine without it, right up until the first time you hit the ‘cancel’ button in the choose from list dialog box — that’s when the script will crash InDesign. why? because the script will go on to ask InDesign to print every document using an undefined printer preset — this is confusing for InDesign, so it gives up and goes berko.

so, we need something in there which will ask InDesign to print ONLY if a printer preset has been selected. the easiest way to do this is to check that the ‘cancel’ button WAS NOT selected. that is, if the ‘cancel’ button was not selected, then the ‘ok’ button MUST have been selected (and the ‘ok’ button cannot be selected until a preset is chosen from the list). make sense?

whenever ‘cancel’ is selected in a dialog box it returns the result ‘false’. so, all we need to do is check that the result of the choose from list dialog box is not false. hence the command : if result is not false then {go on and print those little beauties} end if

ok — now for your homework. what will the script do if the result IS false (the cancel button is selected)? would that behaviour bother you? if so, how could you improve the script?

macgrunt icon