Your prescription for increased productivity and profitability
This article will give you some ideas for adding captions to images using a script. We will be using AppleScript but ExtendScript users can easily convert the script as needed.
Our sample script will depend on the following:
The outline for our sample script will include the following steps:
The first task for our script will be to check for a selected rectangle:
set desiredClass to «class crec» set errStr to "Expects rectangle with image to be selected" tell application "Adobe InDesign CC 2014" --make sure document is not in modal state if modal state error "Please close modal dialogs before running script" end if set selList to selection if length of selList = 0 then error errStr end if (*if rectangle containing an image is selected, return reference to the rectangle*) if class of item 1 of selList is desiredClass then set rectRef to item 1 of selList if (count of page items of rectRef) > 0 and class of page item 1 of rectRef is image then return rectRef end if end if --if the script gets here, rectangle with image is not selected error errStr end tell
There are three places in the above where an error message could be generated. To handle this, we will place our code inside of a handler called checkSelection and call it from within a try/end try block:
try --check for selection set desiredClass to «class crec» set rectRef to checkSelection (desiredClass) on error errStr activate display alert "Error: " & errStr end try on checkSelection (desiredClass) --put code from above with exception of the first line here end checkSelection
At this point you should be able to test the script to make sure it works as expected. Run it with no selection, then with a page item other than a rectangle selected, then with an empty rectangle selected, and then finally with a rectangle having an image.
Notice that the script uses a four-letter code–often called a raw code–to define the rectangle class. This makes it possible to define the class outside of a tell statement to the application.
Now that we have a reference to the container for the image, we can look at the image’s metadata. This will involve getting the properties of the image’s link–or link xmp. For this, the code can be tested at the top of the script prior to setting it up as a handler. Below the end try statement in the code above, add the following:
tell application "Adobe InDesign CC 2014" set imageRef to image 1 of rectRef set linkRef to item link of imageRef set linkM to properties of link xmp of linkRef set creditStr to "" set descStr to "" try if description of linkM is not "" then set descStr to description of linkM end if end try try if author of linkM is not "" then set creditStr to author of linkM end if end try end tell return {descStr, creditStr}
Test your script with a rectangle having metadata assigned and one without. There will always be a value returned even if there is no metadata as the values for the two variables default to empty strings.
Once tested, place the following handler template at the bottom of your script.
(*Returns author and description metadata fields for image of container reference passed*) on getMetadata (rectRef) end getMetadata
Cut all of the code from below the end try statement and paste it inside the handler template.
After the variable rectRef is defined inside the try statement block, add a call to the getMetadata handler:
set {creditStr, capStr} to getMetadata(rectRef)
If a value is returned for the variables creditStr, capStr, or both, the script will create and populate the caption text frame. For this the script will need to make sure the paragraph styles “Credit” and “Caption” exist as well as an object style named “Caption.”
The following is a minimalistic approach. It makes sure there are styles, but does not set any properties other than the name. Add the following five lines after end try at the top of your script and the two handlers following to the bottom.
if creditStr & capStr is not "" then set parastyleList to {"Caption", "Credit"} set parastyleRefs to checkParastyles (parastyleList) set objstyleRef to checkObjstyle ("Caption") end if (*Makes sure paragraph styles named in parastyleList exist; list of style references is returned*) on checkParastyles (parastyleList) set parastyleRefs to {} tell application "Adobe InDesign CC 2014" tell document 1 repeat with i from 1 to length of parastyleList set parastyleName to item i of parastyleList if (exists paragraph style parastyleName) then set parastyleRef to paragraph style parastyleName else set parastyleRef to make paragraph style with properties {name: parastyleName} end if set end of parastyleRefs to parastyleRef end repeat end tell end tell return parastyleRefs end checkParastyles (*Makes sure object style named in objstyleName variable exists; reference to the style is returned*) on checkObjstyle (objstyleName) tell application "Adobe InDesign CC 2014" tell document 1 if (exists object style objstyleName) then set objstyleRef to object style objstyleName else set objstyleRef to make object style with properties {name: objstyleName} end if end tell end tell return objstyleRef end checkObjStyle
With this code added, the script makes sure the styles are in the document even if their styling is not defined.
With all of the pieces for the script in place, the final step is to create the text frame and populate it.
Below the end if statement added at the bottom of the try statement block above, add the following call to a handler named createCaption.
createCaption(rectRef, creditStr, capStr, parastyleRefs, objstyleRef)
The createCaption can now be written as follows:
Put it at the end of your script.
(*Creates caption text frame using reference to container, credit and caption strings, as well as references to paragraph and object styles*) on createCaption(containerRef, creditStr, capStr, parastyleRefs, objstyleRef) tell application "Adobe InDesign CC 2014" set docRef to document 1 set pageRef to parent page of containerRef copy geometric bounds of containerRef to {yp, x0, y1, x1} set captionStr to creditStr & return & capStr tell pageRef set frameRef to make text frame with properties {geometric bounds:{y1, x0, (y1 + 60), x1}, contents:captionStr, applied object style:objstyleRef} end tell repeat with i from 1 to length of parastyleRefs if paragraph i of frameRef is not "" then set applied paragraph style of paragraph i of frameRef to item i of parastyleRefs else delete paragraph i of frameRef end if end repeat set baseLn to (baseline of line -1 of paragraph -1 of frameRef) + 6 set geometric bounds of frameRef to {y1, x0, baseLn, x1} end tell end createCaption
You may wonder why the bottom of the caption frame was calculated rather than using fit given frame to content. The fit method affects both horizontal and vertical dimensions of the frame which is not what is wanted if the caption text is shorter than the width of the image container.
Make sure you place a copy of the script in InDesign’s Scripts Panel and give it a keyboard shortcut.
The sample script can be just a beginning for a full-featured script. You may wish to add an interface to the script to give the user the option to choose one or more of the following:
Once you have your script running the way you want it, pat yourself on the back each time you or your user saves uses the keyboard shortcut to have the caption created without any additional effort required.