Your prescription for increased productivity and profitability
If you have walked through the steps required to create a multi-state object in InDesign, you must have thought to yourself “There must be a better way.” Since you already know how to work with scripts, your thoughts may have matured to the point of wondering how you would go about writing a script to automate the process.
The problem with automating a multi-state object is that there are so many design criterias for creating for the object. This could translate into the script needing to provide the user with a number of options:
As you can see, this could require a custom dialog that might become prohibitively complex.
For this reason, you might want to start small. Pick your most widely-used multi-state object requirement and automate it. As long as your script is written modularly, you should be able to modify it to meet other requirements without much hassle. The biggest task might end up being in creating the user interface.
In this demonstration we will start small with a number of dependencies assumed. We will write the code in AppleScript but ExtendScript users can follow along.
With these dependencies taken care of, the following will return the bounds to the page item selected.
set selBounds to getSelectionBounds() on getSelectionBounds() tell application "Adobe InDesign CC 2014" set selList to selection if length of selList is greater than 0 then set selItem to item 1 of selList if class of selItem is in {rectangle, polygon, text frame} then return geometric bounds of selItem end if end if error "Requires page item selection" end tell end getSelectionBounds
The reference to the selected item will be used later in the script to create the multi-state object.
If the active document is saved in the same folder as the folder with the images, the following will return the path to the image folder. This will be used for placing the images for the multi-state object. Notice the call to the handler passes the name of the images folder as part of the call.
set imagePath to getImagePath("Images") on getImagePath(folderName) tell application "Adobe InDesign CC 2014" tell document 1 set docPath to file path as string end tell end tell return (docPath & folderName) end getImagePath
With the path to the Images folder, list folder will return a list of the names for the files. For our purpose we will assume all of the files in the folder are valid files.
set fileList to getFileList (imagePath) on getFileList (imagePath) set fileList to list folder imagePath without invisibles if length of fileList is less than 3 then error "Requires at least 3 items for multi-state object" end if return fileList end getFileList
It would be better to add code to the getFileList handler to validate that each item in the list returned is a file (not a folder) with either a “.jpg” or “.png” extension. We will leave this up to the reader.
With the above routines in place, the script can create the multi-state object.
set MSObject to makeMSO (selBounds, imagePath, fileList, "MultiImages") on makeMSO (imageBounds, imagePath, fileNames, MSOName) set statesToAdd to (length of fileNames) - 2 tell application "Adobe InDesign CC 2014" tell document 1 set layerRef to layer 1 set MSORef to make multi state object with properties{name:MSOName, geometric bounds:imageBounds, item layer:layerRef} repeat with i from 1 to statesToAdd tell MSORef to make state end repeat end tell repeat with i from 1 to length of fileNames set nameStr to item i of fileNames set fileAlias to (imagePath & ":" & nameStr) as alias tell state i of MSORef set rectRef to make rectangle with properties {geometric bounds:imageBounds, name:("State" & i), fill color:"None", stroke weight:0} end tell tell rectRef to place fileAlias end repeat end tell return MSORef end makeMSO
You will also need to add error handling at the top of the script. When the modules for the script are combined, the top portion of the script should read similar to the following:
try set selBounds to getSelectionBounds() set imagePath to getImagePath("Images") set fileList to getFileList (imagePath) set MSObject to makeMSO(selBounds, imagePath, fileList, "MultiImages") on error errStr activate display alert errStr end try
To make the script more robust, you could present the user with a list of layers from which to choose for placing the multi-state object. The reference to this layer would be used in the above in place of layer 1 for the layer reference (layerRef).
All that is needed now are the buttons. You can create the buttons manually and set their behavior in InDesign’s Buttons and Forms panel. Or, if you are ambitious, you can let the script create the buttons for you. This would be a little more challenging, and something that we will reserve for a future demonstration.
You can use either jpeg or png files for this multi-state object script. If using jpeg, InDesign will give you an alert when you go to export your document to fixed layout EPUB. You may decide to use jpeg anyway as the problem reported does not seem to affect the outcome of the final product, and you save more than one-half as far as total file size is concerned.
Now that your have a script to automate the basics for a multi-state object, add the ability to display a caption with each image. You might decide to have the captions stored as part of the metadata for the image. Alternatively, you could have text files named to correspond to their image file. For styling the text, you might designate an object style that defines the paragraph styles for its contents. As you can see, this script could get fairly complex.