InDesign scripting : lesson 21

here’s a script to accompany the cool feature covered in InDesign tip : #19 which showed how to quickly place a whole bunch of images into a neat grid. the technique is perfect for creating contact sheets — all we need to do now is label those suckers. this script will add image filenames to the page.

as always, to follow along, just copy the script samples into applescript editor (found in applications > utilities) or, for older OS versions, script editor (applications > applescript). then update the first line to your version of InDesign. hopefully the script will run nicely, unless the syntax has changed between versions.

first we need to do a little setting up — change the view preferences, create a layer and create a paragraph style :

tell application "Adobe InDesign CS4"
  tell active document
    set mgOrigPrefs to properties of view preferences
    set ruler origin of view preferences to spread origin
    
    try
      set mgLayer to layer "Image Labels"
    on error
      set mgLayer to make layer with properties {name:"Image Labels"}
    end try
    
    try
      set mgPara to paragraph style "Image Labels"
    on error
      set mgPara to make paragraph style with properties {name:"Image Labels", justification:center align, point size:12, applied font:"Arial Narrow	Bold", fill color:"Black"}
    end try

    -- other script elements will go in here

    set properties of view preferences to mgOrigPrefs
  end tell
end tell

whenever you use applescript to change preferences, it’s good practice to first capture the current settings so that you can reset the preferences once you’re done — this is what the start and end of that script are doing.

the other bits are pretty self explanatory. if you don’t understand why the make layer and make paragraph style parts are contained in try blocks — just ask.

just one thing : you may not have or want the font “Arial Narrow Bold”. just plonking in another font name may not work (notice the big gap in the script’s font name — this is a necessary element for that font). so what’s the easiest way to get the correct name of the font you DO want to use? just open a new InDesign file with one text frame containing some text in the font you prefer. then run this script :

tell application "Adobe InDesign CS4"
  tell active document
    get applied font of story 1
  end tell
end tell

the correct font name (with any weird spacing and whatnot) will appear in the results window. just copy/paste it across.

ok, let’s keep going. the next part of the script goes after that last end try. first we set up a repeat loop to process every page in the document. for each page we have to get all the page items that could contain an image (mgItems). and, because groups are treated as their own special kind of page item, we use a try block to look through any groups for other frames to add to the mgItems list.

next, we set up another repeat loop to process each page item in the mgItems list. since we don’t yet know if the page item contains a link, we try to get the name of any image (raster) or graphic (vector). then we set up an if/then statement to create a label wherever required :

set mgItemTypes to {rectangle, oval, polygon}
repeat with mgCountPage from 1 to (count pages)
  set mgPage to page mgCountPage
  set mgGroups to (every page item of mgPage whose class is group)
  set mgItems to (every page item of mgPage whose class is in mgItemTypes)
  
  try
    repeat with x from 1 to count of mgGroups
      set mgGroupedItems to (every page item of (item x of mgGroups) whose class is in mgItemTypes)
      repeat with z from 1 to count mgGroupedItems
        set end of mgItems to item z of mgGroupedItems
      end repeat
    end repeat
  end try
  
  repeat with mgCountItems from 1 to (count mgItems)
    set mgPageItem to (item mgCountItems of mgItems)
    set mgLinkName to ""
    try
      set mgLinkName to name of item link of image 1 of mgPageItem as string
    on error
      try
        set mgLinkName to name of item link of graphic 1 of mgPageItem as string
      on error
        set mgCountItems to mgCountItems + 1
      end try
    end try
    
    if mgLinkName is not "" then
      set mgGeoBounds to geometric bounds of mgPageItem
      set mgY2 to text item 3 of mgGeoBounds
      set text item 1 of mgGeoBounds to mgY2
      set text item 3 of mgGeoBounds to (mgY2 + 5)
      
      set mgLinkLabel to make text frame in mgPage with properties {geometric bounds:mgGeoBounds, fill color:swatch 2}
      set contents of mgLinkLabel to mgLinkName
      move mgLinkLabel to layer "Image Labels"
    end if
  end repeat
end repeat

the interesting bits are in that last if/then statement. first we get the geometric bounds (mgGeoBounds) of the page item containing the image or graphic (mgPageItem). for an explanation of geometric bounds, see InDesign scripting : lesson 15. we use these as the basis for creating geometric bounds for the label. items 2 and 4 of mgGeoBounds are left unchanged — these are the left and right edges of the frame. item 1 (top) is reset to match item 3 (bottom) and item 3 is reset to 5mm further down (or 5 of whatever measurement units you’re using). so, we end up with a 5mm high text frame whose top edge aligns exactly with the bottom edge of the image frame. hope that makes sense.

and the final part of the script goes immediately after that last end repeat and contains a number of interesting bits and pieces too — but it should be pretty easy to understand just by reading it — set text frame options, apply the paragraph style we created first up, and deal with any overset text :

tell every text frame of layer "Image Labels"
  set vertical justification of text frame preferences to center align
  set ignore wrap of text frame preferences to true
  set inset spacing of text frame preferences to {0.5, 2, 0.8, 2}
end tell

tell parent story of every text frame of layer "Image Labels"
  set applied paragraph style to "Image Labels"
  set applied character style to "[No character style]"
  clear overrides overrides to clear all
end tell

try
  tell (parent story of every text frame of layer "Image Labels" whose overflows = true)
    set leading to 10
    set point size to 10
  end tell
end try
try
  tell (parent story of every text frame of layer "Image Labels" whose overflows = true)
    set leading to 8
    set point size to 8
  end tell
end try
try
  tell (parent story of every text frame of layer "Image Labels" whose overflows = true)
    set leading to 6
    set point size to 6
  end tell
end try

screen shot showing page of labelled images

putting the labels on a separate layer makes it easy to select and move them if you need to (or delete them) :
screen shot of page after labels have been moved

of course, you’re not restricted to labelling images with just a filename. you could add a file size, filepath, xmp data, whatever. this script can be easily adapted to place captions for each image — if the captions are saved as metadata with the image file. go sick.

go here if you want a copy of the complete image labelling script

macgrunt icon

InDesign tip : #12

since CS4 you have been able to place multiple images. the old way was to place only one image at a time — now you can load a whole bunch of images into the place cursor.

when you select more than one image to place, your cursor will have a little counter showing how many images are loaded and ready to place, plus a ghosted preview of the next image to be placed :

screen grab showing multi-image loaded cursor preview

if you have your links panel open you’ll notice that all the images are added to the panel BEFORE being placed on the page (they have a blank in the page column). the next image to be placed is marked “LP” :

screen grab showing loaded links panel

you can scroll through the list of upcoming images by using your up and down arrow keys to access the right one to place next.

if you accidentally load an image that you don’t need, you don’t have to place it and then delete it. just hit your escape key (top left) when that image is the next to place — it will be removed from the loaded cursor and the links panel.

macgrunt icon