Your prescription for increased productivity and profitability
In Adobe InDesign users often take advantage of the pasteboard as a holding area for page items. Drag a page item from the page onto the pasteboard and use it used anywhere within the spread; or copy and paste it anywhere within the document. It’s quick and efficient when working hands-on. Using pasteboard items in InDesign can pose some problems to new scripters. First, InDesign considers the pasteboard to be a hidden layer. When creating scripts that may involve items on the pasteboard, option preferences can be set to include, or not include, items on hidden layers as in the following example:
tell application "Adobe InDesign CC 2015" tell find change text options set include hidden layers to true end tell end tell
For this reason, your script needs to make sure that the <strong>include hidden layers</strong> property for find/change is set appropriately. Set incorrectly, your script can end up changing items stored on the pasteboard.
To access items on the pasteboard, your script needs to reference the spread. For most scripts, this can be the active spread of the active window
tell application "Adobe InDesign CC 2015" set spreadRef to active spread of active window tell spreadRef set pageItems to page items of spreadRef end tell end tell
The problem is that the spread acts as a kind of “meta-container”, including all objects placed within and outside of the actual page bounds. This means that the spread is the parent for page items which are not visible as well as those that are visible. The fact that page items for the spread include items inside as well as outside of the active page bounds takes a it a little doing to reference pasteboard items specifically. InDesign provides a number of options for a script. First, your script may want to check to see if there are any items on the pasteboard.
To get the number of page items on the pasteboard as opposed to those on the actual pages of the spread:
This is demonstrated by the following sample script:
set pageItemCount to 0 tell application "Adobe InDesign CC 2015" set spreadRef to active spread of active window tell spreadRef set spreadPageItems to page items repeat with i from 1 to count of pages tell page i set pageItemCount to pageItemCount + (count of page items) end tell end repeat if (count of spreadPageItems) > pageItemCount then set pasteboardItemCount to count of spreadPageItems - pageItemCount end if activate display alert ("There are " & pasteboardItemCount & " page items on the pasteboard") end tell end tell
To filter out the items on the pasteboard from the total page items (spreadPageItems), the solution comes from looking at InDesign’s object hierarchy. A page item, whether on an actual page or on the pasteboard, returns a reference to the spread as its parent. You can test this out with a document having page items on its pages as well as on the pasteboard. Copy and paste the following into AppleScript editor and view the result after running the script:
set parentList to {} tell application "Adobe InDesign CC 2015" set spreadRef to active spread of active window set itemList to every page item of spreadRef repeat with eachItem in itemList set end of parentList to class of parent of eachItem end repeat end tell parentList
Now replace the word parent in line 6 above to parent page so the statement reads:
set end of parentList to class of parent page of thisItem
Be prepared for an invalid object error to be thrown if you try to run the script.
Now surround the statement with a try/end try block:
try set end of parentList to class of parent page of thisItem end try
When you run the script as modified, you will discover the list of parent items is now smaller, and the class of the parent page is now page. The list now includes only the class of the parent of the actual page items (its parent page). The parent page object was added to InDesign fairly recently, sometime about version CS5.5 or CS6, I believe. If using an earlier version that does not have the parent page object, you will need to use some other method. Items on the pasteboard do not have a parent page object. To filter out pasteboard items from the page item list, the following can then be used.
set pasteboardItems to {} t
tell application "Adobe InDesign CC 2015" set spreadRef to active spread of active window set itemList to every page item of spreadRef repeat with i from 1 to length of itemList set thisItem to item i of itemList if parent page of thisItem is nothing then set end of pasteboardItems to thisItem end if end repeat end tell pasteboardItems
var pasteboardItems = []; var spreadRef = app.activeWindow.activeSpread; var itemList = spreadRef.pageItems.everyItem().getElements(); var thisItem, myParent; for (var i = 0; i < itemList.length; i++) { thisItem = itemList[i]; myParent = thisItem.parentPage; if (myParent == null) { pasteboardItems.push(thisItem); } } pasteboardItems;
You can filter the items on the pasteboard by verifying the class of the page items inside the repeat loop::
(*For AppleScript, inside the repeat loop:*) if parent page of thisItem is nothing then if class of thisItem is text frame then set end of pasteboardItems to thisItem end if end if
//For ExtendScript, inside the repeat loop: if (myParent == null) { if (thisItem.constructor = TextFrame) { pasteboardItems.push(thisItem); } }
Of course, if your script only needs to get specific page items on the pasteboard (such as text frames), you could limit the initial item list to the specific page item by class instead of page items.
For AppleScript:
set itemList to text frames of spreadRef;
For ExtendScript:
var itemList = spreadRef.textFrames.everyItem().getElements();
Now that you have the code to get the items on the spread pasteboard, you can expand your script to do something useful:
Should you want to place the text from a pasteboard item into the active insertion point, your script will need do the following:
It’s the last bullet item above that may cause problems depending on your version of InDesign: The contents of a text frame in version 2015.1 is a reference to the frame itself. Try the following with a text frame selected:
tell application "Adobe InDesign CC 2015" set selList to selection set selItem to item 1 of selList set theTest to contents of selItem end tell theTest
To get the text contained by the item, you have several options:
set theText to contents of the contents of selItem
set theText to contents of parent story of selItem
AppleScript
tell application "Adobe InDesign CC 2015" set selList to selection set selItem to item 1 of selList set theTest to contents of contents of selItem theTest
ExtendScript
var selList = app.selection; var selItem = selList[0]; var theText = selItem.contents; theText;