If this guide is distributed with software that includes an end user agreement, this guide, as well as the software
described in it, is furnished under license and may be used or copied only in accordance with the terms of such license.
Except as permitted by any such license, no part of this guide may be reproduced, stored in a retrieval system, or
transmitted, in any form or by any means, electronic, mechanical, recording, or otherwise, without the prior written
permission of Adobe Systems Incorporated. Please note that the content in this guide is protected under copyright law
even if it is not distributed with software that includes an end user license agreement.
The content of this guide is furnished for informational use only, is subject to change without notice, and should not be
construed as a commitment by Adobe Systems Incorporated. Adobe Systems Incorporated assumes no responsibility or
liability for any errors or inaccuracies that may appear in the informational content contained in this guide.
Please remember that existing artwork or images that you may want to include in your project may be protected under
copyright law. The unauthorized incorporation of such material into your new work could be a violation of the rights of
the copyright owner. Please be sure to obtain any permission required from the copyright owner.
Any references to company names in sample templates are for demonstration purposes only and are not intended to
refer to any actual organization.
Adobe, the Adobe logo, Creative Suite, and InDesign are either registered trademarks or trademarks of Adobe Systems
Incorporated in the United States and/or other countries. Microsoft and Windows are either registered trademarks or
trademarks of Microsoft Corporation in the United States and/or other countries. Mac OS is a trademark of Apple
Computer, Incorporated, registered in the United States and other countries. All other trademarks are the property of
their respective owners.
Adobe Systems Incorporated, 345 Park Avenue, San Jose, California 95110, USA. Notice to U.S. Government End Users.
The Software and Documentation are “Commercial Items,” as that term is defined at 48 C.F.R. §2.101, consisting of
“Commercial Computer Software” and “Commercial Computer Software Documentation,” as such terms are used in 48
C.F.R. §12.212 or 48 C.F.R. §227.7202, as applicable. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §§227.7202-1 through
227.7202-4, as applicable, the Commercial Computer Software and Commercial Computer Software Documentation are
being licensed to U.S. Government end users (a) only as Commercial Items and (b) with only those rights as are granted
to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright
laws of the United States. Adobe Systems Incorporated, 345 Park Avenue, San Jose, CA 95110-2704, USA. For U.S.
Government End Users, Adobe agrees to comply with all applicable equal opportunity laws including, if appropriate, the
provisions of Executive Order 11246, as amended, Section 402 of the Vietnam Era Veterans Readjustment Assistance Act
of 1974 (38 USC 4212), and Section 503 of the Rehabilitation Act of 1973, as amended, and the regulations at 41 CFR
Parts 60-1 through 60-60, 60-250, and 60-741. The affirmative action clause and regulations contained in the preceding
sentence shall be incorporated by reference.
XWork with the Adobe® InDesign® scripting environment.
XUse advanced scripting features.
XPerform basic document tasks like setting up master spreads, printing, and exporting.
XWork with page items (rectangles, ellipses, graphic lines, polygons, text frames, and groups).
XWork with text and type in an InDesign document, including finding and changing text.
XCreate dialog boxes and other user-interface items.
XCustomize and add menus and create menu actions.
XRespond to user-interface events.
XWork with XML, from creating XML elements and importing XML to adding XML elements to a layout.
XApply XML rules, a new scripting feature that makes working with XML in InDesign faster and easier.
We assume that you have already read the Adobe InDesign CS5 Scripting Tutorial and know how to create,
install, and run scripts. If you need to know how to connect with your scripting environment or view the
InDesign scripting object model from your script editor, that information can be found in the Adobe InDesign CS5 Scripting Tutorial.
How to Use the Scripts in this Document
For the most part, the scripts shown in this document are not complete scripts. They are only fragments of
scripts, and are intended to show only the specific part of a script relevant to the point being discussed in
the text. You can copy the script lines shown in this document and paste them into your script editor, but
you should not expect them to run without further editing. Note, in addition, that scripts copied out of this
document may contain line breaks and other characters (due to the document layout) that will prevent
them from executing properly.
A zip archive of all of the scripts shown in this document is available at the InDesign scripting home page,
at: http://www.adobe.com/products/indesign/scripting/index.html
expanded the archive, move the folders corresponding to the scripting language(s) of your choice into the
Scripts Panel folder inside the Scripts folder in your InDesign folder. At that point, you can run the scripts
from the Scripts panel inside InDesign.
About the Structure of the Scripts
. After you have downloaded and
The script examples are all written using a common template that includes the functions “main,”
“mySetup,” “mySnippet,” and “myTeardown.” We did this to simplify automated testing and
publication—there is no reason for you to construct your scripts this way. Most of the time, the part of the
script you will be interested in will be inside the “mySnippet” function.
9
CHAPTER 1: IntroductionFor More Information 10
For More Information
For more information on InDesign scripting, you also can visit the InDesign Scripting User to User forum, at
http://www.adobeforums.com
newest scripts. The forum contains hundreds of sample scripts.
Other JavaScript development options
You can use the ExtendScript Toolkit to create JavaScript scripts explicitly for InDesign, or you can use the
Creative Suite Extension Builder (CS Extension Builder) to develop CS extensions in ActionScript. CS
extensions are Flash-based (SWF) and can potentially work in a variety of Creative Suite applications.
In CS5, the applications have an extensibility infrastructure that allows developers to extend the
capabilities of the applications; the infrastructure is based on Flash/Flex technology, and each CS5
extension is delivered as a compiled Flash (SWF) file. CS5 includes the Extension Manager to enable
installation of CS5 extensions.
An example of a CS5 extension that ships with the point products is Adobe Kuler. Kuler has a consistent
user interface across the different suite applications, but has different logic in each, adapted to the host
application.
. In the forum, scripters can ask questions, post answers, and share their
The user interface for an extension is written in ActionScript, using the Flex framework. A C5S extension is
typically accessed through its own menu item in the application’s Extensions menu. CS Extension Builder
allows you to design the user interface interactively using the Design view of FlashBuilder. It also allows
you to develop all of the application logic for your CS5 extension in ActionScript; you can develop and
debug your extension in the familiar FlashBuilder environment.
To develop your application logic, we recommend using the Creative Suite ActionScript Wrapper Library
CSAWLib), which exposes the scripting DOM of each host application as an ActionScript library. This is
(
tightly integrated with the CS Extension Builder environment, which includes wizards to help you build
your extension’s basic structure, and run and debug your code against suite applications such as Adobe
InDesign, Photoshop and Illustrator.
The methods, properties, and behavior of the scripting DOM is as described in the JavaScript Scripting Reference for the host application. For details of how to use CS Extension Builder and the wrapper libraries,
see the Creative Suite SDK documentation, which is accessible from within the Flash Builder or Eclipse
Help system when you have installed CS Extension Builder.
2
Scripting Features
This chapter covers scripting techniques related to InDesign’s scripting environment. Almost every other
object in the InDesign scripting model controls a feature that can change a document or the application
defaults. By contrast, the features in this chapter control how scripts operate.
This document discusses the following:
XThe scriptPreferences object and its properties.
XGetting a reference to the executing script.
XRunning scripts in prior versions of the scripting object model.
XUsing the doScript method to run scripts.
XWorking with script labels.
XRunning scripts at InDesign start-up.
XControlling the ExtendScript engine in which scripts execute.
We assume you already read Adobe InDesign CS5 Scripting Tutorial and know how to write, install, and run
InDesign scripts in the scripting language of your choice.
Script Preferences
The scriptPreferences object provides objects and properties related to the way InDesign runs scripts.
The following table provides more detail on each property of the scriptPreferences object:
PropertyDescription
enableRedraw
scriptsFolder
scriptsList
Turns screen redraw on or off while a script is running from the Scripts panel.
The path to the scripts folder.
A list of the available scripts. This property is an array of arrays, in the
following form:
[[fileName, filePath], ...]
Where fileName is the name of the script file and filePath is the full path to
the script. You can use this feature to check for the existence of a script in the
installed set of scripts.
11
CHAPTER 2: Scripting FeaturesGetting the Current Script 12
PropertyDescription
userInteractionLevel
This property controls the alerts and dialogs InDesign presents to the user.
When you set this property to
InDesign does not display any alerts or dialogs. Set it to
UserInteractionLevels.interactWithAlerts to enable alerts but
disable dialogs. Set it to
alerts and dialogs. The ability to turn off alert displays is very useful when
you are opening documents via script; often, InDesign displays an alert for
missing fonts or linked graphics files. To avoid this alert, set the
user-interaction level to
opening the document, then restore user interaction (set the property to
interactWithAll) before completing script execution.
version
The version of the scripting environment in use. For more information, see
“Script Versioning” on page 12
version of the application.
Getting the Current Script
You can get a reference to the current script using the activeScript property of the application object.
You can use this property to help you locate files and folders relative to the script, as shown in the
following example (from the ActiveScript tutorial script):
var myScript = app.activeScript;
alert("The current script is: " + myScript);
var myParentFolder = File(myScript).parent;
alert("The folder containing the active script is: " + myParentFolder);
UserInteractionLevels.neverInteract,
interactWithAll to restore the normal display of
UserInteractionLevels.neverInteract before
. Note this property is not the same as the
When you debug scripts using a script editor, the activeScript property returns an error. Only scripts run
from the Scripts palette appear in the
When you debug scripts from the ExtendScript Toolkit, using the
To avoid this error and create a way of debugging scripts that use the
following error handler (from the GetScriptPath tutorial script):
function myGetScriptPath() {
try{
return app.activeScript;
}
catch(myError){
return File(myError.fileName);
}
}
Script Versioning
InDesign CS5 can run scripts using earlier versions of the InDesign scripting object model. To run an older
script in a newer version of InDesign, you must consider the following:
XTargeting — Scripts must be targeted to the version of the application in which they are being run
(i.e., the current version). The mechanics of targeting are language specific.
activeScript property.
activeScript property returns an error.
activeScript property, use the
CHAPTER 2: Scripting FeaturesUsing the doScript Method 13
X
Compilation — This involves mapping the names in the script to the underlying script ids, which are
what the application understands. The mechanics of compilation are language specific.
XInterpretation — This involves matching the ids to the appropriate request handler within the
application. InDesign CS5 correctly interprets a script written for an earlier version of the scripting
object model. To do this, run the script from a folder in the Scripts panel folder named
Scripts (for InDesign CS3 scripts) or Version 2.0 Scripts (for InDesign CS2 scripts), or explicitly set
Version 5.0
the application's script preferences to the old object model within the script (as shown below). Put the
previous version scripts in the folder, and run them from the Scripts panel.
Targ et in g
Targeting for JavaScripts is implicit when the script is launched from the Scripts panel. If the script is
launched externally (from the ESTK), use the
//target CS5
#target "InDesign-6.0"
//target the latest version of InDesign
#target "InDesign"
target directive:
Compilation
JavaScripts are not pre-compiled. For compilation, the application uses the same version of the DOM that
is set for interpretation.
Interpretation
The InDesign application object contains a scriptPreferences object, which allows a script to get/set
the version of the scripting object model to use for interpreting scripts. The version defaults to the current
version of the application and persists.
The following examples show how to set the version to the CS3 (5.0) version of the scripting object model.
//Set to 5.0 scripting object model
app.scriptPreferences.version = 5.0;
Using the doScript Method
The doScript method gives a script a way to execute another script. The script can be a string of valid
scripting code or a file on disk. The script can be in the same scripting language as the current script or
another scripting language. The available languages vary by platform: on Mac OS
AppleScript or JavaScript; on Windows
The
doScript method has many possible uses:
XRunning a script in another language that provides a feature missing in your main scripting language.
For example, VBScript lacks the ability to display a file or folder browser, which JavaScript has.
AppleScript can be very slow to compute trigonometric functions (sine and cosine), but JavaScript
performs these calculations rapidly. JavaScript does not have a way to query Microsoft
contents of a specific spreadsheet cell, but both AppleScript and VBScript have this capability. In all
these examples, the
to overcome a limitation of the language used for the body of the script.
doScript method can execute a snippet of scripting code in another language,
®
, VBScript or JavaScript.
®
, you can run
®
Excel for the
CHAPTER 2: Scripting FeaturesUsing the doScript Method 14
X
Creating a script “on the fly.” Your script can create a script (as a string) during its execution, which it
can then execute using the
doScript method. This is a great way to create a custom dialog or panel
based on the contents of the selection or the attributes of objects the script creates.
XEmbedding scripts in objects. Scripts can use the doScript method to run scripts that were saved as
strings in the
label property of objects. Using this technique, an object can contain a script that
controls its layout properties or updates its content according to certain parameters. Scripts also can
be embedded in XML elements as an attribute of the element or as the contents of an element. See
“Running Scripts at Startup” on page 18
.
Sending parameters to doScript
To send a parameter to a script executed by doScript, use the following form (from the
DoScriptParameters tutorial script):
var myParameters = ["Hello from DoScript", "Your message here."];
var myJavaScript = "alert(\"First argument: \" + arguments[0] + \"\\rSecond argument:
\" + arguments[1]);";
app.doScript(myJavaScript, ScriptLanguage.javascript, myParameters);
if(File.fs == "Windows"){
var myAppleScript = "tell application \"Adobe InDesign CS5\\rdisplay
dialog(\"First argument\" & item 1 of arguments & return & \"Second argument: \"
& item 2 of arguments & return & end tell";
app.doScript(myAppleScript, ScriptLanguage.applescriptLanguage, myParameters);
}
Returning values from doScript
The following script fragment shows how to return a value from a script executed by doScript. This
example uses a JavaScript that is executed as a string, but the same method works for script files. This
example returns a single value, but you can return multiple values by returning an array (for the complete
script, refer to the DoScriptReturnValues script).
CHAPTER 2: Scripting FeaturesUsing the doScript Method 15
//To send parameters to a script run using app.doScript(), the doScript
//statement must not appear inside a function. If it does, the parameters
//will not be passed to the script.
var myDocument = app.documents.add();
var myPage = myDocument.pages.item(0);
var myTextFrame = myPage.textFrames.add();
myTextFrame.geometricBounds = ["72pt", "72pt", "288pt", "288pt"];
myTextFrame.contents = "Example text frame.";
var myDestinationPage = myDocument.pages.add(LocationOptions.after, myPage);
var myPageIndex = myDestinationPage.name;
var myID = myTextFrame.id;
var myJavaScript = "var myDestinationPage = arguments[1];\r" ;
myJavaScript += "myID = arguments[0];\r";
myJavaScript += "var myX = arguments[2];\r";
myJavaScript += "var myY = arguments[3]\r;"
myJavaScript += "var myPageItem =
app.documents.item(0).pages.item(0).pageItems.itemByID(myID);\r";
myJavaScript +=
"myPageItem.duplicate(app.documents.item(0).pages.item(myDestinationPage));\r"
//Create an array for the parameters we want to pass to the JavaScript.
var myArguments = [myID, myPageIndex, 0, 0];
var myDuplicate = app.doScript(myJavaScript, ScriptLanguage.javascript, myArguments);
//myDuplicate now contains a reference to the duplicated text frame.
//Change the text in the duplicated text frame.
myDuplicate.contents = "Duplicated text frame.";
Another way to get values from another script is to use the scriptArgs (short for “script arguments”)
object of the application. The following script fragment shows how to do this (for the complete script, see
DoScriptScriptArgs):
var nameA = "ScriptArgumentA";
var nameB = "ScriptArgumentB";
var nAc = nameA + ": ";
var nBc = nameB + ": ";
//Create a string to be run as a JavaScript.
var p1 = "app.scriptArgs.setValue(\"" + nameA + "\", ";
var p2 = "\"This is the first script argument value.\");\r";
var p3 = "app.scriptArgs.setValue(\"" + nameB + "\", ";
var p4 = "\"This is the second script argument value.\")";
var p5, p6; //Used later.
var myJavaScript = p1 + p2 + p3 + p4;
var myScriptArgumentA = app.scriptArgs.getValue(nameA);
var myScriptArgumentB = app.scriptArgs.getValue(nameB);
alert(nameA + ": " + myScriptArgumentA + "\r" + nameB + ": " + myScriptArgumentB);
if(File.fs == "Windows") {
//Create a string to be run as a VBScript.
p1 = "Set myInDesign = CreateObject(\"InDesign.Application.CS5\")\r";
p2 = "myInDesign.ScriptArgs.SetValue \"" + nameA + "\", ";
p3 = "\"This is the first script argument value.\"\r";
p4 = "myInDesign.ScriptArgs.SetValue \"" + nameB + "\", ";
p5 = "\"This is the second script argument value.\"";
var myVBScript = p1 + p2 + p3 + p4 + p5;
app.doScript(myVBScript, ScriptLanguage.visualBasic);
} else {
CHAPTER 2: Scripting FeaturesControlling Undo with doScript 16
//Create a string to be run as a AppleScript.
p1 = "tell application \"Adobe InDesign CS5\"\r";
p2 = "tell script args" +"\r";
p3 = "set value name\"" + nameA +"\" value ";
p4 = "\"This is the firest AppleScript script argument value.\"" +"\r";
p5 = "set value name\"" + nameB +"\" value ";
p6 = "\"This is the second AppleScript script argument value.\"" +"\r";
p7 = "end tell" + "\r"
p8 = "end tell" + "\r"
var myAppleScript = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;
app.doScript(myAppleScript, ScriptLanguage.applescriptLanguage);
}
var myScriptArgumentA = app.scriptArgs.getValue(nameA);
var myScriptArgumentB = app.scriptArgs.getValue(nameB);
alert(nAc + myScriptArgumentA + nBc + myScriptArgumentB);
Controlling Undo with doScript
InDesign gives you the ability to undo almost every action, but this comes at a price: for almost every
action you make, InDesign writes to disk. For normal work you using the tools presented by the user
interface, this does not present any problem. For scripts, which can perform thousands of actions in the
time a human being can blink, the constant disk access can be a serious drag on performance.
doScript method offers a way around this performance bottleneck by providing two parameters that
The
control the way that scripts are executed relative to InDesign’s Undo behavior. These parameters are
shown in the following examples:
//Given a script "myJavaScript" and an array of parameters "myParameters"...
app.doScript(myJavaScript, ScriptLanguage.javascript, myParameters,
UndoModes.fastEntireScript, "Script Action");
//UndoModes can be:
//UndoModes.autoUnto: Add no events to the Undo queue.
//UndoModes.entireScript: Put a single event in the Undo queue.
//UndoModes.fastEntireScript: Put a single event in the Undo queue.
//UndoModes.scriptRequest: Undo each script action as a separate event.
//The last parameter is the text that appears in the Undo menu item.
Working with Script Labels
Many objects in InDesign scripting have a label property, including page items (rectangles, ovals, groups,
polygons, text frames, and graphic lines), table cells, documents, stories, and pages. This property can
store a very large amount of text.
The label of page items can be viewed, entered, or edited using the Script Label panel (choose Window >
Utilities > Script Label to display this panel), shown below. You also can add a label to an object using
scripting, and you can read the script label via scripting. For many objects, like stories, pages, and
paragraph styles, you cannot set or view the label using the Script Label panel.
CHAPTER 2: Scripting FeaturesWorking with Script Labels 17
The label property can contain any form of text data, such as tab- or comma-delimited text, HTML, or
XML. Because scripts also are text, they can be stored in the
label property.
Page items can be referred to by their
layers) can be referred to by their
label, just like named items (such as paragraph styles, colors, or
name. The following script fragment demonstrates this special case of the
label property (for the complete script, see ScriptLabel):
var myDocument = app.documents.add();
var myPage = myDocument.pages.item(0);
var myX1, myX2, myY1, myY2, myRectangle;
var myPageWidth = myDocument.documentPreferences.pageWidth;
var myPageHeight = myDocument.documentPreferences.pageHeight;
//<fragment>
//Create 10 random page items.
for(var i = 0; i < 10; i++)
{
}
alert("Found " + count + " page items with the label.");
//This function gets a random number in the range myStart to myEnd.
function myGetRandom(myStart, myEnd, myInteger)
{
var myRandom;
var myRange = myEnd - myStart;
if(myInteger == true)
{
In addition, all objects that support the label property also support custom labels. A script can set a
custom label using the
insertLabel method, and extract the custom label using the extractLabel
method, as shown in the following script fragment (from the CustomLabel tutorial script):
CHAPTER 2: Scripting FeaturesRunning Scripts at Startup 18
var myDocument = app.documents.add();
myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
var myPage = myDocument.pages.item(0);
var myRectangle = myPage.rectangles.add({geometricBounds:[72, 72, 144, 144]});
//Insert a custom label using insertLabel. The first parameter is the
//name of the label, the second is the text to add to the label.
myRectangle.insertLabel("CustomLabel", "This is some text stored in a custom label.");
//Extract the text from the label and display it in an alert.
var myString = myRectangle.extractLabel("CustomLabel");
alert("Custom label contained: " + myString);
Running Scripts at Startup
To run a script when InDesign starts, put the script in the Startup Scripts folder in the Scripts folder (for
more information, see “Installing Scripts” in Adobe InDesign CS5 Scripting Tutorial).
N
OTE: Scripts run in the session ExtendScript engine when InDesign starts can create objects and
functions that will be available to other scripts for the duration of the session. For more information, see
“Session and Main Script Execution” on page 18
.
Session and Main Script Execution
InDesign has two ways to run a JavaScript, session and main. These names correspond to the
ExtendScript “engine” used to run the script.
By default, when you run an InDesign JavaScript, the script is interpreted and executed by the “main”
ExtendScript engine, which is destroyed when the script completes execution. Script objects created by
the script do not persist.
Scripts run in the session engine can create objects that persist until you close InDesign. You can refer to
these objects from other scripts run in the
InDesign JavaScript, add the following line to the start of your script.
#targetengine "session"
You can create your own persistent ExtendScript interpretation and execution environment. To do this, use
#targetenging statement and provide your own ExtendScript engine name, as shown in the
the
following script fragment:
#targetengine "adobe"
session engine. To set the session engine as the target of an
3
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.
XApply different sizes to different pages (multiple pages sizes).
XPrint a document.
XExport a document as Adobe PDF.
XExport pages of a document as EPS.
We assume that you have already read Adobe InDesign CS5 Scripting Tutorial and know how to create,
install, and run a script.
19
CHAPTER 3: DocumentsBasic Document Operations 20
Basic Document Operations
Opening, closing, and saving documents are some of the most basic document tasks. This section shows
how to do them using scripting.
Creating a new document
The following script shows how to make a new document using scripting. (For the complete script, see
MakeDocument.)
var myDocument = app.documents.add();
To create a document using a document preset, the add method includes an optional parameter you can
use to specify a document preset, as shown in the following script. (For the complete script, see
MakeDocumentWithPreset.)
//Creates a new document using the specified document preset.
//Replace "myDocumentPreset" in the following line with the name
//of the document preset you want to use.
var myDocument = app.documents.add(true,
app.documentPresets.item("myDocumentPreset"));
You can create a document without displaying it in a window, as shown in the following script fragment
(from the MakeDocumentWithParameters tutorial script):
//Creates a new document without showing the document window.
//The first parameter (showingWindow) controls the visibility of the
//document. Hidden documents are not minimized, and will not appear until
//you add a new window to the document.
var myDocument = app.documents.add(false);
//To show the window:
var myWindow = myDocument.windows.add();
Some script operations are much faster when the document window is hidden.
Opening a document
The following script shows how to open an existing document. (For the complete script, see
OpenDocument.)
app.open(File("/c/myTestDocument.indd"));
You can choose to prevent the document from displaying (that is, hide it) by setting the showing window
parameter of the
performance of a script. To show a hidden document, create a new window, as shown in the following
script fragment (from the OpenDocumentInBackground tutorial script):
//Opens an existing document in the background, then shows the document.
//You'll have to fill in your own file path.
var myDocument = app.open(File("/c/myTestDocument.indd"), false);
//At this point, you could do things with the document without showing the
//document window. In some cases, scripts will run faster when the document
//window is not visible.
//When you want to show the hidden document, create a new window.
var myLayoutWindow = myDocument.windows.add();
open method to false (the default is true). You might want to do this to improve
CHAPTER 3: DocumentsBasic Document Operations 21
Saving a document
In the InDesign user interface, you save a file by choosing File > Save, and you save a file to another file
name by choosing File > Save As. In InDesign scripting, the
shown in the following script fragment (from the SaveDocument tutorial script):
//If the active document has been changed since it was last saved, save it.
if(app.activeDocument.modified == true){
app.activeDocument.save();
}
The save method has two optional parameters: The first (to) specifies the file to save to; the second
stationery) can be set to true to save the document as a template, as shown in the following script
(
fragment (from the SaveDocumentAs tutorial script):
//If the active document has not been saved (ever), save it.
if(app.activeDocument.saved == false){
//If you do not provide a file name, InDesign displays the Save dialog box.
app.activeDocument.save(new File("/c/myTestDocument.indd"));
}
You can save a document as a template, as shown in the following script fragment (from the
SaveAsTemplate tutorial script):
save method can do either operation, as
//Save the active document as a template.
var myFileName;
if(app.activeDocument.saved == true){
//Convert the file name to a string.
myFileName = app.activeDocument.fullName + "";
//If the file name contains the extension ".indd", change it to ".indt".
if(myFileName.indexOf(".indd")!=-1){
}
//If the document has not been saved, then give it a default file name/file path.
else{
myFileName = "/c/myTestDocument.indt";
}
app.activeDocument.save(File(myFileName), true);
Closing a document
The close method closes a document, as shown in the following script fragment (from the
CloseDocument tutorial script):
app.activeDocument.close();
//Note that you could also use:
//app.documents.item(0).close();
The close method can take up to two optional parameters, as shown in the following script fragment
(from the CloseWithParameters tutorial script):
CHAPTER 3: DocumentsBasic Page Layout 22
//Use SaveOptions.yes to save the document,SaveOptions.no to close the
//document without saving, or SaveOptions.ask to display a prompt. If
//you use SaveOptions.yes, you'll need to provide a reference to a file
//to save to in the second parameter (SavingIn).
//Note that the file path is provided using the JavaScript URI form
//rather than the platform-specific form.
//
//If the file has not been saved, display a prompt.
if(app.activeDocument.saved != true){
app.activeDocument.close(SaveOptions.ask);
//Or, to save to a specific file name:
//var myFile = File("/c/myTestDocument.indd");
//app.activeDocument.close(SaveOptions.yes, myFile);
}
else{
//If the file has already been saved, save it.
app.activeDocument.close(SaveOptions.yes);
}
You can close all open documents without saving them, as shown in the following script fragment (from
the CloseAll tutorial script):
Each document has a default page size, assigned number of pages, bleed and slug working areas, and
columns and margins to define the area into which material is placed. Again, all these parameters are
accessible to scripting, as shown in the examples in this section.
Defining page size and document length
When you create a new document using the InDesign user interface, you can specify the default page size,
number of pages, page orientation, and whether the document uses facing pages. To create a document
using InDesign scripting, use the
creating a document, you can use the
the following script fragment (from the DocumentPreferences tutorial script):
var myDocument = app.documents.add();
with(myDocument.documentPreferences){
NOTE: The app object also has a documentPreferences object. You can set the application defaults for
page height, page width, and other properties by changing the properties of this object. You can also set
individual page sizes; see “Adjusting Page Sizes and Layout”
documents.add method, which does not specify these settings. After
documentPreferences object to control the settings, as shown in
.
CHAPTER 3: DocumentsBasic Page Layout 23
Defining bleed and slug areas
Within InDesign, a bleed or a slug is an area outside the page margins that can be printed or included in an
exported PDF. Typically, these areas are used for objects that extend beyond the page edges (bleed) and
job/document information (slug). The two areas can be printed and exported independently; for example,
you might want to omit slug information for the final printing of a document. The following script shows
how to set up the bleed and slug for a new document. (For the complete script, see BleedAndSlug.)
myDocument = app.documents.add();
//The bleed and slug properties belong to the documentPreferences object.
with(myDocument.documentPreferences){
Alternately, if all the bleed distances are equal, as in the preceding example, you can use the
documentBleedUniformSize property, as shown in the following script fragment (from the
UniformBleed tutorial script):
//Create a new document.
myDocument = app.documents.add();
//The bleed properties belong to the documentPreferences object.
with(myDocument.documentPreferences){
If all the slug distances are equal, you can use the documentSlugUniformSize property, as shown in the
following script fragment (from the UniformSlug tutorial script):
//Create a new document.
myDocument = app.documents.add();
//The slug properties belong to the documentPreferences object.
with(myDocument.documentPreferences){
In addition to setting the bleed and slug widths and heights, you can control the color used to draw the
guides defining the bleed and slug. This property is not in the
pasteboardPreferences object, as shown in the following script fragment (from the
in the
documentPreferences object; instead, it is
BleedSlugGuideColors tutorial script):
CHAPTER 3: DocumentsBasic Page Layout 24
with(app.activeDocument.pasteboardPreferences){
//Any of InDesign's guides can use the UIColors constants...
bleedGuideColor = UIColors.cuteTeal;
slugGuideColor = UIColors.charcoal;
//...or you can specify an array of RGB values (with values from 0 to 255)
//bleedGuideColor = [0, 198, 192];
//slugGuideColor = [192, 192, 192];
}
Setting page margins and columns
Each page in a document can have its own margin and column settings. With InDesign scripting, these
properties are part of the
new document, then sets the margins and columns for all pages in the master spread. (For the complete
script, see PageMargins.)
myDocument = app.documents.add();
with (myDocument.pages.item(0).marginPreferences){
columnCount = 3;
//columnGutter can be a number or a measurement string.
columnGutter = "1p";
bottom = "6p"
//When document.documentPreferences.facingPages == true,
//"left" means inside; "right" means outside.
left = "6p"
right = "4p"
top = "4p"
}
marginPreferences object for each page. This following sample script creates a
To set the page margins for an individual page, use the margin preferences for that page, as shown in the
following script fragment (from the PageMarginsForOnePage tutorial script):
myDocument = app.documents.add();
with (myDocument.pages.item(0).marginPreferences){
columnCount = 3;
//columnGutter can be a number or a measurement string.
columnGutter = "1p";
bottom = "6p"
//When document.documentPreferences.facingPages == true,
//"left" means inside; "right" means outside.
left = "6p"
right = "4p"
top = "4p"
}
InDesign does not allow you to create a page that is smaller than the sum of the relevant margins; that is,
the width of the page must be greater than the sum of the left and right page margins, and the height of
the page must be greater than the sum of the top and bottom margins. If you are creating very small
pages (for example, for individual newspaper advertisements) using the InDesign user interface, you can
easily set the correct margin sizes as you create the document, by entering new values in the document
default page Margin fields in the New Document dialog box.
From scripting, however, the solution is not as clear: when you create a document, it uses the application’s
default-margin preferences. These margins are applied to all pages of the document, including master
pages. Setting the document margin preferences affects only new pages and has no effect on existing
pages. If you try to set the page height and page width to values smaller than the sum of the
corresponding margins on any existing pages, InDesign does not change the page size.
CHAPTER 3: DocumentsBasic Page Layout 25
There are two solutions. The first is to set the margins of the existing pages before you try to change the
page size, as shown in the following script fragment (from the PageMarginsForSmallPages tutorial script):
var myDocument = app.documents.add();
myDocument.marginPreferences.top = 0;
myDocument.marginPreferences.left = 0;
myDocument.marginPreferences.bottom = 0;
myDocument.marginPreferences.right = 0;
//The following assumes that your default document contains a single page.
myDocument.pages.item(0).marginPreferences.top = 0;
myDocument.pages.item(0).marginPreferences.left = 0;
myDocument.pages.item(0).marginPreferences.bottom = 0;
myDocument.pages.item(0).marginPreferences.right = 0;
//The following assumes that your default master spread contains two pages.
myDocument.masterSpreads.item(0).pages.item(0).marginPreferences.top = 0;
myDocument.masterSpreads.item(0).pages.item(0).marginPreferences.left = 0;
myDocument.masterSpreads.item(0).pages.item(0).marginPreferences.bottom = 0;
myDocument.masterSpreads.item(0).pages.item(0).marginPreferences.right = 0;
myDocument.masterSpreads.item(0).pages.item(1).marginPreferences.top = 0;
myDocument.masterSpreads.item(0).pages.item(1).marginPreferences.left = 0;
myDocument.masterSpreads.item(0).pages.item(1).marginPreferences.bottom = 0;
myDocument.masterSpreads.item(0).pages.item(1).marginPreferences.right = 0;
myDocument.documentPreferences.pageHeight = "1p";
myDocument.documentPreferences.pageWidth = "6p";
Alternately, you can change the application’s default-margin preferences before you create the document,
as shown in the following script fragment (from the ApplicationPageMargins tutorial script):
with (app.marginPreferences){
//Save the current application default margin preferences.
var myY1 = top;
var myX1 = left;
var myY2 = bottom;
var myX2 = right;
//Set the application default margin preferences.
top = 0;
left = 0;
bottom = 0;
right = 0;
}
//Create a new example document to demonstrate the change.
var myDocument = app.documents.add();
myDocument.documentPreferences.pageHeight = "1p";
myDocument.documentPreferences.pageWidth = "6p";
//Reset the application default margin preferences to their former state.
with (app.marginPreferences){
top = myY1;
left = myX1 ;
bottom = myY2;
right = myX2;
}
Changing the appearance of the pasteboard
The pasteboard is the area that surrounds InDesign pages and spreads. You can use it for temporary
storage of page items or for job-tracking information. You can change the size of the pasteboard and its
color using scripting. The
mode, as shown in the following script fragment (from the PasteboardPreferences tutorial script):
previewBackgroundColor property sets the color of the pasteboard in Preview
//You can use either a number or a measurement string
//to set the space above/below.
minimumSpaceAboveAndBelow = "12p";
//You can set the preview background color to any of
//the predefined UIColor enumerations...
previewBackgroundColor = UIColors.gray;
//...or you can specify an array of RGB values
//(with values from 0 to 255)
//previewBackgroundColor = [192, 192, 192];
}
Guides and grids
Guides and grids make it easy to position objects on your document pages. These are very useful items to
add when you are creating templates for others to use.
Defining guides
Guides in InDesign give you an easy way to position objects on the pages of your document. The following
script fragment shows how to use guides. (For the complete script, see Guides.)
var myDocument = app.documents.add();
var myPageWidth = myDocument.documentPreferences.pageWidth;
var myPageHeight = myDocument.documentPreferences.pageHeight;
with(myDocument.pages.item(0)){
//Place guides at the margins of the page.
guides.add(undefined, {orientation:HorizontalOrVertical.vertical, <lb>
location:marginPreferences.left});
guides.add(undefined, {orientation:HorizontalOrVertical.vertical, <lb>
location:(myPageWidth - marginPreferences.right)});
guides.add(undefined, {orientation:HorizontalOrVertical.horizontal, <lb>
location:marginPreferences.top});
guides.add(undefined, {orientation:HorizontalOrVertical.horizontal, <lb>
location:(myPageHeight - marginPreferences.bottom)});
//Place a guide at the vertical center of the page.
guides.add(undefined, {orientation:HorizontalOrVertical.vertical, <lb>
location:(myPageWidth/2)});
//Place a guide at the horizontal center of the page.
guides.add(undefined, {orientation:HorizontalOrVertical.horizontal, <lb>
location:(myPageHeight/2)});
}
Horizontal guides can be limited to a given page or extend across all pages in a spread. From InDesign
scripting, you can control this using the
fitToPage property. This property is ignored by vertical guides.
You can use scripting to change the layer, color, and visibility of guides, just as you can from the user
interface, as shown in the following script fragment (from the GuideOptions tutorial script):
CHAPTER 3: DocumentsBasic Page Layout 27
var myDocument = app.documents.add();
var myPageWidth = myDocument.documentPreferences.pageWidth;
var myPageHeight = myDocument.documentPreferences.pageHeight;
with(myDocument.pages.item(0)){
//Place guides at the margins of the page.
guides.add(undefined, {orientation:HorizontalOrVertical.vertical, <lb>
location:marginPreferences.left});
guides.add(undefined, {orientation:HorizontalOrVertical.vertical, <lb>
location:(myPageWidth - marginPreferences.right)});
guides.add(undefined, {orientation:HorizontalOrVertical.horizontal, <lb>
location:marginPreferences.top});
guides.add(undefined, {orientation:HorizontalOrVertical.horizontal, <lb>
location:(myPageHeight - marginPreferences.bottom)});
//Place a guide at the vertical center of the page.
guides.add(undefined, {orientation:HorizontalOrVertical.vertical, <lb>
location:(myPageWidth/2)});
//Place a guide at the horizontal center of the page.
guides.add(undefined, {orientation:HorizontalOrVertical.horizontal, <lb>
location:(myPageHeight/2)});
}
You also can create guides using the createGuides method on spreads and master spreads, as shown in
the following script fragment (from the CreateGuides tutorial script):
var myDocument = app.documents.add();
with (myDocument.spreads.item(0)){
//Parameters (all optional): row count, column count, row gutter,
//column gutter,guide color, fit margins, remove existing, layer.
//Note that the createGuides method does not take an RGB array
//for the guide color parameter.
createGuides(4, 4, "1p", "1p", UIColors.gray, true, true,
myDocument.layers.item(0));
}
Setting grid preferences
To control the properties of the document and baseline grid, you set the properties of the
gridPreferences object, as shown in the following script fragment (from the DocumentAndBaselineGrid
tutorial script):
var myDocument = app.documents.add();
//Set the document measurement units to points.
myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
//Set up grid preferences.
with(myDocument.gridPreferences){
documentGridShown = false;
documentGridSnapTo = true;
//Objects "snap" to the baseline grid when
//guidePreferences.guideSnapTo is set to true.
baselineGridShown = true;
}
Changing measurement units and ruler
Thus far, the sample scripts used measurement strings, strings that force InDesign to use a specific
measurement unit (for example, “8.5i” for 8.5 inches). They do this because you might be using a different
measurement system when you run the script.
To specify the measurement system used in a script, use the document’s
viewPreferences object, as
shown in the following script fragment (from the ViewPreferences tutorial script):
var myDocument = app.activeDocument;
with(myDocument.viewPreferences){
//Measurement unit choices are:
//* MeasurementUnits.agates
//* MeasurementUnits.picas
//* MeasurementUnits.points
//* MeasurementUnits.inches
//* MeasurementUnits.inchesDecimal
//* MeasurementUnits.millimeters
//* MeasurementUnits.centimeters
//* MeasurementUnits.ciceros
//Set horizontal and vertical measurement units to points.
horizontalMeasurementUnits = MeasurementUnits.points;
verticalMeasurementUnits = MeasurementUnits.points;
}
If you are writing a script that needs to use a specific measurement system, you can change the
measurement units at the beginning of the script, then restore the original measurement units at the end
of the script. This is shown in the following script fragment (from the ResetMeasurementUnits tutorial
script):
CHAPTER 3: DocumentsBasic Page Layout 29
var myDocument = app.activeDocument
with (myDocument.viewPreferences){
var myOldXUnits = horizontalMeasurementUnits;
var myOldYUnits = verticalMeasurementUnits;
horizontalMeasurementUnits = MeasurementUnits.points;
verticalMeasurementUnits = MeasurementUnits.points;
}
//At this point, you can perform any series of script actions
//that depend on the measurement units you've set. At the end of
//the script, reset the measurement units to their original state.
with (myDocument.viewPreferences){
alert("Could not reset custom measurement units.");
}
}
Defining and applying document presets
InDesign document presets enable you to store and apply common document set-up information (page
size, page margins, columns, and bleed and slug areas). When you create a new document, you can base
the document on a document preset.
Creating a preset by copying values
To create a document preset using an existing document’s settings as an example, open a document that
has the document set-up properties you want to use in the document preset, then run the following script
(from the DocumentPresetByExample tutorial script):
var myDocumentPreset;
if(app.documents.length > 0){
var myDocument = app.activeDocument;
//If the document preset "myDocumentPreset" does not already
//exist, create it.
myDocumentPreset = app.documentPresets.item("myDocumentPreset");
try {
var myPresetName = myDocumentPreset.name;
}
catch (myError){
myDocumentPreset = app.documentPresets.add({name:"myDocumentPreset"});
}
//Set the application default measurement units to match the document
//measurement units.
app.viewPreferences.horizontalMeasurementUnits =
myDocument.viewPreferences.horizontalMeasurementUnits;
app.viewPreferences.verticalMeasurementUnits =
myDocument.viewPreferences.verticalMeasurementUnits;
//Fill in the properties of the document preset with the corresponding
//properties of the active document.
with(myDocumentPreset){
//Note that the following gets the page margins
//from the margin preferences of the document; to get the margin
//preferences from the active page,replace "app.activeDocument" with
//"app.activeWindow.activePage" in the following line (assuming the
CHAPTER 3: DocumentsBasic Page Layout 30
//active window is a layout window).
var myMarginPreferences = app.activeDocument.marginPreferences;
To create a document preset using explicit values, run the following script (from the DocumentPreset
tutorial script):
var myDocumentPreset;
//If the document preset "myDocumentPreset" does not already exist, create it.
myDocumentPreset = app.documentPresets.item("myDocumentPreset");
try {
After setting up the basic document page size, slug, and bleed, you probably will want to define the
document’s master spreads. The following script shows how to do that. (For the complete script, see
MasterSpread.)
myDocument = app.documents.add();
//Set up the document.
with(myDocument.documentPreferences){
}
//Set the document's ruler origin to page origin. This is very important
//--if you don't do this, getting objects to the correct position on the
//page is much more difficult.
myDocument.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin;
with(myDocument.masterSpreads.item(0)){
//Set up the left page (verso).
with(pages.item(0)){
with(marginPreferences){
columnCount = 3;
columnGutter = "1p";
bottom = "6p"
//"left" means inside; "right" means outside.
left = "6p"
right = "4p"
top = "4p"
}
//Add a simple footer with a section number and page number.
with(textFrames.add()){
To apply a master spread to a document page, use the appliedMaster property of the document page, as
shown in the following script fragment (from the ApplyMaster tutorial script):
//Assumes that the active document has a master page named "B-Master"
//and at least three pages--page 3 is pages.item(2) because JavaScript arrays are
zero-based.
app.activeDocument.pages.item(2).appliedMaster =
app.activeDocument.masterSpreads.item("B-Master");
Use the same property to apply a master spread to a master spread page, as shown in the following script
fragment (from the ApplyMasterToMaster tutorial script):
//Assumes that the active document has master spread named "B-Master"
//that is not the same as the first master spread in the document.
app.activeDocument.masterSpreads.item(0).pages.item(0).appliedMaster =
app.activeDocument.masterSpreads.item("B-Master");
Adding XMP metadata
Metadata is information that describes the content, origin, or other attributes of a file. In the InDesign user
interface, you enter, edit, and view metadata using the File Info dialog (choose File > File Info). This
metadata includes the document’s creation and modification dates, author, copyright status, and other
information. All this information is stored using XMP (Adobe Extensible Metadata Platform), an open
standard for embedding metadata in a document.
To learn more about XMP, see the XMP specification at
You also can add XMP information to a document using InDesign scripting. All XMP properties for a
document are in the document’s
XMP data for a document.
This example also shows that XMP information is extensible. If you need to attach metadata to a document
and the data does not fall into a category provided by the metadata preferences object, you can create
your own metadata container (
.
metadataPreferences object. The example below fills in the standard
email, in this example). (For the complete script, see MetadataExample.)
CHAPTER 3: DocumentsBasic Page Layout 33
var myDocument = app.documents.add();
with (myDocument.metadataPreferences){
author = "Adobe";
copyrightInfoURL = "http://www.adobe.com";
copyrightNotice = "This document is copyrighted.";
copyrightStatus = CopyrightStatus.yes;
description = "Example of xmp metadata scripting in InDesign CS";
documentTitle = "XMP Example";
jobName = "XMP_Example_2003";
keywords = ["animal", "mineral", "vegetable"];
//The metadata preferences object also includes the read-only
//creator, format, creationDate, modificationDate, and serverURL
//properties that are automatically entered and maintained by InDesign.
//Create a custom XMP container, "email"
var myNewContainer = createContainerItem("http://ns.adobe.com/xap/1.0/", "email");
setProperty("http://ns.adobe.com/xap/1.0/", "email/*[1]", "someone@adobe.com");
}
Creating a document template
This example creates a new document, defines slug and bleed areas, adds information to the document’s
XMP metadata, sets up master pages, adds page footers, and adds job information to a table in the slug
area. (For the complete script, see DocumentTemplate.)
//Set the application default margin preferences.
with (app.marginPreferences){
//Save the current application default margin preferences.
var myY1 = top;
var myX1 = left;
var myY2 = bottom;
var myX2 = right;
//Set the application default margin preferences.
//Document baseline grid will be based on 14 points, and
//all margins are set in increments of 14 points.
top = 14 * 4 + "pt";
left = 14 * 4 + "pt";
bottom = "74pt";
right = 14 * 5 + "pt";
}
//Make a new document.
var myDocument = app.documents.add();
myDocument.documentPreferences.pageWidth = "7i";
myDocument.documentPreferences.pageHeight = "9i";
myDocument.documentPreferences.pageOrientation = PageOrientation.portrait;
//At this point, we can reset the application default margins to their original state.
with (app.marginPreferences){
top = myY1;
left = myX1;
bottom = myY2;
right = myX2;
}
//Set up the bleed and slug areas.
with(myDocument.documentPreferences){
//Bleed
documentBleedBottomOffset = "3p";
documentBleedTopOffset = "3p";
documentBleedInsideOrLeftOffset = "3p";
documentBleedOutsideOrRightOffset = "3p";
//Slug
CHAPTER 3: DocumentsBasic Page Layout 34
slugBottomOffset = "18p";
slugTopOffset = "3p";
slugInsideOrLeftOffset = "3p";
slugRightOrOutsideOffset = "3p";
}
//Create a color.
try{
myDocument.colors.add({name:"PageNumberRed", model:ColorModel.process,
colorValue:[20, 100, 80, 10]});
}
//Next, set up some default styles.
//Create up a character style for the page numbers.
try{
myDocument.characterStyles.add({name:"page_number"});
}
myDocument.characterStyles.item("page_number").fillColor =
myDocument.colors.item("PageNumberRed");
//Create up a pair of paragraph styles for the page footer text.
//These styles have only basic formatting.
try{
myDocument.paragraphStyles.add({name:"footer_left", pointSize:11, leading:14});
}
//Create up a pair of paragraph styles for the page footer text.
try{
}
}
//Add section marker text--this text will appear in the footer.
myDocument.sections.item(0).marker = "Section 1";
//When you link the master page text frames, one of the frames sometimes becomes
selected. Deselect it.
app.select(NothingEnum.nothing, undefined);
Creating watermarks
You can apply watermarks to documents in InDesign or InDesign Server using scripting. Currently, no user
interface component exists in InDesign for managing watermarks.
A document’s watermark preferences can be set in two ways using scripting:
XApplication-level watermark preferences, if any are set, are applied to the document watermark
preferences for each new document created by InDesign. This setting has no effect on existing
documents.
XDocument-level watermark preferences apply only to that document. Setting or changing a
document’s watermark preferences replaces any previous watermark settings for the document.
Both the document and application watermark preference settings persist after the document or
application is closed until a script changes them.
The same group of watermark preferences exist for both the document and the application objects.
Setting watermark preferences
The following script fragment shows how to set watermarks at the application level. A watermark will be
applied to all documents created after this code finishes. (For the complete script for setting application
preferences, see ApplicationWatermark.)
CHAPTER 3: DocumentsAdjusting Page Sizes and Layout 38
The same preferences can be applied to a document object by referring to a document, rather than to the
application. (For the complete script for setting document preferences, see DocumentWatermark.)
After turning off the application setting for watermarks, InDesign no longer turns on the watermark
settings for new documents by default. However, you can still set watermarks for individual documents.
The following script fragment shows how to turn off application-level watermarks.
Prior to InDesign CS5, pages in a document were limited to a single page size. InDesign CS5 removes this
limitation and allows different page sizes within a single InDesign document. For information on setting
the default page size, see “Defining page size and document length”
You can also apply geometric transformations to individual pages.
Selecting pages
Before changing a page’s size or applying a transformation to the page, you must select the page. In the
InDesign user interface, you do this using the Page Tool on the Tools Panel. You can also select a page
using scripting. The following script shows how. (For the complete script, see PageSelect.)
.
//Given a document with four pages (0, 1, 2, 3)...
var myDocument = app.activeDocument;
var myPages = myDocument.pages;
//Select page 1 and 2.
myPages.item(1).select();
myPages.item(2).select(SelectionOptions.ADD_TO);
//Select last page.
myDocument.select(myPages.item(-1), SelectionOptions.ADD_TO);
CHAPTER 3: DocumentsAdjusting Page Sizes and Layout 39
Resizing and reframing pages
You can resize or reframe page items on a page by scripting. With InDesign CS5, you can also apply the
resize and reframe operations to pages to change their sizes.
NOTE: Your minimum page size is determined by the page’s margins. See “Setting page margins and
columns” for more information.
The following script shows how to change a page’s size using the resize method. (For the complete script,
see PageResize.)
//Given a document with four pages (0, 1, 2, 3)...
var myDocument = app.activeDocument;
var myPages = myDocument.pages;
//Resize page to two times bigger
myPages.item(1).resize(CoordinateSpaces.INNER_COORDINATES,
[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]);
Reframing changes the bounding box of a page, so reframing can be used to change a page’s size by
making the bounding box larger or smaller. The following script shows how to change a page’s size using
the reframe method. (For the complete script, see PageReframe.)
//Given a document with four pages (0, 1, 2, 3)...
var myDocument = app.activeDocument;
var myPages = myDocument.pages;
//Make the page one inch wider and one inch higher.
var myPage = myPages.item(1);
var myBounds = myPage.bounds;
var myY1 = myBounds[0];
var myX1 = myBounds[1];
var myY2 = myBounds[2]+72;
var myX2 = myBounds[3]+72;
myPage.reframe(CoordinateSpaces.INNER_COORDINATES, [[myX1, myY1], [myX2, myY2]]);
Transforming pages
Operations that change the geometry of objects are called transformations. Prior to InDesign CS5, the
transform method could rotate, scale, shear, and move (translate) page items on a page. In InDesign CS5,
the transform method can also be used on pages. For technical details about transformation architecture,
refer to “Transforming Page Items”
To transform a p a g e :
.
1.Create a transformation matrix.
2.Apply the transformation matrix to the page using the transform method.
The following script shows how to transform a page with scripting. (For the complete script, see
PageTransform.)
CHAPTER 3: DocumentsAdjusting Page Sizes and Layout 40
//Given a document with four pages (0, 1, 2, 3)...
var myDocument = app.activeDocument;
var myPages = myDocument.pages;
//Rotate a page around its center point.
var myRotateMatrix =
app.transformationMatrices.add({counterclockwiseRotationAngle:27});
myTransform(myPages.item(0), myRotateMatrix);
//Scale a page around its center point.
var myScaleMatrix = app.transformationMatrices.add({horizontalScaleFactor:0.8,
verticalScaleFactor:0.8});
myTransform(myPages.item(1), myScaleMatrix);
//Shear a page around its center point.
var myShearMatrix = app.transformationMatrices.add({clockwiseShearAngle:30});
myTransform(myPages.item(2), myShearMatrix);
function myTransform(myPage, myTransformationMatrix)
{
Because pages can have multiple sizes, it is possible for a page and its master page to be different sizes. In
addition to tracking which master is applied, pages now also maintain a matrix that determines how the
master page draws on the page. This is called the Master Page Overlay. When you select a page using the
Page Tool on the Tools Panel, you can see how the master page is positioned by checking the Show Master
Page Overlay checkbox on the control panel. You can move the overlay around with the mouse. InDesign
achieves this by applying a transform to the master overlay matrix. Although the user interface allows only
translation (moving x and y), you can do more by scripting. The following script shows how to transform a
master page overlay. (For the complete script, see MasterPageTransform.)
//Given a document with four pages (0, 1, 2, 3)...
var myDocument = app.activeDocument;
var myPages = myDocument.pages;
//Rotate master page overlay around its top-left corner.
var myRotateMatrix =
app.transformationMatrices.add({counterclockwiseRotationAngle:27});
myPages.item(0).masterPageTransform = myRotateMatrix;
//Scale master page overlay around its top-left corner.
var myScaleMatrix = app.transformationMatrices.add({horizontalScaleFactor:0.5,
verticalScaleFactor:0.5});
myPages.item(1).masterPageTransform = myScaleMatrix;
//Shear master page overlay around its top-left corner.
var myShearMatrix =app.transformationMatrices.add({clockwiseShearAngle:30});
myPages.item(2).masterPageTransform = myShearMatrix;
//Translate master page overlay 1 inch right and 2 inches down.
var myTranslateMatrix = app.transformationMatrices.add({horizontalTranslation:72,
verticalTranslation:144});
myPages.item(3).masterPageTransform = myTranslateMatrix;
CHAPTER 3: DocumentsPrinting a Document 41
Printing a Document
The following script prints the active document using the current print preferences. (For the complete
script, see PrintDocument.)
app.activeDocument.print();
Printing using page ranges
To specify a page range to print, set the pageRange property of the document’s print preferences
object before printing, as shown in the following script fragment (from the PrintPageRange tutorial script):
//Prints a page range from the active document.
//Assumes that you have a document open, that it contains a page named "22".
//The page range can be either PageRange.allPages or a page range string.
//A page number entered in the page range must correspond to a page
//name in the document (i.e., not the page index). If the page name is
//not found, InDesign will display an error message.
app.activeDocument.printPreferences.pageRange = "22"
app.activeDocument.print(false);
Setting print preferences
The printpreferences object contains properties corresponding to the options in the panels of the Print
dialog. This following script shows how to set print preferences using scripting. (For the complete script,
see PrintPreferences.)
//PrintPreferences.jsx
//An InDesign CS5 JavaScript
//Sets the print preferences of the active document.
with(app.activeDocument.printPreferences){
//Properties corresponding to the controls in the General panel
//of the Print dialog box. activePrinterPreset is ignored in this
//example--we'll set our own print preferences. printer can be
//either a string (the name of the printer) or Printer.postscriptFile.
printer = Printer.postscriptFile;
//Here's an example of setting the printer to a specific printer.
//printer = "AGFA-SelectSet 5000SF v2013.108";
//If the printer property is the name of a printer, then the ppd property
//is locked (and will return an error if you try to set it).
//ppd = "AGFA-SelectSet5000SF";
//If the printer property is set to Printer.postscript file, the copies
//property is unavailable. Attempting to set it will generate an error.
//copies = 1;
//If the printer property is set to Printer.postscript file, or if the
//selected printer does not support collation, then the collating
//property is unavailable. Attempting to set it will generate an error.
//collating = false;
reverseOrder = false;
//pageRange can be either PageRange.allPages or a page range string.
pageRange = PageRange.allPages;
printSpreads = false;
printMasterPages = false;
//If the printer property is set to Printer.postScript file, then
//the printFile property contains the file path to the output file.
//printFile = "/c/test.ps";
CHAPTER 3: DocumentsPrinting a Document 42
sequence = Sequences.all;
//-----------------------------------------------------------------------//Properties corresponding to the controls in the
//Output panel of the Print dialog box.
//-----------------------------------------------------------------------//negative = true;
//If a device independent PPD is specified, trying to set the colorOutput
//parameter will result in an error.
try{
colorOutput = ColorOutputModes.separations;
//Note the lowercase "i" in "Builtin"
trapping = Trapping.applicationBuiltin;
flip = Flip.none;
}
catch(myError){}
//If trapping is on, attempting to set the following
//properties will generate an error.
try{
}
}
catch(myError){}
//Only change the ink angle and frequency when you want to override the
//screening set by the screening specified by the screening property.
//blackAngle = 45;
//blackFrequency = 175;
//cyanAngle = 15;
//cyanFrequency = 175;
//magentaAngle = 75;
//magentaFreqency = 175;
//yellowAngle = 0;
//yellowFrequency = 175;
//The following properties are not needed (because
//colorOutput is set to separations).
//compositeAngle = 45;
//compositeFrequency = 175;
//simulateOverprint = false;
//If trapping is on, setting the following properties will produce an error.
try{
if(trapping == Trapping.off){
printBlankPages = false;
printGuidesGrids = false;
printNonprinting = false;
}
}
catch(myError){}
//-----------------------------------------------------------------------//Properties corresponding to the controls in the
//Setup panel of the Print dialog box.
//-----------------------------------------------------------------------try{
paperSize = PaperSizes.custom;
//Page width and height are ignored if paperSize is not PaperSizes.custom.
scaleProportional = true;
}
catch(myError){}
//If trapping is on, attempting to set the
//following properties will produce an error.
try{
if(trapping == Trapping.off){
textAsBlack = false;
thumbnails = false;
//The following properties is not needed because
//thumbnails is set to false.
//thumbnailsPerPage = 4;
tile = false;
//The following properties are not needed because tile is set to false.
//tilingOverlap = 12;
//tilingType = TilingTypes.auto;
}
}
catch(myError){}
//-----------------------------------------------------------------------//Properties corresponding to the controls in the Marks and Bleed
//panel of the Print dialog box.
//-----------------------------------------------------------------------//Set the following property to true to print all printer's marks.
//allPrinterMarks = true;
useDocumentBleedToPrint = false;
//If useDocumentBleedToPrint = false then setting
//any of the bleed properties
//will result in an error.
//Get the bleed amounts from the document's bleed and add a bit.
bleedBottom = app.activeDocument.documentPreferences.
documentBleedBottomOffset+3;
bleedTop = app.activeDocument.documentPreferences.documentBleedTopOffset+3;
bleedInside = app.activeDocument.documentPreferences.
documentBleedInsideOrLeftOffset+3;
bleedOutside = app.activeDocument.documentPreferences.
documentBleedOutsideOrRightOffset+3;
//If any bleed area is greater than zero, then export the bleed marks.
if(bleedBottom == 0 && bleedTop == 0 && bleedInside == 0 &&
bleedOutside == 0){
CHAPTER 3: DocumentsExporting a Document as PDF 44
//-----------------------------------------------------------------------//Properties corresponding to the controls in the
//Graphics panel of the Print dialog box.
//-----------------------------------------------------------------------//If a device independent PPD is specified, trying to set the graphics
//send data will result in an error.
try{
postScriptLevel = PostScriptLevels.level3;
}
catch(e){}
//-----------------------------------------------------------------------//Properties corresponding to the controls in the Color Management
//panel of the Print dialog box.
//-----------------------------------------------------------------------//If the useColorManagement property of app.colorSettings is false,
//attempting to set the following properties will return an error.
try{
sourceSpace = SourceSpaces.useDocument;
intent = RenderingIntent.useColorSettings;
crd = ColorRenderingDictionary.useDocument;
profile = Profile.postscriptCMS;
}
catch(e){}
//-----------------------------------------------------------------------//Properties corresponding to the controls in the Advanced
//panel of the Print dialog box.
//-----------------------------------------------------------------------opiImageReplacement = false;
omitBitmaps = false;
omitEPS = false;
omitPDF = false;
//The following line assumes that you have a flattener
//preset named "high quality flattener".
try{
ignoreSpreadOverrides = false;
}
catch(e){}
includeBookmarks = true;
includeHyperlinks = true;
includeICCProfiles = true;
includeSlugWithPDF = false;
includeStructure = false;
interactiveElementsOption = InteractiveElementsOptions.doNotInclude;
//Setting subsetFontsBelow to zero disallows font subsetting;
//set subsetFontsBelow to some other value to use font subsetting.
subsetFontsBelow = 0;
//
//Bitmap compression/sampling/quality options.
colorBitmapCompression = BitmapCompression.zip;
colorBitmapQuality = CompressionQuality.eightBit;
colorBitmapSampling = Sampling.none;
//thresholdToCompressColor is not needed in this example.
//colorBitmapSamplingDPI is not needed when colorBitmapSampling
//is set to none.
grayscaleBitmapCompression = BitmapCompression.zip;
grayscaleBitmapQuality = CompressionQuality.eightBit;
grayscaleBitmapSampling = Sampling.none;
//thresholdToCompressGray is not needed in this example.
//grayscaleBitmapSamplingDPI is not needed when grayscaleBitmapSampling
//is set to none.
monochromeBitmapCompression = BitmapCompression.zip;
monochromeBitmapSampling = Sampling.none;
CHAPTER 3: DocumentsExporting a Document as PDF 46
//thresholdToCompressMonochrome is not needed in this example.
//monochromeBitmapSamplingDPI is not needed when
//monochromeBitmapSampling is set to none.
//
//Other compression options.
compressionType = PDFCompressionType.compressNone;
compressTextAndLineArt = true;
cropImagesToFrames = true;
optimizePDF = true;
//
//Printers marks and prepress options.
//Get the bleed amounts from the document's bleed.
bleedBottom = app.activeDocument.documentPreferences.
documentBleedBottomOffset;
bleedTop = app.activeDocument.documentPreferences.documentBleedTopOffset;
bleedInside = app.activeDocument.documentPreferences.
documentBleedInsideOrLeftOffset;
bleedOutside = app.activeDocument.documentPreferences.
documentBleedOutsideOrRightOffset;
//If any bleed area is greater than zero, then export the bleed marks.
if(bleedBottom == 0 && bleedTop == 0 && bleedInside == 0 &&
bleedOutside == 0){
simulateOverprint = false;
}
catch(e){}
useDocumentBleedWithPDF = true;
//Set viewPDF to true to open the PDF in Acrobat or Adobe Reader.
viewPDF = false;
}
//Now export the document. You'll have to fill in your own file path.
app.activeDocument.exportFile(ExportFormat.pdfType, File("/c/myTestDocument.pdf"),
false);
Exporting a range of pages to PDF
The following script shows how to export a specified page range as PDF. (For the complete script, see
ExportPageRangeAsPDF.)
CHAPTER 3: DocumentsExporting a Document as PDF 47
with(app.pdfExportPreferences){
//pageRange can be either PageRange.allPages or a page range string
//(just as you would enter it in the Print or Export PDF dialog box).
pageRange = "1, 3-6, 7, 9-11, 12";
}
var myPDFExportPreset = app.pdfExportPresets.item("prepress")
app.activeDocument.exportFile(ExportFormat.pdfType, File("/c/myTestDocument.pdf"),
false, myPDFExportPreset);
Exporting individual pages to PDF
The following script exports each page from a document as an individual PDF file. (For the complete script,
see ExportEachPageAsPDF.)
//Display a "choose folder" dialog box.
if(app.documents.length != 0){
var myFolder = Folder.selectDialog ("Choose a Folder");
if(myFolder != null){
myExportPages(myFolder);
}
}
else{
alert("Please open a document and try again.");
}
function myExportPages(myFolder){
var myPageName, myFilePath, myFile;
var myDocument = app.activeDocument;
var myDocumentName = myDocument.name;
var myDialog = app.dialogs.add();
with(myDialog.dialogColumns.add().dialogRows.add()){
staticTexts.add({staticLabel:"Base name:"});
var myBaseNameField = textEditboxes.add({editContents:myDocumentName,
minWidth:160});
}
var myResult = myDialog.show({name:"ExportPages"});
if(myResult == true){
myPageName = myDocument.pages.item(myCounter).name;
app.pdfExportPreferences.pageRange = myPageName;
//The name of the exported files will be the base name + the
//page name + ".pdf".
//If the page name contains a colon (as it will if the
//document contains sections),
//then remove the colon.
var myRegExp = new RegExp(":","gi");
myPageName = myPageName.replace(myRegExp, "_");
myFilePath = myFolder + "/" + myBaseName + "_" + myPageName + ".pdf";
myFile = new File(myFilePath);
myDocument.exportFile(ExportFormat.pdfType, myFile, false);
}
}
else{
myDialog.destroy();
}
}
CHAPTER 3: DocumentsExporting Pages as EPS 48
Exporting PDF with Interactive Features
The following script shows how to export a document with interactive features as a PDF. (For the complete
script, see ExportInteractivePDF.)
When you export a document as EPS, InDesign saves each page of the file as a separate EPS graphic (an
EPS, by definition, can contain only a single page). If you export more than a single page, InDesign
appends the index of the page to the filename. The index of the page in the document is not necessarily
the name of the page (as defined by the section options for the section containing the page).
Exporting all pages to EPS
The following script exports the pages of the active document to one or more EPS files. (For the complete
script, see ExportAsEPS.)
var myFile = new File("/c/myTestFile.eps");
app.activeDocument.exportFile(ExportFormat.epsType, myFile, false);
Exporting a range of pages to EPS
To control which pages are exported as EPS, set the page range property of the EPS export preferences to
a page-range string containing the page or pages you want to export, before exporting. (For the complete
script, see ExportPageRangeAsEPS.)
//Enter the name of the page you want to export in the following line.
//Note that the page name is not necessarily the index of the page in the
//document (e.g., the first page of a document whose page numbering starts
//with page 21 will be "21", not 1).
app.epsExportPreferences.pageRange = "1-3, 6, 9";
var myFile = new File("/c/myTestFile.eps");
app.activeDocument.exportFile(ExportFormat.epsType, myFile, false);
CHAPTER 3: DocumentsExporting Pages as EPS 49
Exporting as EPS with file naming
The following script exports each page as an EPS, but it offers more control over file naming than the
earlier example. (For the complete script, see ExportEachPageAsEPS.)
//Display a "choose folder" dialog box.
if(app.documents.length != 0){
var myFolder = Folder.selectDialog ("Choose a Folder");
if(myFolder != null){
myExportPages(myFolder);
}
}
else{
alert("Please open a document and try again.");
}
function myExportPages(myFolder){
var myFilePath, myPageName, myFile;
var myDocument = app.activeDocument;
var myDocumentName = myDocument.name;
var myDialog = app.dialogs.add({name:"ExportPages"});
with(myDialog.dialogColumns.add().dialogRows.add()){
staticTexts.add({staticLabel:"Base name:"});
var myBaseNameField = textEditboxes.add({editContents:myDocumentName,
minWidth:160});
}
var myResult = myDialog.show();
if(myResult == true){
//The name of the exported files will be the base name +
//the page name + ".eps".
var myBaseName = myBaseNameField.editContents;
//Remove the dialog box from memory.
myDialog.destroy();
//Generate a file path from the folder name, the base document name,
myPageName = myDocument.pages.item(myCounter).name;
app.epsExportPreferences.pageRange = myPageName;
//The name of the exported files will be the base name +
//the page name + ".eps".
//If the page name contains a colon (as it will if the
//document contains sections),
//then remove the colon.
var myRegExp = new RegExp(":","gi");
myPageName = myPageName.replace(myRegExp, "_");
myFilePath = myFolder + "/" + myBaseName + "_" + myPageName + ".eps";
myFile = new File(myFilePath);
app.activeDocument.exportFile(ExportFormat.epsType, myFile, false);
}
}
else{
myDialog.destroy();
}
}
4
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.
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.
This chapter covers scripting techniques related to layers in an InDesign layout and discusses common
operations involving layers.
Understanding the Layer Object Model
The following figure shows the layer object model. Note the following about the diagram:
XIt focuses on the location of a layer and its contents in the context of the object hierarchy of a
document; it does not attempt to show all the other ways a script might work with the content of a
layer (e.g., you can get a reference to a text-frame object from a story, text object, page, or spread, in
addition to finding it inside a layer object).
XIt uses the JavaScript form of the object names; however, the object hierarchy is the same in all
scripting languages.
XThe basic properties of a layer are shown in the column at the left of the figure; the objects that may
be contained by the layer object, at the right.
It is important to note the distinction between the page-items collection and the allPageItems
collection. The former is a collection containing only the top-level page items in a layer. If a page item is
inside a group, for example, it will not appear in the
collection is a flattened collection of all page items assigned to the layer, regardless of their location in the
object hierarchy. A page item inside a group on the layer would appear in the
Similarly, the
regardless of their location in the object hierarchy.
allGraphics property contains all graphics stored in page items assigned to the layer,
pageItems collection. In contrast, the allPageItems
allPageItems collection.
50
CHAPTER 4: Working with LayersScripting Layers 51
Scripting Layers
In InDesign’s user interface, you add, delete, rearrange, duplicate, and merge layers using the Layers panel.
You also can change the layer to which a selected page item is assigned by dragging and dropping the
layer proxy in the Layers panel. (For more on assigning objects to a layer, see the InDesign online help.)
This section shows how to accomplish these tasks using InDesign scripting.
Creating layers
The following script fragment shows how to create a new layer. (For the complete script, see AddLayer.)
//Given a document "myDocument"...
var myLayer = myDocument.layers.add();
When you create a new layer, the layer appears above all other layers in the document.
Referring to layers
InDesign scripting offers several ways to refer to a layer object. This section describes the most common
ways to refer to layers.
CHAPTER 4: Working with LayersScripting Layers 52
Getting the active layer
The active layer is the layer on which new objects are created. You can get the active layer using scripting,
as shown in the following script fragment. (For the complete script, see ActiveLayer.)
//Given a document "myDocument"...
var myDocument = app.documents.item(0);
var myLayer = myDocument.activeLayer;
Referring to layers by layer index
You can get a reference to a layer using the index of the layer in the layers collection of a document. The
script fragment below uses the layer index to iterate through layers. (For the complete script, see
HideOtherLayers.)
//Given a document "myDocument"...
var myTargetLayer = myDocument.activeLayer;
for(var myCounter = 0; myCounter < myDocument.layers.length; myCounter++){
//If the layer is not the target layer, hide it.
if(myDocument.layers.item(myCounter).name != myTargetLayer.name){
Note that you can use negative numbers to refer to the layers in the layers collection of a document. Layer
-1 refers to the last (bottom) layer in the collection.
Referring to layers by layer name
You also can get a reference to a layer using the name of the layer, as shown in the following script
fragment. (For the complete script, see LayerName.)
var myLayer = app.documents.item(0).layers.item("Text Layer");
Using relative references
Given a layer, you can refer to the layer above using the previousItem method, or refer to the layer below
using the
RelativeLayerReferences.) Both methods take a reference layer as a parameter.
//Given a document "myDocument"...
var myLayer = myDocument.layers.item(4);
myDocument.activeLayer = myLayer;
var myNextLayer = myDocument.layers.nextItem(myLayer);
var myPreviousLayer = myDocument.layers.previousItem(myLayer);
var myString = "The layer below the target layer is " + myNextLayer.name + "\r";
myString += "The layer above the target layer is " + myPreviousLayer.name;
alert(myString);
nextItem method, as shown in the following script fragment. (For the complete script, see
The previousItem and nextItem methods return an invalid layer reference if the specified (next or
previous) layer does not exist, rather than generating an error.
CHAPTER 4: Working with LayersScripting Layers 53
Referring to ranges of layers
To refer to a series of layers, you can use the itemByRange method. The following script fragment shows
how to get a reference to a range of layers, then set a property on all layers in the range. (For the complete
script, see HideLayersAbove.)
//Given a document "myDocument"...
var myLayer = myDocument.layers.item(4);
myDocument.activeLayer = myLayer;
//Now hide all of the layers above the current layer.
var myLayers = myDocument.layers.itemByRange(0, myLayer.index -1);
//Even though the result contains multiple layers, you can
//set a property on all of the layers without iterating.
myLayers.visible = false;
Deleting layers
Use the remove method to delete a layer from a specific document, as shown in the following script
fragment. (For the complete script, see DeleteLayer.) You cannot delete the last remaining layer in a
document.
//Given a document "myDocument" containing a layer named "Delete This Layer"...
var myLayer = myDocument.layers.item("Delete This Layer");
myLayer.remove();
Moving layers
Use the move method to change the stacking order of layers in a document, as shown in the following
script fragment. (For the complete script, see MoveLayer.)
//Given a document "myDocument" containing at least two layers...
var myLayerA = myDocument.layers.item(0);
var myLayerB = myDocument.layers.item(1);
myLayerA.move(LocationOptions.AFTER, myLayerB);
Duplicating layers
Use the duplicate method to create a copy of a layer, as shown in the following script fragment. (For the
complete script, see DuplicateLayer.)
//Given a layer "myLayer"...
ar myNewLayer = myLayer.duplicate();
Merging layers
The following script fragment shows how to merge two or more layers, including the page items assigned
to them, into a single layer. (For the complete script, see MergeLayers.)
//Given the layers "myLayer1" and "myLayer2"...
myLayer1.merge(myLayer2);
CHAPTER 4: Working with LayersScripting Layers 54
Assigning page items to layers
You can assign a page item to a layer by either referring to the layer when you create the page item (the
add method of all page items can take a layer as a parameter) or setting the itemLayer property of an
existing page item. The following script fragment shows how to assign a page item to a layer using both
techniques. (For the complete script, see AssignPageItemsToLayers.)
//Given a reference to a page "myPage," and a document "myDocument,"
//create a text frame on a layer named "TextFrames"
var myTextFrame = myPage.textFrames.add(myDocument.layers.item("TextFrames"));
myTextFrame.geometricBounds = [72, 72, 144, 144];
//Create a rectangle on the current target layer.
var myRectangle = myPage.rectangles.add({geometricBounds:[72, 144, 144, 216]});
//Move the rectangle to a specific layer.
myRectangle.itemLayer = myDocument.layers.item("Rectangles");
//Create a series of ovals.
for(var myCounter = 72; myCounter < 172; myCounter+=10){
}
//Move all of the ovals on the page to a specific layer.
myPage.ovals.everyItem().itemLayer = myDocument.layers.item("Ovals");
Setting layer properties
Layer properties control the layer name, color, visibility, and other attributes of a layer. This section shows
how to work with layer properties.
Setting basic layer properties
Basic layer properties include the name of the layer, the highlight color of the layer, the visibility of the
layer, and whether text objects on the layer ignore text-wrap settings. The following script fragment shows
how to set these basic properties of a layer. (For the complete script, see BasicLayerProperties.)
//Given a document "myDocument"...
var myLayer = myDocument.layers.add();
myLayer.name = "myLayer";
myLayer.layerColor = UIColors.CHARCOAL;
myLayer.ignoreWrap = false;
myLayer.visible = true;
Working with layer guides
Guides can be assigned to a specific layer, just like page items. You can choose to show or hide the guides
for a layer, and you can lock or unlock the guides on a layer. The following script fragment shows how to
work with the guides on a layer. (For the complete script, see LayerGuides.)
//Given a document "myDocument" and a page "myPage" containing at least one guide...
//Create a new layer.
var myLayer = myDocument.layers.add();
//Move all of the guides on the page to the new layer.
myPage.guides.everyItem().itemLayer = myLayer;
myLayer.lockGuides = true;
myLayer.showGuides = true;
CHAPTER 4: Working with LayersScripting Layers 55
Controlling layer printing and visibility
You can control the printing and visibility of objects on a layer, as shown in the following script fragment.
(For the complete script, see LayerControl.)
//Given a document "myDocument" containing layers named "Background,"
//"Language A,", "Language B," and "Language C," export the "Background"
//layer and each "Language" layer to PDF as separate PDF files...
var myVersion, myLanguageCounter, myFileName;
var myFolder = Folder.desktop;
for(var myCounter = 0; myCounter < 3; myCounter ++){
Layers can be locked, which means the page items on the layers cannot be edited. The following script
fragment shows how to lock and unlock layers. (For the complete script, see LockLayersBelow.)
//Given a document "myDocument"...
var myTargetLayer = myDocument.activeLayer;
var myLayers = myDocument.layers.itemByRange(myDocument.layers.length-1,
myTargetLayer.index +1);
myLayers.locked = true;
5
Working with Page Items
This chapter covers scripting techniques related to the page items (rectangles, ellipses, graphic lines,
polygons, text frames, buttons, and groups) that can appear in an InDesign layout.
This document discusses the following:
XCreating page items.
XPage item geometry.
XWorking with paths and path points
XCreating groups.
XDuplicating and moving page items.
XTransforming page items.
Creating Page Items
Page items in an InDesign layout are arranged in a hierarchy, and appear within a container object of some
sort. Spreads, pages, other page items, groups, and text characters are all examples of objects that can
contain page items. This hierarchy of containers in the InDesign scripting object model is the same as in
the InDesign user interface--when you create a rectangle by dragging the Rectangle tool on a page, you
are specifying that the page is the container, or parent, of the rectangle. When you paste an ellipse into a
polygon, you are specifying that the polygon is the parent of the ellipse, which, in turn, is a child object of
its parent, a page.
In general, creating a new page item is as simple as telling the object you want to contain the page item to
create the page item, as shown in the MakeRectangle script.
//Given a page "myPage", create a new rectangle at the default size and location...
var myRectangle = myPage.rectangles.add();
In the above script, a new rectangle is created on the first page of a new document. The rectangle appears
at the default location (near the upper left corner of the page) and has a default size (around ten points
square). Moving the rectangle and changing its dimensions are both accomplished by filling its geometric
bounds property with new values, as shown in the MakeRectangleWithProperties script.
//Given a page "myPage", create a new rectangle and specify its size and location...
var myRectangle = myPage.rectangles.add({geometricBounds:[72, 72, 144, 144]});
Page item types
It is important to note that you cannot create a “generic” page item--you have to create a page item of a
specific type (a rectangle, oval, graphic line, polygon, text frame, or button). You will also notice that
InDesign changes the type of a page item as the geometry of the page item changes. A rectangle, for
example, is always made up of a single, closed path containing four path points and having 90 degree
interior angles. Change the location of a single point, however, or add another path, and the type of the
page item changes to a polygon. Open the path and remove two of the four points, and InDesign will
56
CHAPTER 5: Working with Page ItemsCreating Page Items 57
change the type to a graphic line. The only things that define the type of a rectangle, ellipse, graphic line,
or polygon are:
XThe number of paths in the object. Any page item with more than one path is a polygon.
XThe number and location of points on the first path in the object.
To determine the type of a page item, use this example:
var myPageItemType = myPageItem.constructor.name;
The result of the above will be a string containing the type of the page item.
Getting the type of a page item
When you have a reference to a generic page item, and want to find out what type of a page item it is, use
constructor.name to get the specific type.
//Given a generic page item "myPageItem"...
var myType = myPageItem.constructor.name;
alert(myType);
Referring to page items
When you refer to page items inside a given container (a document, layer, page, spread, group, text frame,
or page item), you use the
top level page items inside the object. For example:
var myPageItems = app.documents.item(0).pages.item(0).pageItems;
The resulting collection (myPageItems) does not include objects inside groups (though it does include the
group), objects inside other page items (thought it does contain the parent page item), or page items in
text frames. To get a reference to all of the items in a given container, including items nested inside other
page items, use the
var myAllPageItems = app.documents.item(0).pages.item(0).pageItems;
The resulting collection (myAllPageItems) includes all objects on the page, regardless of their position in
the hierarchy.
Another way to refer to page items is to use their label property, much as you can use the name property
of other objects (such as paragraph styles or layers). In the following examples, we will get an array of page
items whose label has been set to
var myPageItems = app.documents.item(0).pages.item(0).pageItems("myLabel");
If no page items on the page have the specified label, InDesign returns an empty array.
pageItems collection of the container object. This gives you a collection of the
allPageItems property.
myLabel.
Page-item geometry
If you are working with page items, it is almost impossible to do anything without understanding the way
that rulers and measurements work together to specify the location and shape of an InDesign page item. If
you use the Control panel in InDesign’s user interface, you probably are already familiar with InDesign’s
geometry, but here is a quick summary:
XObject are constructed relative to the coordinates shown on the rulers.
CHAPTER 5: Working with Page ItemsCreating Page Items 58
X
Changing the zero point location by either dragging the zero point or by changing the ruler origin
changes the coordinates on the rulers.
XPage items are made up of one or more paths, which, in turn, are made up of two or more path points.
Paths can be open or closed.
XPath points contain an anchor point (the location of the point itself) and two control handles (left
direction, which controls the curve of the line segment preceding the point on the path; and right
direction, which controls the curve of the segment following the point). Each of these properties
contains an array in the form (
x, y) (where x is the horizontal location of the point, and y is the vertical
location). This array holds the location, in current ruler coordinates, of the point or control handle.
All of the above means that if your scripts need to construct page items, you also need to control the
location of the zero point, and you may want to set the measurement units in use.
Working with paths and path points
For most simple page items, you do not need to worry about the paths and path points that define the
shape of the object. Rectangles, ellipses, and text frames can be created by specifying their geometric
bounds, as we did in the earlier example in this chapter.
In some cases, however, you may want to construct or change the shape of a path by specifying path point
locations, you can either set the anchor point, left direction, and right direction of each path point on the
path individually (as shown in the DrawRegularPolygon_Slow script), or you can use the entirePath
property of the path to set all of the path point locations at once (as shown in the
DrawRegularPolygon_Fast script). The latter approach is much faster.
The items in the array you use for the entirePath property can contain anchor points only, or a anchor
points and control handles. Here is an example array containing only anchor point locations:
[[x1, y1], [x2, y2], ...]
Where x and y specify the location of the anchor.
Here is an example containing fully-specified path points (i.e., arrays containing the left direction, anchor,
and right direction, in that order):
Note that the original path does not have to have the same number of points as you specify in the
array—InDesign will add or subtract points from the path as it applies the array to the entirePath property.
The AddPathPoint script shows how to add path points to a path without using the entirePath property.
//Given a graphic line "myGraphicLine"...
var myPathPoint = myGraphicLine.paths.item(0).pathPoints.add();
//Move the path point to a specific location.
myPathPoint.anchor = [144, 144];
The DeletePathPoint script shows how to delete a path point from a path.
CHAPTER 5: Working with Page ItemsGrouping Page Items 59
//Given a polygon "myPolygon", remove the
//last path point in the first path.
myPolygon.paths.item(0).pathPoints.item(-1).remove();
Grouping Page Items
In the InDesign user interface, you create groups of page items by selecting them and then choosing
Group from the Object menu (or by pressing the corresponding keyboard shortcut). In InDesign scripting,
you tell the object containing the page items you want to group (usually a page or spread) to group the
page items, as shown in the Group script.
//Given a page "myPage" containing at least two ovals and two rectangles...
var myArray = new Array;
//Add the items to the array.
myArray.push(myPage.rectangles.item(0));
myArray.push(myPage.ovals.item(0));
myArray.push(myPage.rectangles.item(1));
myArray.push(myPage.ovals.item(1));
//Group the items.
myPage.groups.add(myArray);
To ungroup, you tell the group itself to ungroup, as shown in the Ungroup script.
//Given a group "myGroup"...
myPageItems = myGroup.ungroup();
There is no need to ungroup a group to change the shape, formatting, or content of the page items in the
group. Instead, simply get a reference to the page item you want to change, just as you would with any
other page item.
Duplicating and Moving Page Items
In the InDesign user interface, you can move page items by selecting them and dragging them to a new
location. You can also create copies of page items by copying and pasting, by holding down Option/Alt as
you drag an object, or by choosing Duplicate, Paste In Place, or Step and Repeat from the Edit menu. In
InDesign scripting, you can use the move method to change the location of page items, and the duplicate
method to create a copy of a page item (and, optionally, move it to another location).
The move method can take one of two optional parameters: moveTo and moveBy. Both parameters
consist of an array of two measurement units, consisting of a horizontal value and a vertical value. moveTo
specifies an absolute move to the location specified by the array, relative to the current location of the zero
point. moveBy specifies how far to move the page item relative to the current location of the page item
itself. The Move script shows the difference between these two approaches.
//Given a reference to a rectangle "myRectangle"...
//Move the rectangle to the location (12, 12).
//Absolute move:
myRectangle.move([12, 12]);
//Move the rectangle *by* 12 points horizontally, 12 points vertically.
//Relative move (note undefined first parameter):
myRectangle.move(undefined, [12, 12]);
//Move the rectangle to another page (rectangle appears at (0,0);
var myPage = app.documents.item(0).pages.add();
myRectangle.move(myPage);
//To move a page item to another document, use the duplicate method.
CHAPTER 5: Working with Page ItemsDuplicating and Moving Page Items 60
Note that the move method truly moves the object—when you move a page item to another document, it
is deleted from the original document. To move the object to another while retaining the original, use the
duplicate method (see below).
Use the duplicate method to create a copy of a page item. By default, the duplicate method creates a
“clone” of an object in the same location as the original object. Optional parameters can be used with the
duplicate method to move the duplicated object to a new location (including other pages in the same
document, or to another document entirely).
//Given a reference to a rectangle "myRectangle"...
//Duplicate the rectangle and move the
//duplicate to the location (12, 12).
//Absolute move:
var myDuplicate = myRectangle.duplicate([12, 12]);
//Duplicate the rectangle and move the duplicate *by* 12
//points horizontally, 12 points vertically.
//Relative move (note undefined first parameter):
var myDuplicate = myRectangle.duplicate(undefined, [12, 12]);
//Duplicate the rectangle to another page (rectangle appears at (0,0).
var myPage = app.documents.item(0).pages.add();
var myDuplicate = myRectangle.duplicate(myPage);
//Duplicate the rectangle to another document.
var myDocument = app.documents.add();
var myDuplicate = myRectangle.duplicate(myDocument.pages.item(0));
You can also use copy and paste in InDesign scripting, but scripts using on these methods require that you
select objects (to copy) and rely on the current view to set the location of the pasted elements (when you
paste). This means that scripts that use copy and paste tend to be more fragile (i.e., more likely to fail) than
scripts that use duplicate and move. Whenever possible, try to write scripts that do not depend on the
current view or selection state.
Creating compound paths
InDesign can combine the paths of two or more page items into a single page item containing multiple
paths using the Object > Paths > Make Compound Path menu option. You can do this in InDesign scripting
using the makeCompoundPath method of a page item, as shown in the following script fragment (for the
complete script, refer to the MakeCompoundPath script).
//Given a rectangle "myRectangle" and an Oval "myOval"...
myRectangle.makeCompoundPath(myOval);
When you create a compound path, regardless of the types of the objects used to create the compound
path, the type of the resulting object is polygon.
To release a compound path and convert each path in the compound path into a separate page item, use
the releaseCompoundPath method of a page item, as shown in the following script fragment (for the
complete script, refer to the ReleaseCompoundPath script).
//Given a polygon "myPolygon"...
var myPageItems = myPolygon.releaseCompoundPath();
Using Pathfinder operations
The InDesign Pathfinder features offer ways to work with relationships between page items on an
InDesign page. You can merge the paths of page items, or subtract the area of one page item from another
page item, or create a new page item from the area of intersection of two or more page items. Every page
CHAPTER 5: Working with Page ItemsDuplicating and Moving Page Items 61
item supports the following methods related to the Pathfinder features: AddPath, ExcludeOverlapPath,
IntersectPath, MinusBack, and SubtractPath.
All of the Pathfinder methods work the same way--you provide an array of page items to use as the basis
for the operation (just as you select a series of page items before choosing the Pathfinder operation in the
user interface).
Note that it is very likely that the type of the object will change after you apply one of the Pathfinder
operations. Which object type it will change to depends on the number and location of the points in the
path or paths resulting from the operation.
To merge two page items into a single page item, for example, you would use something like the approach
shown in the following fragment (for the complete script, refer to AddPath).
//Given a rectangle "myRectangle" and an Oval "myOval"...
myRectangle.addPath(myOval);
The excludeOverlapPath method creates a new path based on the non-intersecting areas of two or more
overlapping page items, as shown in the following script fragment (for the complete script, refer to
ExcludeOverlapPath).
//Given a rectangle "myRectangle" and an Oval "myOval"...
myRectangle.excludeOverlapPath(myOval);
The intersectPath method creates a new page item from the area of intersection of two or more page
items, as shown in the following script fragment (for the complete script, refer to IntersectPath).
//Given a rectangle "myRectangle" and an Oval "myOval"...
myRectangle.intersect(myOval);
The minusBack method removes the area of intersection of the back-most object from the page item or
page items in front of it, as shown in the following script fragment (for the complete script, refer to
MinusBack).
//Given a rectangle "myRectangle" and an Oval "myOval"...
myRectangle.minusBack(myOval);
The subtractPath method removes the area of intersection of the frontmost object from the page item or
page items behind it, as shown in the following script fragment (for the complete script, refer to
SubtractPath).
//Given a rectangle "myRectangle" and an Oval "myOval"...
myOval.subtractPath(myRetangle);
Converting page-item shapes
InDesign page items can be converted to other shapes using the options in the Object > Convert Shape
menu or the Pathfinder panel (Window > Object and Layout > Pathfinder). In InDesign scripting, page
items support the convertShape method, as demonstrated in the following script fragment (for the
complete script, refer to ConvertShape).
//Given a rectangle "myRectangle"...
myRectangle.convertShape(ConvertShapeOptions.convertToRoundedRectangle);
The convertShape method also provides a way to open or close reverse paths, as shown in the following
script fragment (for the complete script, refer to OpenPath).
CHAPTER 5: Working with Page ItemsTransforming Page Items 62
//Given a rectangle "myRectangle"...
myRectangle.convertShape(ConvertShapeOptions.convertToOpenPath);
Arranging page items
Page items in an InDesign layout can be arranged in front of or behind each other by adjusting their
stacking order within a layer, or can be placed on different layers. The following script fragment shows how
to bring objects to the front or back of their layer, and how to control the stacking order of objects relative
to each other (for the complete script, refer to StackingOrder).
//Given a rectangle "myRectangle" and an oval "myOval",
//where "myOval" is in front of "myRectangle", bring
//the rectangle to the front...
myRectangle.bringToFront();
When you create a page item, you can specify its layer, but you can also move a page item from one layer
to another. The item layeritemLayerItemLayer property of the page item is the key to doing this, as shown
in the following script fragment (for the complete script, refer to ItemLayer).
//Given a rectangle "myRectangle" and a layer "myLayer",
//send the rectangle to the layer...
myRectangle.itemLayer = app.Documents.item(0).layers.item("myLayer");
The stacking order of layers in a document can also be changed using the move move method of the layer
itself, as shown in the following script fragment (for the complete script, refer to MoveLayer).
//Given a layer "myLayer", move the layer behind
//the default layer (the lowest layer in the document
//is layers.item(-1).
myLayer.move(LocationOptionsafter, app.documents.item(0).layers.item(-1));
Transforming Page Items
Transformations include scaling, rotation, shearing (skewing), and movement (or translation). In scripting,
you apply transformations using the
shear methods used in versions of InDesign prior to InDesign CS3 (5.0).
and
Using the transform method
The transform method requires a transformation matrix (transformationMatrix) object that defines
the transformation or series of transformations to apply to the object. A transformation matrix can contain
any combination of scale, rotate, shear, or translate operations.
The order in which transformations are applied to an object is important. Applying transformations in
differing orders can produce very different results.
To transform an object, you follow two steps:
transform method. This one method replaces the resize, rotate,
1.Create a transformation matrix.
2.Apply the transformation matrix to the object using the transform method. When you do this, you
also specify the coordinate system in which the transformation is to take place. For more on
coordinate systems, see “Coordinate spaces” on page 65
. In addition, you specify the center of
transformation, or transformation origin. For more on specifying the transformation origin, see
“Transformation origin” on page 66
.
CHAPTER 5: Working with Page ItemsTransforming Page Items 63
The following scripting example demonstrates the basic process of transforming a page item. (For the
complete script, see TransformExamples.)
//Rotate a rectangle "myRectangle" around its center point.
var myRotateMatrix =
app.transformationMatrices.add({counterclockwiseRotationAngle:27});
myRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myRotateMatrix);
//Scale a rectangle "myRectangle" around its center point.
var myScaleMatrix = app.transformationMatrices.add({horizontalScaleFactor:.5,
verticalScaleFactor:.5});
myRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myScaleMatrix);
//Shear a rectangle "myRectangle" around its center point.
var myShearMatrix =app.transformationMatrices.add({clockwiseShearAngle:30});
myRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myShearMatrix);
//Rotate a rectangle "myRectangle" around a specified ruler point ([72, 72]).
var myRotateMatrix =
app.transformationMatrices.add({counterclockwiseRotationAngle:27});
myRectangle.transform(CoordinateSpaces.pasteboardCoordinates, [[72, 72],
AnchorPoint.topLeftAnchor], myRotateMatrix, undefined, true);
//Scale a rectangle "myRectangle" around a specified ruler point ([72, 72]).
var myScaleMatrix = app.transformationMatrices.add({horizontalScaleFactor:.5,
verticalScaleFactor:.5});
myRectangle.transform(CoordinateSpaces.pasteboardCoordinates, [[72, 72],
AnchorPoint.topLeftAnchor], myScaleMatrix, undefined, true);
For a script that “wraps” transformation routines in a series of easy-to-use functions, refer to the Transform
script.
Working with transformation matrices
A transformation matrix cannot be changed once it has been created, but a variety of methods can
interact with the transformation matrix to create a new transformation matrix based on the existing
transformation matrix. In the following examples, we show how to apply transformations to a
transformation matrix and replace the original matrix. (For the complete script, see TransformMatrix.)
//Scale a transformation matrix by 50% in both horizontal and vertical dimensions.
var myTransformationMatrix = myTransformationMatrix.scaleMatrix(.5, .5);
//Rotate a transformation matrix by 45 degrees.
myTransformationMatrix = myTransformationMatrix.rotateMatrix(45);
//Shear a transformation matrix by 15 degrees.
myTransformationMatrix = myTransformationMatrix.shearMatrix(15);
When you use the rotateMatrix method, you can use a sine or cosine value to transform the matrix,
rather than an angle in degrees, as shown in the RotateMatrix script.
//The following statements are equivalent
//(0.25881904510252 is the sine of 15 degrees; 0.96592582628907, the cosine).
myTransformationMatrix = myTransformationMatrix.rotateMatrix(15);
myTransformationMatrix = myTransformationMatrix.rotateMatrix(undefined,
When you use the shearMatrixmethod, you can provide a slope, rather than an angle in degrees, as
shown in the ShearMatrix script.
CHAPTER 5: Working with Page ItemsTransforming Page Items 64
//The following statements are equivalent. slope = rise/run--so
//the slope of 45 degrees is 1.
myTransformationMatrix = myTransformationMatrix.shearMatrix(45);
myTransformationMatrix = myTransformationMatrix.shearMatrix(undefined, 1);
You can get the inverse of a transformation matrix using the invertMatrixmethod, as shown in the
following example. (For the complete script, see InvertMatrix.) You can use the inverted transformation
matrix to undo the effect of the matrix.
var myRectangle = app.documents.item(0).pages.item(0).rectangles.item(0);
var myTransformationMatrix =
app.transformationMatrices.add({counterclockwiseRotationAngle:30,
horizontalTranslation:12, verticalTranslation:12});
myRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrix);
var myNewRectangle = myRectangle.duplicate();
//Move the duplicated rectangle to the location of the original
//rectangle by inverting, then applying the transformation matrix.
myTransformationMatrix = myTransformationMatrix.invertMatrix();
myRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrix);
You can add transformation matrices using the catenateMatrixmethod, as shown in the following
example. (For the complete script, see CatenateMatrix.)
var myTransformationMatrixA =
app.transformationMatrices.add({counterclockwiseRotationAngle:30});
var myTransformationMatrixB =
app.transformationMatrices.add({horizontalTranslation:12, verticalTranslation:12});
var myRectangle = app.documents.item(0).pages.item(0).rectangles.item(-1);
var myNewRectangle = myRectangle.duplicate();
//Rotate the duplicated rectangle.
myNewRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrixA);
myNewRectangle = myRectangle.duplicate();
//Move the duplicate (unrotated) rectangle.
myNewRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrixB);
//Merge the two transformation matrices.
myTransformationMatrix =
myTransformationMatrixA.catenateMatrix(myTransformationMatrixB);
myNewRectangle = myRectangle.duplicate();
//The duplicated rectangle will be both moved and rotated.
myNewRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrix);
When an object is transformed, you can get the transformation matrix that was applied to it, using the
transformValuesOf method, as shown in the following script fragment. (For the complete script, see
TransformValues Of.)
CHAPTER 5: Working with Page ItemsTransforming Page Items 65
//Note that transformValuesOf() always returns an array
//containing a single transformationMatrix.
var myTransformArray =
myRectangle.transformValuesOf(CoordinateSpaces.parentCoordinates);
var myTransformationMatrix = myTransformArray[0];
var myRotationAngle = myTransformationMatrix.counterclockwiseRotationAngle;
var myShearAngle = myTransformationMatrix.clockwiseShearAngle;
var myXScale = myTransformationMatrix.horizontalScaleFactor;
var myYScale = myTransformationMatrix.verticalScaleFactor;
var myXTranslate = myTransformationMatrix.horizontalTranslation;
var myYTranslate = myTransformationMatrix.verticalTranslation;
var myString = "Rotation Angle: " + myRotationAngle + "\r";
myString += "Shear Angle: " + myShearAngle + "\r";
myString += "Horizontal Scale Factor: " + myXScale + "\r";
myString += "Vertical Scale Factor: " + myYScale + "\r";
myString += "Horizontal Translation: " + myXTranslate + "\r";
myString += "Vertical Translation: " + myYTranslate + "\r";
alert(myString);
NOTE: The values in the horizontal- and vertical-translation fields of the transformation matrix returned by
this method are the location of the upper-left anchor of the object, in pasteboard coordinates.
Coordinate spaces
In the transformation scripts we presented earlier, you might have noticed the
CoordinateSpaces.pasteboardCoordinates enumeration provided as a parameter for the transform
method. This parameter determines the system of coordinates, or coordinate space, in which the transform
operation occurs. The coordinate space can be one of the following values:
XCoordinateSpaces.pasteboardCoordinates is the coordinate space of the entire InDesign
document. This coordinate space extends behind all spreads in a document. It does not correspond to
InDesign’s rulers or zero point, nor does it have anything to do with the pasteboard area you can see
around pages in the InDesign user interface. Transformations applied to objects have no effect on this
coordinate space (e.g., the angle of the horizontal and vertical axes do not change).
XCoordinateSpaces.parentCoordinates is the coordinate space of the parent of the object. Any
transformations applied to the parent affect the parent coordinates; for example, rotating the parent
object changes the angle of the horizontal and vertical axes of this coordinate space. In this case, the
parent object refers to the group or page item containing the object; if the parent of the object is a
page or spread, parent coordinates are the same as spread coordinates.
XCoordinateSpaces.innerCoordinates is the coordinate space in which the object itself was
created.
XCoordinateSpaces.spreadCoordinates is the coordinate space of the spread. The origin of this
space is at the center of the spread, and does not correspond to the rulers you see in the user interface.
The following script shows the differences between the coordinate spaces. (For the complete script, see
CoordinateSpaces.)
CHAPTER 5: Working with Page ItemsTransforming Page Items 66
var myRectangle =
app.documents.item(0).pages.item(0).groups.item(-1).rectangles.item(0);
alert("The page contains a group which has been\rrotated 45 degrees
(counterclockwise).\rThe rectangle inside the group was\rrotated 45 degrees
counterclockwise\rbefore it was added to the group.\r\rWatch as we apply a series of
scaling\roperations in different coordinate spaces.");
var myTransformationMatrix =
app.transformationMatrices.add({horizontalScaleFactor:2});
//Transform the rectangle using inner coordinates.
myRectangle.transform(CoordinateSpaces.innerCoordinates, AnchorPoint.centerAnchor,
myTransformationMatrix);
//Select the rectangle and display an alert.
app.select(myRectangle);
alert("Transformed by inner coordinates.");
//Undo the transformation.
app.documents.item(0).undo();
//Transform using parent coordinates.
myRectangle.transform(CoordinateSpaces.parentCoordinates, AnchorPoint.centerAnchor,
myTransformationMatrix);
app.select(myRectangle);
alert("Transformed by parent coordinates.");
app.documents.item(0).undo();
//Transform using pasteboard coordinates.
myRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrix);
app.select(myRectangle);
alert("Transformed by pasteboard coordinates.");
app.documents.item(0).undo();
Transformation origin
The transformation origin is the center point of the transformation. The transformation origin can be
specified in several ways:
XBounds space:
Zanchor — An anchor point on the object itself.
AnchorPoint.centerAnchor
Z
anchor, bounds type — An anchor point specified relative to the geometric bounds of the object
BoundingBoxLimits.geometricPathBounds) or the visible bounds of the object
Z(x, y), page index — A point, relative to the ruler origin on a specified page of a spread.
[[72, 144], 0]
(x, y), location — A point, relative to the parent page of the specified location of the object.
Z
Location can be specified as an anchor point or a coordinate pair. It can be specified relative to the
object’s geometric or visible bounds, and it can be specified in a given coordinate space.
[[72, 144], AnchorPoint.centerAnchor]
XTransform space:
Z(x, y) — A point in the pasteboard coordinate space.
[72, 72]
(x, y), coordinate system — A point in the specified coordinate space.
Z
[[72, 72], CoordinateSpaces.parentCoordinates]
((x, y)) — A point in the coordinate space given as the in parameter of the transform method.
Z
[[72, 72]]
The following script example shows how to use some of the transformation origin options. (For the
complete script, see TransformationOrigin.)
//Rotate around the duplicated rectangle's center point.
myNewRectangle.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrix);
//Rotate the rectangle around the ruler location [-100, -100].
//Note that the anchor point specified here specifes the page
//containing the point--*not* that transformation point itself.
//The transformation gets the ruler coordinate [-100, -100] based
//on that page. Setting the considerRulerUnits parameter to true makes
//certain that the transformation uses the current ruler units.
myNewRectangle.transform(CoordinateSpaces.pasteboardCoordinates, [[-100, -100],
AnchorPoint.topLeftAnchor], myTransformationMatrix, undefined, true);
Resolving locations
Sometimes, you need to get the location of a point specified in one coordinate space in the context of
another coordinate space. To do this, you use the
resolve method, as shown in the following script
example. (For the complete script, see ResolveLocation.)
var myPageLocation = myRectangle.resolve([[72, 72], AnchorPoint.topRightAnchor],
CoordinateSpaces.pasteboardCoordinates, true);
//resolve() returns an array containing a single item.
alert("X: " + myPageLocation[0][0] + "\rY: " + myPageLocation[0][1]);
CHAPTER 5: Working with Page ItemsTransforming Page Items 68
Transforming points
You can transform points as well as objects, which means scripts can perform a variety of mathematical
operations without having to include the calculations in the script itself. The ChangeCoordinates sample
script shows how to draw a series of regular polygons using this approach:
//General purpose routine for drawing regular polygons from their center point.
function myDrawPolygon(myParent, myCenterPoint, myNumberOfPoints, myRadius,
myStarPolygon, myStarInset){
var myTransformedPoint;
var myPathPoints = new Array;
var myPoint = [0,0];
if(myStarPolygon == true){
myNumberOfPoints = myNumberOfPoints * 2;
}
var myInnerRadius = myRadius * myStarInset;
var myAngle = 360/myNumberOfPoints;
var myRotateMatrix = app.transformationMatrices.add({
counterclockwiseRotationAngle:myAngle});
var myOuterTranslateMatrix = app.transformationMatrices.add({
horizontalTranslation:myRadius});
var myInnerTranslateMatrix = app.transformationMatrices.add({
horizontalTranslation:myInnerRadius});
for (var myPointCounter = 0; myPointCounter < myNumberOfPoints;
myPointCounter ++){
//Translate the point to the inner/outer radius.
if ((myStarInset == 1)||(myIsEven(myPointCounter)==true)){
}
//Create a new polygon.
var myPolygon = myParent.polygons.add();
//Set the entire path of the polygon to the array we've created.
myPolygon.paths.item(0).entirePath = myPathPoints;
//If the center point is somewhere other than [0,0],
//translate the polygon to the center point.
if((myCenterPoint[0] != 0)||((myCenterPoint[1] != 0))){
var myTranslateMatrix = app.transformationMatrices.add({
horizontalTranslation:myCenterPoint[0],
verticalTranslation:myCenterPoint[1]});
myPolygon.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTranslateMatrix);
}
}
//This function returns true if myNumber is even, false if it is not.
function myIsEven(myNumber){
var myResult = (myNumber%2)?false:true;
return myResult;
}
You also can use the changeCoordinates method to change the positions of curve control points, as
shown in the FunWithTransformations sample script.
CHAPTER 5: Working with Page ItemsResize and Reframe 69
Transforming again
Just as you can apply a transformation or sequence of transformations again in the user interface, you can
do so using scripting. There are four methods for applying transformations again:
XtransformAgain
XtransformAgainIndividually
XtransformSequenceAgain
XtransformSequenceAgainIndividually
The following script fragment shows how to use transformAgain. (For the complete script, see
TransformAgain.)
var myRectangle = myPage.rectangles.item(0);
var myBounds = myRectangle.geometricBounds;
var myX1 = myBounds[1];
var myY1 = myBounds[0];
var myRectangleA = myPage.rectangles.add({geometricBounds:[myY1-12, myX1-12, myY1+12,
myX1+12]});
var myTransformationMatrix =
app.transformationMatrices.add({counterclockwiseRotationAngle:45});
myRectangleA.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrix);
var myRectangleB = myRectangleA.duplicate();
myRectangleB.transform(CoordinateSpaces.pasteboardCoordinates, [[0,0],
AnchorPoint.topLeftAnchor], myTransformationMatrix, undefined, true);
var myRectangleC = myRectangleB.duplicate();
myRectangleC.transformAgain();
var myRectangleD = myRectangleC.duplicate();
myRectangleD.transformAgain();
var myRectangleE = myRectangleD.duplicate();
myRectangleE.transformAgain();
var myRectangleF = myRectangleE.duplicate();
myRectangleF.transformAgain();
var myRectangleG = myRectangleF.duplicate();
myRectangleG.transformAgain();
var myRectangleH = myRectangleG.duplicate();
myRectangleH.transformAgain();
myRectangleB.transform(CoordinateSpaces.pasteboardCoordinates,
AnchorPoint.centerAnchor, myTransformationMatrix);
myRectangleD.transformAgain();
myRectangleF.transformAgain();
myRectangleH.transformAgain();
Resize and Reframe
In addition to scaling page items using the transform method, you can also change the size of the shape
using two other methods: resize and reframe. These methods change the location of the path points of the
page item without scaling the content or stroke weight of the page item. The following script fragment
shows how to use the resize method. For the complete script, see Resize.
//Given a reference to a rectangle "myRectangle"...
var myDuplicate = myRectangle.duplicate();
myDuplicate.resize(CoordinateSpaces.innerCoordinates, AnchorPoint.centerAnchor,
ResizeMethods.multiplyingCurrentDimensionsBy, [2, 2]);
CHAPTER 5: Working with Page ItemsResize and Reframe 70
The following script fragment shows how to use the reframe method. For the complete script, see
Reframe.
//Given a reference to a rectangle "myRectangle"...
var myBounds = myRectangle.geometricBounds;
var myX1 = myBounds[1]-72;
var myY1 = myBounds[0]-72;
var myX2 = myBounds[3]+72;
var myY2 = myBounds[2]+72;
myDuplicate = myRectangle.duplicate();
myDuplicate.reframe(CoordinateSpaces.innerCoordinates, [[myY1, myX1],[myY2, myX2]]);
6
Tex t a nd Type
Entering, editing, and formatting text are the tasks that make up the bulk of the time spent working on
most InDesign documents. Because of this, automating text and type operations can result in large
productivity gains.
This chapter shows how to script the most common operations involving text and type. The sample scripts
in this chapter are presented in order of complexity, starting with very simple scripts and building toward
more complex operations.
We assume that you have already read Adobe InDesign CS5 Scripting Tutorial and know how to create,
install, and run a script. We also assume that you have some knowledge of working with text in InDesign
and understand basic typesetting terms.
Entering and Importing Text
This section covers the process of getting text into your InDesign documents. Just as you can type text into
text frames and place text files using the InDesign user interface, you can create text frames, insert text
into a story, or place text files on pages using scripting.
Creating a text frame
The following script creates a text frame, sets the bounds (size) of the frame, then enters text in the frame
(for the complete script, see the MakeTextFrame tutorial script):
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var myTextFrame = myPage.textFrames.add();
//Set the bounds of the text frame.
myTextFrame.geometricBounds = [72, 72, 288, 288];
//Enter text in the text frame.
myTextFrame.contents = "This is some example text."
//Note that you could also use a properties record to
//create the frame and set its bounds and contents in one line:
//var myTextFrame = myDocument.pages.item(0).textFrames.add(
{geometricBounds:[72, 72, 288, 288], contents:"This is some example text."});
The following script shows how to create a text frame that is the size of the area defined by the page
margins.
other examples in this chapter. (For the complete script, see MakeTextFrameWithinMargins.)
var myDocument = app.documents.item(0);
//Create a text frame on the current page.
var myTextFrame = myPage.textFrames.add();
//Set the bounds of the text frame.
myTextFrame.geometricBounds = myGetBounds(myDocument, myPage);
//Enter text in the text frame.
myTextFrame.contents = "This is some example text."
myGetBounds is a useful function that you can add to your own scripts, and it appears in many
var myPage = myDocument.pages.item(0);
The following script fragment shows the myGetBounds function.
71
CHAPTER 6: Text and TypeEntering and Importing Text 72
function myGetBounds(myDocument, myPage){
var myPageWidth = myDocument.documentPreferences.pageWidth;
var myPageHeight = myDocument.documentPreferences.pageHeight
if(myPage.side == PageSideOptions.leftHand){
var myX2 = myPage.marginPreferences.left;
var myX1 = myPage.marginPreferences.right;
}
else{
var myX1 = myPage.marginPreferences.left;
var myX2 = myPage.marginPreferences.right;
}
var myY1 = myPage.marginPreferences.top;
var myX2 = myPageWidth - myX2;
var myY2 = myPageHeight - myPage.marginPreferences.bottom;
return [myY1, myX1, myY2, myX2];
}
Adding text
To add text to a story, use the contents property of the insertion point at the location where you want to
insert the text. The following sample script uses this technique to add text at the end of a story (for the
complete script, see AddText):
//Add text at the end of the text in the text frame.
//To do this, we'll use the last insertion point in the story.
//("\r" is a return character.)
var myNewText = "\rThis is a new paragraph of example text.";
myTextFrame.parentStory.insertionPoints.item(-1).contents = myNewText;
Stories and text frames
All text in an InDesign layout is part of a story, and every story can contain one or more text frames.
Creating a text frame creates a story, and stories can contain multiple text frames.
In the preceding script, we added text at the end of the parent story rather than at the end of the text
frame. This is because the end of the text frame might not be the end of the story; that depends on the
length and formatting of the text. By adding the text to the end of the parent story, we can guarantee that
the text is added, regardless of the composition of the text in the text frame.
You always can get a reference to the story using the
useful to work with the text of a story instead of the text of a text frame; the following script demonstrates
the difference. The alerts shows that the text frame does not contain the overset text, but the story does
(for the complete script, see StoryAndTextFrame).
parentTextFrame property of a text frame. It can be
CHAPTER 6: Text and TypeEntering and Importing Text 73
var myDocument = app.activeDocument;
//Set the measurement units to points.
myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
//Create a text frame on the current page.
var myTextFrame = app.activeWindow.activePage.textFrames.add();
//Set the bounds of the text frame.
myTextFrame.geometricBounds = [72, 72, 96, 288];
//Fill the text frame with placeholder text.
myTextFrame.contents = TextFrameContents.placeholderText;
//Now add text beyond the end of the text frame.
myTextFrame.insertionPoints.item(-1).contents = "\rThis is some overset text";
alert("The last paragraph in this alert should be \"This is some overset text\". Is
it?\r" + myTextFrame.contents);
alert("The last paragraph in this alert should be \"This is some overset text\". Is
it?\r" + myTextFrame.parentStory.contents);
For more on understanding the relationships between text objects in an InDesign document, see
“Understanding Text Objects” on page 81
.
Replacing text
The following script replaces a word with a phrase by changing the contents of the appropriate object (for
the complete script, see ReplaceWord):
var myDocument = app.activeDocument;
//Set the measurement units to points.
myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
//Create a text frame on the current page.
var myTextFrame = app.activeWindow.activePage.textFrames.add({geometricBounds:[72, 72,
288, 288], contents:"This is some example text."});
//Replace the third word "some" with the phrase
//"a little bit of".
myTextFrame.parentStory.words.item(2).contents = "a little bit of";
The following script replaces the text in a paragraph (for the complete script, see ReplaceText):
//Replace the text in the second paragraph without replacing
//the return character at the end of the paragraph. To do this,
//we'll use the ItemByRange method.
var myStartCharacter = myTextFrame.parentStory.paragraphs.item(1).characters.item(0);
var myEndCharacter = myTextFrame.parentStory.paragraphs.item(1).characters.item(-2);
myTextFrame.texts.itemByRange(myStartCharacter, myEndCharacter).contents = "This text
replaces the text in paragraph 2."
In the preceding script above, we excluded the return character because deleting the return might change
the paragraph style applied to the paragraph. To do this, we used
two characters—the starting and ending characters of the paragraph—as parameters.
Inserting special characters
ItemByRange method, and we supplied
Because the ExtendScript Toolkit supports Unicode, you can simply enter Unicode characters in text
strings that you send to InDesign. Alternately, you can use the JavaScript method of explicitly entering
Unicode characters by their glyph ID number:
The following script shows several ways to enter special characters. (We omitted the
\unnnn (where nnnn is the Unicode code for the character).
myGetBounds
CHAPTER 6: Text and TypePlacing Text and Setting Text-Import Preferences 74
function from this listing; you can find it in “Creating a text frame” on page 71” or in the SpecialCharacters
tutorial script.)
The easiest way to find the Unicode ID for a character is to use InDesign’s Glyphs palette: move the cursor
over a character in the palette, and InDesign displays its Unicode value. To learn more about Unicode, visit
http://www.unicode.org
.
Placing Text and Setting Text-Import Preferences
In addition to entering text strings, you can place text files created using word processors and text editors.
The following script shows how to place a text file on a document page (for the complete script, see
PlaceTextFile):
var myDocument = app.documents.item(0);
//Set the measurement units to points.
myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
//Get the current page.
var myPage = myDocument.pages.item(0);
//Get the top and left margins to use as a place point.
var myX = myPage.marginPreferences.left;
var myY = myPage.marginPreferences.top;
//Autoflow a text file on the current page.
//Parameters for Page.place():
//File as File object,
//[PlacePoint as Array [x, y]]
//[DestinationLayer as Layer object]
//[ShowingOptions as Boolean = False]
//[Autoflowing as Boolean = False]
//You'll have to fill in your own file path.
var myStory = myPage.place(File("/c/test.txt"), [myX, myY], undefined, false, true)[0];
//Note that if the PlacePoint parameter is inside a column, only the vertical (y)
//coordinate will be honored--the text frame will expand horizontally to fit the
column.
CHAPTER 6: Text and TypePlacing Text and Setting Text-Import Preferences 75
The following script shows how to place a text file in an existing text frame. (We omitted the myGetBounds
function from this listing; you can find it in “Creating a text frame” on page 71
,” or see the
PlaceTextFileInFrame tutorial script.)
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var myTextFrame =
myPage.textFrames.add({geometricBounds:myGetBounds(myDocument,myPage)});
//Place a text file in the text frame.
//Parameters for TextFrame.place():
//File as File object,
//[ShowingOptions as Boolean = False]
//You'll have to fill in your own file path.
myTextFrame.place(File("/c/test.txt"));
The following script shows how to insert a text file at a specific location in text. (We omitted the
myGetBounds function from this listing; you can find it in “Creating a text frame” on page 71,” o r s ee t he
InsertTextFile tutorial script.)
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var myTextFrame = myPage.textFrames.item(0);
//Place a text file at the end of the text.
//Parameters for InsertionPoint.place():
//File as File object,
//[ShowingOptions as Boolean = False]
//You'll have to fill in your own file path.
myTextFrame.parentStory.insertionPoints.item(-1).place(File("/c/test.txt"));
To specify the import options for the specific type of text file you are placing, use the corresponding
import-preferences object. The following script shows how to set text-import preferences (for the
complete script, see TextImportPreferences). The comments in the script show the possible values for each
property.
with(app.textImportPreferences){
//Options for characterSet: TextImportCharacterSet.
characterSet = TextImportCharacterSet.UTF8;
convertSpacesIntoTabs = true;
spacesIntoTabsCount = 3;
//The dictionary property can take many values, such as French, Italian.
dictionary = "English: USA";
//platform options: ImportPlatform
platform = ImportPlatform.macintosh;
stripReturnsBetweenLines = true;
stripReturnsBetweenParagraphs = true;
useTypographersQuotes = true;
}
The following script shows how to set tagged text import preferences (for the complete script, see
TaggedTextImportPreferences):
CHAPTER 6: Text and TypeExporting Text and Setting Text-Export Preferences 77
Exporting Text and Setting Text-Export Preferences
The following script shows how to export text from an InDesign document. Note that you must use text or
story objects to export into text file formats; you cannot export all text in a document in one operation.
(We omitted the
page 71,” or see the ExportTextFile tutorial script.)
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var myTextFrame = myPage.textFrames.item(0);
//Text exportFile method parameters:
//Format as ExportFormat
//To As File
//[ShowingOptions As Boolean = False]
//Format parameter can be:
//ExportFormat.inCopy
//ExportFormat.inCopyCS2Story
//ExportFormat.rtf
//ExportFormat.taggedText
//ExportFormat.textType
//Export the story as text. You'll have to fill in a valid file path on your system.
myTextFrame.parentStory.exportFile(ExportFormat.textType, File("/c/test.txt"));
myGetBounds function from this listing; you can find it in “Creating a text frame” on
The following example shows how to export a specific range of text. (We omitted the myGetBounds
function from this listing; you can find it in “Creating a text frame” on page 71
,” or see the ExportTextRange
tutorial script.)
var myDocument = app.documents.item(0);
var myStory = myDocument.stories.item(0);
var myStart = myStory.characters.item(0);
var myEnd = myStory.paragraphs.item(0).characters.item(-1);
myText = myStory.texts.itemByRange(myStart, myEnd);
//Text exportFile method parameters:
//Format as ExportFormat
//To As File
//[ShowingOptions As Boolean = False]
//Format parameter can be:
//ExportFormat.inCopy
//ExportFormat.inCopyCS2Story
//ExportFormat.rtf
//ExportFormat.taggedText
//ExportFormat.textType
//Export the text range. You'll have to fill in a valid file path on your system.
myText.exportFile(ExportFormat.textType, File("/c/test.txt"));
To specify the export options for the specific type of text file you’re exporting, use the corresponding
export preferences object. The following script sets text-export preferences (for the complete script, see
TextExportPreferences):
You cannot export all text in a document in one step. Instead, you need to either combine the text in the
document into a single story and then export that story, or combine the text files by reading and writing
files via scripting. The following script demonstrates the former approach. (We omitted the
function from this listing; you can find it in “Creating a text frame” on page 71
,” or see the ExportAllText
myGetBounds
tutorial script.) For any format other than text only, the latter method can become quite complex.
if(app.documents.length != 0){
if(app.documents.item(0).stories.length != 0){
myExportAllText(app.documents.item(0).name);
}
}
Here is the ExportAllText function referred to in the preceding fragment:
function myExportAllText(myDocumentName){
var myStory;
//File name for the exported text. Fill in a valid file path on your system.
var myFileName = "/c/test.txt";
//If you want to add a separator line between stories, set myAddSeparator to true.
var myAddSeparator = true;
var myNewDocument = app.documents.add();
var myDocument = app.documents.item(myDocumentName);
var myTextFrame = myNewDocument.pages.item(0).textFrames.add(
{geometricBounds:myGetBounds(myNewDocument, myNewDocument.pages.item(0))});
var myNewStory = myTextFrame.parentStory;
for(myCounter = 0; myCounter < myDocument.stories.length; myCounter++){
Do not assume that you are limited to exporting text using existing export filters. Because JavaScript can
write text files to disk, you can have your script traverse the text in a document and export it in any order
you like, using whatever text mark-up scheme you prefer. Here is a very simple example that shows how to
export InDesign text as HTML. (We omitted the
“Creating a text frame” on page 71
var myStory, myParagraph, myString, myTag, myStartTag;
var myEndTag, myTextStyleRange, myTable;
//Use the myStyleToTagMapping array to set up your paragraph style to tag mapping.
var myStyleToTagMapping = new Array;
//For each style to tag mapping, add a new item to the array.
myStyleToTagMapping.push(["body_text", "p"]);
myStyleToTagMapping.push(["heading1", "h1"]);
myStyleToTagMapping.push(["heading2", "h2"]);
myStyleToTagMapping.push(["heading3", "h3"]);
//End of style to tag mapping.
if(app.documents.length !=0){
if(app.documents.item(0).stories.length != 0){
//Open a new text file.
var myTextFile = File.saveDialog("Save HTML As", undefined);
//If the user clicked the Cancel button, the result is null.
if(myTextFile != null){
//Open the file with write access.
myTextFile.open("w");
//Iterate through the stories.
for(var myCounter = 0; myCounter < app.documents.item(0).stories.length;
myCounter ++){
//If the paragraph is a simple paragraph--no tables, no local
//formatting--then simply export the text of the pararaph with
//the appropriate tag.
myTag = myFindTag(myParagraph.appliedParagraphStyle.name,
myStyleToTagMapping);
//If the tag comes back empty, map it to the
//basic paragraph tag.
if(myTag == ""){
myTag = "p";
}
myStartTag = "<" + myTag + ">";
myGetBounds function from this listing; you can find it in
CHAPTER 6: Text and TypeExporting Text and Setting Text-Export Preferences 80
myEndTag = "</" + myTag + ">";
//If the paragraph is not the last paragraph in the story,
//omit the return character.
if(myParagraph.characters.item(-1).contents == "\r"){
myString = myParagraph.texts.itemByRange(
myParagraph.characters.item(0),myParagraph.
characters.item(-2)).contents;
}
else{
myString = myParagraph.contents;
}
//Write the paragraphs' text to the text file.
myTextFile.writeln(myStartTag + myString + myEndTag);
}
else{
//Handle text style range export by iterating through the text
//style ranges in the paragraph..
for(var myRangeCounter = 0; myRangeCounter <
myParagraph.textStyleRanges.length; myRangeCounter ++){
The following diagram shows a view of InDesign’s text object model. As you can see, there are two main
types of text object: layout objects (text frames) and text-stream objects (for example, stories, insertion
points, characters, and words):
CHAPTER 6: Text and TypeUnderstanding Text Objects 82
story
insertion points
characters
words
lines
paragraphs
text columns
text style ranges
texts
text frame
insertion points
characters
words
lines
paragraphs
text columns
text style ranges
texts
text containers
document
spread, page, layer
notes
notes
document
pages.item(0)
textFrames.item(0)
characters.item(0)
stories.item(0)
characters.item(0)
textFrames.item(0)
paragraphs.item(0)
characters.item(0)
stories.item(0)
paragraphs.item(0)
characters.item(0)
There are many ways to get a reference to a given text object. The following diagram shows a few ways to
refer to the first character in the first text frame of the first page of a new document:
For any text stream object, the
the text frame (or text frames) containing the text object, use the
parent of the object is the story containing the object. To get a reference to
parentTextFrames property.
CHAPTER 6: Text and TypeUnderstanding Text Objects 83
For a text frame, the parent of the text frame usually is the page or spread containing the text frame. If the
text frame is inside a group or was pasted inside another page item, the
containing page item. If the text frame was converted to an anchored frame, the
parent of the text frame is the
parent of the text frame
is the character containing the anchored frame.
Working with text selections
Text-related scripts often act on a text selection. The following script demonstrates a way to determine
whether the current selection is a text selection. Unlike many of the other sample scripts, this script does
not actually do anything; it simply presents a selection-filtering routine that you can use in your own
scripts (for the complete script, see TextSelection).
if (app.documents.length != 0){
//If the selection contains more than one item, the selection
//is not text selected with the Type tool.
if (app.selection.length == 1){
//Evaluate the selection based on its type.
switch (app.selection[0].constructor.name){
case "InsertionPoint":
case "Character":
case "Word":
case "TextStyleRange":
case "Line":
case "Paragraph":
case "TextColumn":
case "Text":
case "Story":
//The object is a text object; pass it on to a function.
myProcessText(app.selection[0]);
break;
//In addition to checking for the above text objects, we can
//also continue if the selection is a text frame selected with
//the Selection tool or the Direct Selection tool.
case "TextFrame":
//If the selection is a text frame, get a reference to the
//text in the text frame.
myProcessText(app.selection[0].texts.item(0));
break;
default:
alert("The selected object is not a text object.
Select some text and try again.");
break;
}
}
else{
alert("Please select some text and try again.");
}
}
Moving and copying text
You can move a text object to another location in text using the move method. To copy the text, use the
duplicate method (whose arguments are identical to the move method). The following script fragment
shows how it works (for the complete script, see MoveText):
CHAPTER 6: Text and TypeUnderstanding Text Objects 84
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var myTextFrameA = myPage.textFrames.item(3);
var myTextFrameB = myPage.textFrames.item(2);
var myTextFrameC = myPage.textFrames.item(1);
var myTextFrameD = myPage.textFrames.item(0);
//Move WordC between the words in TextFrameC.
myTextFrameD.parentStory.paragraphs.item(-1).words.item(0).move(LocationOptions.befor
e, myTextFrameC.parentStory.paragraphs.item(0).words.item(1))
//Move WordB after the word in TextFrameB.
myTextFrameD.parentStory.paragraphs.item(-2).words.item(0).move(LocationOptions.after
, myTextFrameB.parentStory.paragraphs.item(0).words.item(0))
//Move WordA to before the word in TextFrameA.
myTextFrameD.parentStory.paragraphs.item(-3).words.item(0).move(LocationOptions.befor
e, myTextFrameA.parentStory.paragraphs.item(0).words.item(0))
//Note that moving text removes it from its original location.
When you want to transfer formatted text from one document to another, you also can use the move
method. Using the
you must make the document visible and select the text you want to copy. Using
move or duplicate method is better than using copy and paste; to use copy and paste,
move or duplicate is
much faster and more robust. The following script shows how to move text from one document to another
move and duplicate. (We omitted the myGetBounds function from this listing; you can find it in
using
“Creating a text frame” on page 71
,” or see the MoveTextBetweenDocuments tutorial script.)
//Create the source document.
var mySourceDocument = app.documents.add();
var mySourcePage = mySourceDocument.pages.item(0);
var mySourceTextFrame =
mySourcePage.textFrames.add({geometricBounds:myGetBounds(mySourceDocument,
mySourcePage), contents:"This is the source text.\rThis text is not the source
text."});
var mySoureParagraph = mySourceTextFrame.parentStory.paragraphs.item(0);
mySoureParagraph.pointSize = 24;
//Create the target document.
var myTargetDocument = app.documents.add();
var myTargetPage = myTargetDocument.pages.item(0);
var myTargetTextFrame =
myTargetPage.textFrames.add({geometricBounds:myGetBounds(myTargetDocument,
myTargetDocument.pages.item(0)), contents:"This is the target text. Insert the source
text before this paragraph.\r"});
//Move the text from the source document to the target document.
//This deletes the text from the source document.
mySoureParagraph.move(LocationOptions.AT_BEGINNING,
myTargetTextFrame.insertionPoints.item(0));
//To duplicate (rather than move) the text, use the following:
//mySoureParagraph.duplicate(LocationOptions.AT_BEGINNING,
myTargetTextFrame.insertionPoints.item(0));
When you need to copy and paste text, you can use the copy method of the application. You will need to
select the text before you copy. Again, you should use copy and paste only as a last resort; other
approaches are faster, less fragile, and do not depend on the document being visible. (We omitted the
myGetBounds function from this listing; you can find it in “Creating a text frame” on page 71,” o r s ee t he
CopyPasteText tutorial script.)
CHAPTER 6: Text and TypeUnderstanding Text Objects 85
var myDocumentA = app.documents.add();
var myPageA = myDocumentA.pages.item(0);
var myString = "Example text.\r";
var myTextFrameA = myPageA.textFrames.add({geometricBounds:myGetBounds(myDocumentA,
myPageA), contents:myString});
var myDocumentB = app.documents.add();
var myPageB = myDocumentB.pages.item(0);
var myTextFrameB = myPageB.textFrames.add({geometricBounds:myGetBounds(myDocumentB,
myPageB)});
//Make document A the active document.
app.activeDocument = myDocumentA;
//Select the text.
app.select(myTextFrameA.parentStory.texts.item(0));
app.copy();
//Make document B the active document.
app.activeDocument = myDocumentB;
//Select the insertion point at which you want to paste the text.
app.select(myTextFrameB.parentStory.insertionPoints.item(0));
app.paste();
One way to copy unformatted text from one text object to another is to get the contents property of a
text object, then use that string to set the
contents property of another text object. The following script
shows how to do this (for the complete script, see CopyUnformattedText):
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
//Create a text frame on the active page.
var myTextFrameA = myPage.textFrames.add({geometricBounds:[72, 72, 144, 288]});
myTextFrameA.contents = "This is a formatted string.";
myTextFrameA.parentStory.texts.item(0).fontStyle = "Bold";
//Create another text frame on the active page.
var myTextFrameB = myPage.textFrames.add({geometricBounds:[228, 72, 300, 288]});
myTextFrameB.contents = "This is the destination text frame. Text pasted here will
retain its formatting.";
myTextFrameB.parentStory.texts.item(0).fontStyle = "Italic";
//Copy from one frame to another using a simple copy.
app.select(myTextFrameA.texts.item(0));
app.copy();
app.select(myTextFrameB.parentStory.insertionPoints.item(-1));
app.paste();
//Create another text frame on the active page.
var myTextFrameC = myPage.textFrames.add({geometricBounds:[312, 72, 444, 288]});
myTextFrameC.contents = "Text copied here will take on the formatting of the existing
text.";
myTextFrameC.parentStory.texts.item(0).fontStyle = "Italic";
//Copy the unformatted string from text frame A to the end of text frame C (note
//that this doesn't really copy the text; it replicates the text string from one
//text frame in another text frame):
myTextFrameC.parentStory.insertionPoints.item(-1).contents =
myTextFrameA.parentStory.texts.item(0).contents;
Text objects and iteration
When your script moves, deletes, or adds text while iterating through a series of text objects, you can
easily end up with invalid text references. The following script demonstrates this problem. (We omitted the
myGetBounds function from this listing; you can find it in “Creating a text frame” on page 71,” o r s ee t he
TextIterationWrong tutorial script.)
CHAPTER 6: Text and TypeWorking with Text Frames 86
var myDocument = app.documents.item(0);
var myStory = myDocument.stories.item(0);
//The following for loop will fail to format all of the paragraphs.
for(var myParagraphCounter = 0; myParagraphCounter < myStory.paragraphs.length;
myParagraphCounter ++){
In the preceding example, some of the paragraphs are left unformatted. How does this happen? The loop
in the script iterates through the paragraphs from the first paragraph in the story to the last. As it does so,
it deletes paragraphs that begin with the word “Delete.” When the script deletes the second paragraph,
the third paragraph moves up to take its place. When the loop counter reaches 2, the script processes the
paragraph that had been the fourth paragraph in the story; the original third paragraph is now the second
paragraph and is skipped.
To avoid this problem, iterate backward through the text objects, as shown in the following script. (We
omitted the
myGetBounds function from this listing; you can find it in “Creating a text frame” on page 71,”
or see the TextIterationRight tutorial script.)
var myDocument = app.documents.item(0);
var myStory = myDocument.stories.item(0);
//The following for loop will format all of the paragraphs by iterating
//backwards through the paragraphs in the story.
for(var myParagraphCounter = myStory.paragraphs.length-1; myParagraphCounter >= 0;
myParagraphCounter --){
In the previous sections of this chapter, we concentrated on working with text stream objects; in this
section, we focus on text frames, the page-layout items that contain text in an InDesign document.
Linking text frames
The nextTextFrame and previousTextFrame properties of a text frame are the keys to linking (or
“threading”) text frames in InDesign scripting. These properties correspond to the in port and out port on
InDesign text frames, as shown in the following script fragment (for the complete script, see
LinkTextFrames):
CHAPTER 6: Text and TypeWorking with Text Frames 87
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var myTextFrameA = myPage.textFrames.item(1);
var myTextFrameB = myPage.textFrames.item(0);
//Add a page.
var myNewPage = myDocument.pages.add();
//Create another text frame on the new page.
var myTextFrameC = myNewPage.textFrames.add({geometricBounds:[72, 72, 144, 144]})
//Link TextFrameA to TextFrameB using the nextTextFrame property.
myTextFrameA.nextTextFrame = myTextFrameB;
//Link TextFrameC to TextFrameB using the previousTextFrame property.
myTextFrameC.previousTextFrame = myTextFrameB;
//Fill the text frames with placeholder text.
myTextFrameA.contents = TextFrameContents.placeholderText;
Unlinking text frames
The following example script shows how to unlink text frames (for the complete script, see
UnlinkTextFrames):
//Unlink the two text frames.
myTextFrameA.nextTextFrame = NothingEnum.nothing;
Removing a frame from a story
In InDesign, deleting a frame from a story does not delete the text in the frame, unless the frame is the only
frame in the story. The following script fragment shows how to delete a frame and the text it contains from
a story without disturbing the other frames in the story (for the complete script, see BreakFrame):
var myObjectList = new Array;
//Script does nothing if no documents are open or if no objects are selected.
if(app.documents.length != 0){
if(app.selection.length != 0){
//Process the objects in the selection to create a list of
}
function myPadString(myString, myLength) {
var myTempString = "";
var myNewLength = myLength-String(myString).length;
for (var myCounter = 0; myCounter<myNewLength; myCounter++) {
myTempString += "0";
}
return myTempString + myString;
}
CHAPTER 6: Text and TypeWorking with Text Frames 89
Splitting all frames in a story
The following script fragment shows how to split all frames in a story into separate, independent stories,
each containing one unlinked text frame (for the complete script, see SplitStory):
if(app.documents.length != 0){
if(app.selection.length != 0){
//Get the first item in the selection.
var mySelection = app.selection[0];
//Process the selection. If text or a text frame is
//selected, do something; otherwise, do nothing.
switch(mySelection.constructor.name){
case "Text":
case "InsertionPoint":
case "Character":
case "Word":
case "Line":
case "TextStyleRange":
case "Paragraph":
case "TextColumn":
case "TextFrame":
//If the text frame is the only text frame in the story, do nothing.
if(mySelection.parentStory.textContainers.length != 1){
//Splitting the story is a two-step process: first, duplicate
//the text frames, second, delete the original text frames.
mySplitStory(mySelection.parentStory);
myRemoveFrames(mySelection.parentStory);
}
break;
}
}
}
Here is the mySplitStory function referred to in the preceding script:
function mySplitStory(myStory){
var myTextFrame;
//Duplicate each text frame in the story.
for(var myCounter = myStory.textContainers.length-1; myCounter >= 0;
myCounter --){
To create an anchored frame (also known as an inline frame), you can create a text frame (or rectangle,
oval, polygon, or graphic line) at a specific location in text (usually an insertion point). The following script
fragment shows an example (for the complete script, see AnchoredFrame):
CHAPTER 6: Text and TypeFormatting Text 90
var myInsertionPoint = myTextFrame.paragraphs.item(0).insertionPoints.item(0);
var myInlineFrame = myInsertionPoint.textFrames.add();
//Recompose the text to make sure that getting the
//geometric bounds of the inline graphic will work.
myTextFrame.texts.item(0).recompose;
//Get the geometric bounds of the inline frame.
var myBounds = myInlineFrame.geometricBounds;
//Set the width and height of the inline frame. In this example, we'll
//make the frame 24 points tall by 72 points wide.
var myArray = [myBounds[0], myBounds[1], myBounds[0]+24, myBounds[1]+72];
myInlineFrame.geometricBounds = myArray;
myInlineFrame.contents = "This is an inline frame.";
myInsertionPoint = myTextFrame.paragraphs.item(1).insertionPoints.item(0);
var myAnchoredFrame = myInsertionPoint.textFrames.add();
//Recompose the text to make sure that getting the
//geometric bounds of the inline graphic will work.
myTextFrame.texts.item(0).recompose;
//Get the geometric bounds of the inline frame.
var myBounds = myAnchoredFrame.geometricBounds;
//Set the width and height of the inline frame. In this example, we'll
//make the frame 24 points tall by 72 points wide.
myArray = [myBounds[0], myBounds[1], myBounds[0]+24, myBounds[1]+72];
myAnchoredFrame.geometricBounds = myArray;
myAnchoredFrame.contents = "This is an anchored frame.";
with(myAnchoredFrame.anchoredObjectSettings){
In the previous sections of this chapter, we added text to a document, linked text frames, and worked with
stories and text objects. In this section, we apply formatting to text. All the typesetting capabilities of
InDesign are available to scripting.
Setting text defaults
You can set text defaults for both the application and each document. Text defaults for the application
determine the text defaults in all new documents; text defaults for a document set the formatting of all
new text objects in that document. (For the complete script, see TextDefaults.)
CHAPTER 6: Text and TypeFormatting Text 91
var myDocument = app.documents.item(0);
//To set the application text formatting defaults, replace the variable "myDocument"
//with "app" in the following lines.
with(myDocument.textDefaults){
alignToBaseline = true;
//Because the font might not be available, it's usually best
//to apply the font within a try...catch structure. Fill in the
//name of a font on your system.
try{
appliedFont = app.fonts.item("Minion Pro");
}
catch(e){}
//Because the font style might not be available, it's usually best
//to apply the font style within a try...catch structure.
try{
fontStyle = "Regular";
}
catch(e){}
//Because the language might not be available, it's usually best
//to apply the language within a try...catch structure.
try{
The fonts collection of the InDesign application object contains all fonts accessible to InDesign. The fonts
collection of a document, by contrast, contains only those fonts used in the document. The fonts
collection of a document also contains any missing fonts—fonts used in the document that are not
accessible to InDesign. The following script shows the difference between application fonts and document
fonts. (We omitted the
var myApplicationFonts = app.fonts;
var myDocument = app.documents.item(0);
var myStory = myDocument.stories.item(0);
var myDocumentFonts = myDocument.fonts;
var myFontNames = myApplicationFonts.everyItem().name;
var myDocumentFontNames = myDocument.fonts.everyItem().name;
var myString = "Document Fonts:\r";
for(var myCounter = 0;myCounter<myDocumentFontNames.length; myCounter++){
NOTE: Font names typically are of the form familyName<tab>fontStyle, where familyName is the name
of the font family,
"Adobe Caslon Pro<tab>Semibold Italic"
<tab> is a tab character, and fontStyle is the name of the font style. For example:
myGetBounds function here; for the complete script, see FontCollections.)
CHAPTER 6: Text and TypeFormatting Text 94
Applying a font
To apply a local font change to a range of text, use the appliedFont property, as shown in the following
script fragment (from the ApplyFont tutorial script):
//Given a font name "myFontName" and a text object "myText"...
myText.appliedFont = app.fonts.item(myFontName);
You also can apply a font by specifying the font family name and font style, as shown in the following script
fragment:
Text objects in InDesign have literally dozens of properties corresponding to their formatting attributes.
Even one insertion point features properties that affect the formatting of text—up to and including
properties of the paragraph containing the insertion point. The SetTextProperties tutorial script shows
how to set every property of a text object. A fragment of the script is shown below:
You can apply colors to the fill and stroke of text characters, as shown in the following script fragment
(from the TextColors tutorial script):
var myColorA, myColorB, myName;
//Access the active document and page.
var myDocument = app.activeDocument;
var myPage = app.activeWindow.activePage;
//Create a color.
try{
myColorA = myDocument.colors.item("DGC1_664a");
//If the color does not exist, trying to get its name will generate an error.
myName = myColorA.name;
}
catch (myError){
//The color style did not exist, so create it.
myColorA = myDocument.colors.add({name:"DGC1_664a", model:ColorModel.process,
colorValue:[90, 100, 70, 0]});
}
//Create another color.
try{
myColorB = myDocument.colors.item("DGC1_664b");
//If the color does not exist, trying to get its name will generate an error.
myName = myColorB.name;
}
catch (myError){
//The color style did not exist, so create it.
myColorB = myDocument.colors.add({name:"DGC1_664b", model:ColorModel.process,
colorValue:[70, 0, 30, 50]});
}
//Create a text frame on the active page.
var myTextFrame = myPage.textFrames.add();
//Set the bounds of the text frame.
myTextFrame.geometricBounds = myGetBounds(myDocument, myPage);
//Enter text in the text frame.
myTextFrame.contents = "Text\rColor"
var myText = myTextFrame.parentStory.paragraphs.item(0)
myText.pointSize = 72;
myText.justification = Justification.centerAlign;
//Apply a color to the fill of the text.
myText.fillColor = myColorA;
//Use the itemByRange method to apply the color to the stroke of the text.
myText.strokeColor = myColorB;
var myText = myTextFrame.parentStory.paragraphs.item(1)
myText.strokeWeight = 3;
myText.pointSize = 144;
myText.justification = Justification.centerAlign;
myText.fillColor = myColorB;
myText.strokeColor = myColorA;
myText.strokeWeight = 3;
Creating and applying styles
While you can use scripting to apply local formatting—as in some of the examples earlier in this
chapter—you probably will want to use character and paragraph styles to format your text. Using styles
creates a link between the formatted text and the style, which makes it easier to redefine the style, collect
the text formatted with a given style, or find and/or change the text. Paragraph and character styles are
CHAPTER 6: Text and TypeFormatting Text 98
the keys to text formatting productivity and should be a central part of any script that applies text
formatting.
The following example script fragment shows how to create and apply paragraph and character styles (for
the complete script, see CreateStyles):
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
//Create a color for use by one of the paragraph styles we'll create.
try{
myColor = myDocument.colors.item("Red");
//If the color does not exist, trying to get its name will generate an error.
myName = myColor.name;
}
catch (myError){
//The color style did not exist, so create it.
myColor = myDocument.colors.add({name:"Red", model:ColorModel.process,
colorValue:[0, 100, 100, 0]});
}
//Create a text frame on the active page.
var myTextFrame = myPage.textFrames.add();
//Set the bounds of the text frame.
myTextFrame.geometricBounds = myGetBounds(myDocument, myPage);
//Fill the text frame with placeholder text.
myTextFrame.contents = "Normal text. Text with a character style applied to it. More
normal text.";
//Create a character style named "myCharacterStyle" if
//no style by that name already exists.
try{
myCharacterStyle = myDocument.characterStyles.item("myCharacterStyle");
//If the style does not exist, trying to get its name will generate an error.
myName = myCharacterStyle.name;
}
catch (myError){
//The style did not exist, so create it.
myCharacterStyle = myDocument.characterStyles.add({name:"myCharacterStyle"});
}
//At this point, the variable myCharacterStyle contains a reference to a character
//style object, which you can now use to specify formatting.
myCharacterStyle.fillColor = myColor;
//Create a paragraph style named "myParagraphStyle" if
//no style by that name already exists.
try{
myParagraphStyle = myDocument.paragraphStyles.item("myParagraphStyle");
//If the paragraph style does not exist, trying to get its name will generate an
error.
myName = myParagraphStyle.name;
}
catch (myError){
//The paragraph style did not exist, so create it.
myParagraphStyle = myDocument.paragraphStyles.add({name:"myParagraphStyle"});
}
//At this point, the variable myParagraphStyle contains a reference to a paragraph
//style object, which you can now use to specify formatting.
myTextFrame.parentStory.texts.item(0).applyParagraphStyle(myParagraphStyle, true);
var myStartCharacter = myTextFrame.parentStory.characters.item(13);
var myEndCharacter = myTextFrame.parentStory.characters.item(54);
myTextFrame.parentStory.texts.itemByRange(myStartCharacter,
myEndCharacter).applyParagraphStyle(myParagraphStyle, true);
CHAPTER 6: Text and TypeFormatting Text 99
Why use the applyParagraphStyle method instead of setting the appliedParagraphStyle property of
the text object? The
applyParagraphStyle method gives the ability to override existing formatting;
setting the property to a style retains local formatting.
Why check for the existence of a style when creating a new document? It always is possible that the style
exists as an application default style. If it does, trying to create a new style with the same name results in an
error.
Nested styles apply character-style formatting to a paragraph according to a pattern. The following script
fragment shows how to create a paragraph style containing nested styles (for the complete script, see
NestedStyles):
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var myTextFrame = myPage.textFrames.item(0);
var myParagraphStyle = myDocument.paragraphStyles.item("myParagraphStyle");
var myNestedStyle =
myParagraphStyle.nestedStyles.add({appliedCharacterStyle:myCharacterStyle,
delimiter:".", inclusive:true, repetition:1});
var myStartCharacter = myTextFrame.parentStory.characters.item(0);
var myEndCharacter = myTextFrame.parentStory.characters.item(-1);
//Use the itemByRange method to apply the paragraph to all of the text in the story.
//(Note that the story object does not have the applyParagraphStyle method.)
myTextFrame.parentStory.texts.itemByRange(myStartCharacter,
myEndCharacter).applyParagraphStyle(myParagraphStyle, true);
Deleting a style
When you delete a style using the user interface, you can choose the way you want to format any text
tagged with that style. InDesign scripting works the same way, as shown in the following script fragment
(from the RemoveStyle tutorial script):
var myDocument = app.activeDocument;
var myParagraphStyleA = myDocument.paragraphStyles.item("myParagraphStyleA");
//Remove the paragraph style myParagraphStyleA and replace with myParagraphStyleB.
myParagraphStyleA.remove(myDocument.paragraphStyles.item("myParagraphStyleB"));
Importing paragraph and character styles
You can import character and paragraph styles from other InDesign documents, as shown in the following
script fragment (from the ImportTextStyles tutorial script):
//Create a new document.
myDocument = app.documents.add();
//Import the styles from the saved document.
//importStyles parameters:
// Format as ImportFormat enumeration. Options for text styles are:
// ImportFormat.paragraphStylesFormat
// ImportFormat.characterStylesFormat
// ImportFormat.textStylesFormat
// From as File
// GlobalStrategy as GlobalClashResolutionStrategy enumeration. Options are:
// GlobalClashResolutionStrategy.doNotLoadTheStyle
// GlobalClashResolutionStrategy.loadAllWithOverwrite
// GlobalClashResolutionStrategy.loadAllWithRename
myDocument.importStyles(ImportFormat.textStylesFormat, File("/c/styles.indd"),
GlobalClashResolutionStrategy.loadAllWithOverwrite);
CHAPTER 6: Text and TypeFinding and Changing Text 100
Finding and Changing Text
The find/change feature is one of the most powerful InDesign tools for working with text. It is fully
supported by scripting, and scripts can use find/change to go far beyond what can be done using the
InDesign user interface. InDesign has three ways of searching for text:
XYou can find text and/or text formatting and change it to other text and/or text formatting. This type
of find/change operation uses the
specify parameters for the
XYou can find text using regular expressions, or “grep.” This type of find/change operation uses the
findGrepPreferences and changeGrepPreferences objects to specify parameters for the findGrep
changeGrep methods.
and
XYou can find specific glyphs (and their formatting) and replace them with other glyphs and formatting.
findText and changeText methods.
This type of find/change operation uses the
objects to specify parameters for the
findTextPreferences and changeTextPreferences objects to
findGlyphPreferences and changeGlyphPreferences
findGlyph and changeGlyph methods.
All the find/change methods take one optional parameter,
which the results of the search are returned. If you are processing the results of a find or change operation
in a way that adds or removes text from a story, you might face the problem of invalid text references, as
discussed earlier in this chapter. In this case, you can either construct your loops to iterate backward
through the collection of returned text objects, or you can have the search operation return the results in
reverse order and then iterate through the collection normally.
About find/change preferences
Before you search for text, you probably will want to clear find and change preferences, to make sure the
settings from previous searches have no effect on your search. You also need to set some find/change
preferences to specify the text, formatting, regular expression, or glyph you want to find and/or change. A
typical find/change operation involves the following steps:
1.Clear the find/change preferences. Depending on the type of find/change operation, this can take one
of the following three forms: