Scripting InDesign

This section provides an overview of how to use scripting objects to perform typical programming tasks in InDesign CS5.

Basics:
Additional topics:

Referring to objects in scripts

When you write a script, you must first decide which file, or document, the script should act on. To access to InDesign Application object in ActionScript use this code:

import com.adobe.csawlib.indesign.InDesign;
import com.adobe.indesign.Application;
var app:com.adobe.indesign.Application = InDesign.app;

Through the Application object, the script can create a new document, open an existing document, or act on a document that is already open. To refer to the currently selected document, get the first member of the Application object’s documents list: app.documents.item(0). You can use the Document object’s activeLayer property to refer to the currently selected layer, and so on. For details, see the scripting reference documentation.

Through the Document object, the script can create new pages, text objects, and page-item objects, operate on objects that the user selected, or operate on objects in one of the object collections.

Dynamic collections and object types

InDesign collections are dynamic, and can change their order in response to changes your extension makes to the objects in the model. As you create new documents, for example, the order of the Document objects in the Documents collection changes. The front-most document is always the first Document in the collection. Creating a new document automatically brings that document to the front, so any new document you create is added to the beginning of the Documents collection.

In addition, some objects can change their type based on changes your extension makes to them. For example, PageItems (Rectangles, Ovals, GraphicLines, TextFrames, and Polygons) can change their type when you change their contents or the location of the path points in the object. For example, setting the contentType of a Rectangle to <object>.textType  changes the type of the object to TextFrame. It also removes the object from the Rectangles collection of its parent container and add it to the TextFrames collection of the same container.

Keep  in mind when you are iterating through the contents of a collection that changes you make to the collection may result in invalid references. For example, consider the following range of paragraphs::

Paragraph 1.

Delete this paragraph.

Paragraph 2.

Paragraph 3.

Paragraph 4.

Paragraph 5.

Delete this paragraph.

Paragraph 6.

We want our extension to iterate over the paragraphs, remove the paragraphs that contain the word "Delete," and apply formatting to the remaining paragraphs. To avoid problems that result from the dynamic changes to the collection, the correct way to handle this is to iterate backward through the text objects, from the last paragraph in the story to the first:

var myDocument:Document = app.documents.item(0);
var myStory:Story = myDocument.stories.item(0);

//This loop formats all of the paragraphs by iterating
//backwards through the paragraphs in the story.
for(var myParagraphCounter:int = myStory.paragraphs.length-1; myParagraphCounter >= 0; myParagraphCounter --)
{
   if(myStory.paragraphs.item(myParagraphCounter).words.item(0).contents=="Delete"){
      myStory.paragraphs.item(myParagraphCounter).remove();
   }
   else{
      myStory.paragraphs.item(myParagraphCounter).pointSize = 24;
   }
}

If you iterate forward through the collection, from the first paragraph in the story to the last, some of the paragraphs are left unformatted. Why does this happen? When the loop counter reaches 1, the loop deletes the second paragraph, which begins with the word “Delete.” Because the collection is dynamic, the third paragraph moves up to take its place. When the loop counter reaches 2, the code processes the paragraph that had been the fourth paragraph in the story; the original third paragraph is now the second paragraph and is skipped.

Measurements and positioning

InDesign, like all page-layout and drawing programs, uses simple, two-dimensional geometry to set the position of objects on a page or spread. When you select an object using the Selection tool, you can see these coordinates in the Transform panel or control. InDesign  coordinates are measured relative to the current location of the ruler’s zero point; the vertical (Y-axis) coordinates below the zero point are positive numbers; coordinates above the zero point are negative numbers.

When you get or set  the location of a path point, the coordinates are passed and returned in the typical (x, y) order. InDesign returns some coordinates in a different order, however, and it expects you to supply them in that order. Geometric bounds and visible bounds are arrays containing four coordinates, which define (in order) the top, left, bottom, and right edges of the object’s bounding box,  (y1, x1, y2, x2).

Working with measurement units

InDesign returns coordinates and other measurement values using the publication’s current measurement units. In some cases, these units do not resemble the measurement values shown in the InDesign Transform panel. For example, if the current measurement system is picas, InDesign returns fractional values as decimals, rather than using the picas-and-points notation used by the Transform panel. “1p6,” for example, is returned as “1.5.”

When you send measurement values to InDesign, you can send numbers (for example, 14.65) or measurement strings (for example, “1p7.1”). If you send numbers, InDesign uses the publication’s current unit of measurement. If you send measurement strings, InDesign uses the units of measurement specified in the string; this is called a measurement override; it overrides the publication's unit. A measurement override is a string containing one of these unit override codes:

Override code

Meaning

Example

c

Ciceros (add didots after the c, if necessary)

1.4c

cm

Centimeters

.635cm

i (or in)

Inches

.25i

mm

Millimeters

6.35mm

p

Picas (add points after the p, if necessary)

1p6

pt

Points

18pt

If your extension depends on adding, subtracting, multiplying, or dividing specific measurement values, you can cache the current  measurement units (kept in the verticalMeasurementUnits and horizontalMeasurementUnits properties of the viewPreferences object of the document) and set them to your preferred unit before sending the values to the application. This allows you to use simple numeric values that are easy to manipulate. Use the cached values to set the measurement units back to what they were before you ran the extension.

Working with documents

The work you do in InDesign revolves around documents—creating them, saving them, printing or exporting them, and populating them with page items, colors, styles, and text. Almost every document-related task can be automated using InDesign scripting.

You can access existing Document objects through the documents collection in the Application object, or create new ones using the add() method of the Documents collection object:

// create a new document
var myDocument:Document = app.documents.add();

// get the currently active document
var myDocument:Document = app.activeDocument;

The Document object has methods for the basic document operations, open(), close(), save(). You can also print the document, or export it  to different formats (PDF or EPS). The  Document object contains preference objects that control how these operations are performed. For example, this sets the pageRange property of the document’s print preferences object before printing:

app.activeDocument.printPreferences.pageRange = "22"
app.activeDocument.print(false);

The page range value can be either PageRange.allPages or a page-range name string. This example assumes that you have a document open, and that it contains a page named "22". A page number entered in the page range must correspond to a page name in the document (not the page index);if the page name is not found, InDesign displays an error message.

Controlling page layout

Each document has a default page size, assigned number of pages, page orientation, bleed and slug working areas, and columns and margins to define the area into which material is placed, whether to use facing pages, and so on. All of these things are represented by properties in a DocumentPreferences object.

The DocumentPreferences object kept in the Document object controls the settings for that document:

var myDocument:Document = app.documents.add();
myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.POINTS;
myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.POINTS;
myDocument.documentPreferences.pageHeight = 800;
myDocument.documentPreferences.pageWidth = 600;
myDocument.documentPreferences.pageOrientation = PageOrientation.LANDSCAPE;
myDocument.documentPreferences.pagesPerDocument = 16;

A  DocumentPreferences object kept in the Application object controls the default settings for new document.

You can also set individual page sizes, and apply geometric transformations to individual pages. To select pages:

//Given a document with four pages (1, 2, 3, 4)
var myDocument:Document = app.activeDocument;
var myPages:Pages = myDocument.pages;

//Select page 1 and 2
myPages.item(0).select();
myPages.item(1).select(SelectionOptions.ADD_TO);

//Select last page
myDocument.select(myPages.item(-1), SelectionOptions.ADD_TO);

You can use the methods of an individual Page object to resize it within the limits allowed by its margin values. For example:

//Resize page to two times bigger
myPages.item(1).resize(CoordinateSpaces.INNER_COORDINATES, AnchorPoint.CENTER_ANCHOR, ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY, [2, 2]);

//Resize page to 400 points width and 600 points height
myPages.item(2).resize(CoordinateSpaces.INNER_COORDINATES, AnchorPoint.CENTER_ANCHOR, ResizeMethods.REPLACING_CURRENT_DIMENSIONS_WITH, [400, 600]);

You can use the resize() method to change a page’s size by making the bounding box larger or smaller. For example:

///Given a page "myPage," make the page 72 points wider and 72 points taller.
myPage.resize(CoordinateSpaces.PASTEBOARD_COORDINATES, AnchorPoint.TOP_LEFT_ANCHOR, ResizeMethods.ADDING_CURRENT_DIMENSIONS_TO, [72, 72]);

The Page.transform() method also allows you to apply geometric transformations to a page, using a transformation matrix. This is similar to transforming an individual page item; see Working with page items.

Working with layers

InDesign’s layers are the key to controlling the stacking order of objects in your layout. You can think of layers as transparent planes stacked on top of each other. You also can use layers as an organizational tool,putting one type of content on a given layer or set of layers.

Creating and referring to layers

A document can contain one or more layers, and each document includes at least one layer. Layers are document-wide, not bound to specific pages or spreads. The Layers collection is stored in the Document.layers property, and the Document objects also provides access to the currently active layer:

var myDocument:Document = app.documents.item(0);
var myLayer:Layer = myDocument.activeLayer;

When you create a new layer, the layer appears above all other layers in the document. You can reference individual Layer objects in the Document.layers collection using an array index; the top-most layer is at index 0. You can use the index -1 to reference the last or bottom-most layer in a collection. You can also reference layers by name; for example:

var myLayer:Layer = app.documents.item(0).layers.item("Text Layer");

Use the Layers collection object itself to create new layers, using the add() method,  For example:

var myLayer:Layer = myDocument.layers.add();

The  Layers collection also provides the previousItem()and nextItem(), methods for iterating through layers; these methods take a reference to one layer, and return the  previous or next layer in the stacking order. The method itemByRange() returns a reference to a contiguous range of layers in the document's layers collection.

Manipulating layers

Use the methods of an individual Layer object to delete, rearrange, duplicate, and merge layers in a document. For example, you can use the move() method to change the stacking order of layers in the document:

var myLayerA:Layer = myDocument.layers.item(0);
var myLayerB:Layer = myDocument.layers.item(1);
myLayerA.move(LocationOptions.AFTER, myLayerB);

Layer properties

 Basic Layer properties include the name of the layer, the highlight color, visibility, and whether text objects on the layer ignore text-wrap settings. For example:

var myLayer:Layer = myDocument.layers.add();
myLayer.name = "myLayer";
myLayer.layerColor = UIColors.CHARCOAL;
myLayer.ignoreWrap = false;
myLayer.visible = true;

A layer contains collections of page items that belong to it, either immediately (Layer.pageItems) or anywhere in the page-item hierarchy (Layer.allPageItems). A PageItem object points back to the layer it belongs to in the itemLayer property; you can change the containing layer by setting this value. When you do so, the item lists in the affected layers are automatically updated. Page guides also point back to their containing layer, and can be moved from one layer to another; see  examples in Working_with_page_items.

You can lock a layer by setting the Layer.lock property, which means the page items on that layer cannot be edited. For example:

var myTargetLayer:Layer = myDocument.activeLayer;
var myLayers:Layers = myDocument.layers.itemByRange(myDocument.layers.length-1, myTargetLayer.index +1);
myLayers.locked = true;

You can set the Boolean printable property to false in order to prevent that layer from being output by the print() or exportFile() method of the document. You can use this together with the visible property to create conditional content in a document (different language versions, for example) that show the same set of layers on the screen, when printed, and when exported to PDF or EPS.

 

 

 

Copyright © 2010 Adobe Systems Incorporated. All rights reserved.