ANCHORED OBJECTS WITH CAPTIONS

The process in our previous blog post dealt with anchored objects that use the above line option. The script assumes that the user has an insertion point selected for placing the image. Preferably, the insertion point would be on its own paragraph. This is preferred; as to place an image in the middle of a paragraph can be too disruptive to the text flow. However, there are the times that there may be no other option.

The script developed in the post prompts the user to choose the image for placement. From there the script does everything but add a caption. The anchored object is placed above the paragraph for the selected insertion. This makes adding a caption below to be a simple matter for the user, as the content will become the text for the selected insertion point. As such it will flow within the story text. With this workflow it is advised that a paragraph style for the caption be assigned to the insertion point.

We can take the script one step further and have it assign the paragraph style while adding dummy text for the caption. For this the script defines a variable for the name of the caption style and one for the dummy text itself. (You may want to refer to the previous blog post for the previous script.)

Anchored Image With Caption

--define variables
set folderName to "Images"
set captionText to "Caption Here"
set captionTextStyle to "Caption"
set objectStyleName to "InlineImage"

Next, within a try statement block, pass the name of the paragraph style to the getInsertionPoint() handler

try
   set insertPoint to getInsertPoint(captionTextStyle)
...
end try

The getInsertPoint() handler checks for an insertion point selection and, if successful, assigns the paragraph style

(*Adds Caption style to insertion point and returns reference or error*)
on getInsertPoint(styleName)
   set errorMsg to "Requires insertion point for image placement"
   tell application "Adobe InDesign CC 2015"
      if not (selection exists) then
         error errorMsg
      end if
      set selList to selection
      set selItem to item 1 of selList
      if class of selItem is not insertion point then
         error errorMsg
      end if
      set styleRef to paragraph style styleName of document 1
      set applied paragraph style of selItem to styleRef
   end tell
   return selItem
end getInsertPoint

Next add a call to a routine, addCaption(), to add the caption. The try/end try block now reads as follows

try
   set insertPoint to getInsertPoint(anchoredTextStyle)
   set imageToInsert to getImage(folderName)
   placeImage(insertPoint, imageToInsert, objectStyleName)
   addCaption(insertPoint, captionText)
on error errStr
   activate
   display alert ("Error: " & errStr)
end try

To place the caption, the routine requires a reference to the insertion point and the caption text

(*Places caption text at insertPoint*)
on addCaption(insertPoint, captionText)
   tell application "Adobe InDesign CC 2015"
      tell insertPoint
         set contents to captionText
      end tell
   end tell
end addCaption

To complete the script, you will also need to add the getImage() and placeImage() placeImage handlers from the script in our previous blog post.

 Image anchored between paragraphs

ANCHORING OBJECTS WITHIN A PARAGRAPH

If the anchored object is placed in the middle of a paragraph, adding a caption poses a special problem. The reason for this can best be explained in understanding that InDesign treats anchored objects as a character with some behavior as that of an object. As such the anchored object can have attributes the same as text, including paragraph and character styles. When assigned an object style, additional properties specific to anchored objects can also be applied to the object. On the other hand, there are some things you can do with objects that don’t apply to anchored objects, most specifically, adding the object to a group. With this in mind, how would one keep a caption with the anchored object? The trick is to use a table.

Putting graphics inside table cells should be easy, but it’s not. That’s because table cells are like text frames, so adding images is just like adding anchored objects inline.

If we look at the reference to a placed image inside a table cell, it reads similar the code to following (underscores will be replaced with appropriate index values):
{image id ___ of rectangle id ___ of cell id __ of table id ___ of text frame id ___ of spread id ___ of document id __ of application "Adobe InDesign CC 2015"}

To understand this further, the following quotes from my favorite reference, Real World Adobe InDesign.

You place a graphic in a table cell in exactly the same fashion as you insert a graphic in text: click the Type tool in a cell, or select some text inside a cell, then place a file or paste a graphic you copied to the Clipboard earlier. Note that you must select text or have an active text insertion point; selecting the cell itself will not get the graphic into the cell. If you want the graphic to fill the entire cell, make sure the Cell Insets values are set to zero. That last piece — setting the Cell Insets to zero — is very important. If you don’t do that, you’ll always have some space around the cell. If the anchored graphic frame is too large for the cell, you can crop it down along its right edge by opening Table > Cell Options > Text and turning on the Clip Contents to Cell checkbox. You cannot, however, crop the height of the graphic. Why? Because the row height cannot be made smaller than the graphic frame. (Well, it can, but you’ll get text overset).

The Script

A script to automate placing an anchored object with a caption using a table is similar to the script discussed above.

Anchored In Text_Table

set folderName to "Images"
set captionTextStyle to "Caption"
set captionText to "Caption Here"
try
   set insertPoint to getInsertPoint()
   set imageRef to getImage(folderName)
   placeImage(insertPoint, imageRef, captionText, captionTextStyle)
on error errStr
   activate
   display alert ("Error: " & errStr)
end try
--====HANDLERS====
on placeImage(insertPoint, imageRef, captionText, captionTextStyle)
   tell application "Adobe InDesign CC 2015"
      set docRef to document 1
      set captionStyle to paragraph style captionTextStyle of docRef
      set measurement unit of script preferences to points
      --add table
      tell insertPoint
         set tableRef to make table with properties ¬
         {body row count:2, column count:1, space before:12, ¬
         space after:6, bottom border stroke weight:0, ¬
         left border stroke weight:0, top border stroke weight:0, ¬
         right border stroke weight:0}
      end tell
      set auto grow of row 1 of tableRef to true
      --place image
      set cellInsert to insertion point 1 of cell 1 of tableRef
      tell cellInsert
         set placedList to place imageRef
         set theImage to item 1 of placedList
      end tell
      --fit image
      set imageParent to parent of theImage
      tell parent of theImage
         fit given frame to content
      end tell
      --set properties for text cell and add caption
      tell cell 2 of tableRef
         set height to 18
         set text top inset to 6
         set text bottom inset to 0
         set top edge stroke weight to 0
         set contents to captionText
         set applied paragraph style of paragraph 1 to captionStyle
      end tell
   end tell
end placeImage

(*Returns reference to image file selected or error
Requires checkFile subroutine*)
on getImage(folderName)
   set userPrompt to "Choose file for placement"
   tell application "Adobe InDesign CC 2015"
      set docRef to document 1
      set filePath to (file path of docRef) as string
      set dLocation to (filePath & folderName) as alias
      set imageToImport to choose file with prompt userPrompt default location dLocation
      set {fileType, fileExt} to my checkFile(imageToImport)
      if not ((fileType is in placeable file types) ¬
         or (fileExt is in placeable file extensions)) then
         error "in getImage improper file selected"
      end if
   end tell
   return imageToImport
end getImage

(*returns reference to file type and file name extension for alias reference passed*)
on checkFile(imageToImport)
   set fileInfo to info for imageToImport
   set fileType to file type of fileInfo
   set fileExt to name extension of fileInfo
   if fileType is not "" and fileExt is not in {"", "txt", "doc", "docx"} then
      return {fileType, fileExt}
   else
      error "Improper file selected"
   end if
end checkFile

(*Returns reference to insertion point selection or error*)
on getInsertPoint()
   set errorMsg to "Requires insertion point for image placement"
   tell application "Adobe InDesign CC 2015"
      if not (selection exists) then
         error errorMsg
      end if
      set selList to selection
      set selItem to item 1 of selList
      if class of selItem is not insertion point then
         error errorMsg
      end if
   end tell
   return selItem
end getInsertPoint

screen shot of page with anchored image with caption  Anchored image with caption inside paragraph

For using these scripts it is important that graphics to be placed are cropped and sized as needed.

Notice that the script is the same as that for the script for our previous post with added functionality for adding a caption. We have also added code to check to make sure the file selected by the user is the correct type.

But there is still more that can be done to make this script complete. Although the script creates a caption with the appropriate paragraph style, it uses dummy text. Instead, you may want to provide a dialog for the user to define the text for the caption.

CAPTION TEXT

To allow the user to enter text for the caption, you could use something as simple as a display dialog. Or, should you want to give your user options, you could incorporate a custom dialog. For our purpose here, we will use a display dialog.

To accommodate the dialog, the top part of the script above, is changed to read as follows:

set folderName to "Images"
set captionTextStyle to "Caption"
set defaultCaption to "Caption Here"
set promptStr to "Enter text for caption"
try
   set insertPoint to getInsertPoint()
   set imageRef to getImage(folderName)
   set captionText to getString(promptStr, defaultCaption)
   placeImage(insertPoint, imageRef, captionText, captionTextStyle)
on error errStr
   activate
   display alert ("Error: " & errStr)
end try 

And the routine (handler) will read as follows:

(*Returns default text if user fails to enter caption*)
on getString(promptStr, defaultCaption)
   set defaultText to ""
   activate
   set userResponse to display dialog promptStr default answer defaultText default button 2
   set userText to text returned of userResponse
   if userText is "" then
      set userText to defaultCaption
   end if
   return userText
end getString

Dialog created by script for entering caption text Display Dialog for entering caption text

UPWARD AND ONWARD

The script above assumes that the default table that is created conforms to the properties set as defaults by InDesign. That may not be the case. The table, even with the properties set by the script, may not be as anticipated. To make the script more compact, and assure that all settings for the table are as anticipated, you will want to create a table style and apply the style to the table created. This will be the subject of our next blog post, so keep tuned.

Disclaimer

Scripts are provided to give users a starting point from which they can create their own scripts. No representation is made to their completeness. Users are advised to use as written at their own risk