Happy and Prosperous New Year

WHY APPLESCRIPT

I am often asked why most of the example scripts I write are for AppleScript. Do I prefer AppleScript over JavaScript? Not really. But being that I work primarily with Macintosh, not Windows, it just makes sense for me. Also for the beginning script writer, AppleScript is a tad bit easier to learn, even if more verbose.

In the Macintosh environment AppleScript simply gives access to applications and automations that are not open to ExtendScript. Support for files and folders is simply superior, not to mention the ability to work with auxiliary applications on the Macintosh that are open to AppleScript.

Think about a simple process of getting a list of files from a chosen folder and allowing the user to choose one or more items from names of items listed. A little script can eliminate a lot of folder-diving (with attendant distractions).

 

CHOOSE FOLDER

The following one-liner returns an alias reference to the folder chosen:

set folderRef to choose folder with prompt "Choose folder of images for processing" ¬ 
without invisibles and multiple selections allowed

PATH TO

If you want the folder chosen to be from a specific location on the computer, you can specify the location using the path to command with a specified domain. For instance, the following defines the path to the user’s home folder:

set userFolder to path to home folder from user domain

The good news is that just about every pre-defined folder location on the Macintosh can be accessed this way. (See path to command under File Commands for the StandardAdditions dictionary.)

DEFAULT LOCATION

The folder path can be added to the result returned from the choose folder command to have the system’s choose screen start at a specified folder location

set userPrompt to "Choose folder of images for processing"
set userFolder to path to home folder from user domain
set folderRef to choose folder with prompt userPrompt ¬
default location userFolder without invisibles and multiple selections allowed

LIST FOLDER

To get a list of the files in the folder, the list folder method is added to the script. This time the path is to the user’s desktop

set userPrompt to "Choose folder of images for processing"
set userFolder to path to desktop from user domain
set folderRef to choose folder with prompt  userPrompt default location ¬
userFolder without invisibles and multiple selections allowed
set fileList to list folder folderRef 
fileList

CHOOSE FROM LIST

Now that the demonstration script has a list of file names, the user can choose the file or files wanted from the list. For this, the script can now invoke the choose from list method to present a list of files found at the specified location. Here the script uses the path to desktop folder for demonstration.

set userPrompt to "Choose folder of images for processing"
set userFolder to path to desktop from user domain
set folderRef to choose folder with prompt userPrompt ¬
default location userFolder without invisibles and multiple selections allowed
set fileList to list folder folderRef
set fileChosen to choose from list fileList without multiple selections allowed

Notice the result of choose from list is a list, even if only one item is chosen. Also, if the user pushes the Cancel button from the Choose from List method, the script throws an error. Not so, when Cancelling from the list folder method. The false boolean is returned.

Test this out with the following:

Script with Try Error Trap

   try
        set userPrompt to "Choose folder of images for processing"
	set userFolder to path to desktop from user domain
	set folderRef to choose folder with prompt userPrompt ¬
default location userFolder without invisibles and multiple selections allowed
	set fileList to list folder folderRef
	set fileChosen to choose from list fileList without multiple selections allowed
	if fileChosen is not false then
	   set fileName to item 1 of fileChosen
	else
	   error "No file chosen"
	end if
	fileName
   on error errStr
	activate
	display alert ("Error: " & errStr)
   end try

PLACE IMAGE

We could create the code we have so far as aa handler and use it in any number of scripts for placing images into an InDesign document. In the following example the images chosen are placed in InDesign’s place gun for placement by the user:

   set folderPath to path to desktop from user domain
   set multipleImages to false
   set promptStr to "Choose folder of images for processing"
   set imageList to {}
   try
	set {folderRef, fileNames} to chooseImages(folderPath, promptStr, multipleImages)
	repeat with i from 1 to length of fileNames
		set end of imageList to (folderRef & item i of fileNames) as alias
	end repeat
	tell application "Adobe InDesign CC 2018"
		activate
		tell place gun 1 of document 1
			load place gun imageList without showing options
		end tell
	end tell
	
   on error errStr
	activate
	display alert ("Error: " & errStr)
   end try

   (*Returns list of images chosen from folderPath defined. 
MultipleImages is boolean indicating if multiple images can be chosen*)
   on chooseImages(folderPath, promptStr, multipleImages)
	set folderRef to choose folder with prompt promptStr ¬
default location folderPath multiple selections allowed multipleImages without invisibles
	set fileList to list folder folderRef
	set fileList to choose from list fileList without multiple selections allowed
	if fileList is false then
		error "No file chosen"
	end if
	return {folderRef as string, fileList}
   end chooseImages

INFO FOR

Of course, the user can really foul up the script by choosing files that are not images or may not even be placeable for InDesign. We will take advantage of another builtin AppleScript method: info for which is part of StandardAdditions. When presented a file reference, infor for returns a record containing the information for the specified file or folder. This record defines among others: the name extension, the type identifier, file type, and whether the file reference is a folder.

Our demonstration script can use this information to create another handler for our script to filter through the list of chosen files to make sure they are images.

   set folderPath to path to desktop from user domain
   set multipleImages to true
   set promptStr to "Choose folder of images for processing"
   set imageList to {}
   set validFileTypes to ¬  
{"JPEG image", "Portable Network Graphics image", "TIFF image", "Adobe Photoshop file"}
   try
	set {folderRef, fileNames} to chooseImages(folderPath, promptStr, multipleImages)
	set validList to filterfiles(folderRef, fileNames, validFileTypes)
	--the validList can then be passed to a handler that actually places the file
   on error errStr
	activate
	display alert ("Error: " & errStr)
   end try

   (*Filters list of file names with parent folder to determine if file is appropriate file type. 
File type is determined by typeList variable*)
   on filterfiles(folderPath, fileNames, typeList)
	set validFiles to {}
	repeat with i from 1 to length of fileNames
		set fileRef to (folderPath & item i of fileNames) as alias
		set theInfo to info for fileRef
		if folder of theInfo is false and kind of theInfo is in typeList then
			set end of validFiles to fileRef
		end if
	end repeat
	return validFiles
   end filterfiles

   (*Returns list of images chosen from folderPath defined. 
MultipleImages is a boolean value indicating if multiple images can be chosen*)
   on chooseImages(folderPath, promptStr, multipleImages)
	set folderRef to choose folder with prompt promptStr ¬
default location folderPath multiple selections allowed multipleImages without invisibles
	set fileList to list folder folderRef without invisibles
	set fileList to choose from list fileList multiple selections allowed multipleImages
	if fileList is false then
		error "No file chosen"
	end if
	return {folderRef as string, fileList}
   end chooseImages 

It goes without saying that JavaScript users can work around these issues, but having some of these builtin methods makes working with files and folders so much easier.

IMAGE EVENTS

One application that you may use often on the Macintosh when working with image files is the little Image Events extension. It gives a script the capability of peeking inside an image file to get get its dimensions (width and height in pixels), resolution (horizontal and vertical in dots pr inch), color space (CMYK, Gray, Lab, RGB, etc.), and more. You can even perform simple processes to an image such as scale (by factor or to size using a maximum width or length integer), rotate, flip, and even crop the image if you so desire.

Think of the times this could br used in place of having to work with Photoshop if for nothing else than to check a folder of files to see if the user has provided images with enough bits of information to be used for a given process. (Perhaps for a book that has over 100 images all of which need to be at least 14 picas wide for a half page photo or 28 picas wide for a full width photo.) A quick script would give that information.

You will want to tune in to our next blog where we will use Image Events as part of a script to create an automated slideshow.

ONWARD AND UPWARD

The demonstration script above is far from complete. First, you will need to make sure that the document is open and prepared for image placement. You can have the user place the files using the place gun as demonstrated above, or you might have a document that has placeholders named to contain the files. (“01_Image”, or “pg01_Image01”, etc.) See what you can do with the code above to create a script to automate your next image placement or image replacement task.

IMPORTANT:

If you decide to copy code from above, be advised that we are using the continuation character (¬) to indicate that the line of code continues to the next line. Remove these characters by placing your cursor on the line below and backspacing. This will rejoin the second line to the first.