Set Ruler Origin (CS2/CS3)



Very important for ease of placing elements according to Adobe’s own documentation. I’m only duplicating this code (duped almost verbatim from their guides) because this command’s importance cannot be understated in ensuring that your scripts will run as expected.


set ruler origin of view preferences of SLCDocument to page origin


Changing individual objects



In these examples, select objects first. The selection is actually an array, even if only one object is selected.

Set/Alter the label of an object



This is fairly straightforward and simple, but I use the label property for all sorts of uses especially for dynamic layouts.


tell application "Adobe InDesign CS2"
tell document 1
set theItem to item 1 of selection
set label of theItem to "biblio_frame"
return label of theItem
end tell
end tell


Get Page Item



This subroutine essentially requires that a page item be tagged in some manner


on GetPageItem(PageNumber, PageItemName) -- as page item (usually text frame) (Integer, String)
log "sub GetPageItem"
tell application "Adobe InDesign CS3"
tell kCurrentDocument
tell page PageNumber

set thisPageItem to 1
set firstPageItem to 1
set lastPageItem to (get count of page items)

repeat with thisPageItem from firstPageItem to lastPageItem
set thePageItem to page item thisPageItem
set thePageItemLabel to label of thePageItem

if thePageItemLabel is PageItemName then
return thePageItem
end if
end repeat

end tell
end tell
end tell
end GetPageItem


Get Bounds Of Page




on GetGeometricBoundsOfPage(PageNumber) --as list of integers {y1, x1, y2, x2}
tell application "Adobe InDesign CS3"
tell document 1
set thePage to page PageNumber
return geometric bounds of thePage
end tell
end tell
end GetGeometricBoundsOfPage


Create text frame, insert auto page number, style text



This is the core of all dynamic layouts.


set newTextFrame to make new text frame with properties {geometric bounds:{729, 36, 750, 75}, label:"PageNumberVerso"}

tell newTextFrame
set contents to auto page number -- inserts the glyph behind "^#" in the find and change window/preferences
tell every paragraph
set applied paragraph style to "FolioVerso"
set justification to left align
end tell
end tell


Expand Text Frame



This expands a text frame until the text contained inside is no longer overflowed. This and the Shrink Text Frame snippet below make for easy dynamic layouts.


on ExpandTextFrame(theFrame, theIncrement)
log "Sub ExpandTextFrame"

tell application "Adobe InDesign CS3"

set frameOverflow to overflows of theFrame

repeat while frameOverflow is true

set frameBounds to geometric bounds of theFrame

set mY1top to (item 1 of frameBounds)
set mX1left to (item 2 of frameBounds)
set mY2bottom to (item 3 of frameBounds)
set mX2right to (item 4 of frameBounds)

set mY2bottom to mY2bottom + theIncrement

tell theFrame

set geometric bounds to {mY1top, mX1left, mY2bottom, mX2right}

end tell

set frameOverflow to overflows of theFrame

end repeat
end tell

end ExpandTextFrame


Shrink Text Frame and Move Another Frame Relative To Final Size



As I’ve written elsewhere in the site, I prefer readable over all else. MoveFrameDownRelativeToFrameAbove is neither brief nor abbreviated, but there is absolutely no mistaking what it does.


on ShrinkTextFrame(theFrame, theIncrement)
log "Sub ShrinkTextFrame"

tell application "Adobe InDesign CS3"

set frameOverflow to overflows of theFrame

repeat while frameOverflow is false

set frameBounds to geometric bounds of theFrame

set mY1top to (item 1 of frameBounds)
set mX1left to (item 2 of frameBounds)
set mY2bottom to (item 3 of frameBounds)
set mX2right to (item 4 of frameBounds)

set mY2bottom to mY2bottom - theIncrement

tell theFrame

set geometric bounds to {mY1top, mX1left, mY2bottom, mX2right}

end tell

set frameOverflow to overflows of theFrame

end repeat
end tell

end ShrinkTextFrame

on MoveFrameDownRelativeToFrameAbove(currentFrame, frameAbove)
log "MoveFrameDownRelativeToFrameAbove"

tell application "Adobe InDesign CS3"

set frameAboveBounds to geometric bounds of frameAbove
set faY2bottom to (item 3 of frameAboveBounds)

set currentFrameBounds to geometric bounds of currentFrame

set cfY1top to (item 1 of currentFrameBounds)
set cfX1left to (item 2 of currentFrameBounds)
set cfY2bottom to (item 3 of currentFrameBounds)
set cfX2right to (item 4 of currentFrameBounds)

set cfHeight to cfY2bottom - cfY1top

set cfY1top to faY2bottom + kFrameMargin --move the top of the current frame down.
set cfY1Bottom to cfY1top + cfHeight -- move the bottom of the current frame down.

tell currentFrame
set geometric bounds to {cfY1top, cfX1left, cfY2bottom, cfX2right}
end tell

end tell

end MoveFrameDownRelativeToFrameAbove


Get Margins



This makes use of one of several properties that are contained in preferences.


tell page 1
set pageMarginPreferences to margin preferences
set bottomMargin to bottom of pageMarginPreferences
end tell


Delete a page if the main text frame is empty



Uses the aforementioned GetPageItem


set pageTwoTextFrameText to ""

tell page pageTwoNumber
set kPageTwoTextFrame to GetPageItem(pageTwoNumber, kPageTwoTextFrameName) of me
set pageTwoTextFrameText to get count of text of kPageTwoTextFrame
end tell

if pageTwoTextFrameText is 0 then
delete page pageTwoNumber
end if


Get name of linked file in an image frame



QuarkXpress can't do this and they should. This is one of the most useful things that InDesign can do for transforming content. If Quark had put this much thought into their Applescript implementation (and their software in general), I’d be using it today.


tell application "Adobe InDesign CS3"
tell document 1
set theSelection to the selection
set selectionProperties to properties of selection
set theImage to item 1 of all graphics of selectionProperties
set theGraphicItemLink to item link of theImage
set theGraphicName to name of theGraphicItemLink
return theGraphicName
end tell
end tell


The Transformation Matrix (Rotating and Moving Objects)



Rotate a page item



Rotating a page item is about as an obfuscated, non-obvious tasks one can do in Applescript with InDesign (and that's a very unfortunate turn of events for the API). Looking at Move, a related action, is of no help. In order to rotate an object, we have to use the transform command. From the Dictionary (via Script Debugger)...

transform reference ¬
in in ¬
from anything ¬
with matrix anything ¬
replacing current anything ¬
considering ruler units boolean


The trick with the transform command is the value needed for the with matrix argument: anything isn't really anything, it is actually a transformation matrix. To make a simple rotation transformation matrix, just start with the following code...

tell application "Adobe InDesign CS4"
set myMatrix to make transformation matrix with properties {counterclockwise rotation angle:90}
transform myLayoutObject in pasteboard coordinates from center anchor with matrix myMatrix
end tell

The transformation matrix is an all-purpose class that can also replace the Move command.

Applying multiple transformations to a single object



When applying both scale and movement transformations to an object, it is important to note two things
  • Scale is a 1-based number, and not a percentage. Scaling something by 150% needs to be translated to 1.5 when applying it to the transformation matrix.
  • Scale is applied first, then the object is moved second. In other words, translation needs to be based on the position of the anchor after the scale has been applied.

tell application "Adobe InDesign CS4"
set theSelection to selection

set scaleFactor to 1.3

set rectoXPre to 396
set rectoYPre to 304.5
set rectoXPost to 97.2
set rectoYPost to 396.5

set versoXPre to 396.5
set versoYPre to 304.5
set versoXPost to 514.8
set versoYPost to 396.5

set myMatrix to make transformation matrix with properties {horizontal scale factor:scaleFactor, horizontal translation:(versoXPost - versoXPre), vertical scale factor:scaleFactor, vertical translation:(versoYPost - versoYPre)}

transform theSelection in parent coordinates from center anchor with matrix myMatrix
end tell