InDesignCS5 Scripting Guide As
InDesignCS5 Scripting Guide As
Adobe InDesign CS5 Scripting Guide: AppleScript 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.
Contents
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
How to Use the Scripts in this Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 About the Structure of the Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 For More Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Scripting Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Script Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Getting the Current Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Script Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Targeting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interpretation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 13 13 13
Using the do script Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Sending parameters to do script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Returning values from do script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Controlling Undo with do Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Working with Script Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Running Scripts at Startup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Basic Document Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a new document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Opening a document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Saving a document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Closing a document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Basic Page Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defining page size and document length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defining bleed and slug areas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting page margins and columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Changing the appearance of the pasteboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Guides and grids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Changing measurement units and ruler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defining and applying document presets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting up master spreads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding XMP metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a document template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating watermarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adjusting Page Sizes and Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Selecting pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resizing and reframing pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Transforming pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 20 20 21 22 23 23 23 25 27 27 30 31 33 35 35 39 41 41 41 42
Contents
Master page overlay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Printing a Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Printing using page ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting print preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Printing with printer presets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting a Document as PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting to PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting PDF export options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting a range of pages to PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting individual pages to PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting PDF with Interactive Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting Pages as EPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting all pages to EPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting a range of pages to EPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exporting as EPS with file naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 43 43 47 47 47 48 49 50 51 51 52 52 52
Contents
Placing Text and Setting Text-Import Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Exporting Text and Setting Text-Export Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Understanding Text Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Working with text selections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Moving and copying text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Text objects and iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Working with Text Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Linking text frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unlinking text frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Removing a frame from a story . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Splitting all frames in a story . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating an anchored frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 90 90 93 93 93 94 94 95 96
Formatting Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Setting text defaults . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Working with fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Applying a font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Changing text properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Changing text color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Creating and applying styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Deleting a style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Importing paragraph and character styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Finding and Changing Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 About find/change preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Finding and changing text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Finding and changing text formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Using grep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Using glyph search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Working with Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Path Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Autocorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Footnotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Span Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 Setting Text Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Contents
Creating a More Complex User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Working with ScriptUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Creating a progress bar with ScriptUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Understanding the Event Scripting Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 About event properties and event propagation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 Working with Event Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Sample afterNew Event Listener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 Sample beforePrint Event Listener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 Sample Selection Event Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Sample onIdle Event Listener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Understanding the Menu Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 Localization and menu names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Running a Menu Action from a Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Adding Menus and Menu Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 Menus and Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 Working with scriptMenuActions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 A More Complex Menu-scripting Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
10
Contents
ADBE_ScaledType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 ADBE_SmallText . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 ADBE_SpotColorSetup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 ADBE_StrokeRequirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 ADBE_TextOverrides . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 ADBE_TransparencyBlending . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
11
12
XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 The Best Approach to Scripting XML in InDesign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Scripting XML Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Setting XML preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Setting XML import preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Importing XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Creating an XML tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Loading XML tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Saving XML tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Creating an XML element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Moving an XML element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Deleting an XML element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Duplicating an XML element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Removing items from the XML structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Creating an XML comment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Creating an XML processing instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Working with XML attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 Working with XML stories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Exporting XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Adding XML Elements to a Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Associating XML elements with page items and text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Marking up existing layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Applying styles to XML elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Working with XML tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
13
Contents
Why use XML rules? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 XML-rules programming model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 XML Rules Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 Setting up a sample document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Getting started with XML rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Changing the XML structure using XML rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Duplicating XML elements with XML rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 XML rules and XML attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 Applying multiple matching rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Finding XML elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 Extracting XML elements with XML rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 Applying formatting with XML rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Creating page items with XML rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 Creating Tables using XML Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 Scripting the XML-rules Processor Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
14
Introduction
This document shows how to do the following: Work with the Adobe InDesign scripting environment. Use advanced scripting features. Perform basic document tasks like setting up master spreads, printing, and exporting. Work with page items (rectangles, ellipses, graphic lines, polygons, text frames, and groups). Work with text and type in an InDesign document, including finding and changing text. Create dialog boxes and other user-interface items. Customize and add menus and create menu actions. Respond to user-interface events. Work with XML, from creating XML elements and importing XML to adding XML elements to a layout. Apply 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.
CHAPTER 1: Introduction
10
Scripting Features
This chapter covers scripting techniques related to InDesigns 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: The script preferences object and its properties. Getting a reference to the executing script. Running scripts in prior versions of the scripting object model. Using the do script method to run scripts. Working with script labels. Running scripts at InDesign start-up. 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 script preferences object provides objects and properties related to the way InDesign runs scripts. The following table provides more detail on each property of the script preferences object: Property
enable redraw scripts folder scripts list
Description 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
12
Property
user interaction level
Description This property controls the alerts and dialogs InDesign presents to the user. When you set this property to never interact, InDesign does not display any alerts or dialogs. Set it to interact with alerts to enable alerts but disable dialogs. Set it to interact with all to restore the normal display of 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 never interact before opening the document, then restore user interaction (set the property to interact with all) before completing script execution. The version of the scripting environment in use. For more information, see Script Versioning on page 12. Note this property is not the same as the version of the application.
version
When you debug scripts using a script editor, the active script property returns an error. Only scripts run from the Scripts palette appear in the active script property.
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: Targeting 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. 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. Interpretation 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 Version 5.0 Scripts (for InDesign CS3 scripts) or Version 2.0 Scripts (for InDesign CS2 scripts), or explicitly set 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.
13
Targeting
Targeting for AppleScripts is done using the tell statement. You do not need a tell statement if you run the script from the Scripts Panel, because there is an implicit tell statement for the application launching the script.
--Target InDesign CS5 tell application "Adobe InDesign CS5"
Compilation
Typically, AppleScripts are compiled using the targeted application's dictionary. This behavior may be overridden by means of the using terms from statement, which substitutes another application's dictionary for compilation purposes:
tell application "Adobe InDesign CS5" --target CS5 using terms from application "InDesign CS3" --compile using CS3 --InDesign CS2 version script goes here. end using terms from end tell
To generate a CS3 version of the AppleScript dictionary, use the publish terminology command, which is exposed on the application object. The dictionary is published into a folder (named with the version of the DOM) that is in the Scripting Support folder in your application's preferences folder. For example,
/Users/user-name/Library/Preferences/Adobe InDesign/Version 4.0/Scripting Support/4.0-J (where user-name is your user name. tell application "Adobe InDesign CS5" --publish the InDesign CS3 dictionary (version 5.0 DOM) publish terminology version 5.0 end tell
Interpretation
The InDesign application object contains a script preferences 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 set version of script preferences to 5.0
14
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 Excel for the contents of a specific spreadsheet cell, but both AppleScript and VBScript have this capability. In all these examples, the do script method can execute a snippet of scripting code in another language, to overcome a limitation of the language used for the body of the script. 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 do script 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. Embedding scripts in objects. Scripts can use the do script 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.
15
set myDocument to document 1 set myPage to page 1 of myDocument set myTextFrame to text frame 1 of myPage tell myDocument set myDestinationPage to make page end tell set myPageIndex to name of myDestinationPage set myID to id of myTextFrame set myJavaScript to "var myDestinationPage = arguments[1];" & return set myJavaScript to myJavaScript & "myID = arguments[0];" & return set myJavaScript to myJavaScript & "var myX = arguments[2];" & return set myJavaScript to myJavaScript & "var myY = arguments[3];" & return set myJavaScript to myJavaScript & "var myPageItem = app.documents.item(0).pages.item(0).pageItems.itemByID(myID);" & return set myJavaScript to myJavaScript & "myPageItem.duplicate(app.documents.item(0).pages.item(myDestinationPage));" & return --Create an array for the parameters we want to pass to the JavaScript. set myArguments to {myID, myPageIndex, 0, 0} set myDuplicate to do script myJavaScript language javascript with arguments myArguments --myDuplicate now contains a reference to the duplicated text frame. --Change the text in the duplicated text frame. set contents of myDuplicate to "Duplicated text frame."
Another way to get values from another script is to use the script args (short for script arguments) object of the application. The following script fragment shows how to do this (for the complete script, see DoScriptScriptArgs):
tell application "Adobe InDesign CS5" --Create a string to be run as an AppleScript. set myAppleScript to "tell application \"Adobe InDesign CS5\"" & return set myAppleScript to myAppleScript & "tell script args" & return set myAppleScript to myAppleScript & "set value name \"ScriptArgumentA\" value \"This is the first AppleScript script argument value.\"" & return set myAppleScript to myAppleScript & "set value name \"ScriptArgumentB\" value \"This is the second AppleScript script argument value.\"" & return set myAppleScript to myAppleScript & "end tell" & return set myAppleScript to myAppleScript & "end tell" --Run the AppleScript string. do script myAppleScript language applescript language --Retrieve the script argument values set by the script. tell script args set myScriptArgumentA to get value name "ScriptArgumentA" set myScriptArgumentB to get value name "ScriptArgumentB" end tell --Display the script argument values in a dialog box. display dialog "ScriptArgumentA: " & myScriptArgumentA & return & "ScriptArgumentB: " & myScriptArgumentB --Create a string to be run as a JavaScript.
16
set myJavaScript to "app.scriptArgs.setValue(\"ScriptArgumentA\", \"This is the first JavaScript script argument value.\");" & return set myJavaScript to myJavaScript & "app.scriptArgs.setValue(\"ScriptArgumentB\", \"This is the second JavaScript script argument value.\");" & return --Run the JavaScript string. do script myJavaScript language javascript --Retrieve the script argument values set by the script. tell script args set myScriptArgumentA to get value name "ScriptArgumentA" set myScriptArgumentB to get value name "ScriptArgumentB" end tell --Display the script argument values in a dialog box. display dialog "ScriptArgumentA: " & myScriptArgumentA & return & "ScriptArgumentB: " & myScriptArgumentB end tell
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 label, just like named items (such as paragraph styles, colors, or layers) can be referred to by their name. The following script fragment demonstrates this special case of the label property (for the complete script, see ScriptLabel):
set myDocument to make document set myPage to page 1 of myDocument set myPageWidth to page width of document preferences of myDocument set myPageHeight to page height of document preferences of myDocument --Create 10 random page items. repeat with i from 1 to 10 set myX1 to my myGetRandom(0, myPageWidth, false) set myY1 to my myGetRandom(0, myPageHeight, false) set myX2 to my myGetRandom(0, myPageWidth, false) set myY2 to my myGetRandom(0, myPageHeight, false) tell myPage set myRectangle to make rectangle with properties {geometric bounds:{myY1, myX1, myY2, myX2}} end tell if my myGetRandom(0, 1, true) = 1 then set label of myRectangle to "myScriptLabel" end if end repeat set myCount to 0 repeat with i from 1 to count of page items of myPage if label of page item i of myPage is "myScriptLabel" then set myCount to myCount + 1 end if end repeat display dialog ("Found " & myCount & " page items with the label.") --This function gets a random number in the range myStart to myEnd. on myGetRandom(myStart, myEnd, myInteger) set myRange to myEnd - myStart if myInteger = true then set myRandom to myStart + (random number from myStart to myEnd) else set myRandom to myStart + (random number from myStart to myEnd) as integer end if return myRandom end myGetRandom
In addition, all objects that support the label property also support custom labels. A script can set a custom label using the insert label method, and extract the custom label using the extract label method, as shown in the following script fragment (from the CustomLabel tutorial script):
18
tell application "Adobe InDesign CS5" set myDocument to make document tell view preferences of myDocument set horizontal measurement units to points set vertical measurement units to points end tell set myPage to page 1 of myDocument tell myPage set myRectangle to make rectangle with properties {geometric bounds:{72, 72, 144, 144}} --Insert a custom label using insert label. The first parameter is the --name of the label, the second is the text to add to the label. tell myRectangle insert label key "CustomLabel" value "This is some text stored in a custom label." --Extract the text from the label and display it in an alert. set myString to extract label key "CustomLabel" end tell display dialog ("Custom label contained: " & myString) end tell end tell
Documents
The work you do in InDesign revolves around documentscreating 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. This chapter shows you how to do the following Perform basic document-management tasks, including: Creating a new document. Opening a document. Saving a document. Closing a document. Perform basic page-layout operations, including: Setting the page size and document length. Defining bleed and slug areas. Specifying page columns and margins. Change the appearance of the pasteboard. Use guides and grids. Change measurement units and ruler origin. Define and apply document presets. Set up master pages (master spreads) Set text-formatting defaults. Add XMP metadata (information about a file). Create a document template. Create watermarks. Apply different sizes to different pages (multiple pages sizes). Print a document. Export a document as Adobe PDF. Export 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: Documents
20
To create a document using a document preset, the make command includes an optional parameter you can use to specify a document preset, as shown in the following script. (For the complete script, see MakeDocumentWithPreset.)
tell application "Adobe InDesign CS5" --Replace "myDocumentPreset" in the following line with the name --of the document preset you want to use. set myDocument to make document with properties {document preset:"myDocumentPreset"} end tell
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 "showing window" parameter controls the visibility of the document. --Hidden documents are not minimized, and will not appear until --you tell the document to create a new window. tell application "Adobe InDesign CS5" set myDocument to make document with properties {showing window:false} --To show the window: --tell myDocument --set myWindow to make window --end tell end tell
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.)
tell application "Adobe InDesign CS5" --You'll have to fill in your own file path. set myDocument to open "yukino:myTestDocument.indd" end tell
You can choose to prevent the document from displaying (that is, hide it) by setting the showing window parameter of the open command to false (the default is true). You might want to do this to improve 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):
CHAPTER 3: Documents
21
tell application "Adobe InDesign CS5" --You can use the "showing window" parameter to open files --without displaying them. This can speed up many scripting --operations, and makes it possible for a script to operate --on a file in the background. To display a document you've --opened this way, tell the document to create a new window. --You'll have to fill in your own file path. set myDocument to open "yukino:myTestDocument.indd" <lb> without showing window --At this point, your script could change or get information --from the hidden document. Once you've done that, you can show --the document window: tell myDocument to make window end tell
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 save command can do either operation, as shown in the following script fragment (from the SaveDocument tutorial script):
--Saves the active document. --If the active document has been changed since it was last saved, save it. tell application "Adobe InDesign CS5" if modified of active document is true then tell active document to save end if end tell
The save command 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. tell application "Adobe InDesign CS5" if saved of active document is false then --If you do not provide a file name, InDesign displays the Save dialog box. tell active document to save saving in "yukino:myTestDocument.indd" end if end tell
You can save a document as a template, as shown in the following script fragment (from the SaveAsTemplate tutorial script):
CHAPTER 3: Documents
22
--Save the active document as a template. tell application "Adobe InDesign CS5" set myDocument to active document tell myDocument if saved is true then --Convert the file name to a string. set myFileName to full name set myFileName to my myReplace(myFileName, ".indd", ".indt") else --If the document has not been saved, then give it a default file --name/file path. You'll have to fill in the file path. set myFileName to "yukino:myTestDocument.indt" end if save to myFileName with stationery end tell end tell on myReplace(myString, myFindString, myChangeString) set AppleScript's text item delimiters to myFindString set myTextList to every text item of (myString as text) set AppleScript's text item delimiters to myChangeString set myString to myTextList as string set AppleScript's text item delimiters to "" return myString end myReplace
Closing a document
The close command closes a document, as shown in the following script fragment (from the CloseDocument tutorial script):
tell application "Adobe InDesign CS5" close document 1 --document 1 always refers to the front-most document. --Note that you could also use: --close active document end tell
The close command can take up to two optional parameters, as shown in the following script fragment (from the CloseWithParameters tutorial script):
tell application "Adobe InDesign CS5" --Use "saving yes" to save the document, --or "saving no" to close the document without saving, --or "saving ask" to display a prompt. If you use --"saving yes",you'll need to provide a reference --to a file to save to in the second parameter (saving in). --If the file has never been saved (it's an untitled file), --display a prompt. if saved of active document is not equal to true then close active document saving ask --Or, to save to a specific file name --(you'll have to fill in the file path): --set myFile to "yukino:myTestDocument.indd" --close active document saving yes saving in myFile else --If the file has already been saved to a file, save it. close active document saving yes end if end tell
CHAPTER 3: Documents
23
You can close all open documents without saving them, as shown in the following script fragment (from the CloseAll tutorial script):
tell application "Adobe InDesign CS5" tell documents to close without saving end tell
NOTE: The application object also has a document preferences 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.
CHAPTER 3: Documents
24
tell application "Adobe InDesign CS5" --Create a new document. set myDocument to make document --The bleed and slug properties belong to the document preferences object. tell document preferences of myDocument --Bleed set document bleed bottom offset to "3p" set document bleed top offset to "3p" set document bleed inside or left offset to "3p" set document bleed outside or right offset to "3p" --Slug set slug bottom offset to "18p" set slug top offset to "3p" set slug inside or left offset to "3p" set slug right or outside offset to "3p" end tell end tell
Alternately, if all the bleed distances are equal, as in the preceding example, you can use the document bleed uniform size property, as shown in the following script fragment (from the UniformBleed tutorial script):
tell application "Adobe InDesign CS5" --Create a new document. set myDocument to make document --The bleed properties belong to the document preferences object. tell document preferences of myDocument --Bleed set document bleed top offset to "3p" set document bleed uniform size to true end tell end tell
If all the slug distances are equal, you can use the document slug uniform size property, as shown in the following script fragment (from the UniformSlug tutorial script):
tell application "Adobe InDesign CS5" --Create a new document. set myDocument to make document --The bleed properties belong to the document preferences object. tell document preferences of myDocument --Slug set document slug uniform size to true set slug top offset to "3p" end tell end tell
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 document preferences object; instead, it is in the pasteboard preferences object, as shown in the following script fragment (from the BleedSlugGuideColors tutorial script):
CHAPTER 3: Documents
25
tell application "Adobe InDesign CS5" --Assumes you have a document open. tell pasteboard preferences of active document --Any of InDesign's guides can use the UIColors constants... set bleed guide color to cute teal set slug guide color to charcoal --...or you can specify a list of RGB values --(with values from 0 to 255) set bleed guide color to {0, 198, 192} set slug guide color to {192, 192, 192} end tell end tell
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):
tell application "Adobe InDesign CS5" set myDocument to make document tell view preferences of myDocument set horizontal measurement units to points set vertical measurement units to points end tell tell margin preferences of page 1 of myDocument set top to 36 set left to 36 set bottom to 48 set right to 36 end tell end tell
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
CHAPTER 3: Documents
26
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 applications 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. 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):
tell application "Adobe InDesign CS5" set myDocument to make document tell margin preferences of page 1 of myDocument set top to 0 set left to 0 set bottom to 0 set right to 0 end tell tell master spread 1 of myDocument tell margin preferences of pages set top to 0 set left to 0 set bottom to 0 set right to 0 end tell end tell --At this point, you can set your page size to a small width --and height (1x1 picas minimum). set page height of document preferences of myDocument to "1p" set page width of document preferences of myDocument to "6p" end tell
Alternately, you can change the applications default-margin preferences before you create the document, as shown in the following script fragment (from the ApplicationPageMargins tutorial script):
CHAPTER 3: Documents
27
tell application "Adobe InDesign CS5" tell margin preferences --Save the current application default margin preferences. set myY1 to top set myX1 to left set myY2 to bottom set myX2 to right --Set the application default margin preferences. set top to 0 set left to 0 set bottom to 0 set right to 0 end tell --At this point, you can create a new document. set myDocument to make document --At this point, you can set your page size to a small width and height --(1x1 picas minimum). set page height of document preferences of myDocument to "1p" set page width of document preferences of myDocument to "1p" --Reset the application default margin preferences to their former state. tell margin preferences set top to myY1 set left to myX1 set bottom to myY2 set right to myX2 end tell end tell
CHAPTER 3: Documents
28
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.)
tell application "Adobe InDesign CS5" set myDocument to make document set myPageWidth to page width of document preferences of myDocument set myPageHeight to page height of document preferences of myDocument tell page 1 of myDocument set myMarginPreferences to margin preferences --Place guides at the margins of the page. make guide with properties {orientation:vertical, location:left of myMarginPreferences} make guide with properties {orientation:vertical, location:(myPageWidth - (right of myMarginPreferences))} make guide with properties {orientation:horizontal, location:top of myMarginPreferences} make guide with properties {orientation:horizontal, location:(myPageHeight - (bottom of myMarginPreferences))} --Place a guide at the vertical center of the page. make guide with properties {orientation:vertical, location:(myPageWidth / 2)} --Place a guide at the horizontal center of the page. make guide with properties {orientation:horizontal, location:(myPageHeight / 2)} end tell end tell
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 fit to page 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: Documents
29
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument --Create a layer named "guide layer". set myLayer to make layer with properties {name:"guide layer"} --Add a series of guides to page 1. tell page 1 --Create a guide on the layer we created above. make guide with properties {orientation:horizontal, <lb> location:"12p", item layer:myLayer} make guide with properties {item layer:myLayer, <lb> orientation:horizontal, location:"14p"} --Make a locked guide. make guide with properties {locked:true, <lb> orientation:horizontal, location:"16p"} --Set the view threshold of a guide. make guide with properties {view threshold:100, <lb> orientation:horizontal, location:"18p"} --Set the guide color of a guide using a UIColors constant. make guide with properties {guide color:gray, <lb> orientation:horizontal, location:"20p"} --Set the guide color of a guide using an RGB array. make guide with properties {guide color:{192, 192, 192}, <lb> orientation:horizontal, location:"22p"} end tell end tell end tell
You also can create guides using the create guides command on spreads and master spreads, as shown in the following script fragment (from the CreateGuides tutorial script):
tell application "Adobe InDesign CS5" set myDocument to make document tell spread 1 of myDocument --Parameters (all optional): row count, column count, row gutter, --column gutter, guide color, fit margins, remove existing, layer. --Note that the create guides command does not take an RGB --array for the guide color parameter. create guides number of rows 4 number of columns 4 row gutter "1p" <lb> column gutter "1p" guide color gray with fit margins and remove existing end tell end tell
CHAPTER 3: Documents
30
tell application "Adobe InDesign CS5" set myDocument to make document set horizontal measurement units of view preferences of myDocument to points set vertical measurement units of view preferences of myDocument to points tell grid preferences of myDocument set baseline start to 56 set baseline division to 14 set baseline grid shown to true set horizontal gridline division to 14 set horizontal grid subdivision to 5 set vertical gridline division to 14 set vertical grid subdivision to 5 set document grid shown to true end tell end tell
CHAPTER 3: Documents
31
tell application "Adobe InDesign CS5" set myDocument to active document tell view preferences of myDocument --Measurement unit choices are: --picas, points, inches, inches decimal, millimeters, centimeters, or ciceros --Set horizontal and vertical measurement units to points. set horizontal measurement units to points set vertical measurement units to points end tell end tell
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):
tell application "Adobe InDesign CS5" set myDocument to active document tell view preferences of myDocument set myOldXUnits to horizontal measurement units set myOldYUnits to vertical measurement units set horizontal measurement units to points set vertical measurement units to points end tell --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. tell view preferences of myDocument set horizontal measurement units to myOldXUnits set vertical measurement units to myOldYUnits end tell end tell
CHAPTER 3: Documents
32
tell application "Adobe InDesign CS5" if (count documents) > 0 then set myDocument to active document --If the document preset "myDocumentPreset" --does not already exist, create it. try set myDocumentPreset to document preset "myDocumentPreset" on error set myDocumentPreset to make document preset with properties {name:"myDocumentPreset"} end try --Fill in the properties of the document preset --with the corresponding --properties of the active document. tell 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 "myDocument" with "active page of active window" in the --following line (assuming the active window is a layout window). set myMarginPreferences to margin preferences of myDocument set left to left of myMarginPreferences set right to right of myMarginPreferences set top to top of myMarginPreferences set bottom to bottom of myMarginPreferences set column count to column count of myMarginPreferences set column gutter to column gutter of myMarginPreferences set document bleed bottom offset to document bleed bottom offset of document preferences of myDocument set document bleed top offset to document bleed top offset of document preferences of myDocument set document bleed inside or left offset to document bleed inside or left offset of document preferences of myDocument set document bleed outside or right offset to document bleed outside or right offset of document preferences of myDocument set facing pages to facing pages of document preferences of myDocument set page height to page height of document preferences of myDocument set page width to page width of document preferences of myDocument set page orientation to page orientation of document preferences of myDocument set pages per document to pages per document of document preferences of myDocument set slug bottom offset to slug bottom offset of document preferences of myDocument set slug top offset to slug top offset of document preferences of myDocument set slug inside or left offset to slug inside or left offset of document preferences of myDocument set slug right or outside offset to slug right or outside offset of document preferences of myDocument end tell end if end tell
CHAPTER 3: Documents
33
tell application "Adobe InDesign CS5" --If the document preset "myDocumentPreset" does not already exist, create it. try set myDocumentPreset to document preset "myDocumentPreset" on error set myDocumentPreset to make document preset with properties {name:"myDocumentPreset"} end try --Fill in the properties of the document preset. tell myDocumentPreset set page height to "9i" set page width to "7i" set left to "4p" set right to "6p" set top to "4p" set bottom to "9p" set column count to 1 set document bleed bottom offset to "3p" set document bleed top offset to "3p" set document bleed inside or left offset to "3p" set document bleed outside or right offset to "3p" set facing pages to true set page orientation to portrait set pages per document to 1 set slug bottom offset to "18p" set slug top offset to "3p" set slug inside or left offset to "3p" set slug right or outside offset to "3p" end tell end tell
CHAPTER 3: Documents
34
set top to "4p" end tell --Add a simple footer with a section number and page number. tell page 1 set myTextFrame to make text frame with properties {geometric bounds:{"61p", "4p", "62p", "45p"}} tell myTextFrame set contents of insertion point 1 to section marker set contents of insertion point 1 to Em space set contents of insertion point 1 to auto page number set justification of paragraph 1 to left align end tell end tell --Set up the right page (recto). tell margin preferences of page 2 set column count to 3 set column gutter to "1p" set bottom to "6p" --"left" means inside, "right" means outside. set left to "6p" set right to "4p" set top to "4p" end tell --Add a simple footer with a section number and page number. tell page 2 set myTextFrame to make text frame with properties {geometric bounds:{"61p", "6p", "62p", "47p"}} tell myTextFrame set contents of insertion point 1 to auto page number set contents of insertion point 1 to Em space set contents of insertion point 1 to section marker set justification of paragraph 1 to right align end tell end tell end tell end tell
To apply a master spread to a document page, use the applied master 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 document pages. tell application "Adobe InDesign CS5" tell active document set applied master of page 2 to master spread "B-Master" end tell end tell
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. tell application "Adobe InDesign CS5" tell active document set applied master of page 2 of master spread 1 to master spread "B-Master" end tell end tell
CHAPTER 3: Documents
35
CHAPTER 3: Documents
36
tell application "Adobe InDesign CS5" --Make a new document. set myDocument to make document tell myDocument tell document preferences set page width to "7i" set page height to "9i" set page orientation to portrait end tell tell margin preferences set top to ((14 * 4) & "pt") as string set left to ((14 * 4) & "pt") as string set bottom to "74pt" set right to ((14 * 5) & "pt") as string end tell --Set up the bleed and slug areas. tell document preferences --Bleed set document bleed bottom offset to "3p" set document bleed top offset to "3p" set document bleed inside or left offset to "3p" set document bleed outside or right offset to "3p" --Slug set slug bottom offset to "18p" set slug top offset to "3p" set slug inside or left offset to "3p" set slug right or outside offset to "3p" end tell --Create a color. try set myColor to color "PageNumberRed" on error set myColor to make color with properties {name:"PageNumberRed", model:process, color value:{20, 100, 80, 10}} end try --Next, set up some default styles. --Create up a character style for the page numbers. try set myCharacterStyle to character style "page_number" on error set myCharacterStyle to make character style with properties {name:"page_number"} end try set fill color of myCharacterStyle to color "PageNumberRed" --Create up a pair of paragraph styles for the page footer text. --These styles have only basic formatting. try set myParagraphStyle to paragraph style "footer_left" on error set myParagraphStyle to make paragraph style with properties {name:"footer_left"} end try --Create up a pair of paragraph styles for the page footer text. try set myParagraphStyle to paragraph style "footer_right" on error set myParagraphStyle to make paragraph style with properties {name:"footer_right", based on:paragraph style "footer_left", justification:right align} end try
CHAPTER 3: Documents
37
--Create a layer for guides. try set myLayer to layer "GuideLayer" on error set myLayer to make layer with properties {name:"GuideLayer"} end try --Create a layer for the footer items. try set myLayer to layer "Footer" on error set myLayer to make layer with properties {name:"Footer"} end try --Create a layer for the slug items. try set myLayer to layer "Slug" on error set myLayer to make layer with properties {name:"Slug"} end try --Create a layer for the body text. try set myLayer to layer "BodyText" on error set myLayer to make layer with properties {name:"BodyText"} end try tell view preferences set ruler origin to page origin set horizontal measurement units to points set vertical measurement units to points end tell --Document baseline grid and document grid tell grid preferences set baseline start to 56 set baseline division to 14 set baseline grid shown to false set horizontal gridline division to 14 set horizontal grid subdivision to 5 set vertical gridline division to 14 set vertical grid subdivision to 5 set document grid shown to false end tell --Document XMP information. tell metadata preferences set author to "Adobe" set copyright info URL to "http:--www.adobe.com" set copyright notice to "This document is not copyrighted." set copyright status to no set description to "Example 7 x 9 book layout" set document title to "Example" set job name to "7 x 9 book layout template" set keywords to {"7 x 9", "book", "template"} set myNewContainer to create container item namespace "http://ns.adobe.com/xap/1.0/" path "email" set property namespace "http://ns.adobe.com/xap/1.0/" path "email/*[1]" value "[email protected]" end tell --Set up the master spread. tell master spread 1 tell page 1 set myMarginPreferences to margin preferences set myBottomMargin to (page height of document preferences of
CHAPTER 3: Documents
38
myDocument - (bottom of myMarginPreferences) set myLeftMargin to right of myMarginPreferences set myRightMargin to (page width of document preferences of myDocument) - (left of myMarginPreferences) make guide with properties {orientation:vertical, location:myRightMargin,item layer:layer "GuideLayer" of myDocument} make guide with properties {orientation:vertical, location:myLeftMargin,item layer:layer "GuideLayer" of myDocument} make guide with properties {orientation:horizontal, location:top of myMarginPreferences, item layer:layer "GuideLayer" of myDocument, fit to page:false} make guide with properties {orientation:horizontal, location:myBottomMargin, item layer:layer "GuideLayer" of myDocument, fit to page:false} make guide with properties {orientation:horizontal, location:myBottomMargin + 14, item layer:layer "GuideLayer" of myDocument, fit to page:false} make guide with properties {orientation:horizontal, location:myBottomMargin + 28, item layer:layer "GuideLayer" of myDocument, fit to page:false} set myLeftFooter to make text frame with properties {item layer:layer "Footer" of myDocument, geometric bounds:{myBottomMargin + 14, right of myMarginPreferences, myBottomMargin + 28, myRightMargin}} set contents of insertion point 1 of parent story of myLeftFooter to section marker set contents of insertion point 1 of parent story of myLeftFooter to Em space set contents of insertion point 1 of parent story of myLeftFooter to auto page number set applied character style of character 1 of parent story of myLeftFooter to character style "page_number" of myDocument set applied paragraph style of paragraph 1 of parent story of myLeftFooter to paragraph style "footer_left" of myDocument --Slug information. tell metadata preferences of myDocument set myEmail to get property namespace "http://ns.adobe.com/xap/1.0/" path "email/*[1]" set myDate to current date set myString to "Author:" & tab & author & tab & "Description:" & tab & description & return & "Creation Date:" & tab & myDate & tab & "Email Contact" & tab & myEmail end tell set myLeftSlug to make text frame with properties {item layer:layer "Slug" of myDocument, geometric bounds:{(page height of document preferences of myDocument) + 36, right of myMarginPreferences, (page height of document preferences of myDocument) + 144, myRightMargin}, contents:myString} tell parent story of myLeftSlug convert to table text 1 end tell --Body text master text frame. set myLeftFrame to make text frame with properties {item layer:layer "BodyText" of myDocument, geometric bounds:{top of myMarginPreferences, right of myMarginPreferences, myBottomMargin, myRightMargin}} end tell tell page 2 set myMarginPreferences to margin preferences
CHAPTER 3: Documents
39
set myLeftMargin to left of myMarginPreferences set myRightMargin to (page width of document preferences of myDocument) - (right of myMarginPreferences) make guide with properties {orientation:vertical, location:myLeftMargin,item layer:layer "GuideLayer" of myDocument} make guide with properties {orientation:vertical, location:myRightMargin, item layer:layer "GuideLayer" of myDocument} set myRightFooter to make text frame with properties {item layer:layer "Footer" of myDocument, geometric bounds:{myBottomMargin + 14, left of myMarginPreferences, myBottomMargin + 28, myRightMargin}} set contents of insertion point 1 of parent story of myRightFooter to auto page number set contents of insertion point 1 of parent story of myRightFooter to Em space set contents of insertion point 1 of parent story of myRightFooter to section marker set applied character style of character -1 of parent story of myRightFooter to character style "page_number" of myDocument set applied paragraph style of paragraph 1 of parent story of myRightFooter to paragraph style "footer_right" of myDocument --Slug information. set myRightSlug to make text frame with properties {item layer:layer "Slug" of myDocument, geometric bounds:{(page height of document preferences of myDocument) + 36, left of myMarginPreferences,(page height of document preferences of myDocument) + 144,myRightMargin}, contents:myString} tell parent story of myRightSlug convert to table text 1 end tell --Body text master text frame. set myRightFrame to make text frame with properties {item layer:layer "BodyText" of myDocument, geometric bounds:{top of myMarginPreferences, left of myMarginPreferences, myBottomMargin, myRightMargin}} end tell end tell --Add section marker text--this text will appear in the footer. set marker of section 1 of myDocument to "Section 1" --When you link the master page text frames, one of the frames sometimes --becomes selected. Deselect it. select nothing end tell end tell
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 documents watermark preferences can be set in two ways using scripting: Application-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. Document-level watermark preferences apply only to that document. Setting or changing a documents watermark preferences replaces any previous watermark settings for the document.
CHAPTER 3: Documents
40
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.
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.)
tell watermark preferences of document 1 set watermark visibility to true set watermark do print to true set watermark draw in back to true set watermark text to "Confidential" set watermark font family to "Arial" set watermark font style to "Bold" set watermark font point size to 72 set watermark font color to blue set watermark opacity to 60 set watermark rotation to -45 set watermark horizontal position to watermark h center set watermark horizontal offset to 0 set watermark vertical position to watermark v center set watermark vertical offset to 0 end tell
Disabling watermarks
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.
tell application "Adobe InDesign CS5" set watermark visibility of watermark preferences to false end tell
CHAPTER 3: Documents
41
You can turn off watermarks in an individual document at any time, as shown in the following script fragment.
tell application "Adobe InDesign CS5" tell document 1 set watermark visibility of watermark preferences to false end tell end tell
Selecting pages
Before changing a pages 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 (1, 2, 3, 4)... set myPages to pages of active document --Select page 2 and 3. select item 2 of myPages select item 3 of myPages existing selection add to --Select last page. select item -1 of myPages existing selection add to
Reframing changes the bounding box of a page, so reframing can be used to change a pages size by making the bounding box larger or smaller. The following script shows how to change a pages size using the reframe method. (For the complete script, see PageReframe.)
CHAPTER 3: Documents
42
--Given a document with four pages (1, 2, 3, 4)... tell item 2 of pages of active document --Make the page one inch wider and one inch higher. set myBounds to bounds set myY1 to item 1 of myBounds set myX1 to item 2 of myBounds set myY2 to (item 3 of myBounds) + 72 set myX2 to (item 4 of myBounds) + 72 reframe in inner coordinates opposing corners {{myX1, myY1}, {myX2, myY2}} end tell
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 page: 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.)
--Given a document with four pages (1, 2, 3, 4)... set myDocument to active document set myPages to pages of myDocument --Rotate a page around its center point. set myRotateMatrix to make transformation matrix with properties {counterclockwise rotation angle:27} my myTransform(item 1 of myPages, myRotateMatrix) --Scale a page around its center point. set myScaleMatrix to make transformation matrix with properties {horizontal scale factor:0.8, vertical scale factor:0.8} my myTransform(item 2 of myPages, myScaleMatrix) --Shear a page around its center point. set myShearMatrix to make transformation matrix with properties {clockwise shear angle:30} my myTransform(item 3 of myPages, myShearMatrix) on myTransform(myPage, myTransformationMatrix) tell application "Adobe InDesign CS5" transform myPage in pasteboard coordinates from center anchor with matrix myTransformationMatrix end tell end myTransform
CHAPTER 3: Documents
Printing a Document
43
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 (1, 2, 3, 4)... set myDocument to active document set myPages to pages of myDocument --Rotate master page overlay around its top-left corner. set myRotateMatrix to make transformation matrix with properties {counterclockwise rotation angle:27} set master page transform of item 1 of myPages to myRotateMatrix --Scale master page overlay around its top-left corner. set myScaleMatrix to make transformation matrix with properties {horizontal scale factor:0.5, vertical scale factor:0.5} set master page transform of item 2 of myPages to myScaleMatrix --Shear master page overlay around its top-left corner. set myShearMatrix to make transformation matrix with properties {clockwise shear angle:30} set master page transform of item 3 of myPages to myShearMatrix --Translate master page overlay 1 inch right and 2 inches down. set myTranslateMatrix to make transformation matrix with properties {horizontal translation:72, vertical translation:144} set master page transform of item 4 of myPages to myTranslateMatrix
Printing a Document
The following script prints the active document using the current print preferences. (For the complete script, see PrintDocument.)
tell application "Adobe InDesign CS5" print active document end tell
CHAPTER 3: Documents
Printing a Document
44
--PrintPreferences.as --An InDesign CS5 AppleScript --Sets the print preferences of the active document. tell application "Adobe InDesign CS5" --Get the bleed amounts from the document's bleed and add a bit. tell document preferences of active document set myX1Offset to document bleed inside or left offset + 3 set myY1Offset to document bleed top offset + 3 set myX2Offset to document bleed outside or right offset + 3 set myY2Offset to document bleed bottom offset + 3 end tell tell print preferences of active document --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 --postscript file. set printer to postscript file --Here's an example of setting the printer to a specific printer. --set printer to "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). try --set PPD to "Device Independent" end try --If the printer property is set to postscript file, the copies --property is unavailable. Attempting to set it will generate an error. --set copies to 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. --set collating to false set reverse order to false --The setting of color output determines the settings available --to almost all other properties in the print preferences. try set color output to separations end try --pageRange can be either PageRange.allPages or a page range string. set page range to all pages set print spreads to false set print master pages to false --If the printer property is set to postScript file, then --the print file property contains the file path to the output file. --set printFile to "yukino:test.ps" set sequence to all --If trapping is on, setting the following properties --will produce an error. try if trapping is off then set print blank pages to false set print guides grids to false set print nonprinting to false end if end try ------------------------------------------------------------------------Properties corresponding to the controls in the Setup panel of --the Print dialog. -----------------------------------------------------------------------
CHAPTER 3: Documents
Printing a Document
45
set paper size to custom --Page width and height are ignored if paper Size is not custom. --set paper height to 1200 --set paper width to 1200 set print page orientation to portrait set page position to centered set paper gap to 0 set paper offset to 0 set paper transverse to false set scale height to 100 set scale width to 100 set scale mode to scale width height set scale proportional to true --If trapping is on (application built in or Adobe inRip), --attempting to set the following properties will produce an error. if trapping is off then set thumbnails to false --The following properties are not needed because thumbnails is set to false. --set thumbnails per page to 4 set tile to false --The following properties are not needed because tile is set to false. --set tiling overlap to 12 --set tiling type to auto end if ------------------------------------------------------------------------Properties corresponding to the controls in the Marks and Bleed --panel of the Print dialog. ------------------------------------------------------------------------Set the following property to true to print all printer's marks. --set all Printer Marks to true; set use document bleed to print to false --If use document bleed to print is true then setting any of the -- bleed properties --will result in an error. set bleed bottom to myY2Offset set bleed top to myY1Offset set bleed inside to myX1Offset set bleed outside to myX2Offset --If any bleed area is greater than zero, then export the bleed marks. if bleed bottom is equal to 0 and bleed top is equal to 0 and bleed inside is equal to 0 and bleed outside is equal to 0 then set bleed marks to true else set bleed marks to false end if set color bars to true set crop marks to true set include slug to print to false set mark line weight to p125pt set mark offset to 6 --set mark Type to default set page information marks to true set registration marks to true ------------------------------------------------------------------------Properties corresponding to the controls in the Output panel --of the Print dialog. ----------------------------------------------------------------------set negative to true set color output to separations --Note the lowercase "i" in "Builtin"
CHAPTER 3: Documents
Printing a Document
46
set trapping to application builtin set screening to "175 lpi/2400 dpi" set flip to none --If trapping is on, attempting to set the following properties --will generate an error. if trapping is off then set print black to true set print cyan to true set print magenta to true set print yellow to true end if --Only change the ink angle and frequency when you want to override the --screening set by the screening specified by the screening property. --set black angle to 45 --set black frequency to 175 --set cyan angle to 15 --set cyan frequency to 175 --set magenta angle to 75 --set magenta frequency to 175 --set yellow angle to 0 --set yellow frequency to 175 --The following properties are not needed (because colorOutput --is set to separations). --set composite angle to 45 --set composite frequency to 175 --set simulate overprint to false ------------------------------------------------------------------------Properties corresponding to the controls in the Graphics panel --of the Print dialog. ----------------------------------------------------------------------set send image data to all image data set font downloading to complete try set download PPD fonts to true end try try set data format to binary end try try set PostScript level to level 3 end try ------------------------------------------------------------------------Properties corresponding to the controls in the Color Management panel --of the Print dialog. ------------------------------------------------------------------------If the use color management property of color settings is false, --attempting to set the following properties will return an error. try set source space to use document set intent to use color settings set CRD to use document set profile to PostScript CMS end try -----------------------------------------------------------------------
CHAPTER 3: Documents
--Properties corresponding to the controls in the Advanced panel --of the Print dialog. ----------------------------------------------------------------------set OPI image replacement to false set omit bitmaps to false set omit EPS to false set omit PDF to false --The following line assumes that you have a flattener preset --named "high quality flattener". try set flattener preset name to "high quality flattener" end try set ignore spread overrides to false end tell end tell
Exporting to PDF
The following script exports the current document as PDF, using the current PDF export options. (For the complete script, see ExportPDF.)
tell application "Adobe InDesign CS5" tell active document --You'll have to fill in a valid file path for your system. export format PDF type to "yukino:test.pdf" without showing options end tell end tell
The following script fragment shows how to export to PDF using a PDF export preset. (For the complete script, see ExportPDFWithPreset.)
tell application "Adobe InDesign CS5" tell active document --You'll have to fill in a valid file path for your system and --a valid PDF export preset name. export format PDF type to "yukino:test.pdf" using PDF export preset "myTestPreset" without showing options end tell end tell
CHAPTER 3: Documents
CHAPTER 3: Documents
--Printers marks and prepress options. set bleed bottom to myY2Offset set bleed top to myY1Offset set bleed inside to myX1Offset set bleed outside to myX2Offset --If any bleed area is greater than zero, then export the bleed marks. if bleed bottom is 0 and bleed top is 0 and bleed inside is 0 and bleed outside is 0 then set bleed marks to true else set bleed marks to false end if set color bars to true --Color tile size and gray tile size are not used --unless the compression method chosen is JPEG 2000. --set color tile size to 256 --set Gray tile size to 256 set crop marks to true set omit bitmaps to false set omit EPS to false set omit PDF to false set page information marks to true set page marks offset to "12 pt" set PDF color space to unchanged color space set PDF mark type to default set printer mark weight to p125pt set registration marks to true --simulate overprint is only available when the export standard --is PDF/X-1a or PDF/X-3 --set simulate overprint to false set use document bleed with PDF to true --Set viewPDF to true to open the PDF in Acrobat or Adobe Reader. set view PDF to false end tell --Now export the document. tell active document --You'll have to fill in a valid file path for your system. export format PDF type to "yukino:test.pdf" without showing options end tell end tell
CHAPTER 3: Documents
--Assumes you have a document open, and that that document --contains at least 12 pages. tell application "Adobe InDesign CS5" tell PDF export preferences --page range can be either all pages or a page range string --(just as you would enter it in the Print or Export PDF dialog box). set page range to "1, 3-6, 7, 9-11, 12" end tell tell active document --You'll have to fill in a valid file path for your system and --a valid PDF export preset name. export format PDF type to "yukino:test.pdf" using PDF export preset "myTestPreset" without showing options end tell end tell
CHAPTER 3: Documents
51
destroy myDialog repeat with myCounter from 1 to (count pages in myDocument) set myPageName to name of page myCounter of myDocument set page range of PDF export preferences to name of page myCounter of myDocument --Generate a file path from the folder name, the base document --name, and the page name. --Replace any colons in the page name (e.g., "Sec1:1") so that --they don't cause problems with file naming. set myPageName to my myReplace(myPageName, ":", "_") set myFilePath to myFolder & myBaseName & "_" & myPageName & ".pdf" tell myDocument --The export command will fail if you provide the file path --as Unicode text--that's why we had to convert the folder name --to plain text. export format PDF type to myFilePath end tell end repeat else destroy myDialog end if end tell end myExportPages on myReplace(myString, myFindString, myChangeString) set AppleScript's text item delimiters to myFindString set myTextList to every text item of (myString as text) set AppleScript's text item delimiters to myChangeString set myString to myTextList as string set AppleScript's text item delimiters to "" return myString end myReplace
CHAPTER 3: Documents
52
CHAPTER 3: Documents
53
end myChooseFolder on myExportPages(myFolder) tell application "Adobe InDesign CS5" set myDocument to active document set myDocumentName to name of myDocument set myDialog to make dialog with properties {name:"ExportPages"} tell myDialog tell (make dialog column) tell (make dialog row) make static text with properties {static label:"Base Name:"} set myBaseNameField to make text editbox with properties {edit contents:myDocumentName, min width:160} end tell end tell end tell set myResult to show myDialog if myResult is true then --The name of the exported files will be the base name + the --value of the counter + ".pdf". set myBaseName to edit contents of myBaseNameField --Remove the dialog box from memory. destroy myDialog repeat with myCounter from 1 to (count pages in myDocument) --Get the name of the page and assign it to the variable "myPageName" set myPageName to name of page myCounter of myDocument --Set the page range to the name of the specific page. set page range of EPS export preferences to myPageName --Generate a file path from the folder name, the base document --name, and the page name. --Replace any colons in the page name (e.g., "Sec1:1") so that --they don't cause problems with file naming. set myPageName to my myReplace(myPageName, ":", "_") set myFilePath to myFolder & myBaseName & "_" & myPageName & ".eps" tell myDocument export format EPS type to myFilePath without showing options end tell end repeat else destroy myDialog end if end tell end myExportPages on myReplace(myString, myFindString, myChangeString) set AppleScript's text item delimiters to myFindString set myTextList to every text item of (myString as text) set AppleScript's text item delimiters to myChangeString set myString to myTextList as string set AppleScript's text item delimiters to "" return myString end myReplace
54
Scripting Layers
55
Scripting Layers
In InDesigns 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"... tell myDocument set myLayer to make layer end tell
When you create a new layer, the layer appears above all other layers in the document.
Scripting Layers
56
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.
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.
Scripting Layers
57
Deleting layers
Use the delete 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"... set myLayer to layer "Delete This Layer" of myDocument tell myLayer delete end tell
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... set myLayerA to layer 1 of myDocument set myLayerB to layer 2 of myDocument tell myLayer1 move to after myLayer2 end tell
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"... tell myLayer set myNewLayer to duplicate end tell
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"... tell myLayer1 merge with myLayer2 end tell
Scripting Layers
58
--Given a reference to a page "myPage," and a document "myDocument"... tell myPage --Create a text frame on a layer named "TextFrames" set myTextFrame to make text frame with properties {item layer:layer "TextFrames", geometric bounds:{72, 72, 144, 144}} --Create a rectangle on the current target layer. set myRectangle to make rectangle with properties {geometric bounds:{72, 144, 144, 216}} --Move the rectangle to a specific layer. set item layer of myRectangle to layer "Rectangles" of myDocument --Create a series of ovals. repeat with myCounter from 72 to 172 by 10 make oval with properties {geometric bounds:{216, myCounter, 226, myCounter + 10}} end repeat --Move all of the ovals on the page to a specific layer. repeat with myCounter from 1 to (count ovals) set item layer of oval myCounter to layer "Ovals" of myDocument end repeat end tell
Scripting Layers
59
Scripting Layers
60
Locking layers
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"... tell myDocument set myLayer to active layer repeat with myCounter from ((index of myLayer) + 1) to (count layers) set locked of layer myCounter to true end repeat end tell
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... tell myPage set myRectangle to make rectangle with properties {geometric bounds:{72, 72, 144, 144}} end tell
61
62
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 change the type to a graphic line. The only things that define the type of a rectangle, ellipse, graphic line, or polygon are: The number of paths in the object. Any page item with more than one path is a polygon. The number and location of points on the first path in the object. To determine the type of a page item, use this example:
set myPageItemType to class of myPageItem
The result of the above will be a string containing the type of the page item.
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 all page items property.
set myAllPageItems to all page items of page 1 of document 1
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 myLabel.
set myPageItems to page items whose label is "myLabel" of page 1 of document 1
If no page items on the page have the specified label, InDesign returns an empty array.
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
63
you use the Control panel in InDesigns user interface, you probably are already familiar with InDesigns geometry, but here is a quick summary: Object are constructed relative to the coordinates shown on the rulers. Changing the zero point location by either dragging the zero point or by changing the ruler origin changes the coordinates on the rulers. Page 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. Path 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.
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):
{{{xL1, YL1}, {x1, y1}, {xR1, yR1}}, {{xL2, YL2}, {x2, y2}, {xR2, yR2}}, ...}
Where xL and yL specify the left direction, x and y specify the anchor point, and xR and yR specify the right direction. You can also mix the two approaches, as shown in the following example:
{{{xL1, YL1}, {x1, y1}, {xR1, yR1}}, {x2, y2}, ...}
Note that the original path does not have to have the same number of points as you specify in the arrayInDesign will add or subtract points from the path as it applies the array to the entire path property. The AddPathPoint script shows how to add path points to a path without using the entire path property.
64
--Given a graphic line "myGraphicLine"... tell path 1 of myGraphicLine set myPathPoint to add path point end tell --Move the path point to a specific location. set anchor of myPathPoint to {144, 144}
The DeletePathPoint script shows how to delete a path point from a path.
--Given a polygon "myPolygon", remove the --last path point in the first path. tell path 1 of myPolgon delete path point -1 end tell
To ungroup, you tell the group itself to ungroup, as shown in the Ungroup script.
--Given a group "myGroup"... tell myGroup set myPageItems to ungroup end tell
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.
65
point. move by 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: tell myRectangle move to {12, 12} end tell --Move the rectangle *by* 12 points horizontally, 12 points vertically. --Relative move: tell myRectangle move by {12, 12} end tell --Move the rectangle to another page (rectangle appears at (0,0); tell document 1 set myPage to make page end tell tell myRectangle move to myPage end tell --To move a page item to another document, use the duplicate method.
Note that the move method truly moves the objectwhen 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: tell myRectangle set myDuplicate to duplicate to {12, 12} end tell --Duplicate the rectangle and move the duplicate *by* 12 --points horizontally, 12 points vertically. --Relative move: tell myRectangle set myDuplicate to duplicate by {12, 12} end tell --Duplicate the rectangle to another page (rectangle appears at (0,0). tell document 1 set myPage to make page end tell tell myRectangle set myDuplicate do duplicate to myPage end tell --Duplicate the rectangle to another document. set myDocument to make document tell myRectangle myDuplicate to page 1 of myDocument end tell
66
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.
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 release compound path command of a page item, as shown in the following script fragment (for the complete script, refer to the ReleaseCompoundPath script).
--Given a polygon "myPolygon"... tell myPolygon set myPageItems to release compound path end tell
67
The exclude overlap path command 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"... tell myRectangle exclude overlap path with myOval end tell
The intersect path command 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"... tell myRectangle intersect path with myOval end tell
The minus back command 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"... tell myRectangle minus back with myOval end tell
The subtract path command 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"... tell myOval subtract with myRectangle end tell
The convert shape command also provides a way to open or close reverse paths, as shown in the following script fragment (for the complete script, refer to OpenPath).
--Given a rectangle "myRectangle"... tell myRectangle convert shape given convert to open path end tell
68
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... tell myRectangle set item layer to layer "myLayer" of document 1 end tell
The stacking order of layers in a document can also be changed using the move move command 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. tell myLayer move to end of layers of document 1 end tell
69
transformation, or transformation origin. For more on specifying the transformation origin, see Transformation origin on page 72. 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. set myRotateMatrix to make transformation matrix with properties {counterclockwise rotation angle:27} transform myRectangle in pasteboard coordinates from center anchor with matrix myRotateMatrix --Scale a rectangle "myRectangle" around its center point. set myScaleMatrix to make transformation matrix with properties {horizontal scale factor:.5, vertical scale factor:.5} transform myRectangle in pasteboard coordinates from center anchor with matrix myScaleMatrix --Shear a rectangle "myRectangle" around its center point. set myShearMatrix to make transformation matrix with properties {clockwise shear angle: 30} transform myRectangle in pasteboard coordinates from center anchor with matrix myShearMatrix --Rotate a rectangle "myRectangle" around a specified ruler point ({72, 72}). set myRotateMatrix to make transformation matrix with properties {counterclockwise rotation angle:27} transform myRectangle in pasteboard coordinates from {{72, 72}, center anchor} with matrix myRotateMatrix with considering ruler units --Scale a rectangle "myRectangle" around a specified ruler point ({72, 72}). set myScaleMatrix to make transformation matrix with properties {horizontal scale factor:.5, vertical scale factor:.5} transform myRectangle in pasteboard coordinates from {{72, 72}, center anchor} with matrix myScaleMatrix with considering ruler units
For a script that wraps transformation routines in a series of easy-to-use handlers, refer to the Transform script.
When you use the rotate matrix 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.
70
set myRectangle to rectangle 1 of page 1 of document 1 set myTransformationMatrix to make transformation matrix --rotate matrix can take the following parameters: byAngle, byCosine, bySine; --The following statements are equivalent (0.25881904510252 is the sine of 15 degrees, 0.96592582628907 is the cosine). set myTransformationMatrix to rotate matrix myTransformationMatrix by angle 15 set myTransformationMatrix to rotate matrix myTransformationMatrix by cosine 0.965925826289 set myTransformationMatrix to rotate matrix myTransformationMatrix by sine 0.258819045103 --Rotate the rectangle by the rotated matrix--45 degrees. transform myRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrix
When you use the shear matrixmethod, you can provide a slope, rather than an angle in degrees, as shown in the ShearMatrix script.
set myRectangle to rectangle 1 of page 1 of document 1 set myTransformationMatrix to make transformation matrix --shear matrix can take the following parameters: by angle, by slope --The following statements are equivalent. slope = rise/run --so a 45 degree slope is 1. set myTransformationMatrix to shear matrix myTransformationMatrix by slope 1 --Shear the rectangle. transform myRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrix
You can get the inverse of a transformation matrix using the invert matrixmethod, 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.
set myRectangle to rectangle 1 of page 1 of document 1 set myTransformationMatrix to make transformation matrix with properties {counterclockwise rotation angle:30, horizontal translation:12, vertical translation:12} transform myRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrix set myNewRectangle to duplicate myRectangle --Move the duplicated rectangle to the location of the original --rectangle by inverting, then applying the transformation matrix. set myTransformationMatrix to invert matrix myTransformationMatrix transform myNewRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrix
You can add transformation matrices using the catenate matrixmethod, as shown in the following example. (For the complete script, see CatenateMatrix.)
71
set myTransformationMatrixA to make transformation matrix with properties {counterclockwise rotation angle:30} set myTransformationMatrixB to make transformation matrix with properties {horizontal translation:72, vertical translation:72} set myRectangle to rectangle -1 of page 1 of document 1 set myNewRectangle to duplicate myRectangle --Rotate the duplicated rectangle. transform myNewRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrixA set myNewRectangle to duplicate myRectangle --Move the duplicate (unrotated) rectangle. transform myNewRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrixB --Merge the two transformation matrices. set myTransformationMatrix to catenate matrix myTransformationMatrixA with matrix myTransformationMatrixB set myNewRectangle to duplicate myRectangle --The duplicated rectangle will be both moved and rotated. transform myNewRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrix
When an object is transformed, you can get the transformation matrix that was applied to it, using the transform values of method, as shown in the following script fragment. (For the complete script, see TransformValuesOf.)
set myRectangle to rectangle -1 of page 1 of document 1 --Note that transform values of always returns a list containing a --single transformation matrix. set myTransformArray to transform values of myRectangle in pasteboard coordinates set myTransformationMatrix to item 1 of myTransformArray set myRotationAngle to counterclockwise rotation angle of myTransformationMatrix set myShearAngle to clockwise shear angle of myTransformationMatrix set myXScale to horizontal scale factor of myTransformationMatrix set myYScale to vertical scale factor of myTransformationMatrix set myXTranslate to horizontal translation of myTransformationMatrix set myYTranslate to vertical translation of myTransformationMatrix set myString to "Rotation Angle: " & myRotationAngle & return set myString to myString & "Shear Angle: " & myShearAngle & return set myString to myString & "Horizontal Scale Factor: " & myXScale & return set myString to myString & "Vertical Scale Factor: " & myYScale & return set myString to myString & "Horizontal Translation: " & myXTranslate & return set myString to myString & "Vertical Translation: " & myYTranslate & return & return set myString to myString & "Note that the Horizontal Translation and" & return set myString to myString & "Vertical Translation values are the location" & return set myString to myString & "of the center anchor in pasteboard coordinates." display dialog (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 pasteboard coordinates 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:
72
pasteboard coordinates is the coordinate space of the entire InDesign document. This coordinate
space extends behind all spreads in a document. It does not correspond to InDesigns 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).
parent coordinates 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. inner coordinates is the coordinate space in which the object itself was created. spread coordinates 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.)
set myRectangle to rectangle 1 of group 1 of page 1 of document 1 set myString to "The page contains a group which has been" & return set myString to myString & "rotated 45 degrees (counterclockwise)." & return set myString to myString & "The rectangle inside the group was" & return set myString to myString & "rotated 45 degrees counterclockwise before" & return set myString to myString & "it was added to the group." & return & return set myString to myString & "Watch as we apply a series of scaling" & return set myString to myString & "operations in different coordinate spaces." display dialog myString set myTransformationMatrix to make transformation matrix with properties {horizontal scale factor:2} --Transform the rectangle using inner coordinates. transform myRectangle in inner coordinates from center anchor with matrix myTransformationMatrix --Select the rectangle and display an alert. select myRectangle display dialog "Transformed using inner coordinates." --Undo the transformation. tell document 1 to undo --Transform using parent coordinates. transform myRectangle in parent coordinates from center anchor with matrix myTransformationMatrix select myRectangle display dialog "Transformed using parent coordinates." tell document 1 to undo --Transform using pasteboard coordinates. transform myRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrix select myRectangle display dialog "Transformed using pasteboard coordinates." tell document 1 to undo
Transformation origin
The transformation origin is the center point of the transformation. The transformation origin can be specified in several ways:
73
Ruler space: (x, y), page index A point, relative to the ruler origin on a specified page of a spread.
{{72, 144}, 1}
(x, y), location A point, relative to the parent page of the specified location of the object. Location can be specified as an anchor point or a coordinate pair. It can be specified relative to the objects geometric or visible bounds, and it can be specified in a given coordinate space.
{{72, 144}, center anchor}
((x, y)) A point in the coordinate space given as the in parameter of the transform method.
{{72, 72}}
The following script example shows how to use some of the transformation origin options. (For the complete script, see TransformationOrigin.)
set myRectangle to rectangle 1 of document 1 set myString to "Watch as we rotate the rectangle using different anchor points," & return set myString to myString & "bounds types, and coordinate spaces." & return & return set myString to myString & "You might have to drag the alert aside to" & return set myString to myString & "see the effect of the transformation." set myNewRectangle to duplicate myRectangle set myTransformationMatrix to make transformation matrix with properties {counterclockwise rotation angle:30} --Rotate around the duplicated rectangle's center point. transform myNewRectangle in pasteboard coordinates from center anchor with matrix myTransformationMatrix --Select the rectangle and display an alert. select myNewRectangle display dialog "Rotated around center anchor." --Undo the transformation. tell document 1 to undo --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
74
--on that page. Setting the considerRulerUnits parameter to true makes certain that the transformation uses the current --ruler units. transform myNewRectangle in pasteboard coordinates from {{-100, -100}, top left anchor} with matrix myTransformationMatrix with considering ruler units --Move the page guides to reflect the transformation point. tell guide 1 of page 1 of document 1 to set location to -100 tell guide 2 of page 1 of document 1 to set location to -100 --Select the rectangle and display an alert. select myNewRectangle display dialog "Rotated around -100x, -100y." --Undo the transformation and the guide moves. tell document 1 to undo tell document 1 to undo tell document 1 to undo
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.)
set myRectangle to rectangle 1 of group 1 of page 1 of document 1 --Get ruler coordinate {72, 72} in pasteboard coordinates. set myPageLocation to resolve myRectangle location {{72, 72}, top right anchor} in pasteboard coordinates with considering ruler units --resolve returns a list containing a single item. set myPageLocation to item 1 of myPageLocation display dialog "Pasteboard Coordinates:" & return & return & "X: " & item 1 of myPageLocation & return & "Y: " & item 2 of myPageLocation --Get ruler coordinate {72, 72} in parent coordinates. set myPageLocation to resolve myRectangle location {{72, 72}, top right anchor} in parent coordinates with considering ruler units --resolve returns a list containing a single item. set myPageLocation to item 1 of myPageLocation display dialog "Parent Coordinates:" & return & return & "X: " & item 1 of myPageLocation & return & "Y: " & item 2 of myPageLocation
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. This is particularly useful for AppleScript, which lacks the basic trigonometric functions (sine, cosine) required for most transformations. The ChangeCoordinates sample script shows how to draw a series of regular polygons using this approach:
75
--General purpose routine for drawing regular polygons from their center point. on myDrawPolygon(myParent, myCenterPoint, myNumberOfPoints, myRadius, myStarPolygon, myStarInset) local myPathPoints, myTransformedPoint tell application "Adobe InDesign CS5" set myPathPoints to {} set myPoint to {0, 0} if myStarPolygon is true then set myNumberOfPoints to myNumberOfPoints * 2 end if set myInnerRadius to myRadius * myStarInset set myAngle to 360 / myNumberOfPoints set myRotateMatrix to make transformation matrix with properties {counterclockwise rotation angle:myAngle} set myOuterTranslateMatrix to make transformation matrix with properties {horizontal translation:myRadius} set myInnerTranslateMatrix to make transformation matrix with properties {horizontal translation:myInnerRadius} repeat with myPointCounter from 0 to myNumberOfPoints - 1 --Translate the point to the inner/outer radius. if myStarInset = 1 or my myIsEven(myPointCounter) is true then set myTransformedPoint to change coordinates myOuterTranslateMatrix point myPoint else set myTransformedPoint to change coordinates myInnerTranslateMatrix point myPoint end if --Rotate the point. set myTransformedPoint to change coordinates myRotateMatrix point myTransformedPoint copy myTransformedPoint to the end of myPathPoints set myRotateMatrix to rotate matrix myRotateMatrix by angle myAngle end repeat --Create a new polygon. tell myParent set myPolygon to make polygon end tell --Set the entire path of the polygon to the array we've created. set entire path of path 1 of myPolygon to myPathPoints --If the center point is somewhere other than [0,0], --translate the polygon to the center point. if item 1 of myCenterPoint is not equal to 0 or item 2 of myCenterPoint is not equal to 0 then set myTransformationMatrix to make transformation matrix with properties {horizontal translation:item 1 of myCenterPoint, vertical translation:item 2 of myCenterPoint} transform myPolygon in pasteboard coordinates from {myCenterPoint,
76
center anchor} with matrix myTransformationMatrix with considering ruler units end if end tell end myDrawPolygon --This function returns true if myNumber is even, false if it is not. on myIsEven(myNumber) set myResult to myNumber mod 2 if myResult = 0 then set myResult to true else set myResult to false end if return myResult end myIsEven
You also can use the change coordinates method to change the positions of curve control points, as shown in the FunWithTransformations sample script.
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:
transform again transform again individually transform sequence again transform sequence again individually
The following script fragment shows how to use transform again. (For the complete script, see TransformAgain.)
set myTransformationMatrix to make transformation matrix with properties {counterclockwise rotation angle:45} transform myRectangleA in pasteboard coordinates from center anchor with matrix myTransformationMatrix set myRectangleB to duplicate myRectangleA transform myRectangleB in pasteboard coordinates from {{0, 0}, top left anchor} with matrix myTransformationMatrix with considering ruler units set myRectangleC to duplicate myRectangleB set myResult to transform again myRectangleC set myRectangleD to duplicate myRectangleC set myResult to transform again myRectangleD set myRectangleE to duplicate myRectangleD set myResult to transform again myRectangleE set myRectangleF to duplicate myRectangleE set myResult to transform again myRectangleF set myRectangleG to duplicate myRectangleF set myResult to transform again myRectangleG set myRectangleH to duplicate myRectangleG set myResult to transform again myRectangleH transform myRectangleB in pasteboard coordinates from center anchor with matrix myTransformationMatrix set myResult to transform again myRectangleD set myResult to transform again myRectangleF set myResult to transform again myRectangleH
77
The following script fragment shows how to use the reframe command. For the complete script, see Reframe.
--Given a reference to a rectangle "myRectangle"... set myBounds to geometric bounds of myRectangle set myX1 to item 2 of myBounds - 72 set myY1 to item 1 of myBounds - 72 set myX2 to item 4 of myBounds + 72 set myY2 to item 3 of myBounds + 72 set myDuplicate to duplicate myRectangle myDuplicate = myRectangle.duplicate(); reframe myDuplicate in inner coordinates opposing corners {{myY1, myX1},{myY2, myX2}}
The following script shows how to create a text frame that is the size of the area defined by the page margins. myGetBounds is a useful function that you can add to your own scripts, and it appears in many other examples in this chapter. (For the complete script, see MakeTextFrameWithinMargins.)
--Given a document "myDocument" set myPage to page 1 of myDocument tell myPage set myTextFrame to make text frame --Set the bounds of the text frame. set geometric bounds of myTextFrame to my myGetBounds(myDocument, myPage) end tell
78
79
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):
--Given a document "myDocument" with a text frame on page 1 set myTextFrame to text frame 1 of page 1 of myDocument --Add text to the end of the text frame. To do this, --We'll use the last insertion point in the story. set myNewText to "This is a new paragraph of example text." tell parent story of myTextFrame set contents of insertion point -1 to return & myNewText end tell
80
--Given a document "myDocument" with a text frame on page 1... set myTextFrame to text frame 1 of myDocument --Now add text beyond the end of the text frame. set myString to return & "This is some overset text" tell insertion point -1 of myTextFrame to set contents to myString set myString to contents of text 1 of myTextFrame display dialog ("The last paragraph in this dialog should be \"This is some overset text\". Is it?" & return & myString) set myString to contents of parent story of myTextFrame display dialog ("The last paragraph in this alert should be \"This is some overset text\". Is it?" & return & myString)
For more on understanding the relationships between text objects in an InDesign document, see Understanding Text Objects on page 88.
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):
--Given a document "myDocument" with a text frame on page 1... set myTextFrame to text frame 1 of page 1 of myDocument --Replace the third word with the phrase "a little bit of". tell word 3 of parent story of myTextFrame set contents to "a little bit of" end tell
The following script replaces the text in a paragraph (for the complete script, see ReplaceText):
--Given a document "myDocument" with a text frame on page 1... set myTextFrame to text frame 1 of page 1 of myDocument --Replace the text in the second paragraph without --replacing the return character at the end of the paragraph --(character -2 is the character before the return). tell parent story of myTextFrame set myText to object reference of text from character 1 to character -2 of paragraph 2 set contents of myText to "This text replaces the text in paragraph 2." end tell end tell
In thepreceding script , we excluded the return character because deleting the return might change the paragraph style applied to the paragraph. To do this, we supplied a character rangefrom the first character of the paragraph to the last character before the return character that ends the paragraph.
81
--Given a document "myDocument" containing a story... set myStory to story 1 of myDocument --Entering special characters directly: set contents of myStory to "Registered trademark: ?" & return & "Copyright: " & return & "Trademark: " & return --Entering special characters by their Unicode glyph ID value: set contents of insertion point -1 of myStory to "Not equal to: <2260>" & return set contents of insertion point -1 of myStory to "Square root: <221A>" & return set contents of insertion point -1 of myStory to "Square root: <00B6>" & return --Entering special characters by their enumerations: set contents of insertion point -1 of myStory to "Automatic page number marker: " set contents of insertion point -1 of myStory to auto page number set contents of insertion point -1 of myStory to return & "Section symbol: " set contents of insertion point -1 of myStory to section symbol set contents of insertion point -1 of myStory to return & "En dash: " set contents of insertion point -1 of myStory to En dash set contents of insertion point -1 of myStory to return
The easiest way to find the Unicode ID for a character is to use InDesigns 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.
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 78, or see the PlaceTextFileInFrame tutorial script.)
82
--Given a document "myDocument" with a text frame on page 1... set myTextFrame to text frame 1 of page 1 of myDocument tell insertion point -1 of myTextFrame --You'll need to fill in a valid file path for your system. place "yukino:test.txt" without showing options end tell
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 78, or see the InsertTextFile tutorial script.)
--Given a document "myDocument" with a text frame on page 1... --Place a text file at the end of the text. set myTextFrame to text frame 1 of page 1 of myDocument tell insertion point -1 of parent story of myTextFrame --You'll need to fill in a valid file path for your system. place "yukino:test.txt" without showing options end tell
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.
tell text import preferences --Options for character set: set character set to UTF8 set convert spaces into tabs to true set spaces into tabs count to 3 --The dictionary property can take many values, such as French, Italian. set dictionary to "English: USA" --platform options: --macintosh --pc set platform to macintosh set strip returns between lines to true set strip returns between paragraphs to true set use typographers quotes to true end tell
The following script shows how to set tagged text import preferences (for the complete script, see TaggedTextImportPreferences):
tell tagged text import preferences set remove text formatting to false --Options for style conflict are: --publication definition --tag file definition set style conflict to publication definition set use typographers quotes to true end tell
The following script shows how to set Word and RTF import preferences (for the complete script, see WordRTFImportPreferences):
83
tell word RTF import preferences --convert page breaks property can be: --column break --none --page break set convert page breaks to none --convert tables to property can be: --unformatted tabbed text --unformatted table set convert tables to to Unformatted Table set import endnotes to true set import footnotes to true set import index to true set import TOC to true set import unused styles to false set preserve graphics to false set preserve local overrides to false set preserve track changes to false set remove formatting to false --resolve character style clash and resolve paragraph style clash properties can be: --resolve clash auto rename --resolve clash use existing --resolve clash use new set resolve character style clash to resolve clash use existing set resolve paragraph style clash to resolve clash use existing set use typographers quotes to true end tell
The following script shows how to set Excel import preferences (for the complete script, see ExcelImportPreferences):
tell application "Adobe InDesign CS5" tell excel import preferences --alignment Style property can be: --center align --left align --right align --spreadsheet set alignment style to spreadsheet set decimal places to 4 set preserve graphics to false --Enter the range you want to import as "start cell:end cell". set range name to "A1:B16" set sheet index to 1 set sheet name to "pathpoints" set show hidden cells to false --table formatting property can be: --excel formatted table --excel unformatted tabbed text --excel unformatted table set table formatting to excel formatted table set use typographers quotes to true set view name to "" end tell end tell
84
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 78, or see the ExportTextRange tutorial script.)
--Given a document with a text frame on page 1... set myTextFrame to text frame 1 of page 1 of active document set myStory to parent story of myTextFrame set myStartCharacter to index of character 1 of paragraph 1 of myStory set myEndCharacter to the index of last character of paragraph 1 of myStory set myText to object reference of text from character myStartCharacter to character myEndCharacter of myStory --Export the text range. You'll have to fill in a valid file path on your system. tell myText to export to "Macintosh HD:scripting:test.txt" format text type
To specify the export options for the specific type of text file youre exporting, use the corresponding export preferences object. The following script sets text-export preferences (for the complete script, see TextExportPreferences):
85
tell text export preferences --Options for character set: --UTF8 --UTF16 --platform set character set to UTF8 --platform options: --macintosh --pc set platform to macintosh end tell
The following script sets tagged text export preferences (for the complete script, see TaggedTextExportPreferences):
tell tagged text export preferences --Options for character set: --ansi --ascii --gb18030 --ksc5601 --shiftJIS --unicode set character set to unicode --tag form options: --abbreviated --verbose set tag form to verbose end tell
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 myGetBounds function from this listing; you can find it in Creating a text frame on page 78, or see the ExportAllText tutorial script.) For any format other than text only, the latter method can become quite complex.
tell application "Adobe InDesign CS5" if (count documents) > 0 then set myDocument to active document if (count stories of myDocument) > 0 then my myExportAllText(name of myDocument) end if end if end tell
86
on myExportAllText(myDocumentName) tell application "Adobe InDesign CS5" --File name for the exported text. Fill in a valid file path on your system. set myFileName to "Adobe:test.txt" --If you want to add a separator line between stories, --set myAddSeparator to true. set myAddSeparator to true set myNewDocument to make document set myDocument to document myDocumentName tell page 1 of myNewDocument set myTextFrame to make text frame with properties {geometric bounds:my myGetBounds(myNewDocument, page 1 of myNewDocument)} set myNewStory to parent story of myTextFrame repeat with myCounter from 1 to (count stories in myDocument) set myStory to story myCounter of myDocument --Duplicate the text of the story to the end of the temporary story. tell text 1 of myStory duplicate to after insertion point -1 of story 1 of myNewDocument end tell --If the imported text did not end with a return, enter a return --to keep the stories from running together. if myCounter is not equal to (count stories of myDocument) then if contents of character -1 of myNewStory is not return then set contents of insertion point -1 of myNewStory to return if myAddSeparator is true then set contents of insertion point -1 of myNewStory to "----------------------------------------" & return end if end if end if end repeat tell myNewStory export to myFileName format text type end tell close myNewDocument saving no end tell end tell end myExportAllText
Do not assume that you are limited to exporting text using existing export filters. Because AppleScript 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 myGetBounds function from this listing; you can find it in Creating a text frame on page 78, or see the ExportHTML tutorial script.)
tell application "Adobe InDesign CS5" --Use the myStyleToTagMapping array to set up your paragraph style to tag mapping. set myStyleToTagMapping to {} --For each style to tag mapping, add a new item to the array. copy {"body_text", "p"} to end of myStyleToTagMapping copy {"heading1", "h1"} to end of myStyleToTagMapping copy {"heading2", "h3"} to end of myStyleToTagMapping copy {"heading3", "h3"} to end of myStyleToTagMapping --End of style to tag mapping. if (count documents) is not equal to 0 then set myDocument to document 1 if (count stories of myDocument) is not equal to 0 then --Open a new text file. set myTextFile to choose file name with prompt "Save HTML As" --Iterate through the stories.
87
repeat with myCounter from 1 to (count stories of myDocument) set myStory to story myCounter of myDocument repeat with myParagraphCounter from 1 to (count paragraphs of myStory) set myParagraph to object reference of paragraph myParagraphCounter of myStory if (count tables of myParagraph) is 0 then --If the paragraph is a simple paragraph--no tables, --no local formatting--then simply export the text of the --pararaph with the appropriate tag. if (count text style ranges of myParagraph) is 1 then set myTag to my myFindTag(name of applied paragraph style of myParagraph, myStyleToTagMapping) --If the tag comes back empty, map it to the --basic paragraph tag. if myTag = "" then set myTag to "p" end if set myStartTag to "<" & myTag & ">" set myEndTag to "</" & myTag & ">" --If the paragraph is not the last paragraph in the story, --omit the return character. if the contents of character -1 of myParagraph is return then set myText to object reference of text from character 1 to character -2 of myParagraph set myString to contents of myText else set myString to contents of myParagraph end if --Write the text of the paragraph to the text file. if myParagraphCounter = 1 then set myAppendData to false else set myAppendData to true end if my myWriteToFile(myStartTag & myString & myEndTag & return, myTextFile, myAppendData) else --Handle text style range export by iterating through --the text style ranges in the paragraph. set myTextStyleRanges to text style ranges of myParagraph repeat with myRangeCounter from 1 to (count text style ranges of myParagraph) set myTextStyleRange to object reference of text style range myRangeCounter of myParagraph if character -1 of myTextStyleRange is return then set myStartCharacter to index of character 1 of myTextStyleRange set myEndCharacter to index of character -2 of myTextStyleRange set myText to object reference of text from character myStartCharacter to character myEndCharacter of myStory set myString to contents of myText else set myString to contents of myTextStyleRange end if if font style of myTextStyleRange is "Bold" then set myString to "<b>" & myString & "</b>" else if font style of myTextStyleRange is "Italic" then set myString to "<i>" & myString & "</i>" end if
88
my myWriteToFile(myString, myTextFile, true) end repeat my myWriteToFile(return, myTextFile, true) end if else --Handle table export (assumes that there is only --one table per paragraph, --and that the table is in the paragraph by itself). set myTable to table 1 of myParagraph my myWriteToFile("<table border = 1>", myTextFile, true) repeat with myRowCounter from 1 to (count rows of myTable) my myWriteToFile("<tr>", myTextFile, true) repeat with myColumnCounter from 1 to (count columns of myTable) if myRowCounter = 1 then set myString to "<th>" set myString to myString & text 1 of cell myColumnCounter of row myRowCounter of myTable set myString to myString & "</th>" else set myString to "<td>" set myString to myString & text 1 of cell myColumnCounter of row myRowCounter of myTable set myString to myString & "</td>" end if my myWriteToFile(myString, myTextFile, true) end repeat my myWriteToFile("</tr>" & return, myTextFile, true) end repeat my myWriteToFile("</table>" & return, myTextFile, true) end if end repeat end repeat end if end if end tell
89
document
story
textContainers textFrame insertionPoints characters words lines paragraphs textColumns textStyleRanges texts
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:
document pages.item(0) textFrames.item(0) characters.item(0) textFrames.item(0) paragraphs.item(0) characters.item(0) stories.item(0) characters.item(0) stories.item(0) paragraphs.item(0) characters.item(0)
For any text stream object, the parent of the object is the story containing the object. To get a reference to the text frame (or text frames) containing the text object, use the parent text frames property. 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 parent of the text frame is the
90
containing page item. If the text frame was converted to an anchored frame, the parent of the text frame is the character containing the anchored frame.
91
--Given a document myDocument" with four text frams on page 1... set myTextFrameA to text frame 4 of page 1 of myDocument set myTextFrameB to text frame 3 of page 1 of myDocument set myTextFrameC to text frame 2 of page 1 of myDocument set myTextFrameD to text frame 1 of page 1 of myDocument --Note that moving text removes it from its original location. tell parent story of myTextFrameD --Move WordC between the words in TextFrameC. move paragraph 4 to before word -1 of paragraph 1 of parent story of myTextFrameC --Move WordB after the word in TextFrameB. move paragraph 3 to after insertion point -1 of myTextFrameB --Move WordA to before the word in TextFrameA. move paragraph 2 to before word 1 in myTextFrameA end tell
When you want to transfer formatted text from one document to another, you also can use the move method. Using the move or duplicate method is better than using copy and paste; to use copy and paste, you must make the document visible and select the text you want to copy. Using move or duplicate is much faster and more robust. The following script shows how to move text from one document to another using move and duplicate. (We omitted the myGetBounds function from this listing; you can find it in Creating a text frame on page 78, or see the MoveTextBetweenDocuments tutorial script.)
--Given a document "mySourceDocument"... set mySourceStory to story 1 of mySourceDocument --Create a new document to move the text to. set myTargetDocument to make document set myPage to page 1 of myTargetDocument tell myPage set myTextFrame to make text frame with properties {geometric bounds:my myGetBounds(myTargetDocument, myPage)} end tell set myTargetStory to story 1 of myTargetDocument set contents of myTargetStory to "This is the target text. Insert the source text after this paragraph." & return duplicate paragraph 1 of mySourceStory to after insertion point -1 of myTargetStory
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 78, or see the CopyPasteText tutorial script.)
92
--Given an open document with a text frame on page 1 set myDocumentA to document 1 set myTextFrameA to text frame 1 of page 1 of myDocumentA --Create another example document. set myDocumentB to make document set myPageB to page 1 of myDocumentB tell myPageB set myTextFrameB to make text frame with properties {geometric bounds:my myGetBounds(myDocumentB, myPageB)} end tell --Make document A the active document. set active document to myDocumentA --Select the text. select text 1 of parent story of myTextFrameA copy --Make document B the active document. set active document to myDocumentB --Select the insertion point at which you want to paste the text. select insertion point -1 of myTextFrameB 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):
tell application "Adobe InDesign CS5" set myDocument to document 1 set myPage to page 1 of myDocument tell myPage set myTextFrameA to make text frame with properties {geometric bounds:{72, 72, 144, 288}} set contents of myTextFrameA to "This is a formatted string." set font style of text 1 of parent story of myTextFrameA to "Bold" set myTextFrameB to make text frame with properties {geometric bounds:{228, 72, 300, 288}} set contents of myTextFrameB to "This is the destination text frame. Text pasted here will retain its formatting." set font style of text 1 of myTextFrameB to "Italic" end tell --Copy from one frame to another using a simple copy. select text 1 of myTextFrameA copy select insertion point -1 of myTextFrameB paste --Create another text frame on the active page. tell myPage set myTextFrameC to make text frame with properties {geometric bounds:{312, 72, 444, 288}} end tell set contents of myTextFrameC to "Text copied here will take on the formatting of the existing text." set font style of text 1 of parent story of myTextFrameC to "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): set contents of insertion point -1 of myTextFrameC to contents of text 1 of parent story of myTextFrameA end tell
93
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 3, 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 78, or see the TextIterationRight tutorial script.)
--By iterating backwards we can avoid the error. repeat with myParagraphCounter from (count paragraphs of myStory) to 1 by -1 if contents of word 1 of paragraph myParagraphCounter of myStory is "Delete" then tell paragraph myParagraphCounter of myStory to delete else set point size of paragraph myParagraphCounter of myStory to 24 end if end repeat
94
--Given a document "myDocument" with two unlinked text frames on page 1... set myTextFrameA to text frame 2 of page 1 of document 1 set myTextFrameB to text frame 1 of page 1 of document 1 --Link TextFrameA to TextFrameB using the next text frame property. set next text frame of myTextFrameA to myTextFrameB --Add a page. tell myDocument set myNewPage to make page end tell --Create another text frame on the new page. tell myNewPage set myTextFrameC to make text frame with properties {geometric bounds:{72, 72, 144, 144}} --Link TextFrameC to TextFrameB using the previousTextFrame property. set previous text frame of myTextFrameC to myTextFrameB --Fill the text frames with placeholder text. set contents of myTextFrameA to placeholder text end tell
95
set myObjectList to {} --Script does nothing if no documents are open or if no objects are selected. tell application "Adobe InDesign CS5" if (count documents) is not equal to 0 then set mySelection to selection if (count mySelection) is not equal to 0 then --Process the objects in the selection to create a list of --qualifying objects (text frames). repeat with myCounter from 1 to (count mySelection) if class of item myCounter of mySelection is text frame then set myObjectList to myObjectList & item myCounter of mySelection else if class of item myCounter of mySelection is in {text, insertion point, character, word, line, text style range, paragraph, text column} then set myObject to item 1 of parent text frames of item myCounter of mySelection set myObjectList to myObjectList & myObject end if end repeat --If the object list is not empty, pass it on to the handler --that does the real work. if (count myObjectList) is not equal to 0 then my myBreakFrames(myObjectList) end if end if end if end tell
96
on mySplitStory(myStory) tell application "Adobe InDesign CS5" tell document 1 local myTextContainers set myTextContainers to text containers in myStory if (count myTextContainers) is greater than 1 then repeat with myCounter from (count myTextContainers) to 1 by -1 set myTextFrame to item myCounter of myTextContainers tell myTextFrame duplicate if text 1 of myTextFrame is not equal to "" then tell text 1 of myTextFrame delete end tell end if delete end tell end repeat end if end tell end tell end mySplitStory
Formatting Text
97
set e2 to item 2 of myBounds set e3 to (item 1 of myBounds) + 24 set e4 to (item 2 of myBounds) + 72 set geometric bounds of myAnchoredFrame to {e1, e2, e3, e4} set contents of myAnchoredFrame to "This is an anchored frame." tell anchored object settings of myAnchoredFrame set anchored position to anchored set anchor point to top left anchor set horizontal reference point to anchor location set horizontal alignment to left align set anchor xoffset to 72 set vertical reference point to line baseline set anchor yoffset to 24 set anchor space above to 24 end tell
Formatting Text
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.
Formatting Text
98
set desiredWordSpacing to 100 set drop cap characters to 0 if drop cap characters is not equal to 0 then dropCapLines to 3 --Assumes that the application has a default character style named "myDropCap" set drop cap style to character style "myDropCap" end if set fill color to "Black" set fill tint to 100 set first line indent to 14 set grid align first line only to false set horizontal scale to 100 set hyphenate after first to 3 set hyphenate before last to 4 set hyphenate capitalized words to false set hyphenate ladder limit to 1 set hyphenate words longer than to 5 set hyphenation to true set hyphenation zone to 36 set hyphen weight to 9 set justification to left align set keep all lines together to false set keep lines together to true set keep first lines to 2 set keep last lines to 2 set keep with next to 0 set kerning method to "Optical" set leading to 14 set left indent to 0 set ligatures to true set maximum glyph scaling to 100 set maximum letter spacing to 0 set maximum word spacing to 160 set minimum glyph scaling to 100 set minimum letter spacing to 0 set minimum word spacing to 80 set no break to false set OTF contextual alternate to true set OTF discretionary ligature to false set OTF figure style to proportional oldstyle set OTF fraction to true set OTF historical to false set OTF ordinal to false set OTF slashed zero to false set OTF swash to false set OTF titling to false set overprint fill to false set overprint stroke to false set pointSize to 11 set position to normal set right indent to 0 set rule above to false if rule above = true then set rule above color to color "Black" set rule above gap color to swatch "None" set rule above gap overprint to false set rule above gap tint to 100 set rule above left indent to 0 set rule above line weight to 0.25 set rule above offset to 14
Formatting Text
99
set rule above overprint to false set rule above right indent to 0 set rule above tint to 100 set rule above type to stroke style "Solid" set rule above width to column width end if set rule below to false if rule below = true then set rule below color to color "Black" set rule below gap color to swatch "None" set rule below gap overprint to false set rule below gap tint to 100 set rule below left indent to 0 set rule below line weight to 0.25 set rule below offset to 14 set rule below overprint to false set rule below right indent to 0 set rule below tint to 100 set rule below type to stroke style "Solid" set rule below width to column width end if set single word justification to left align set skew to 0 set space after to 0 set space before to 0 set start paragraph to anywhere set strike thru to false if strike thru = true then set strike through color to color "Black" set strike through gap color to swatch "None" set strike through gap overprint to false set strike through gap tint to 100 set strike through offset to 3 set strike through overprint to false set strike through tint to 100 set strike through type to stroke style "Solid" set strike through weight to 0.25 end if set stroke color to "None" set stroke tint to 100 set stroke weight to 0 set tracking to 0 set underline to false if underline = true then set underline color to color "Black" set underline gap color to swatch "None" set underline gap overprint to false set underline gap tint to 100 set underline offset to 3 set underline overprint to false set underline tint to 100 set underline type to stroke style "Solid" set underline weight to 0.25 end if set vertical scale to 100 end tell
Formatting Text
100
NOTE: Font names typically are of the form familyName<tab>fontStyle, where familyName is the name of the font family, <tab> is a tab character, and fontStyle is the name of the font style. For example:
"Adobe Caslon Pro<tab>Semibold Italic"
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"... set applied font of myText to myFontName
You also can apply a font by specifying the font family name and font style, as shown in the following script fragment:
tell myText set applied font to "Adobe Caslon Pro" set font style to "Semibold Italic" end tell
Formatting Text
101
--Given a document "myDocument" containing a story... set myStory to story 1 of myDocument tell character 1 of myStory set align to baseline to false set applied character style to character style "[None]" of myDocument set applied font to "Minion ProRegular" set applied language to "English: USA" set applied numbering list to "[Default]" set applied paragraph style to paragraph style "[No Paragraph Style]" of myDocument set auto leading to 120 set balance ragged lines to no balancing set baseline shift to 0 set bullets alignment to left align set bullets and numbering list type to no list set bullets character style to character style "[None]" of myDocument set bullets text after to "^t" set capitalization to normal set composer to "Adobe Paragraph Composer" set desired glyph scaling to 100 set desired letter spacing to 0 set desired word spacing to 100 set drop cap characters to 0 set drop cap lines to 0 set drop cap style to character style "[None]" of myDocument set dropcap detail to 0 set fill color to color "Black" of myDocument set fill tint to -1 set first line indent to 0 set font style to "Regular" set gradient fill angle to 0 set gradient fill length to -1 set gradient fill start to [0, 0] set gradient stroke angle to 0 set gradient stroke length to -1 set gradient stroke start to [0, 0] set grid align first line only to false set horizontal scale to 100 set hyphen weight to 5 set hyphenate across columns to true set hyphenate after first to 2 set hyphenate before last to 2 set hyphenate capitalized words to true set hyphenate ladder limit to 3 set hyphenate last word to true set hyphenate words longer than to 5 set hyphenation to true set hyphenation zone to 3 set ignore edge alignment to false set justification to left align set keep all lines together to false set keep first lines to 2 set keep last lines to 2 set keep lines together to false set keep rule above in frame to false set keep with next to 0 set kerning method to "Optical" set last line indent to 0 set leading to 12 set left indent to 0 set ligatures to true
Formatting Text
102
set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set set
maximum glyph scaling to 100 maximum letter spacing to 0 maximum word spacing to 133 minimum glyph scaling to 100 minimum letter spacing to 0 minimum word spacing to 80 no break to false numbering alignment to left align numbering apply restart policy to true numbering character style to character style "[None]" of myDocument numbering continue to true numbering expression to "^#.^t" numbering format to "1, 2, 3, 4..." numbering level to 1 numbering start at to 1 OTF contextual alternate to true OTF discretionary ligature to false OTF figure style to proportional lining OTF fraction to false OTF historical to false OTF locale to true OTF mark to true OTF ordinal to false OTF slashed zero to false OTF stylistic sets to 0 OTF swash to false OTF titling to false overprint fill to false overprint stroke to false point size to 72 position to normal positional form to none right indent to 0 rule above to false rule above color to "Text Color" rule above gap color to swatch "None" of myDocument rule above gap overprint to false rule above gap tint to 100 rule above left indent to 0 rule above line weight to 0.25 rule above offset to 14 rule above overprint to false rule above right indent to 0 rule above tint to 100 rule above type to stroke style "Solid" of myDocument rule above width to column width rule below to false rule below color to "Text Color" rule below gap color to swatch "None" of myDocument rule below gap overprint to false rule below gap tint to 100 rule below left indent to 0 rule below line weight to 0.25 rule below offset to 14 rule below overprint to false rule below right indent to 0 rule below tint to 100 rule below type to stroke style "Solid" of myDocument rule below width to column width single word justification to left align
Formatting Text
103
set skew to 0 set space after to 0 set space before to 0 set start paragraph to anywhere set strike thru to false set strike through color to color "Black" of myDocument set strike through gap color to swatch "None" of myDocument set strike through gap overprint to false set strike through gap tint to 100 set strike through offset to 3 set strike through overprint to false set strike through tint to 100 set strike through type to stroke style "Solid" of myDocument set strike through weight to 0.25 set stroke color to swatch "None" of myDocument set stroke tint to -1 set stroke weight to 1 set tracking to 0 set tracking to 0 set underline to false set underline color to color "Black" of myDocument set underline gap color to swatch "None" of myDocument set underline gap overprint to false set underline gap tint to 100 set underline offset to 3 set underline overprint to false set underline tint to 100 set underline type to stroke style "Solid" of myDocument set underline weight to 0.25 set vertical scale to 100 end tell
Formatting Text
104
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.
Formatting Text
105
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):
--Given a document "myDocument"... --Get the last paragraph style. set myParagraphStyle to paragraph style -1 of myDocument --Get the last character style set myCharacterStyle to character style -1 of myDocument --At this point, the variable myParagraphStyle contains a reference to a paragraph --style object. Next, add a nested style to the paragraph style. tell myParagraphStyle set myNestedStyle to make nested style with properties {applied character style:myCharacterStyle, delimiter:".", inclusive:true, repetition:1} end tell set myPage to page 1 of myDocument set myTextFrame to text frame 1 of myPage --Apply the paragraph style to the story so that we can see the --effect of the nested style we created. --(Note that the story object does not have the apply paragraph style method.) set myStory to parent story of myTextFrame tell text 1 of myStory apply paragraph style using myParagraphStyle end tell
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):
--Given a document "myDocment" with paragraph styles named --"myParagraphStyleA" and "myParagraphStyleB", remove the --paragraph style "myParagraphStyleA" and replace with --"myParagraphStyleB." tell myDocument delete paragraph style "myParagraphStyleA" replacing with paragraph style "myParagraphStyleB" end tell
106
--You'll have to fill in a valid file path for your system. set myFilePath to "Macintosh HD:scripting:styles.indd" --Create a new document. set myDocument to make document tell myDocument --Import the styles from the saved document. --importStyles parameters: --Format options for text styles are: -paragraph styles format -character styles format -text styles format --From as file or string --Global Strategy options are: -do not load the style -load all with overwrite -load all with rename import styles format text styles format from myFilePath global strategy load all with overwrite end tell
107
--find/change text preferences tell application "Adobe InDesign CS5" set find text preferences to nothing set change text preferences to nothing end tell --find/change grep preferences tell application "Adobe InDesign CS5" set find grep preferences to nothing set change grep preferences to nothing end tell --find/change glyph preferences tell application "Adobe InDesign CS5" set find glyph preferences to nothing set change glpyh preferences to nothing end tell
2. Set up search parameters. 3. Execute the find/change operation. 4. Clear find/change preferences again.
The following script fragment shows how to find a specified string of text and replace it with a different string (for the complete script, see ChangeText):
108
--Clear the find/change preferences. set find text preferences to nothing set change text preferences to nothing --Search the document for the string "copy". set find what of find text preferences to "copy" set change to of change text preferences to "text" --Set the find options. set case sensitive of find change text options to false set include footnotes of find change text options to false set include hidden layers of find change text options to false set include locked layers for find of find change text options to false set include locked stories for find of find change text options to false set include master pages of find change text options to false set whole word of find change text options to false tell active document set myFoundItems to change text display dialog ("Found " & (count myFoundItems) & " instances of the search string.") end tell
Using grep
InDesign supports regular expression find/change through the findGrep and changeGrep methods. Regular-expression find/change also can find text with a specified format or replace the formatting of the text with formatting specified in the properties of the changeGrepPreferences object. The following
109
script fragment shows how to use these methods and the related preferences objects (for the complete script, see FindGrep):
--Clear the find/change preferences. set find grep preferences to nothing set change grep preferences to nothing --Set the find options. set include footnotes of find change grep options to false set include hidden layers of find change grep options to false set include locked layers for find of find change grep options to false set include locked stories for find of find change grep options to false set include master pages of find change grep options to false --Regular expression for finding an email address. set find what of find grep preferences to "(?i)[A-Z0-9]*?@[A-Z0-9]*?[.]..." --Apply the change to 24-point text only. set point size of find grep preferences to 24 set underline of change grep preferences to true tell myDocument change grep end tell --Clear the find/change preferences after the search. set find grep preferences to nothing set change grep preferences to nothing
NOTE: The findChangeGrepOptions object lacks two properties of the findChangeTextOptions object: wholeWord and caseSensitive. This is because you can set these options using the regular expression string itself. Use (?i) to turn case sensitivity on and (?-i) to turn case sensitivity off. Use \> to match the beginning of a word and \< to match the end of a word, or use \b to match a word boundary. One handy use for grep find/change is to convert text mark-up (i.e., some form of tagging plain text with formatting instructions) into InDesign formatted text. PageMaker paragraph tags (which are not the same as PageMaker tagged-text format files) are an example of a simplified text mark-up scheme. In a text file marked up using this scheme, paragraph style names appear at the start of a paragraph, as shown below:
<heading1>This is a heading. <body_text>This is body text.
We can create a script that uses grep find in conjunction with text find/change operations to apply formatting to the text and remove the mark-up tags, as shown in the following script fragment (from the ReadPMTags tutorial script):
set myDocument to document 1 set myStory to story 1 of myDocument myReadPMTags(myStory)
110
on myReadPMTags(myStory) local myFoundTags, myFoundItems, myFoundTag, myString, myStyleName, myStyle tell application "Adobe InDesign CS5" set myDocument to parent of myStory --Reset the find grep preferences to ensure that --previous settings do not affect the search. set find grep preferences to nothing set change grep preferences to nothing --Set the find options. set include footnotes of find change grep options to false set include hidden layers of find change grep options to false set include locked layers for find of find change grep options to false set include locked stories for find of find change grep options to false set include master pages of find change grep options to false --Find the tags. set find what of find grep preferences to "(?i)^<\\s*\\w+\\s*>" tell myStory set myFoundItems to find grep end tell if (count myFoundItems) is not equal to 0 then set myFoundTags to {} repeat with myCounter from 1 to (count myFoundItems) set myFoundTag to contents of item myCounter of myFoundItems if myFoundTags does not contain myFoundTag then copy myFoundTag to end of myFoundTags end if end repeat --At this point, we have a list of tags to search for. repeat with myCounter from 1 to (count myFoundTags) set myString to item myCounter of myFoundTags --Find the tag using find what. set find what of find text preferences to myString --Extract the style name from the tag. set myStyleName to text 2 through ((count characters of myString) - 1) of myString tell myDocument --Create the style if it does not already exist. try set myStyle to paragraph style myStyleName on error set myStyle to make paragraph style with properties {name:myStyleName} end try end tell --Apply the style to each instance of the tag. set applied paragraph style of change text preferences to myStyle tell myStory change text end tell --Reset the change text preferences.
111
set change text preferences to nothing --Set the change to property to an empty string. set change to of change text preferences to "" --Search to remove the tags. tell myStory change text end tell --Reset the find/change preferences again. set change text preferences to nothing end repeat end if --Reset the findGrepPreferences. set find grep preferences to nothing end tell end myReadPMTags
112
--Given a document "myDocument" containing a story... set myStory to story 1 of myDocument tell myStory set myStartCharacter to index of character 1 of paragraph 7 set myEndCharacter to index of character -2 of paragraph 7 set myText to object reference of text from character myStartCharacter to character myEndCharacter --The convertToTable method takes three parameters: --[column separator as string] --[row separator as string] --[number of columns as integer] (only used if the column separator --and row separator values are the same) --In the last paragraph in the story, columns are separated by commas --and rows are separated by semicolons, so we provide those characters --to the method as parameters. tell myText set myTable to convert to table column separator "," row separator ";" end tell set myStartCharacter to index of character 1 of paragraph 2 set myEndCharacter to index of character -2 of paragraph 5 set myText to object reference of text from character myStartCharacter to character myEndCharacter --In the second through the fifth paragraphs, colums are separated by --tabs and rows are separated by returns. These are the default delimiter --parameters, so we don't need to provide them to the method. tell myText set myTable to convert to table column separator tab row separator return end tell --You can also explicitly add a table--you don't have to convert text to a table. tell insertion point -1 set myTable to make table set column count of myTable to 3 set body row count of myTable to 3 end tell end tell
The following script fragment shows how to merge table cells. (For the complete script, see MergeTableCells.)
--Given a document "myDocument" containing a story... tell story 1 of myDocument tell table 1 --Merge all of the cells in the first column. merge cell 1 of column 1 with cell -1 of column 1 --Convert column 2 into 2 cells (rather than 4). merge cell 3 of column 2 with cell -1 of column 2 merge cell 1 of column 2 with cell 2 of column 2 --Merge the last two cells in row 1. merge cell -2 of row 1 with cell -1 of row 1 --Merge the last two cells in row 3. merge cell -2 of row 3 with cell -1 of row 3 end tell end tell
The following script fragment shows how to split table cells. (For the complete script, see SplitTableCells.)
113
tell table 1 of story 1 of document 1 split cell 1 using horizontal split column 1 using vertical split cell 1 using vertical split row -1 using horizontal split cell -1 using vertical --Fill the cells with row:cell labels. repeat with myRowCounter from 1 to (count rows) set myRow to row myRowCounter repeat with myCellCounter from 1 to (count cells of myRow) set myString to "Row: " & myRowCounter & " Cell: " & myCellCounter set contents of text 1 of cell myCellCounter of row myRowCounter to myString end repeat end repeat end tell
The following script fragment shows how to create header and footer rows in a table (for the complete script, see HeaderAndFooterRows):
--Given a document containing a story that contains a table... tell table 1 of story 1 of document 1 --Convert the first row to a header row. set row type of row 1 to header row --Convert the last row to a footer row. set row type of row -1 to footer row end tell
The following script fragment shows how to apply formatting to a table (for the complete script, see TableFormatting):
set myTable to table 1 of story 1 of myDocument tell myTable --Convert the first row to a header row. set row type of row 1 to header row --Use a reference to a swatch, rather than to a color. set fill color of row 1 to swatch "DGC1_446b" of myDocument set fill tint of row 1 to 40 set fill color of row 2 to swatch "DGC1_446a" of myDocument set fill tint of row 2 to 40 set fill color of row 3 to swatch "DGC1_446a" of myDocument set fill tint of row 3 to 20 set fill color of row 4 to swatch "DGC1_446a" of myDocument set fill tint of row 4 to 40 tell every cell in myTable set top edge stroke color to swatch "DGC1_446b" of myDocument set top edge stroke weight to 1 set bottom edge stroke color to swatch "DGC1_446b" of myDocument set bottom edge stroke weight to 1 --When you set a cell stroke to a swatch, make certain that --you also set the stroke weight. set left edge stroke color to swatch "None" of myDocument set left edge stroke weight to 0 set right edge stroke color to swatch "None" of myDocument set right edge stroke weight to 0 end tell end tell
The following script fragment shows how to add alternating row formatting to a table (for the complete script, see AlternatingRows):
Path Text
114
--Given a document "myDocument" containing a story that --contains a table... set myTable to table 1 of story 1 of myDocument tell myTable --Apply alternating fills to the table. set alternating fills to alternating rows set start row fill color to swatch "DGC1_446a" of myDocument set start row fill tint to 60 set end row fill color to swatch "DGC1_446b" of myDocument set end row fill tint to 50 end tell
The following script fragment shows how to process the selection when text or table cells are selected. In this example, the script displays an alert for each selection condition, but a real production script would then do something with the selected item(s). (For the complete script, see TableSelection.)
--Check to see if any documents are open. if (count documents) is not equal to 0 then --If the selection contains more than one item, the selection --is not text selected with the Type tool. set mySelection to selection if (count mySelection) is not equal to 0 then --Evaluate the selection based on its type. set myTextClasses to {insertion point, word, text style range, line, paragraph, text column, text, story} if class of item 1 of selection is in myTextClasses then --The object is a text object; display the text object type. --A practical script would do something with the selection, --or pass the selection on to a function. if class of parent of item 1 of mySelection is cell then display dialog ("The selection is inside a table cell") else display dialog ("The selection is not in a table") end if else if class of item 1 of selection is cell then display dialog ("The selection is a table cell") else if class of item 1 of selection is row then display dialog ("The selection is a table row") else if class of item 1 of selection is column then display dialog ("The selection is a table column") else if class of item 1 of selection is table then display dialog ("The selection is a table.") else display dialog ("The selection is not in a table") end if else display dialog ("Please select some text and try again.") end if else display dialog ("Nothing is selected. Please select some text and try again.") end if
Path Text
You can add path text to any rectangle, oval, polygon, graphic line, or text frame. The following script fragment shows how to add path text to a page item (for the complete script, see PathText):
Autocorrect
115
--Given a document "myDocument" with a rectangle on page 1... set myRectangle to rectangle 1 of page 1 of myDocument tell myRectangle set myTextPath to make text path with properties {contents:"This is path text."} end tell
To link text paths to another text path or text frame, use the nextTextFrame and previousTextFrame properties, just as you would for a text frame (see Working with Text Frames on page 93).
Autocorrect
The autocorrect feature can correct text as you type. The following script shows how to use it (for the complete script, see Autocorrect):
tell auto correct preferences set autocorrect to true set auto correct capitalization errors to true --Add a word pair to the autocorrect list. Each auto correct table --is linked to a specific language. end tell set myAutoCorrectTable to auto correct table "English: USA" --To safely add a word pair to the auto correct table, get the current --word pair list, then add the new word pair to that array, and then --set the autocorrect word pair list to the array. set myWordPairList to {} set myWordPairList to myWordPairList & auto correct word pair list of myAutoCorrectTable --Add a new word pair to the array. set myWordPairList to myWordPairList & {{"paragarph", "paragraph"}} --Update the word pair list. set auto correct word pair list of auto correct table "English: USA" to myWordPairList --To clear all autocorrect word pairs in the current dictionary: --myAutoCorrectTable.autoCorrectWordPairList to {{}}
Footnotes
The following script fragment shows how to add footnotes to a story (for the complete script, including the myGetRandom function, see Footnotes):
Span Columns
116
set myDocument to document 1 tell footnote options of myDocument set separator text to tab set marker positioning to superscript marker end tell set myStory to story 1 of myDocument --Add four footnotes at random locations in the story. local myStoryLength, myRandomNumber set myStoryLength to (count words of myStory) repeat with myCounter from 1 to 5 set myRandomNumber to my myGetRandom(1, myStoryLength) tell insertion point -1 of word myRandomNumber of myStory set myFootnote to make footnote end tell --Note: when you create a footnote, it contains text--the footnote marker --and the separator text (if any). If you try to set the text of the footnote --by setting the footnote contents, you will delete the marker. Instead, append --the footnote text, as shown below. tell insertion point -1 of myFootnote set contents to "This is a footnote." end tell end repeat
Span Columns
A paragraph layout can span multiple columns or split into subcolumns with the Span Columns attribute or Split Column attribute applied. The following script fragment shows how to set the Span Columns and Split Column style for a paragraph (for the complete script, see SpanColumns):
set myDocument to active document set myPage to page 1 of myDocument set myTextFrame to item 1 of text frames of myPage tell myTextFrame set text column count of text frame preferences to 3 set myStory to parent story tell item 1 of paragraphs of myStory --split column set span column type to split columns set span split column count to 2 set split column outside gutter to 0 set split column inside gutter to 1 end tell set mySpanIndex to (count of paragraphs of myStory) div 2 + 1 tell item mySpanIndex of paragraphs of myStory --span columns set span column type to span columns set span split column count to all end tell end tell
117
tell text preferences set abut text to text wrap to true --baseline shift key increment can range from .001 to 200 points. set baseline shift key increment to 1 set highlight custom spacing to false set highlight hj violations to true set highlight keeps to true set highlight substituted fonts to true set highlight substituted glyphs to true set justify text wraps to true --kerning key increment value is 1/1000 of an em. set kerning key increment to 10 --leading key increment value can range from .001 to 200 points. set leading key increment to 1 set link text files when importing to false set show invisibles to true set small cap to 60 set subscript position to 30 set subscript size to 60 set superscript position to 30 set superscript size to 60 set typographers quotes to false set use optical size to false set use paragraph leading to false set z order text wrap to false end tell --Text editing preferences are application-wide. tell text editing preferences set allow drag and drop text in story to true set drag and drop text in layout to true set smart cut and paste to true set triple click selects line to false end tell
User Interfaces
AppleScript can create dialogs for simple yes/no questions and text entry, but you probably will need to create more complex dialogs for your scripts. InDesign scripting can add dialogs and populate them with common user-interface controls, like pop-up lists, text-entry fields, and numeric-entry fields. If you want your script to collect and act on information entered by you or any other user of your script, use the dialog object. This chapter shows how to work with InDesign dialog scripting. The sample scripts in this chapter are presented in order of complexity, starting with very simple scripts and building toward more complex operations. NOTE: InDesign scripts written in JavaScript also can include user interfaces created using the Adobe ScriptUI component. This chapter includes some ScriptUI scripting tutorials; for more information, see Adobe CS5 JavaScript Tools Guide. We assume you already read Adobe InDesign CS5 Scripting Tutorial and know how to create and run a script.
Dialog Overview
An InDesign dialog box is an object like any other InDesign scripting object. The dialog box can contain several different types of elements (known collectively as widgets), as shown in the following figure. The elements of the figure are described in the table following the figure.
dialog
dialog column
static text border panel checkbox control radiobutton group radiobutton control
measurement editbox
dropdown
118
119
Dialog box element Text-edit fields Numeric-entry fields Pop-up menus Control that combines a text-edit field with a pop-up menu Check box Radio buttons
InDesign name Text editbox control Real editbox, integer editbox, measurement editbox, percent editbox, angle editbox Drop-down control Combo-box control Check-box control Radio-button control
The dialog object itself does not directly contain the controls; that is the purpose of the dialog column object. dialog columns give you a way to control the positioning of controls within a dialog box. Inside dialog columns, you can further subdivide the dialog box into other dialog columns or border panels (both of which can, if necessary, contain more dialog columns and border panels). Like any other InDesign scripting object, each part of a dialog box has its own properties. A checkbox control, for example, has a property for its text (static label) and another property for its state (checked state). The dropdown control has a property (string list) for setting the list of options that appears on the controls menu. To use a dialog box in your script, create the dialog object, populate it with various controls, display the dialog box, and then gather values from the dialog-box controls to use in your script. Dialog boxes remain in InDesigns memory until they are destroyed. This means you can keep a dialog box in memory and have data stored in its properties used by multiple scripts, but it also means the dialog boxes take up memory and should be disposed of when they are not in use. In general, you should destroy a dialog-box object before your script finishes executing.
120
set myDialog to make dialog with properties {name:"Simple Dialog"} tell myDialog tell (make dialog column) make static text with properties {static label:"This is a very simple dialog box."} end tell end tell --Show the dialog box. set myResult to show myDialog --If the user clicked OK, display one message; --if they clicked Cancel, display a different message. if myResult is true then display dialog ("You clicked the OK button") else display dialog ("You clicked the Cancel button") end if --Remove the dialog box from memory. destroy myDialog
121
on myMakeDocument(myPointSize, myString) tell application "Adobe InDesign CS5" set myDocument to make document tell view preferences of myDocument end tell tell page 1 of myDocument --Create a text frame. set myTextFrame to make text frame set geometric bounds of myTextFrame to my myGetBounds (myDocument, page 1 of myDocument) --Apply the settings from the dialog box to the text frame. set contents of myTextFrame to myString --Set the point size of the text in the text frame. set point size of text 1 of myTextFrame to myPointSize end tell end tell end myMakeDocument
122
tell myDialogColumn make static text with properties {static label:"Point Size:"} end tell set myDialogColumn to make dialog column tell myDialogColumn set myPointSizeField to make measurement editbox with properties {edit value:72, edit units:points} end tell end tell set myBorderPanel to make border panel tell myBorderPanel set myDialogColumn to make dialog column tell myDialogColumn make static text with properties {static label:"Vertical Justification:"} end tell set myDialogColumn to make dialog column tell myDialogColumn set myVerticalJustificationMenu to make dropdown with properties {string list:{"Top", "Center", "Bottom"}, selected index:0} end tell end tell set myBorderPanel to make border panel tell myBorderPanel make static text with properties {static label:"Paragraph Alignment:"} set myParagraphAlignmentGroup to make radiobutton group tell myParagraphAlignmentGroup set myLeftRadioButton to make radiobutton control with properties {static label:"Left", checked state:true} set myCenterRadioButton to make radiobutton control with properties {static label:"Center"} set myRightRadioButton to make radiobutton control with properties {static label:"Right"} end tell end tell end tell end tell set myResult to show myDialog if myResult is true then --Get the settings from the dialog box. --Get the point size from the point size field. set myPointSize to edit value of myPointSizeField --Get the example text from the text edit field. set myString to edit contents of myTextEditField --Get the vertical justification setting from the pop-up menu. if selected index of myVerticalJustificationMenu is 0 then set myVerticalJustification to top align else if selected index of myVerticalJustificationMenu is 1 then set myVerticalJustification to center align else set myVerticalJustification to bottom align end if --Get the paragraph alignment setting from the radiobutton group. get properties of myParagraphAlignmentGroup
123
if selected button of myParagraphAlignmentGroup is 0 then set myParagraphAlignment to left align else if selected button of myParagraphAlignmentGroup is 1 then set myParagraphAlignment to center align else set myParagraphAlignment to right align end if --Remove the dialog box from memory. destroy myDialog my myMakeDocument(myPointSize, myString, myParagraphAlignment, myVerticalJustification) else destroy myDialog end if end tell
124
#targetengine "session" //Because these terms are defined in the "session" engine, //they will be available to any other JavaScript running //in that instance of the engine. var myMaximumValue = 300; var myProgressBarWidth = 300; var myIncrement = myMaximumValue/myProgressBarWidth; myCreateProgressPanel(myMaximumValue, myProgressBarWidth); function myCreateProgressPanel(myMaximumValue, myProgressBarWidth){ myProgressPanel = new Window('window', 'Progress'); with(myProgressPanel){ myProgressPanel.myProgressBar = add('progressbar', [12, 12, myProgressBarWidth, 24], 0, myMaximumValue); } }
The following script fragment shows how to call the progress bar created in the above script using an AppleScript (for the complete script, see CallProgressBar):
set myDocument to make document --Add pages to the active document. --If you don't do this, the progress bar will --go by too quickly. --Note that the JavaScripts must use the "session" --engine for this to work. set myJavaScript to "#targetengine \"session\"" & return set myJavaScript to myJavaScript & "myCreateProgressPanel(100, 400);" & return set myJavaScript to myJavaScript & "myProgressPanel.show();" & return do script myJavaScript language javascript repeat with myCounter from 1 to 40 set myJavaScript to "#targetengine \"session\"" & return set myJavaScript to myJavaScript & "myProgressPanel.myProgressBar.value = " set myJavaScript to myJavaScript & myCounter & "/myIncrement;" & return do script myJavaScript language javascript tell myDocument to make page if myCounter = 100 then set myJavaScript to "#targetengine \"session\"" & return set myJavaScript to myJavaScript & "myProgressPanel.myProgressBar.value = 0;" & return set myJavaScript to myJavaScript & "myProgressPanel.hide();" & return do script myJavaScript language javascript close myDocument saving no end if end repeat
Events
InDesign scripting can respond to common application and document events, such as opening a file, creating a new file, printing, and importing text and graphic files from disk. In InDesign scripting, the event object responds to an event that occurs in the application. Scripts can be attached to events using the event listener scripting object. Scripts that use events are the same as other scriptsthe only difference is that they run automatically when the corresponding event occurs, rather than being run by the user (from the Scripts palette). This chapter shows how to work with InDesign event scripting. 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. For a discussion of events related to menus, see Chapter 9, Menus. The InDesign event scripting model is similar to the Worldwide Web Consortium (W3C) recommendation for Document Object Model Events. For more information, see http://www.w3c.org.
125
CHAPTER 8: Events
126
The following table provides more detail on the properties of an event and the ways in which they relate to event propagation through the scripting object model. Property
Bubbles
Description If true, the event propagates to scripting objects above the object initiating the event. If true, the default behavior of the event on its target can be canceled. To do this, use the prevent default command . The current scripting object processing the event. See target in this table. If true, the default behavior of the event on the current target was prevented, thereby canceling the action. See target in this table. The current stage of the event propagation process. The type of the event, as a string (for example, "beforeNew"). If true, the event has stopped propagating beyond the current target (see target in this table). To stop event propagation, use the stop propagation command . The object from which the event originates. For example, the target of a beforeImport event is a document; of a beforeNew event, the application. The time and date when the event occurred.
Cancelable
CurrentTarget DefaultPrevented
Target
TimeStamp
When you use an event handler defined in the script, rather than an event handler defined in a separate script file, the script will work correctly when run from the InDesign Scripts panel, but will not work when you run it from a script editing application (such as the Apple Script Editor).
CHAPTER 8: Events
127
To remove the event listener created by the preceding script, run the following script (from the RemoveEventListener tutorial script):
tell application "Adobe InDesign CS5" remove event listener event type "afterNew" handler myDisplayEventType end tell
When an event listener responds to an event, the event may still be processed by other event listeners that might be monitoring the event (depending on the propagation of the event). For example, the afterOpen event can be observed by event listeners associated with both the application and the document.
event listeners do not persist beyond the current InDesign session. To make an event listener
available in every InDesign session, add the script to the startup scripts folder. (For more on installing scripts, see "Installing Scripts" in Adobe InDesign CS5 Scripting Tutorial.) When you add an event listener script to a document, it is not saved with the document or exported to IDML. NOTE: If you are having trouble with a script that defines an event listener, you can either run a script that removes the event listener or quit and restart InDesign. An event can trigger multiple event listeners as it propagates through the scripting object model. The following sample script demonstrates an event triggering event listeners registered to different objects (for the full script, see MultipleEventListeners):
--Shows that an event can trigger multiple event listeners. tell application "Adobe InDesign CS5" set myDocument to make document --You'll have to fill in a valid file path for your system make event listener with properties {event type:"beforeImport", handler:my myEventInfo} tell myDocument make event listener with properties {event type:"beforeImport", handler:my myEventInfo} end tell end tell
The handler referred to in the preceding script fragment contains the following:
on myEventInfo(myEvent) tell application "Adobe InDesign CS5" set myString to "Current Target: " & name of current target of myEvent display dialog (myString) end tell end myEventInfo
When you run the preceding script and place a file, InDesign displays alerts showing, in sequence, the name of the document, then the name of the application. To remove the event listeners added by the preceding script, run the RemoveMultipleEventListeners script. The following sample script creates an event listener for each document event and displays information about the event in a simple dialog box. For the complete script, see EventListenersOn.
CHAPTER 8: Events
128
tell application "Adobe InDesign CS5" set myEventNames to {"beforeNew", "afterNew", "beforeQuit", "afterQuit", "beforeOpen", "afterOpen", "beforeClose", "afterClose", "beforeSave", "afterSave", "beforeSaveAs", "afterSaveAs", "beforeSaveACopy", "afterSaveACopy", "beforeRevert", "afterRevert", "beforePrint", "afterPrint", "beforeExport", "afterExport", "beforeImport", "afterImport", "beforePlace", "afterPlace"} repeat with myEventName in myEventNames make event listener with properties {event type:myEventName, handler:"yukino:IDEventHandlers:GetEventInfo.applescript"} end repeat end tell
The preceding script refers to the following script. The file reference in the preceding script must match the location of this script on your disk. For the complete script, see GetEventInfo.applescript.
main(evt) on main(myEvent) tell application "Adobe InDesign CS5" set myString to "Handling Event: " & event type of myEvent & return set myString to myString & "Target: " & name of target of myEvent & return set myString to myString & "Current: " & name of current target of myEvent & return set myString to myString & "Phase: " & my myGetPhaseName(event phase o f myEvent) & return set myString to myString & "Bubbles: " & bubbles of myEvent & return set myString to myString & "Cancelable: " & cancelable of myEvent & return set myString to myString & "Stopped: " & propagation stopped of myEvent & return set myString to myString & "Canceled: " & default prevented of myEvent & return set myString to myString & "Time: " & time stamp of myEvent & return display dialog (myString) end tell end main --Function returns a string corresponding to the event phase. on myGetPhaseName(myEventPhase) tell application "Adobe InDesign CS5" if myEventPhase is at target then set myString to "At Target" else if myEventPhase is bubbling phase then set myString to "Bubbling" else if myEventPhase is done then set myString to "Done" else if myEventPhase is not dispatching then set myString to "Not Dispatching" else set myString to "Unknown Phase" end if return myString end tell end myGetPhaseName
The following sample script shows how to turn off all event listeners on the application object. For the complete script, see EventListenersOff.
-tell application "Adobe InDesign CS5" tell event listeners to delete end tell
CHAPTER 8: Events
129
The preceding script refers to the following script. The file reference in the preceding script must match the location of this script on your disk. For the complete script, see AfterNewHandler.applescript.
--AfterNewHandler.applescript --An InDesign CS5 AppleScript ---This script is called by the AfterNew.applescript. It --Sets up a basic document layout and adds XMP information --to the document. main(evt) on main(myEvent) tell application "Adobe InDesign CS5" if user name = "" then set user name to "Adobe" end if set myUserName to user name --set myDocument to parent of myEvent set myDocument to document 1 tell view preferences of myDocument set horizontal measurement units to points set vertical measurement units to points set ruler origin to page origin end tell --MySlugOffset is the distance from the bottom of the page --to the top of the slug. set mySlugOffset to 12 --MySlugHeight is the height of the text frame --containing the job information. set mySlugHeight to 72 tell document preferences of myDocument set documentSlugUniformSize to false set slug bottom offset to mySlugOffset + mySlugHeight set slug top offset to 0 set slug inside or left offset to 0 set slug right or outside offset to 0 end tell repeat with myCounter from 1 to (count master spreads of myDocument) set myMasterSpread to master spread myCounter of myDocument repeat with myMasterPageCounter from 1 to (count pages of myMasterSpread) set myPage to page myMasterPageCounter of myMasterSpread set mySlugBounds to my myGetSlugBounds(myDocument, myPage, mySlugOffset, mySlugHeight) tell myPage set mySlugFrame to make text frame with properties {geometric
CHAPTER 8: Events
130
bounds:mySlugBounds, contents:"Created: " & time stamp of myEvent & return & "by: " & myUserName} end tell end repeat end repeat tell metadata preferences of myDocument set author to "Adobe Systems" set description to "This is an example document containing XMP metadata. Created: " & time stamp of myEvent end tell end tell end main on myGetSlugBounds(myDocument, myPage, mySlugOffset, mySlugHeight) tell application "Adobe InDesign CS5" tell myDocument set myPageWidth to page width of document preferences set myPageHeight to page height of document preferences end tell set myLeft to left of margin preferences of myPage set myRight to right of margin preferences of myPage set myX1 to myLeft set myY1 to myPageHeight + mySlugOffset set myX2 to myPageWidth - myRight set myY2 to myY1 + mySlugHeight return {myY1, myX1, myY2, myX2} end tell end myGetSlugBounds
The preceding script refers to the following script. The file reference in the preceding script must match the location of this script on your disk. For the complete script, see BeforePrintHandler.applescript.
CHAPTER 8: Events
131
--BeforePrintHandler.applescript --An InDesign CS5 AppleScript ---Peforms a preflight check on a document. Called by the --BeforePrint.applescript event listener example. --"evt" is the event passed to this script by the event listener. main(evt) on main(myEvent) tell application "Adobe InDesign CS5" --The parent of the event is the document. set myDocument to parent of myEvent if my myPreflight(myDocument) is false then tell myEvent stop propagation prevent default end tell display dialog ("Document did not pass preflight check. Please fix the problems and try again.") else display dialog ("Document passed preflight check. Ready to print.") end if end tell end main on myPreflight(myDocument) set myPreflightCheck to true set myFontCheck to my myCheckFonts(myDocument) set myGraphicsCheck to my myCheckGraphics(myDocument) display dialog ("Fonts: " & myFontCheck & return & "Links:" & myGraphicsCheck) if myFontCheck = false or myGraphicsCheck = false then set myPreflightCheck to false return myPreflightCheck end if end myPreflight on myCheckFonts(myDocument) tell application "Adobe InDesign CS5" set myFontCheck to true repeat with myCounter from 1 to (count fonts of myDocument) set myFont to font myCounter of myDocument if font status of myFont is not installed then set myFontCheck to false exit repeat end if end repeat return myFontCheck end tell end myCheckFonts on myCheckGraphics(myDocument) tell application "Adobe InDesign CS5" set myGraphicsCheck to true repeat with myCounter from 1 to (count graphics of myDocument) set myGraphic to graphic myCounter of myDocument set myLink to item link of myGraphic if link status of myLink is not normal then set myGraphicsCheck to false exit repeat end if end repeat return myGraphicsCheck end tell end myCheckGraphics
CHAPTER 8: Events
132
The event handler referred to in the preceding script fragment looks like this:
on myDisplaySelectionType(en) tell application "Adobe InDesign CS5" if (count documents) is greater than 0 then tell document 1 set mySelection to selection if (count mySelection) is greater than 0 then set myString to "Selection Contents:" & return repeat with myCounter from 1 to (count mySelection) set myString to myString & class of item myCounter of mySelection & return end repeat display dialog myString end if end tell end if end tell end myDisplaySelectionType
To remove the event listener added by the preceding script, run the RemoveAfterSelectionChanged script. The following script fragment shows how to respond to a change in the attributes of a selection. In this example, the event handler checks the selection to see whether the Registration swatch has been applied. (Accidental application of the Registration swatch can cause problems at your commercial printer.) If the Registration swatch has been applied, the script asks whether the change was intentional. For the complete script, see AfterSelectionAttributeChanged.
set myDocument to make document tell myDocument set myEventListener to make event listener with properties {event type:"afterSelectionAttributeChanged", handler:my myCheckForRegistration}\ end tell
The event handler referred to in the preceding script fragment looks like this:
CHAPTER 8: Events
133
on myCheckForRegistration() tell application "Adobe InDesign CS5" if (count documents) is greater than 0 then tell document 1 set mySelection to selection if (count mySelection) is greater than 0 then set myRegistrationSwatchUsed to false repeat with myCounter from 1 to (count mySelection) set myFillColor to fill color of item myCounter of mySelection set myStrokeColor to stroke color of item myCounter of mySelection if name of myFillColor is "Registration" or name of myStrokeColor is "Registration" then set myRegistrationSwatchUsed to true end if end repeat if myRegistrationSwatchUsed is true then display dialog "The Registration swatch is applied to some of the" & return & "objects in the selection. Did you really intend to apply this swatch?" end if end if end tell end if end tell end myCheckForRegistration
To remove the event listener added by the preceding script, run the RemoveAfterSelectionAttributeChanged script.
CHAPTER 8: Events
134
To remove the idle task created by preceding script, run the following script (for the complete script, see RemoveIdleTask):
set taskCount to count of idle tasks if taskCount is 0 then display alert "There is no idle task." else set myIdleTaskName to "my_idle_task" repeat with i from taskCount to 1 by -1 set myIdleTask to item i of idle tasks if name of myIdleTask is myIdleTaskName then delete myIdleTask end if end repeat display alert "Idle task " & myIdleTaskName & " removed." end if
To remove all idle tasks, run the following script (for the complete script, see RemoveAllIdleTasks):
set taskCount to count of idle tasks if taskCount is 0 then display alert "There is no idle task." else repeat with i from taskCount to 1 by -1 set myIdleTask to item i of idle tasks delete myIdleTask end repeat display alert "" & taskCount & " idle task(s) removed." end if
To list existing idle tasks, run the following script (for the complete script, see ListIdleTasks):
CHAPTER 8: Events
135
set taskCount to count of idle tasks if taskCount is 0 then display alert "There is no idle task." else set str to "" repeat with i from 1 to taskCount set myIdleTask to item i of idle tasks tell myIdleTask set str to str & "idle task " & id & ": " & name & return end tell end repeat display alert str end if
Menus
InDesign scripting can add menu items, remove menu items, perform any menu command, and attach scripts to menu items. This chapter shows how to work with InDesign menu scripting. 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 you already read Adobe InDesign CS5 Scripting Tutorial and know how to create, install, and run a script.
Every menu item is connected to a menu action through the associated menu action property. The properties of the menu action define what happens when the menu item is chosen. In addition to the menu actions defined by the user interface, InDesign scripters can create their own, script menu actions, which associate a script with a menu selection. A menu action or script menu action can be connected to zero, one, or more menu items. The following diagram shows how the different menu objects relate to each other:
136
CHAPTER 9: Menus
137
application menuActions menuAction area checked enabled eventListeners id index label name events parent title scriptMenuActions scriptMenuAction same as menuAction event event ... eventListener eventListener ...
To create a list (as a text file) of all menu actions, run the following script fragment (from the GetMenuActions tutorial script):
set myTextFile to choose file name("Save menu action names as:") if myTextFile is not equal to "" then tell application "Adobe InDesign CS5" set myString to "" set myMenuActionNames to name of every menu action repeat with myMenuActionName in myMenuActionNames set myString to myString & myMenuActionName & return end repeat my myWriteToFile(myString, myTextFile, false) end tell end if on myWriteToFile(myString, myFileName, myAppendData) set myTextFile to open for access myFileName with write permission if myAppendData is false then set eof of myTextFile to 0 end if write myString to myTextFile starting at eof close access myTextFile end myWriteToFile
To create a list (as a text file) of all available menus, run the following script fragment (for the complete script, see GetMenuNames). These scripts can be very slow, as there are many menu names in InDesign.
CHAPTER 9: Menus
138
--Open a new text file. set myTextFile to choose file name ("Save Menu Action Names As") --If the user clicked the Cancel button, the result is null. if (myTextFile is not equal to "") then tell application "Adobe InDesign CS5" --Open the file with write access. my myWriteToFile("Adobe InDesign CS5 Menu Names" & return, myTextFile, false) repeat with myCounter from 1 to (count menus) set myMenu to item myCounter of menus set myString to "----------" & return & name of myMenu & return & "----------" & return set myString to my myProcessMenu(myMenu, myString) my myWriteToFile(myString, myTextFile, true) end repeat display dialog ("done!") end tell end if on myProcessMenu(myMenu, myString) tell application "Adobe InDesign CS5" set myIndent to my myGetIndent(myMenu) repeat with myCounter from 1 to (count menu elements of myMenu) set myMenuElement to menu element myCounter of myMenu set myClass to class of myMenuElement if myClass is not equal to menu separator then set myMenuElementName to name of myMenuElement set myString to myString & myIndent & myMenuElementName & return if class of myMenuElement is submenu then if myMenuElementName is not "Font" then set myString to my myProcessMenu(myMenuElement, myString) end if end if end if end repeat return myString end tell end myProcessMenu on myGetIndent(myObject) tell application "Adobe InDesign CS5" set myString to "" repeat until class of myObject is menu set myString to myString & tab set myObject to parent of myObject end repeat return myString end tell end myGetIndent on myWriteToFile(myString, myFileName, myAppendData) set myTextFile to open for access myFileName with write permission if myAppendData is false then set eof of myTextFile to 0 end if write myString to myTextFile starting at eof close access myTextFile end myWriteToFile
CHAPTER 9: Menus
139
NOTE: It is much better to get the locale-independent name of a menu action than of a menu, menu item, or submenu, because the title of a menu action is more likely to be a single string. Many of the other menu objects return multiple strings when you use the find key strings method. Once you have the locale-independent string you want to use, you can include it in your scripts. Scripts that use these strings will function properly in locales other than that of your version of InDesign. To translate a locale-independent string into the current locale, use the following script fragment (from the TranslateKeyString tutorial script):
tell application "Adobe InDesign CS5" set myString to translate key string for "$ID/NotesMenu_ConvertToNote" display dialog(myString) end tell
NOTE: In general, you should not try to automate InDesign processes by scripting menu actions and user-interface selections; InDesigns scripting object model provides a much more robust and powerful way to work. Menu actions depend on a variety of user-interface conditions, like the selection and the
CHAPTER 9: Menus
140
state of the window. Scripts using the object model work with the objects in an InDesign document directly, which means they do not depend on the user interface; this, in turn, makes them faster and more consistent.
To remove the custom menu item created by the above script, use RemoveCustomMenu.
tell application "Adobe InDesign CS3" set myMainMenu to menu "Main" try set myKozukaMenu to submenu "Kozuka Mincho Pro" of myMainMenu tell myKozukaMenu to delete end try end tell
Event
beforeDisplay
Description Runs the attached script before the contents of the menu is shown. Runs the attached script when the associated menu item is selected, but after the onInvoke event. Runs the attached script when the associated menu item is selected, but before the onInvoke event.
menu action
afterInvoke
beforeInvoke
CHAPTER 9: Menus
141
Object
script menu action
Event
afterInvoke
Description Runs the attached script when the associated menu item is selected, but after the onInvoke event. Runs the attached script when the associated menu item is selected, but before the onInvoke event. Runs the attached script before an internal request for the enabled/checked status of the script menu actionscript menu action. Runs the attached script when the script menu action is invoked. Runs the attached script before the contents of the submenu are shown.
beforeInvoke
beforeDisplay
onInvoke
submenu
beforeDisplay
For more about events and event listeners, see Chapter 8, Events. To change the items displayed in a menu, add an event listener for the beforeDisplay event. When the menu is selected, the event listener can then run a script that enables or disables menu items, changes the wording of menu item, or performs other tasks related to the menu. This mechanism is used internally to change the menu listing of available fonts, recent documents, or open windows.
CHAPTER 9: Menus
142
tell application "Adobe InDesign CS5" --Create the script menu action "Display Message" --if it does not already exist. try set myScriptMenuAction to script menu action "Display Message" on error set myScriptMenuAction to make script menu action with properties {title:"Display Message"} end try tell myScriptMenuAction --If the script menu action already existed, --remove the existing event listeners. if (count event listeners) > 0 then tell every event listener to delete end if set myEventListener to make event listener with properties {event type:"onInvoke", handler:"yukino:message.applescript"} end tell tell menu "$ID/Main" set mySampleScriptMenu to make submenu with properties {title:"Script Menu Action"} tell mySampleScriptMenu set mySampleScriptMenuItem to make menu item with properties {associated menu action:myScriptMenuAction} end tell end tell end tell
To remove the menu, submenu, menu item, and script menu action created by the above script, run the following script fragment (from the RemoveScriptMenuAction tutorial script):
tell application "Adobe InDesign CS5" try set myScriptMenuAction to script menu action "Display Message" tell myScriptMenuAction delete end tell tell submenu "Script Menu Action" of menu "$ID/Main" to delete end try end tell
You also can remove all script menu action, as shown in the following script fragment (from the RemoveAllScriptMenuActions tutorial script). This script also removes the menu listings of the script menu action, but it does not delete any menus or submenus you might have created.
tell application "Adobe InDesign CS5" delete every script menu action end tell
You can create a list of all current script menu actions, as shown in the following script fragment (from the ListScriptMenuActions tutorial script):
CHAPTER 9: Menus
143
set myTextFile to choose file name {"Save Script Menu Action Names As"} --If the user clicked the Cancel button, the result is null. if myTextFile is not equal to "" then tell application "Adobe InDesign CS5" set myString to "" set myScriptMenuActionNames to name of every script menu action repeat with myScriptMenuActionName in myScriptMenuActionNames set myString to myString & myScriptMenuActionName & return end repeat my myWriteToFile(myString, myTextFile, false) end tell end if on myWriteToFile(myString, myFileName, myAppendData) set myTextFile to open for access myFileName with write permission if myAppendData is false then set eof of myTextFile to 0 end if write myString to myTextFile starting at eof close access myTextFile end myWriteToFile script menu actions also can run scripts during their beforeDisplay event, in which case they are executed before an internal request for the state of the script menu action (e.g., when the menu item is about to be displayed). Among other things, the script can then change the menu names and/or set the enabled/checked status.
In the following sample script, we add an event listener to the beforeDisplay event that checks the current selection. If there is no selection, the script in the event listener disables the menu item. If an item is selected, the menu item is enabled, and choosing the menu item displays the type of the first item in the selection. (For the complete script, see BeforeDisplay.)
tell application "Adobe InDesign CS5" --Create the script menu action "Display Message" --if it does not already exist. try set myScriptMenuAction to script menu action "Display Message" on error set myScriptMenuAction to make script menu action with properties {title:"Display Message"} end try tell myScriptMenuAction --If the script menu action already existed, --remove the existing event listeners. if (count event listeners) > 0 then tell every event listener to delete end if --Fill in a valid file path for your system.
CHAPTER 9: Menus
144
make event listener with properties {event type:"onInvoke", handler:"yukino:WhatIsSelected.applescript"} end tell tell menu "$ID/Main" set mySampleScriptMenu to make submenu with properties {title:"Script Menu Action"} tell mySampleScriptMenu set mySampleScriptMenuItem to make menu item with properties {associated menu action:myScriptMenuAction} --Fill in a valid file path for your system. make event listener with properties {event type:"beforeDisplay", handler:"yukino:BeforeDisplayHandler.applescript"} end tell end tell end tell
CHAPTER 9: Menus
145
tell application "Adobe InDesign CS5" --The locale-independent name (aka "key string") for the --Layout context menu is "$ID/RtMouseLayout". set myLayoutMenu to menu "$ID/RtMouseLayout" --Note that the following script actions only create the script menu action --and set up event listeners--they do not actually add the menu item to the --Layout context menu. That job is taken care of by the event handler scripts --themselves. The Layout context menu will not display the menu item unless --a graphic is selected. tell myLayoutContextMenu set myBeforeDisplayEventListener to make event listener with properties{event type:"beforeDisplay", handler:"yukino:IDEventHandlers:LayoutMenuBeforeDisplay.applescript", captures:false} end tell end tell
The LayoutMenuBeforeDisplay.applescript file referred to in the above example contains the following:
myBeforeDisplayHandler(evt) on myBeforeDisplayHandler(myEvent) tell application "Adobe InDesign CS5" set myGraphicList to {PDF, EPS, image} set myParentList to {rectangle, oval, polygon} set myObjectList to {} set myLayoutContextMenu to menu "$ID/RtMouseLayout" if (count documents) > 0 then set mySelection to selection if (count mySelection) > 0 then repeat with myCounter from 1 to (count mySelection) set myObject to item myCounter of mySelection if class of myObject is in myGraphicList then copy myObject to end of myObjectList else if class of myObject is in myParentList then if (count graphics of myObject) > 0 then copy graphic 1 of myObject to end of myObjectList end if end if end repeat if (count myObjectList) is not equal to 0 then --The selection contains a qualifying item or items. --Add the menu item if it does not already exist. if my myMenuItemExists(myLayoutContextMenu, "Create Graphic Label") is false then my myMakeLabelGraphicMenuItem(myLayoutContextMenu) end if else --Remove the menu item if it exists. if my myMenuItemExists(myLayoutContextMenu, "Create Graphic Label") is true then tell myLayoutContextMenu delete menu item "Create Graphic Label" end tell end if end if end if end if end tell end myBeforeDisplayHandler
CHAPTER 9: Menus
146
on myMakeLabelGraphicMenuItem(myLayoutContextMenu) tell application "Adobe InDesign CS5" if my myScriptMenuActionExists("Create Graphic Label") is false then set myLabelGraphicMenuAction to make script menu action with properties {name:"Create Graphic Label"} tell myLabelGraphicMenuAction set myLabelGraphicEventListener to make event listener with properties {event type:"onInvoke",handler: "yukino:IDEventHandlers:LayoutMenuOnInvoke.applescript", captures:false} end tell else set myLabelGraphicMenuAction to script menu action "Create Graphic Label" end if tell myLayoutContextMenu set myLabelGraphicMenuItem to make menu item with properties {associated menu action:myLabelGraphicMenuAction} end tell end tell end myMakeLabelGraphicMenuItem
The LayoutMenuOnInvoke.applescript referred to in the above example defines the script menu action that is activated when the menu item is selected (onInvoke event):
LabelGraphicEventHandler(evt) on LabelGraphicEventHandler(myEvent) tell application "Adobe InDesign CS5" set myGraphicList to {PDF, EPS, image} set myParentList to {rectangle, oval, polygon} set myObjectList to {} set myLayoutContextMenu to menu "$ID/RtMouseLayout" if (count documents) > 0 then set mySelection to selection if (count mySelection) > 0 then repeat with myCounter from 1 to (count mySelection) set myObject to item myCounter of mySelection if class of myObject is in myGraphicList then copy myObject to end of myObjectList else if class of myObject is in myParentList then if (count graphics of myObject) > 0 then copy graphic 1 of myObject to end of myObjectList end if end if end repeat if (count myObjectList) is not equal to 0 then --The selection contains a qualifying item or items. my myDisplayDialog(myObjectList) end if end if end if end tell end LabelGraphicEventHandler --Displays a dialog box containing label options. on myDisplayDialog(myObjectList) tell application "Adobe InDesign CS5" set myLabelWidth to 100 set myStyleNames to my myGetParagraphStyleNames(document 1) set myLayerNames to my myGetLayerNames(document 1) set myDialog to make dialog with properties {name:"LabelGraphics"}
CHAPTER 9: Menus
147
tell myDialog tell (make dialog column) --Label Type tell (make dialog row) tell (make dialog column) make static text with properties {static label:"Label Type:", min width:myLabelWidth} end tell tell (make dialog column) set myLabelTypeDropdown to make dropdown with properties {string list:{"File Name", "File Path", "XMP Author", "XMP Description"}, selected index:0} end tell end tell --Text frame height tell (make dialog row) tell (make dialog column) make static text with properties {static label:"Label Height:", min width:myLabelWidth} end tell tell (make dialog column) set myLabelHeightField to make measurement editbox with properties {edit value:24, edit units:points} end tell end tell --Text frame offset tell (make dialog row) tell (make dialog column) make static text with properties {static label:"Label Offset:", min width:myLabelWidth} end tell tell (make dialog column) set myLabelOffsetField to make measurement editbox with properties {edit value:0, edit units:points} end tell end tell --Paragraph style to apply tell (make dialog row) tell (make dialog column) make static text with properties {static label:"Label Style:", min width:myLabelWidth} end tell tell (make dialog column) set myLabelStyleDropdown to make dropdown with properties {string list:myStyleNames, selected index:0} end tell end tell --Layer tell (make dialog row) tell (make dialog column) make static text with properties {static label:"Layer:", min width:myLabelWidth} end tell tell (make dialog column) set myLayerDropdown to make dropdown with properties {string list:myLayerNames, selected index:0} end tell end tell end tell end tell
CHAPTER 9: Menus
148
set myResult to show myDialog if myResult is true then set myLabelType to (selected index of myLabelTypeDropdown) set myLabelHeight to edit value of myLabelHeightField set myLabelOffset to edit value of myLabelOffsetField set myLabelStyleName to item ((selected index of myLabelStyleDropdown)+ 1) of myStyleNames set myLayerName to item ((selected index of myLayerDropdown) + 1) of myLayerNames destroy myDialog tell view preferences of document 1 set myOldXUnits to horizontal measurement units set myOldYUnits to vertical measurement units set horizontal measurement units to points set vertical measurement units to points end tell repeat with myCounter from 1 to (count myObjectList) set myGraphic to item myCounter of myObjectList my myAddLabel(myGraphic, myLabelType, myLabelHeight, myLabelOffset, myLabelStyleName, myLayerName) end repeat tell view preferences of document 1 set horizontal measurement units to myOldXUnits set vertical measurement units to myOldYUnits end tell else destroy myDialog end if end tell end myDisplayDialog on myAddLabel(myGraphic, myLabelType, myLabelHeight, myLabelOffset, myLabelStyleName, myLayerName) tell application "Adobe InDesign CS5" set myDocument to document 1 set myLabelStyle to paragraph style myLabelStyleName of myDocument try set myLabelLayer to layer myLayerName of myDocument on error tell myDocument set myLabelLayer to make layer with properties {name:myLayerName} end tell end try set myLink to item link of myGraphic if myLabelType is 0 then set myLabel to name of myLink else if myLabelType is 1 then set myLabel to file path of myLink else if myLabelType is 2 then try set myLabel to author of link xmp of myLink on error set myLabel to "No author available." end try else if myLabelType is 3 then try set myLabel to description of link xmp of myLink on error set myLabel to "No description available." end try end if
CHAPTER 9: Menus
149
set myFrame to parent of myGraphic set myBounds to geometric bounds of myFrame set myX1 to item 2 of myBounds set myY1 to (item 3 of myBounds) + myLabelOffset set myX2 to item 4 of myBounds set myY2 to myY1 + myLabelHeight tell parent of myFrame set myTextFrame to make text frame with properties {item layer:myLabelLayer, contents:myLabel, geometric bounds:{myY1, myX1, myY2, myX2}} set first baseline offset of text frame preferences of myTextFrame to leading offset tell myTextFrame set applied paragraph style of paragraph 1 to myLabelStyle end tell end tell end tell end myAddLabel
10
150
151
152
You also can load a profile with scripting. The following script fragment imports a profile called Test. For the complete script, see ImportPreflightProfile.
set myProfile to load preflight profile from "Macintosh HD:tmp:Test.idpp" if myProfile is nothing then display alert "The profile did not load successfully" else display alert "Preflight profile " & (name of myProfile) & " is loaded." end if
It is easier to create profiles using the Preflight panel than with scripting. One workflow would be to create all profiles in the user interface, export them to files, and import them using scripting. This approach avoids the challenges involved with manually adding rules via scripting.
153
You also can create a profile with scripting. The following script fragment adds a single profile called Test. For the complete script, see CreatePreflightProfile.
--Add a new preflight profile. set myProfile to make preflight profile display alert "Preflight profile " & (name of myProfile) & " is created." --Rename the profile tell myProfile set oldName to name set name to "Test" set description to "Test description" end tell display alert "Profile " & oldName & " is renamed to " & (name of myProfile) & "."
Preflight-profile names must be unique. If the script above is executed more than once within the same InDesign instance, an error is raised, indicating that a profile with that name already exists. To avoid this, either access the existing profile using app.preflightProfiles.itemByName(), or check to see if a profile exists and remove it; see the following script fragment. For the complete script, see DeletePreflightProfile.
Adding Rules
154
on removeProfile(profileName) tell application "Adobe InDesign CS5" set myProfiles to preflight profiles set profileCount to count of myProfiles repeat with i from 1 to profileCount if name of item i of myProfiles is equal to profileName then delete item i of myProfiles end if end repeat end tell end removeProfile
Adding Rules
A preflight profile contains a mutually exclusive set of rules. To add a rule to a profile, follow these steps: 1. Add a rule to a profile by name. Rules are added by name. For information on rule names, see Available Rules on page 156. The following adds the ADBE_PageSizeOrientation rule to the profile.
--Add a rule that requires a specific page size and orientation --(portrait or landscape). set RULE_NAME to "ADBE_PageSizeOrientation" set myRule to make preflight profile rule in myProfile with properties {name:RULE_NAME, id:RULE_NAME}
2. Set the rules data values. Many, but not all, rules have data properties. For a complete specification of the rules available with InDesign, see Available Rules on page 156. The ADBE_PageSizeOrientation rule contains particular data properties that allow you to specify a page size. The following sets the acceptable page height and width, a tolerance (fudge factor), and an option for handling page orientation.
tell myRule --Requires the page size to be 8.5in x 11in (Letter Size) --enters a value for tolerance make rule data object with properties {name:"tolerance", data type:real data type, data value:0.01} --Sets the width to the point equivalent of 8.5 inches make rule data object with properties {name:"width", data type:real data type, data value:612} --Sets the width to the point equivalent of 11 inches make rule data object with properties {name:"height", data type:real data type, data value:792} --true = ignore orientation is checked make rule data object with properties {name:"ignore_orientation", data type:boolean data type, data value:true} end tell
3. Set the rules reporting state. This is done using the rules flag property. There are several choices (disabled, information, warning, and error), controlled by the PreflightRuleFlag enumeration.
Processing a Profile
155
--set the rule to return an error set flag of myRule to return as error
Processing a Profile
In the desktop version of InDesign, preflight errors are reported in the user interface. In scripting (especially for InDesign Server), the errors are generated on demand. The following script processes an InDesign document. (For the complete script, see ProcessPreflightProfile.) If there are errors, it writes the results to a new PDF file. For an example of the output, see the figure below the script.
--Assume there is an document. set myDoc to document 1 --Use the second preflight profile set myProfile to preflight profile 2 --Process the doc with the profile set myProcess to make preflight process with properties {target object:myDoc, applied profile:myProfile} wait for process myProcess set results to process results of myProcess -- If errors were found if results is not "None" then -- Export the file to PDF, and to open the file after export. save report myProcess to "Macintosh HD:tmp:PreflightResults.pdf" with auto open end if --Cleanup delete myProcess
If you would rather produce a text file, simply name your output file with a .txt extension. Alternately, you may prefer to iterate the errors yourself. The following demonstrates how to access the errors array. For the complete script, see ProcessPreflightProfileShowErrors.
Custom Rules
156
-- If errors were found if results is not "None" then --array containing detailed results tell aggregated results of myProcess set str to "Document: " & item 1 & ", Profile: " & item 2 & ", Results: [" set errorResults to item 3 end tell --Show the errors in a message box. repeat with i from 1 to count of errorResults if i > 1 then str = str & ", " end if set str to str & item 2 of item i of errorResults end repeat set str to str & "]" display alert str end if
Custom Rules
It is not possible to create custom rules through the Preflight panel or scripting; however, this can be done through a C++ plug-in. The InDesign Products SDK contains a sample, PreflightRule, that demonstrates how to add custom rules with a plug-in.
Available Rules
One of the hardest aspects of scripting rules is discovering rule names and properties. Due to the dynamic nature of rules (they really are just strings), specific rule names and properties do not appear in the Extend Script Tool Kits Object Model Viewer. To discover this information, see Exploring Preflight Profiles on page 150. For your convenience, the DumpPreflightRules.jsx script is provided in the SDK to produce the following output as an HTML file (SDK\docs\references\PreflightRules.html). If you use a plug-in that adds custom rules, you can run the script to extract the new names and properties. Rule name
ADBE_BlankPages ADBE_BleedSlug ADBE_BleedTrimHazard ADBE_CMYPlates ADBE_Colorspace ADBE_ConditionIndicators ADBE_CrossReferences ADBE_FontUsage ADBE_ImageColorManagement ADBE_ImageResolution ADBE_InteractiveContent
Rule properties ADBE_BlankPages on page 157 ADBE_BleedSlug on page 157 ADBE_BleedTrimHazard on page 158 no ADBE_Colorspace on page 159 no ADBE_CrossReferences on page 159yes ADBE_FontUsage on page 159 ADBE_ImageColorManagement on page 160 ADBE_ImageResolution on page 160 no
Available Rules
157
Rule name
ADBE_LayerVisibility ADBE_MissingFonts ADBE_MissingGlyph ADBE_MissingModifiedGraphics ADBE_OPI ADBE_Overprint ADBE_OversetText ADBE_PageCount ADBE_PageSizeOrientation ADBE_Registration ADBE_ScaledGraphics ADBE_ScaledType ADBE_SmallText ADBE_SpellCheck ADBE_SpotColorSetup ADBE_StrokeRequirements ADBE_TextOverrides ADBE_TransparencyBlending ADBE_TransparencyUsage ADBE_WhiteOverprint
Rule properties no no no no no no no ADBE_PageCount on page 160 ADBE_PageSizeOrientation on page 161 no ADBE_ScaledGraphics on page 161 ADBE_ScaledType on page 161 ADBE_SmallText on page 161 no ADBE_SpotColorSetup on page 161 ADBE_StrokeRequirements on page 162 ADBE_TextOverrides on page 162 ADBE_TransparencyBlending on page 162 no no
ADBE_BlankPages
Data Type Boolean Boolean Name
ignore_master ignore_nonprinting
ADBE_BleedSlug
Data Type Real Real Name
bleed_b bleed_b_aux
Default value 9 9
Available Rules
158
Data Type Integer Boolean Real Real Real Real Real Real Real Real Integer Boolean Real Real Real Real Real Real Real
Name
bleed_comparison_type bleed_enabled bleed_l bleed_l_aux bleed_r bleed_r_aux bleed_t bleed_t_aux slug_b slug_b_aux slug_comparison_type slug_enabled slug_l slug_l_aux slug_r slug_r_aux slug_t slug_t_aux tolerance
ADBE_BleedTrimHazard
Data Type Boolean Real Real Real Real Real Real Name
binding_enabled binding_width live_b live_l live_r live_t tolerance
Available Rules
159
ADBE_Colorspace
Data Type Boolean Boolean Boolean Boolean Boolean Name
no_cmyk no_gray no_lab no_rgb no_spot
ADBE_CrossReferences
Data Type Boolean Boolean Name
xrefs_out_of_date xrefs_unresolved
ADBE_FontUsage
Data Type Boolean Boolean Boolean Boolean Boolean Boolean Boolean Boolean Boolean Boolean Name
no_ATC no_Bitmap no_CID no_MultipleMaster no_OpenTypeCFF no_OpenTypeCID no_OpenTypeTT no_TrueType no_Type1 no_protected
Default value false false false false false false false false false true
Available Rules
160
ADBE_ImageColorManagement
Data Type Boolean Boolean Boolean Name
no_cmyk_profiles no_image_overrides overrides_exclude_uncal
ADBE_ImageResolution
Data Type Boolean Real Boolean Real Boolean Real Boolean Real Boolean Real Boolean Real Real Name
bw_max_enabled bw_max_res bw_min_enabled bw_min_res color_max_enabled color_max_res color_min_enabled color_min_res gray_max_enabled gray_max_res gray_min_enabled gray_min_res tolerance
Default value false 2400 true 800 false 1200 true 250 false 1200 true 250 0.5
ADBE_PageCount
Data Type Integer Integer Integer Name
comparison_type comparison_value comparison_value_aux
Default value 2 1 1
Available Rules
161
ADBE_PageSizeOrientation
Data Type Real Boolean Real Real Name
height ignore_orientation tolerance width
ADBE_ScaledGraphics
Data Type Real Name
max_scale
ADBE_ScaledType
Data Type Boolean Real Name
ignore_justification max_scale
ADBE_SmallText
Data Type Real Boolean Name
minSize minSize_trap_safe_only
ADBE_SpotColorSetup
Data Type Boolean Boolean Integer Boolean Name
lab_spots lab_spots_enabled max_spots max_spots_enabled
Available Rules
162
ADBE_StrokeRequirements
Data Type Real Boolean Name
min_width min_width_trap_safe_only
ADBE_TextOverrides
Data Type Boolean Boolean Boolean Boolean Name
ignore_color_overrides ignore_font_overrides ignore_kerning_tracking_overrides ignore_language_overrides
ADBE_TransparencyBlending
Data Type Integer Name
space
Default value 3
11
The following script fragment shows how to import a sound file and control the playback and display of the sound in an exported document (for the complete script, refer to PlaceSound).
163
Creating Buttons
164
--Given a page "myPage" in a document "myDocument..." --Import a sound file (you'll have to provide a valid file path on your system) tell myPage set mySound to place file "hazuki:sound.mp3" place point {72, 72} end tell set mySound to item 1 of mySound tell mySound set embed in PDF to true set do not print poster to true set sound loop to true set stop on page turn to true end tell --Add a preview image. You'll have to provide a valid path on your system. set poster file of mySound to "hazuki:sound poster.jpg"
Buttons can be used to control the playback of sounds and movies. For information on how to script buttons, see the next section.
Creating Buttons
Buttons are often used for navigation in dynamic documents. Buttons contain three states, known as Normal, Rollover, and Click, which, in turn, can contain page items such as rectangles, ovals, text frames, or images. The button can display only one state at a time; the other states are displayed when triggered by mouse actions. Behaviors control what the button does when you perform a specific mouse action. Behaviors correspond to the Actions shown in the Buttons panel in InDesigns user interface. Buttons can contain multiple behaviors. The following script fragment shows how to create a simple button that displays the next page in an exported PDF or SWF (for the complete script, refer to SimpleButton). This button makes use of only the Normal state.
--Given a page "myPage" and a document containing the color "Red"... --Make a button by converting a page item. tell myPage set myRightArrow to make polygon with properties {fill color:"Red", name:"GoToNextPageButton"} set entire path of path 1 of myRightArrow to {{72, 72}, {144, 108}, {72, 144}} set myButton to make button with properties {geometric bounds:{72, 72, 144, 144}} end tell tell state 1 of myButton add items to state pageitems {myRightArrow} end tell tell myButton set myGoToNextPageBehavior to make goto next page behavior with properties {behavior event:mouse up} end tell
The following script fragment shows how to create a somewhat more complicated button, containing page items that change the appearance of each of the three button states. For the complete script, refer to ButtonStates.
Creating Buttons
165
--Given a page "myPage" in a document "myDocument," containing the colors --"Blue" and "Red"... --Make a button "from scratch." tell page 1 of myDocument set myButton to make button with properties {geometric bounds:{72, 72, 144, 144}, name:"GoToNextPageButton"} end tell tell state 1 of myButton set myRightArrow to make polygon with properties {fill color:color "Red" of myDocument, stroke color:"None"} set entire path of path 1 of myRightArrow to {{72, 72}, {144, 108}, {72, 144}} end tell --Add the Rollover state. tell myButton set myRolloverState to make state end tell tell myRolloverState set myRolloverArrow to make polygon with properties {fill color:color "Red" of myDocument, stroke color:"None"} set entire path of path 1 of myRolloverArrow to {{72, 72}, {144, 108}, {72, 144}} --Add a shadow to the polygon in the Rollover state. end tell tell drop shadow settings of fill transparency settings of myRolloverArrow set mode to drop set angle to 90 set x offset to 0 set y offset to 0 set size to 6 end tell tell myButton set myClickState to make state end tell tell myClickState set myClickArrow to make polygon with properties {fill color:color "Blue" of myDocument, stroke color:"None"} set entire path of path 1 of myClickArrow to {{72, 72}, {144, 108}, {72, 144}} end tell --Set the behavior for the button. tell myButton set myGoToNextPageBehavior to make goto next page behavior with properties {behavior event:mouse up} end tell
Buttons can be used to control the playback of movie and sound files. The following script fragment shows an example of using a set of buttons to control the playback of a moving file (for the complete script, refer to MovieControl).
Creating Buttons
166
--Given a page "myPage" in a document "myDocument," --containing the colors "Gray" and "Red"... tell myPage set myFrame to make rectangle with properties {geometric bounds:{72, 72, 288, 288}} --Import a movie file (you'll have to provide a valid file path on your system) tell myFrame to place file "hazuki:movie.flv" --Create the movie "Start" button. set myPlayButton to make button with properties {geometric bounds: {294, 186, 354, 282}, name:"PlayMovieButton"} tell myPlayButton set myRightArrow to make polygon with properties {fill color:color "Gray" of myDocument, stroke color:"None"} end tell set entire path of path 1 of myRightArrow to {{186, 294}, {186, 354}, {282, 324}} --Add the Rollover state. tell myPlayButton set myRolloverState to make state end tell --Add a shadow to the polygon in the Rollover state. tell myRolloverState set myRolloverArrow to make polygon with properties {fill color:color "Gray" of myDocument, stroke color:"None"} end tell set entire path of path 1 of myRolloverArrow to {{186, 294}, {186, 354}, {282, 324}} tell drop shadow settings of fill transparency settings of myRolloverArrow set mode to drop set angle to 90 set x offset to 0 set y offset to 0 set size to 6 end tell tell myPlayButton set myClickState to make state end tell tell myClickState set myClickArrow to make polygon with properties {fill color:color "Red" of myDocument, stroke color:"None"} end tell set entire path of path 1 of myClickArrow to {{186, 294}, {186, 354}, {282, 324}} --Set the behavior for the button. tell myPlayButton set myMovieStartBehavior to make movie behavior with properties {movie item: movie 1 of myFrame, behavior event:mouse up, operation:play} end tell --Create the movie "Stop" button. set myStopButton to make button with properties {geometric bounds: {294, 78, 354, 174}, name:"StopMovieButton"} tell state 1 of myStopButton set myNormalRectangle to make rectangle with properties {geometric bounds: {294, 78, 354, 174}, fill color:color "Gray" of myDocument} end tell tell myStopButton set myRolloverState to make state end tell tell myRolloverState set myRolloverRectangle to make rectangle with properties {geometric bounds: {294, 78, 354, 174}, fill color:color "Gray" of myDocument} end tell tell drop shadow settings of fill transparency settings of myRolloverRectangle set mode to drop
167
set angle to 90 set x offset to 0 set y offset to 0 set size to 6 end tell tell myStopButton set myClickState to make state end tell tell myClickState set myClickRectangle to make rectangle with properties {geometric bounds: {294, 78, 354, 174}, fill color:color "Red" of myDocument} end tell tell myStopButton set myMovieStopBehavior to make movie behavior with properties {movie item: movie 1 of myFrame, behavior event:mouse up, operation:stop} end tell end tell
Buttons are also important in controlling the appearance of multistate objects, as well demonstrate in the next section.
168
set myPolygon to make polygon with properties {fill color:myColorB, stroke color:"None"} set entire path of path 1 of myPolygon to {{72, 72}, {72, 144}, {144, 108}} end tell tell state 3 of myMSO set myPolygon to make polygon with properties {fill color:myColorC, stroke color:"None"} set entire path of path 1 of myPolygon to {{72, 72}, {108, 144}, {144, 72}} end tell tell state 4 of myMSO set myPolygon to make polygon with properties {fill color:myColorD, stroke color:"None"} set entire path of path 1 of myPolygon to {{144, 72}, {72, 108}, {144, 144}} end tell end tell
Typically, youll control the display of the states in a multistate object using a button. The following script fragment shows how to do this (for the complete script, refer to MultiStateObjectControl).
--Given a document "myDocument" and a page "myPage" and --four colors "myColorA," "myColorB," "myColorC," and "myColorD"... tell myPage set myMSO to make multi state object with properties {name:"Spinner", geometric bounds:{72, 72, 144, 144}} --New multistate objects contain two states when they're created. Add two more. tell myMSO set name of state 1 to "Up" set name of state 2 to "Right" make state with properties {name:"Down"} make state with properties {name:"Left"} end tell --Add page items to the states. tell state 1 of myMSO set myPolygon to make polygon with properties {fill color:myColorA, stroke color:"None"} set entire path of path 1 of myPolygon to {{72, 144}, {144, 144}, {108, 72}} end tell tell state 2 of myMSO set myPolygon to make polygon with properties {fill color:myColorB, stroke color:"None"} set entire path of path 1 of myPolygon to {{72, 72}, {72, 144}, {144, 108}} end tell tell state 3 of myMSO set myPolygon to make polygon with properties {fill color:myColorC, stroke color:"None"} set entire path of path 1 of myPolygon to {{72, 72}, {108, 144}, {144, 72}} end tell tell state 4 of myMSO set myPolygon to make polygon with properties {fill color:myColorD, stroke color:"None"} set entire path of path 1 of myPolygon to {{144, 72}, {72, 108}, {144, 144}} end tell set myButton to make button with properties {geometric bounds:{72, 72, 144, 144}} tell myButton set myRolloverState to make state set myClickState to make state set myNextStateBehavior to make goto next state behavior with properties {associated multi state object:myMSO, behavior event:mouse down, enable behavior:true, loops to next or previous:true} end tell
169
tell myRolloverState set myRolloverRectangle to rectangle 1 of group 1 end tell set stroke color of myRolloverRectangle to myColorD set stroke weight of myRolloverRectangle to 1 set myStrokeTransparencySettings to stroke transparency settings of myRolloverRectangle set myDropShadowSettings to drop shadow settings of myStrokeTransparencySettings tell myDropShadowSettings set mode to drop set angle to 90 set x offset to 0 set y offset to 0 set size to 6 end tell end tell
Basic animation
The following script fragment shows how to create a simple animation (for the complete script, refer to SimpleAnimation). The most basic forms of animation can be applied without using timing settings.
--Given a document "myDocument" and a page "myPage" and a color "myColorA"... --Add a page items to animate. tell myPage set myPolygon to make polygon with properties {fill color:myColorA, stroke color:"None"} end tell set entire path of path 1 of myPolygon to {{72, 72}, {72, 144}, {144, 108}} --Create a motion path. set myMotionPathPoints to {{{{108, 108}, {108, 108}, {108, 108}}, {{516, 108}, {516, 108}, {516, 108}}}, true} --Set animation preferences for the polygon. We havent' set a dynamic trigger --for the animation, so the polygon's animation will be triggered by --on page load (the default). tell animation settings of myPolygon set duration to 2 set motion path points to myMotionPathPoints end tell
170
TimingSettings
The timing settings objects of spreads, pages, and page items control the timing of the animation(s) applied to the object and to any objects contained by the object. timing settings contain:
timing lists, which define the trigger event (page load, page click, and so on) that start the
animation.
timing groups, which associate a page item or series of page items with a specific timing and define the sequence in which animations are shown. timing groups contain timing targets, which define the objects associated with a given timing group. timing targets also specify a delay value for the animation applied to the page item, relative to the start of the animation of the timing group (for the first item in the timing group), or from the start of the previous item in the timing group (for other items in the timing group).
The following script fragment shows how to control the timing of the animation of an object using the various timing objects (for the complete script, refer to TimingSettings). Note that the parameters used to create a timing group specify the properties of the first timing target in the timing group; subsequent timing targets, if any, can be added separately.
--Given a document "myDocument" and a page "myPage" and the color "myColorA", --"myColorB", and "myColorC"... --Add a page items to animate. tell myPage set myPolygonA to make polygon with properties {fill color:myColorA, strokeColor:"None"} set entire path of path 1 of myPolygonA to {{72, 72}, {72, 144}, {144, 108}} set myPolygonB to make polygon with properties {fill color:myColorB, strokeColor:"None"} set entire path of path 1 of myPolygonB to {{72, 72}, {72, 144}, {144, 108}} set myPolygonC to make polygon with properties {fill color:myColorC, strokeColor:"None"} set entire path of path 1 of myPolygonC to {{72, 72}, {72, 144}, {144, 108}} end tell --Create a motion path. set myMotionPathPoints to {{{{108, 108}, {108, 108}, {108, 108}}, {{516, 108}, {516, 108}, {516, 108}}}, true} --Set animation preferences for the polygons. tell animation settings of myPolygonA set duration to 2 set motion path points to myMotionPathPoints end tell tell animation settings of myPolygonB set duration to 2 set motion path points to myMotionPathPoints end tell tell animation settings of myPolygonC set duration to 2 set motion path points to myMotionPathPoints end tell set myTimingSettings to timing settings of parent of myPage
171
--Remove the default timing list. tell myTimingSettings delete timing list 1 --Add a new timing list that triggers when the page is clicked. set myTimingList to make timing list with properties {trigger event:on page click} end tell --Add the polygons to a single timing group. tell myTimingList set myTimingGroup to make timing group with properties {dynamic target:myPolygonA, delay seconds:0} end tell tell myTimingGroup make timing target with properties {dynamic target:myPolygonB, delay seconds:2} make timing target with properties {dynamic target:myPolygonC, delay seconds:2} end tell
Note that attempting to add a page item whose has custom settings property (in the animation settings object of the page item) is false to a timing target generates an error. The following script fragment shows how to control the sequence of animations applied to objects on a page (for the complete script, refer to MultipleTimingGroups). Note that the order in which timing groups are added to a timing list determines the order in which the animations play when the trigger event specified in the timing list occurs. Some trigger events, such as on page load, trigger the animations in the timing list (in sequence); others, such as on page click, trigger the animations one by one, in sequence, with each instance of the event. For example, a timing list containing five timing groups, each containing a single timing target, and having the trigger event on page click requires five mouse clicks to process all the animations.
--Given a document "myDocument" and a page "myPage" and the color "myColorA", --"myColorB", and "myColorC"... --Add a page items to animate. tell myPage set myPolygonA to make polygon with properties {fill color:myColorA, strokeColor:"None"} set entire path of path 1 of myPolygonA to {{72, 72}, {72, 144}, {144, 108}} set myPolygonB to make polygon with properties {fill color:myColorB, strokeColor:"None"} set entire path of path 1 of myPolygonB to {{72, 72}, {72, 144}, {144, 108}} set myPolygonC to make polygon with properties {fill color:myColorC, strokeColor:"None"} set entire path of path 1 of myPolygonC to {{72, 72}, {72, 144}, {144, 108}} set myPolygonD to make polygon with properties {fill color:myColorA, strokeColor:"None"} set entire path of path 1 of myPolygonD to {{72, 144}, {72, 216}, {144, 180}} set myPolygonE to make polygon with properties {fill color:myColorB, strokeColor:"None"} set entire path of path 1 of myPolygonE to {{72, 144}, {72, 216}, {144, 180}} set myPolygonF to make polygon with properties {fill color:myColorC, strokeColor:"None"} set entire path of path 1 of myPolygonF to {{72, 144}, {72, 216}, {144, 180}} end tell --Create a motion path. set myMotionPathPointsA to {{{{108, 108}, {108, 108}, {108, 108}}, {{516, 108}, {516, 108}, {516, 108}}}, true} set myMotionPathPointsB to {{{{108, 180}, {108, 180}, {108, 180}}, {{516, 180}, {516, 180}, {516, 180}}}, true} --Set animation preferences for the polygons. --DynamicTriggerEvents.onPageLoad (the default). set duration of animation settings of myPolygonA to 2
172
set motion path points of animation settings of myPolygonA to myMotionPathPointsA set duration of animation settings of myPolygonB to 2 set motion path points of animation settings of myPolygonB to myMotionPathPointsA set duration of animation settings of myPolygonC to 2 set motion path points of animation settings of myPolygonC to myMotionPathPointsA set duration of animation settings of myPolygonD to 2 set motion path points of animation settings of myPolygonD to myMotionPathPointsB set duration of animation settings of myPolygonE to 2 set motion path points of animation settings of myPolygonE to myMotionPathPointsB set duration of animation settings of myPolygonF to 2 set motion path points of animation settings of myPolygonF to myMotionPathPointsB set myTimingSettings to timing settings of parent of myPage --Remove the default timing list. tell myTimingSettings delete timing list 1 --Add a new timing list that triggers when the page is clicked. set myTimingList to make timing list with properties {trigger event:on page click} --Add the polygons to a single timing group. tell myTimingList set myTimingGroupA to make timing group with properties {dynamic target:myPolygonA, delay seconds:0} tell myTimingGroupA make timing target with properties {dynamic target:myPolygonB, delay seconds:2} make timing target with properties {dynamic target:myPolygonC, delay seconds:2} end tell --myTimingGroupB will play on the second page click. set myTimingGroupB to make timing group with properties {dynamic target:myPolygonD, delay seconds:0} tell myTimingGroupB make timing target with properties {dynamic target:myPolygonE, delay seconds:2} make timing target with properties {dynamic target:myPolygonF, delay seconds:2} end tell end tell end tell
A given timing settings object can contain multiple timing list objects, each of which responds to a different trigger event. The following script fragment shows a series of animations triggered by on page load, by on page click (for the complete script, refer to MultipleTimingLists).
set myTimingSettings to timing settings of parent of myPage tell myTimingSettings --At this point, all of the polygons have already been added as timing targets --of the default timing list. Change the delay of myPolygonB and myPolygonC, --which are the targets of the second and third timing groups. set myTimingListA to timing list 1 tell myTimingListA tell timing group 2 set delay seconds of timing target 1 to 2 end tell tell timing group 3 set delay seconds of timing target 1 to 2 end tell --Remove the last three timing groups in the timing list. --We have to do this, because we don't want these polygons to be --animated when the page loads. delete timing group -1
173
delete timing group -1 delete timing group -1 end tell --Add a new timing list that triggers when the page is clicked. set myTimingListB to make timing list with properties {trigger event:on page click} tell myTimingListB set myTimingGroupB to make timing group with properties {dynamic target:myPolygonD, delay seconds:0} tell myTimingGroupB make timing target with properties {dynamic target:myPolygonE, delay seconds:2} make timing target with properties {dynamic target:myPolygonF, delay seconds:2} end tell end tell end tell
In the previous examples, weve worked with the timing settings of the spread containing the page items we want to animate. When you want to animate a page item when a user clicks the item, youll need to use the timing settings of the page item itself, as shown in the following script fragment (for the complete script, refer to PageItemTimingSettings).
--Given a page "myPage"... tell myPage set myPolygonA to make polygon with properties {fill color:myColorA, stroke color:"None"} set entire path of path 1 of myPolygonA to {{72, 72}, {72, 144}, {144, 108}} --Create a motion path. set myMotionPathPointsA to {{{{108, 108}, {108, 108}, {108, 108}}, {{516, 108}, {516, 108}, {516, 108}}}, true} --Set animation preferences for the polygon. tell animation settings of myPolygonA set duration to 2 set motion path points to myMotionPathPointsA end tell --Remove the default timing list in the timing settings for the spread. set myTimingSettings to timing settings of parent of myPage tell myTimingSettings delete timing list 1 end tell set myTimingSettings to timing settings of myPolygonA tell myTimingSettings set myTimingList to make timing list with properties {trigger event:on click} end tell tell myTimingList set myTimingGroup to make timing group with properties {dynamic target:myPolygonA, delay seconds:0} end tell end tell
Animating transformations
Page items can change size, rotation or skewing angles, opacity, and visibility as their animation plays. The animation settings of the page item contain properties (such as rotation array or hidden after) that define the transformations that are applied during animation. The following script fragment shows how to make a page item rotate as it follows a motion path (for the complete script, refer to AnimateRotation).
174
--Given a document "myDocument" and a page "myPage" and the color "myColorA"... --Add a page items to animate. tell page 1 set myPolygon to make polygon with properties {fill color:myColorA, stroke color:"None"} end tell --Create a motion path. set entire path of path 1 of myPolygon to {{72, 72}, {72, 144}, {144, 108}} set myMotionPathPoints to {{{{108, 108}, {108, 108}, {108, 108}}, {{516, 108}, {516, 108}, {516, 108}}}, true} --Set animation preferences for the polygon. tell animation settings of myPolygon set duration to 2 set motion path points to myMotionPathPoints --Assuming 24 Frames Per Second (FPS) --23 = 1 second, 47 = 2 seconds, 71 = 3 seconds, 95 = 4 seconds, --119 = 5 seconds, 143 = 6 seconds --Since the duration of our animation is 2 seconds, the following line will --make the polygon rotate 360 degrees from the start to the end --of the animation. set rotation array to {{0, 0}, {47, 360}} end tell set myTimingSettings to timing settings of parent of myPage tell myTimingSettings --Remove the default timing list. delete timing list 1 --Add a new timing list that triggers when the page is clicked. set myTimingList to make timing list with properties {trigger event:on page click} tell myTimingList --Add the polygon to a single timing group. make timing group with properties {dynamic target:myPolygon, delay seconds:0} end tell end tell
Scripting offers more control over animation than can be achieved with InDesigns user interface. A scripted animation can, for example, apply transformations at each key frame of a given motion path. For more on this topic, see Key frames later in this chapter.
Motion presets
In the preceding examples, weve constructed motion paths and specified animation settings as if we were creating animations from the basic level in InDesigns user interface. But InDesign can also use motion presets to define the animation of page items in a layout. A motion preset can apply a number of animation properties at once, as seen in the following script fragment (for the complete script, refer to MotionPreset). InDesign comes with a large number of motion presets, and you can add new presets using either the user interface or scripting.
--Given a page containing the oval "myOvalA"... set myMotionPreset to Motion Preset "move-right-grow" tell animation settings of myOvalA set duration to 2 set plays loop to true set preset to myMotionPreset end tell
175
Design options
Design options affect the way that an animated object appears, relative to the motion specified in the objects animation settings. The following script fragment shows how the design options for an animated shape can affect the playback of the animation (for the complete script, refer to DesignOptions).
--Given a page containing the ovals "myOvalA" and "myOvalB"... set myMotionPreset to Motion Preset "move-right-grow" tell animation settings of myOvalA set duration to 2 set plays loop to true set preset to myMotionPreset set design option to from current appearance end tell tell animation settings of myOvalB set duration to 2 set plays loop to true set preset to myMotionPreset set design option to to current appearance end tell
Key frames
Key frames are points in the timeline of an animation. With InDesign scripting, you can add key frames at any time in the animation, which gives you the ability to apply changes to objects as they are animated. Key frames are part of the motion path applied to an animated page item, and are specified relative to the duration and speed of the animation. For example, for an animation with a duration of two seconds, playing at 24 frames per second, the last frame in the animation is frame 48. The following script fragment shows how to add key frames to a motion path, and how to change the transformations applied to an animated page item at each key frame. For the complete script, refer to TransformAnimation.
--Given a page containing ovals "myOvalA," "myOvalB," and "myOvalC"... --The motion path is constructed relative to the center of the object, and key frames --are based on the duration of the animation divided by the number of frames per second --(usually 24). The following array sets key frames at the start, midpoint, and end --of a path. set myMotionPath to {{0, {{0, 0}, {0, 0}, {0, 0}}}, {23, {{234, 0}, {234, 0}, {234, 0}}}, {47, {{468, 0}, {468, 0}, {468, 0}}}} tell animation settings of myOvalA set duration to 2 set motion path to myMotionPath --The transformation changes at each key frame. --scale x array in the form {{keyframe, scale_percentage}, {keyframe, scalePercentage}, ...} set scale x array to {{0, 100}, {23, 200}, {47, 100}} --scale y array in the form {{keyframe, scale_percentage}, {keyframe, scalePercentage}, ...} set scale y array to {{0, 100}, {23, 200}, {47, 100}} --opacity array in the form {{keyframe, opacity}, {keyframe, opacity},...} set opacity array to {{0, 100}, {23, 20}, {47, 100}} set plays loop to true end tell tell animation settings of myOvalB set duration to 2
176
set motion path to myMotionPath set scale x array to {{0, 200}, {23, 300}, {47, 50}} set scale y array to {{0, 200}, {23, 300}, {47, 50}} set opacity array to {{0, 10}, {23, 80}, {47, 60}} set plays loop to true end tell tell animation settings of myOvalC set duration to 2 set motion path to myMotionPath set scale x array to {{0, 50}, {23, 200}, {47, 400}} set scale y array to {{0, 50}, {23, 200}, {47, 400}} set opacity array to {{0, 100}, {23, 40}, {47, 80}} set plays loop to true end tell end tell
12
XML
Extensible Markup Language, or XML, is a text-based mark-up system created and managed by the World Wide Web Consortium (www.w3.org). Like Hypertext Markup Language (HTML), XML uses angle brackets to indicate markup tags (for example, <article> or <para>). While HTML has a predefined set of tags, XML allows you to describe content more precisely by creating custom tags. Because of its flexibility, XML increasingly is used as a format for storing data. InDesign includes a complete set of features for importing XML data into page layouts, and these features can be controlled using scripting. We assume you already read Adobe InDesign CS5 Scripting Tutorial and know how to create and run a script. We also assume you have some knowledge of XML, DTDs, and XSLT.
Overview
Because XML is entirely concerned with content and explicitly not concerned with formatting, making XML work in a page-layout context is challenging. InDesigns approach to XML is quite complete and flexible, but it has a few limitations: Once XML elements are imported into an InDesign document, they become InDesign elements that correspond to the XML structure. The InDesign representations of the XML elements are not the same thing as the XML elements themselves. Each XML element can appear only once in a layout. If you want to duplicate the information of the XML element in the layout, you must duplicate the XML element itself. The order in which XML elements appear in a layout largely depends on the order in which they appear in the XML structure. Any text that appears in a story associated with an XML element becomes part of that elements data.
177
178
You also can specify XML tagging preset preferences (the default tag names and user-interface colors for tables and stories) using the XML preferences object., as shown in the following script fragment (from the XMLPreferences tutorial script):
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument tell XML preferences set default cell tag color to blue set default cell tag name to "cell" set default image tag color to brick red set default image tag name to "image" set default story tag color to charcoal set default story tag name to "text" set default table tag color to cute teal set default table tag name to "table" end tell end tell end tell
179
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument tell XML import preferences set allow transform to false set create link to XML to false set ignore unmatched incoming to true set ignore whitespace to true set import CALS tables to true set import style to merge import set import text into tables to false set import to selected to false set remove unmatched existing to false set repeat text elements to true --The following properties are only used when the --allow transform property is set to true. --set transform filename to "yukino:myTransform.xsl" --If you have defined parameters in your XSL file, --you can pass them to the file during the XML import --process. For each parameter, enter a list containign two --strings. The first string is the name of the parameter, --the second is the value of the parameter. --set transform parameters to {{"format", "1"}} end tell end tell end tell
Importing XML
Once you set the XML import preferences the way you want them, you can import an XML file, as shown in the following script fragment (from the ImportXML tutorial script):
tell myDocument import XML from "yukino:xml_test.xml" end tell
When you need to import the contents of an XML file into a specific XML element, use the importXML method of the XML element, rather than the corresponding method of the document. See the following script fragment (from the ImportXMLIntoElement tutorial script):
set myRootElement to XML element 1 tell myRootElement import XML from "yukino:xml_test.xml" end tell --Place the root XML element so that you can see the result. tell story 1 place XML using myRootElement end tell
You also can set the import to selected property of the xml import preferences object to true, then select the XML element, and then import the XML file, as shown in the following script fragment (from the ImportXMLIntoSelectedElement tutorial script):
tell XML import preferences set import to selected to true end tell select myXMLElement import XML from "yukino:xml_test.xml"
180
181
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument set myXMLTag to make XML tag with properties {name:"myXMLTag"} set myRootElement to XML element 1 tell myRootElement set myXMLElement to make XML element with properties {markup tag:myXMLTag} end tell set contents of myXMLElement to "This is an XML element containing text." end tell end tell
182
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument set myXMLTag to make XML tag with properties {name:"myXMLTag"} set myRootElement to XML element 1 tell myRootElement set myXMLElementA to make XML element with properties {markup tag:myXMLTag} set contents of myXMLElementA to "This is XML element A." set myXMLElementB to make XML element with properties {markup tag:myXMLTag} set contents of myXMLElementB to "This is XML element B." end tell duplicate myXMLElementA end tell end tell
183
The following script fragment shows how to add an XML processing instruction (for the complete script, see MakeProcessingInstruction):
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument set myRootXMLElement to XML element 1 tell myRootXMLElement set myXMLInstruction to make XML instruction with properties {target:"xml-stylesheet type=\"text/css\"", data:"href=\"generic.css\""} end tell end tell end tell
In addition to creating attributes directly using scripting, you can convert XML elements to attributes. When you do this, the text contents of the XML element become the value of an XML attribute added to the parent of the XML element. Because the name of the XML element becomes the name of the attribute, this method can fail when an attribute with that name already exists in the parent of the XML element. If the XML element contains page items, those page items are deleted from the layout. When you convert an XML attribute to an XML element, you can specify the location where the new XML element is added. The new XML element can be added to the beginning or end of the parent of the XML attribute. By default, the new element is added at the beginning of the parent element. You also can specify am XML mark-up tag for the new XML element. If you omit this parameter, the new XML element is created with the same XML tag as XML element containing the XML attribute. The following script shows how to convert an XML element to an XML attribute (for the complete script, see ConvertElementToAttribute):
184
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument set myXMLTag to make XML tag with properties {name:"myXMLElement"} set myRootXMLElement to XML element 1 end tell tell myRootXMLElement set myXMLElement to make XML element with properties {markup tag:myXMLTag, contents:"This is content in an XML element."} end tell tell myXMLElement convert to attribute end tell end tell
You also can convert an XML attribute to an XML element, as shown in the following script fragment (from the ConvertAttributeToElement tutorial script):
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument set myXMLTag to make XML tag with properties {name:"myXMLElement"} set myRootXMLElement to XML element 1 end tell tell myRootXMLElement set myXMLElement to make XML element with properties {markup tag:myXMLTag, contents:"This is content in an XML element."} end tell tell myXMLElement convert to attribute end tell end tell
185
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument set myXMLTag to make XML tag with properties {name:"myXMLElement"} set myRootXMLElement to XML element 1 end tell tell myRootXMLElement set myXMLElementA to make XML element with properties {markup tag:myXMLTag, contents:"This is a paragraph in an XML story."} set myXMLElementB to make XML element with properties {markup tag:myXMLTag, contents:"This is another paragraph in an XML story."} set myXMLElementC to make XML element with properties {markup tag:myXMLTag, contents:"This is the third paragraph in an example XML story."} set myXMLElementD to make XML element with properties {markup tag:myXMLTag, contents:"This is the last paragraph in the XML story."} end tell set myXMLStory to xml story 1 of myDocument set the point size of text 1 of myXMLStory to 72 end tell
Exporting XML
To export XML from an InDesign document, export either the entire XML structure in the document or one XML element (including any child XML elements it contains). The following script fragment shows how to do this (for the complete script, see ExportXML):
tell myDocument export to "yukino:test.xml" format "XML" end tell
In addition, you can use the export from selected property of the xml export preferences object to export an XML element selected in the user interface. The following script fragment shows how to do this (for the complete script, see ExportSelectedXMLElement):
tell myDocument set export from selected of xml export preferences to true select xml element 2 of xml element 1 export to "yukino:selectedXMLElement.xml" format "XML" set export from selected of xml export preferences to false end tell
186
tell text frame 1 of page 1 of myDocument place XML using xml element 1 of myDocument end tell
To associate an existing page item or text object with an existing XML element, use the markup method. This merges the content of the page item or text with the content of the XML element (if any). The following script fragment shows how to use the markup method (for the complete script, see Markup):
tell XML element 1 of XML element 1 of myDocument markup text frame 1 of page 1 of myDocument end tell
To associate an XML element with an inline page item (i.e., an anchored object), use the place into copy method, as shown in the following script fragment (from the PlaceIntoCopy tutorial script):
tell application "Adobe InDesign CS5" set myDocument to document 1 set myPage to page 1 of myDocument set myTextFrame to text frame 1 of myPage tell XML element 1 of myDocument set myFrame to place into copy on myPage place point {288, 72} copy item myTextFrame end tell end tell
To associate an existing page item (or a copy of an existing page item) with an XML element and insert the page item into the XML structure at the location of the element, use the place into inline copy method, as shown in the following script fragment (from the PlaceIntoInlineCopy tutorial script):
187
tell application "Adobe InDesign CS5" set myDocument to document 1 set myPage to page 1 of myDocument tell myPage set myNewTextFrame to make text frame with properties {geometric bounds:{72, 72, 96, 144}} end tell set myXMLElement to XML element 3 of XML element 1 of myDocument set myFrame to place into inline copy myXMLElement copy item myNewTextFrame without retain existing frame end tell
To associate an XML element with a new inline frame, use the placeIntoInlineFrame method, as shown in the following script fragment (from the PlaceIntoInlineFrame tutorial script):
set myDocument to document 1 set myXMLElement to xml element 2 of xml element 1 of myDocument set myFrame to place into inline frame myXMLElement place point {72, 24}
188
tell myXMLElementC insert text as content position element start insert text as content position element end end tell tell myXMLElementD insert text as content before element insert text as content after element end tell end tell end tell end tell
using "Text at the start of an element: " using " Text at the end of an element. "
using "Text before the element: " position using " Text after the element. " position
189
Another approach is simply to have your script create a new XML tag for each paragraph or character style in the document, and then apply the style to tag mapping, as shown in the following script fragment (from the MapAllStylesToTags tutorial script):
tell application "Adobe InDesign CS5" set myDocument to document 1 tell myDocument --Create a tag to style mapping. repeat with myParagraphStyle in paragraph styles set myParagraphStyleName to name of myParagraphStyle set myXMLTagName to my myReplace(myParagraphStyleName, " ", "_") set myXMLTagName to my myReplace(myXMLTagName, "[", "") set myXMLTagName to my myReplace(myXMLTagName, "]", "") set myMarkupTag to make XML tag with properties {name:myXMLTagName} make XML export map with properties {markup tag:myMarkupTag, mapped style:myParagraphStyle} end repeat map styles to XML tags end tell end tell
Marking up graphics
The following script fragment shows how to associate an XML element with a graphic (for the complete script, see MarkingUpGraphics):
190
tell application "Adobe InDesign CS5" set myDocument to document 1 tell myDocument set myXMLTag to make xml tag with properties{name:"graphic"} tell page 1 set myGraphic to place "yukino:test.tif" --Associate the graphic with a new XML element as you create the --element tell XML element 1 set myXMLElement to make XML element with properties {markup tag:myXMLTag, content:myGraphic} end tell end tell end tell
191
insert text as content using return position after element apply paragraph style using myHeading1Style clearing overrides yes end tell set myXMLElementB to make XML element with properties {markup tag:myPara1XMLTag, contents:"This is the first paragraph in the article."} tell myXMLElementB insert text as content using return position after element apply paragraph style using myPara1Style clearing overrides yes end tell set myXMLElementC to make XML element with properties {markup tag:myBodyTextXMLTag, contents:"This is the second paragraph in the article."} tell myXMLElementC insert text as content using return position after element apply paragraph style using myBodyTextStyle clearing overrides yes end tell set myXMLElementD to make XML element with properties {markup tag:myHeading2XMLTag, contents:"Heading 2"} tell myXMLElementD insert text as content using return position after element apply paragraph style using myHeading2Style clearing overrides yes end tell set myXMLElementE to make XML element with properties {markup tag:myPara1XMLTag, contents:"This is the first paragraph following the subhead."} tell myXMLElementE insert text as content using return position after element apply paragraph style using myPara1Style clearing overrides yes end tell set myXMLElementF to make XML element with properties {markup tag:myBodyTextXMLTag, contents:"Note:"} tell myXMLElementF insert text as content using " " position after element apply character style using myCharacterStyle end tell set myXMLElementG to make XML element with properties {markup tag:myBodyTextXMLTag, contents:"This is the second paragraph following the subhead."} tell myXMLElementG insert text as content using return position after element apply paragraph style using myBodyTextStyle clearing overrides no end tell end tell end tell set myPage to page 1 tell page 1 set myTextFrame to make text frame with properties{geometric bounds: my myGetBounds(myDocument, myPage)} end tell set myStory to parent story of myTextFrame tell myStory place XML using myRootXMLElement end tell end tell end mySnippet
192
Once you are working with a table containing XML elements, you can apply table styles and cell styles to the XML elements directly, rather than having to apply the styles to the tables or cells associated with the XML elements. To do this, use the apply table style and apply cell style methods, as shown in the following script fragment (from the ApplyTableStyles tutorial script):
193
tell application "Adobe InDesign CS5" set myDocument to make document tell myDocument --Create a series of XML tags. set myRowTag to make XML tag with properties {name:"Row"} set myCellTag to make XML tag with properties {name:"Cell"} set myTableTag to make XML tag with properties {name:"Table"} --Add XML elements. set myRootXMLElement to XML element 1 tell myRootXMLElement set myTableXMLElement to make XML element with properties {markup tag:myTableTag} tell myTableXMLElement repeat with myRowCounter from 1 to 6 set myXMLRow to make XML element with properties {markup tag:myRowTag} tell myXMLRow set myString to "Row " & myRowCounter repeat with myCellCounter from 1 to 4 make XML element with properties {markup tag:myCellTag, contents:myString & ":Cell " & myCellCounter} end repeat end tell end repeat convert element to table row tag myRowTag cell tag myCellTag end tell end tell set myPage to page 1 tell page 1 set myTextFrame to make text frame with properties{geometric bounds: my myGetBounds(myDocument, myPage)} end tell set myStory to parent story of myTextFrame tell myStory place XML using XML element 1 of myDocument end tell end tell end tell
13
XML Rules
The InDesign XML- rules feature provides a powerful set of scripting tools for working with the XML content of your documents. XML rules also greatly simplify the process of writing scripts to work with XML elements and dramatically improve performance of finding, changing, and formatting XML elements. While XML rules can be triggered by application events, like open, place, and close, typically you will run XML rules after importing XML into a document. (For more information on attaching scripts to events, see Chapter 8, Events.) This chapter gives an overview of the structure and operation of XML rules, and shows how to do the following: Define an XML rule. Apply XML rules. Find XML elements using XML rules. Format XML data using XML rules. Create page items based on XML rules. Restructure data using XML rules. Use the XML-rules processor. We assume you already read Adobe InDesign CS5 Scripting Tutorial and know how to create and run a script. We also assume you have some knowledge of XML and have read Chapter 12, XML.
Overview
InDesigns XML rules feature has three parts: XML rules processor (a scripting object) Locates XML elements in an XML structure using XPath and applies the appropriate XML rule(s). It is important to note that a script can contain multiple XML rule processor objects, and each rule-processor object is associated with a given XML rule set. Glue code A set of routines provided by Adobe to make the process of writing XML rules and interacting with the XML rules-processor easier. XML rules The XML actions you add to a script. XML rules are written in scripting code. A rule combines an XPath-based condition and a function to apply when the condition is met. The apply function can perform any set of operations that can be defined in InDesign scripting, including changing the XML structure; applying formatting; and creating new pages, page items, or documents. A script can define any number of rules and apply them to the entire XML structure of an InDesign document or any subset of elements within the XML structure. When an XML rule is triggered by an XML rule processor, the rule can apply changes to the matching XML element or any other object in the document. You can think of the XML rules feature as being something like XSLT. Just as XSLT uses XPath to locate XML elements in an XML structure, then transforms the XML elements in some way, XML rules use XPath to
194
Overview
195
locate and act on XML elements inside InDesign. Just as an XSLT template uses an XML parser outside InDesign to apply transformations to XML data, InDesign's XML Rules Processor uses XML rules to apply transformations to XML data inside InDesign.
In the above example, RuleNameAsString is the name of the rule and matches the RuleName; ValidXPathSpecifier is an XPath expression. Later in this chapter, we present a series of functioning XML-rule examples. NOTE: XML rules support a limited subset of XPath 1.0. See XPath limitations on page 200.
XML-rule sets
An XML-rule set is an array of one or more XML rules to be applied by an XML-rules processor. The rules are applied in the order in which they appear in the array. Here is a sample XML-rule set:
set myRuleSet to {my SortByName(), my AddStaticText(), my LayoutElements(), my FormatElements()}
Overview
196
In the above example, the rules listed in the myRuleSet array are defined elsewhere in the script. Later in this chapter, we present several functioning scripts containing XML-rule sets.
Glue code
In addition to the XML-rules processor object built into InDesigns scripting model, Adobe provides a set of functions intended to make the process of writing XML rules much easier. These functions are defined within the glue code.as file:
__processRuleSet(root, ruleSet) To execute a set of XML rules, your script must call the __processRuleSet function and provide an XML element and an XML rule set. The XML element
defines the point in the XML structure at which to begin processing the rules.
__processChildren(ruleProcessor) This function directs the XML-rules processor to apply
matching XML rules to child elements of the matched XML element. This allows the rule applied to a parent XML element to execute code after the child XML elements are processed. By default, when an XML-rules processor applies a rule to the children of an XML element, control does not return to the rule. You can use the __processChildren function to return control to the apply function of the rule after the child XML elements are processed.
__skipChildren(ruleProcessor) This function tells the processor not to process any
descendants of the current XML element using the XML rule. Use this function when you want to move or delete the current XML element or improve performance by skipping irrelevant parts of an XML structure.
Overview
197
Root 1
B 2 9
BA 3 4 5
BB
BC
Iteration with __processChildren (assuming a rule that matches every XML element in the structure) is shown in the following figure:
Root 9
B 8 6 7
BA 5 4 3
BB
BC
BAA
BAB
BAC 2 1
BACA
BACB
Iteration given the following rule set is shown in the figure after the script fragment. The rule set includes two rules that match every element, including one that uses __processChildren. Every element is processed twice. (For the complete script, see ProcessChildren.)
Overview
198
to NormalRule() script NormalRule property name : "NormalRule" property xpath : "//XMLElement" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell insertion point -1 of story 1 of document set contents to value of XML attribute 1 of return end tell on error myError set myReturnString to myError end try end tell return false end apply end script end NormalRule to ProcessChildrenRule() script ProcessChildrenRule property name : "ProcessChildrenRule" property xpath : "//XMLElement" on apply(myXMLElement, myRuleProcessor) tell myGlueCode __processChildren(myRuleProcessor) end tell global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell insertion point -1 of story 1 of document set contents to value of XML attribute 1 of return end tell on error myError set myReturnString to myError end try end tell return false end apply end script end ProcessChildrenRule
1 myXMLElement &
1 myXMLElement &
Overview
199
Root 1 19 2 14 B 18 16
BA 3 5 7 13
BB 15
BC 17
BAA 4
BAB 6 8
BAC 12 10
BACA 9
BACB 11
Overview
200
When an apply function returns false, you can control the matching behavior of the XML rule based on a condition other than the XPath property defined in the XML rule, like the state of another variable in the script.
XPath limitations
InDesigns XML rules support a limited subset of the XPath 1.0 specification, specifically including the following capabilities: Find an element by name, specifying a path from the root; for example, /doc/title. Find paths with wildcards and node matches; for example, /doc/*/subtree/node(). Find an element with a specified attribute that matches a specified value; for example, /doc/para[@font='Courier']. Find an element with a specified attribute that does not match a specified value; for example, /doc/para[@font !='Courier']. Find a child element by numeric position (but not last()); for example, /doc/para[3]. Find self or any descendent; for example, //para. Find comment as a terminal; for example, /doc/comment(). Find PI by target or any; for example, /doc/processing-instruction('foo'). Find multiple predicates; for example, /doc/para[@font='Courier'][@size=5][2]. Find along following-sibling axes; for example, /doc/note/following-sibling::*. Due to the one-pass nature of this implementation, the following XPath expressions are specifically excluded: No ancestor or preceding-sibling axes, including .., ancestor::, preceding-sibling::. No path specifications in predicates; for example, foo[bar/c]. No last() function. No text() function or text comparisons; however, you can use InDesign scripting to examine the text content of an XML element matched by a given XML rule. No compound Boolean predicates; for example, foo[@bar=font or @c=size]. No relational predicates; for example, foo[@bar < font or @c > 3]. No relative paths; for example, doc/chapter.
Error handling
Because XML rules are part of the InDesign scripting model, scripts that use rules do not differ in nature from ordinary scripts, and they benefit from the same error-handling mechanism. When InDesign generates an error, an XML-rules script behaves no differently than any other script. InDesign errors can be captured in the script using whatever tools the scripting language provides to achieve that; for example, try...catch blocks.
201
InDesign does include a series of errors specific to XML-rules processing. An InDesign error can occur at XML-rules processor initialization, when a rule uses a non-conforming XPath specifier (see XPath limitations on page 200). An InDesign error also can be caused by a model change that invalidates the state of an XML-rules processor. XML structure changes caused by the operation of XML rules can invalidate the XML-rules processor. These changes to the XML structure can be caused by the script containing the XML-rules processor, another concurrently executing script, or a user action initiated from the user interface. XML structure changes that invalidate an XML-rules processor lead to errors when the XML-rules processor's iteration resumes. The error message indicates which XML structural change caused the error.
glue code
XML element
XPath evaluation
apply()
__processChildren
t XML elemen
__skipChildren
202
<device> <name></name> <type></type> <part_number></part_number> <supply_voltage> <minimum></minimum> <maximum></maximum> </supply_voltage> <package> <type></type> <pins></pins> </package> <price></price> <description></description> </device>
The scripts are presented in order of complexity, starting with a very simple script and building toward more complex operations.
203
204
global myGlueCode on run tell application "Adobe InDesign CS5" set myRootXML to first XML element of document 1 set myApplicationPath to file path set myFilePath to file path as string set myFilePath to myFilePath & "Scripts:Xml rules:glue code.scpt" set myGlueCode to load script file myFilePath set myRuleSet to {my ProcessDevice(), my ProcessName(), my ProcessType(), my ProcessPartNumber(), my ProcessSupplyVoltage(), my ProcessPackageType(), my ProcessPackageOne(), my ProcessPackages(), my ProcessPrice()} end tell tell myGlueCode --The third parameter of __processRuleSet is a --prefix mapping table; we'll leave it empty. __processRuleSet(myRootXML, myRuleSet, {}) end tell end run to ProcessDevice() script ProcessDevice property name : "ProcessDevice" property xpath : "/devices/device" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using return position after element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessDevice to ProcessName() script ProcessName property name : "ProcessName" property xpath : "/devices/device/name" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Device Name: " position before element insert text as content using return position after element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessName
205
to ProcessType() script ProcessType property name : "ProcessType" property xpath : "/devices/device/type" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Circuit Type: " position before element insert text as content using return position after element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessType to ProcessPartNumber() script ProcessPartNumber property name : "ProcessPartNumber" property xpath : "/devices/device/part_number" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Part Number: " position before element insert text as content using return position after element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPartNumber to ProcessSupplyVoltage() script ProcessSupplyVoltage property name : "ProcessSupplyVoltage" property xpath : "/devices/device/supply_voltage" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Supply Voltage: From: " position before element insert text as content using return position after element tell XML element 1 insert text as content using " to " position after element
206
end tell tell XML element -1 insert text as content using " volts" position after element end tell end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessSupplyVoltage to ProcessPackageType() script ProcessPackageType property name : "ProcessPackageType" property xpath : "/devices/device/package/type" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "-" position after element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPackageType --Add the text "Package:" before the list of packages. to ProcessPackageOne() script ProcessPackageOne property name : "ProcessPackageOne" property xpath : "/devices/device/package[1]" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Package: " position before element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPackageOne --Add commas between the package types and a return at the end of the packages. to ProcessPackages() script ProcessPackages property name : "ProcessPackages"
207
property xpath : "/devices/device/package" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement set myIndex to index of myXMLElement if myIndex is not 1 then insert text as content using ", " position before element end if end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPackages to ProcessPrice() script ProcessPrice property name : "ProcessPrice" property xpath : "/devices/device/price" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using return position before element insert text as content using "Price: $" position before element insert text as content using return position after element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPrice
NOTE: The above script uses scripting logic to add commas between repeating elements (in the ProcessPackages XML rule). If you have a sequence of similar elements at the same level, you can use forward-axis matching to do the same thing. Given the following example XML structure:
<xmlElement><item>1</item><item>2</item><item>3</item><item>4</item> </xmlElement>
To add commas between each item XML element in a layout, you could use an XML rule like the following (from the ListProcessing tutorial script):
208
global myGlueCode on run tell application "Adobe InDesign CS5" set myRootXML to first XML element of document 1 set myApplicationPath to file path set myFilePath to file path as string set myFilePath to myFilePath & "Scripts:Xml rules:glue code.scpt" set myGlueCode to load script file myFilePath set myRuleSet to {my ListItems()} end tell tell myGlueCode __processRuleSet(myRootXML, myRuleSet, {}) end tell end run to ListItems() script ListItems property name : "ListItems" property xpath : "/xmlElement/item[1]/following-sibling::*" on apply(myXMLElement, myRuleProcessor) tell application "Adobe InDesign CS5" tell myXMLElement insert text as content using ", " position before element end tell end tell return false end apply end script end ListItems
209
property name : "MoveElement" property xpath : "/devices/device/part_number" on apply(myXMLElement, myRuleProcessor) tell myGlueCode __skipChildren(myRuleProcessor) end tell global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement set myParent to parent set myTargetXMLElement to XML element 1 of myParent move to before myTargetXMLElement end tell on error myError set myReturnString to myError end try end tell return true end apply end script end MoveElement
210
end tell global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement duplicate end tell on error myError set myReturnString to myError end try end tell return true end apply end script end DuplicateElement
211
tell myXMLElement set myString to contents of text 1 tell parent make XML attribute with properties {name:"part_number", value:myString} end tell end tell on error myError set myReturnString to myError end try end tell return true end apply end script end AddAttribute
In the previous XML rule, we copied the data from an XML element into an XML attribute attached to its parent XML element. Instead, what if we want to move the XML element data into an attribute and remove the XML element itself? Use the convertToAttribute method, as shown in the following script (from the ConvertToAttribute tutorial script):
global myGlueCode on run tell application "Adobe InDesign CS5" set myRootXML to first XML element of document 1 set myApplicationPath to file path set myFilePath to file path as string set myFilePath to myFilePath & "Scripts:Xml rules:glue code.scpt" set myGlueCode to load script file myFilePath set myRuleSet to {my ConvertToAttribute()} end tell tell myGlueCode __processRuleSet(myRootXML, myRuleSet, {}) end tell end run to ConvertToAttribute() script ConvertToAttribute property name : "ConvertToAttribute" property xpath : "/devices/device/part_number" on apply(myXMLElement, myRuleProcessor) tell myGlueCode __skipChildren(myRuleProcessor) end tell global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement convert to attribute ("PartNumber") end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ConvertToAttribute
212
To move data from an XML attribute to an XML element, use the convertToElement method, as described in Chapter 12, XML.
213
end ReturnTrue to ReturnFalse() script ReturnFalse property name : "ReturnFalse" property xpath : "//*" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement set fill color of text 1 to "ColorB" end tell on error myError set myReturnString to myError end try end tell --Leave the XML element available for further matching rules. return false end apply end script end ReturnFalse
214
--the parent of the XML element. This can make finding the --element by its contnet much easier and faster. on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement set myString to contents of text 1 tell parent make XML attribute with properties {name:"part_number", value:myString} end tell end tell on error myError set myReturnString to myError end try end tell return true end apply end script end AddAttribute to FindAttribute() script FindAttribute property name : "FindAttribute" property xpath : "/devices/device[@part_number = 'DS001']" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement set fill color of text 1 to "ColorA" end tell on error myError set myReturnString to myError end try end tell return false end apply end script end FindAttribute
The following script shows how to use the findText method to find and format XML content (for the complete script, see FindXMLElementByFindText):
215
global myGlueCode on run tell application "Adobe InDesign CS5" set myFilePath to file path as string set myFilePath to myFilePath & "Scripts:Xml rules:glue code.scpt" tell document 1 set myRootXML to first XML element set myColorA to make color with properties {name:"ColorA", model:process, color value:{0, 100, 80, 0}} end tell end tell set myGlueCode to load script file myFilePath set myRuleSet to {my FindByFindTExt()} tell myGlueCode __processRuleSet(myRootXML, myRuleSet, {}) end tell end run to FindByFindTExt() script FindByFindTExt property name : "FindByFindText" property xpath : "/devices/device/description" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" set find text preferences to nothing set change text preferences to nothing set find what of find text preferences to "triangle" try tell myXMLElement set myFoundItems to find text if (count myFoundItems) is greater than 0 then set fill color of text 1 to "ColorA" end if end tell on error myError set myReturnString to myError end try set find text preferences to nothing set change text preferences to nothing end tell return false end apply end script end FindByFindTExt
The following script shows how to use the findGrep method to find and format XML content (for the complete script, see FindXMLElementByFindGrep):
216
global myGlueCode on run tell application "Adobe InDesign CS5" set myFilePath to file path as string set myFilePath to myFilePath & "Scripts:Xml rules:glue code.scpt" tell document 1 set myRootXML to first XML element set myColorA to make color with properties {name:"ColorA", model:process, color value:{0, 100, 80, 0}} end tell end tell set myGlueCode to load script file myFilePath set myRuleSet to {my FindByFindGrep()} tell myGlueCode __processRuleSet(myRootXML, myRuleSet, {}) end tell end run to FindByFindGrep() script FindByFindGrep property name : "FindByFindGrep" property xpath : "/devices/device/description" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" set find grep preferences to nothing set change grep preferences to nothing --Find all of the devices the mention both "pulse" and --"triangle" in their description. set find what of find grep preferences to "(?i)pulse.*?triangle|triangle.*?pulse" try tell myXMLElement set myFoundItems to find grep if (count myFoundItems) is greater than 0 then set fill color of text 1 to "ColorA" end if end tell on error myError set myReturnString to myError end try set find grep preferences to nothing set change grep preferences to nothing end tell return false end apply end script end FindByFindGrep
217
global myGlueCode on run tell application "Adobe InDesign CS5" set myFilePath to file path as string set myFilePath to myFilePath & "Scripts:Xml rules:glue code.scpt" tell document 1 set myRootXML to first XML element set myXMLTag to make XML tag with properties {name:"VCOs"} tell myRootXML set myXMLElement to make XML element with properties {markup tag:myXMLTag} end tell end tell end tell set myGlueCode to load script file myFilePath set myRuleSet to {my ExtractVCO()} tell myGlueCode __processRuleSet(myRootXML, myRuleSet, {}) end tell end run to ExtractVCO() script ExtractVCO property name : "ExtractVCO" property xpath : "/devices/device/type" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try if contents of text 1 of myXMLElement is "VCO" then set myNewXMLElement to duplicate parent of myXMLElement end if move myNewXMLElement to end of XML element -1 of XML element 1 of document 1 on error myError set myReturnString to myError end try end tell return true end apply end script end ExtractVCO
218
global myGlueCode on run tell application "Adobe InDesign CS5" set myApplicationPath to file path set myFilePath to file path as string set myFilePath to myFilePath & "Scripts:Xml rules:glue code.scpt" tell document 1 tell view preferences set horizontal measurement units to points set vertical measurement units to points set ruler origin to page origin end tell set myRootXML to first XML element set myColor to make color with properties {model:process, color value:{0, 100, 100, 0}, name:"Red"} make paragraph style with properties {name:"DeviceName", point size:24, leading:24, space before:24, fill color:"Red", rule above:true, rule above offset:24} make paragraph style with properties {name:"DeviceType", point size:12, font style:"Bold", leading:12} make paragraph style with properties {name:"PartNumber", point size:12, font style:"Bold", leading:12} make paragraph style with properties {name:"Voltage", point size:10, leading:12} make paragraph style with properties {name:"DevicePackage", pointSize:10, leading:12} make paragraph style with properties {name:"Price", point size:10, leading:12, font style:"Bold", space after:12} end tell end tell set myGlueCode to load script file myFilePath set myRuleSet to {my ProcessDevice(), my ProcessName(), my ProcessType(), my ProcessPartNumber(), my ProcessSupplyVoltage(), my ProcessPackageType(), my ProcessPrice(), my ProcessPackageOne(), my ProcessPackages()} tell myGlueCode __processRuleSet(myRootXML, myRuleSet, {}) end tell end run to ProcessDevice() script ProcessDevice property name : "ProcessDevice" property xpath : "/devices/device" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using return position after element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessDevice to ProcessName() script ProcessName
219
property name : "ProcessName" property xpath : "/devices/device/name" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using return position after element apply paragraph style using "DeviceName" end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessName to ProcessType() script ProcessType property name : "ProcessType" property xpath : "/devices/device/type" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Circuit Type: " position before element insert text as content using return position after element apply paragraph style using "DeviceType" end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessType to ProcessPartNumber() script ProcessPartNumber property name : "ProcessPartNumber" property xpath : "/devices/device/part_number" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Part Number: " position before element insert text as content using return position after element apply paragraph style using "PartNumber" end tell on error myError set myReturnString to myError end try
220
end tell return true end apply end script end ProcessPartNumber to ProcessSupplyVoltage() script ProcessSupplyVoltage property name : "ProcessSupplyVoltage" property xpath : "/devices/device/supply_voltage" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Supply Voltage: From: " position before element tell XML element 1 insert text as content using " to " position after element end tell tell XML element -1 insert text as content using " volts" position after element end tell insert text as content using return position after element apply paragraph style using "Voltage" end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessSupplyVoltage to ProcessPackageType() script ProcessPackageType property name : "ProcessPackageType" property xpath : "/devices/device/package/type" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "-" position after element end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPackageType --Add the text "Package:" before the list of packages. to ProcessPackageOne() script ProcessPackageOne property name : "ProcessPackageOne"
221
property xpath : "/devices/device/package[1]" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement insert text as content using "Package: " position before element apply paragraph style using "DevicePackage" end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPackageOne --Add commas between the package types and a return at the end of the packages. to ProcessPackages() script ProcessPackages property name : "ProcessPackages" property xpath : "/devices/device/package" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try tell myXMLElement set myIndex to index of myXMLElement if myIndex is not 1 then insert text as content using ", " position before element end if end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPackages to ProcessPrice() script ProcessPrice property name : "ProcessPrice" property xpath : "/devices/device/price" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" try
222
tell myXMLElement insert text as content using return position before element insert text as content using "Price: $" position before element insert text as content using return position after element apply paragraph style using "Price" end tell on error myError set myReturnString to myError end try end tell return true end apply end script end ProcessPrice
223
The ProcessType rule moves the type XML element to a new frame on the page:
to ProcessType() script ProcessType property name : "ProcessType" property xpath : "/devices/device/type" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" set myDocument to document 1 tell myDocument try tell myXMLElement insert text as content using "Circuit Type: " position before element insert text as content using return position after element apply paragraph style using "DeviceType" end tell set myPage to page -1 of myDocument set myBounds to my myGetBounds(myDocument, myPage) set myX1 to item 2 of myBounds set myY1 to (item 1 of myBounds) - 24 set myX2 to myX1 + 48 set myY2 to item 1 of myBounds set myTextFrame to place into frame myXMLElement on myPage geometric bounds {myY1, myX1, myY2, myX2} set fill color of myTextFrame to "Red" tell text frame preferences of myTextFrame set inset spacing to {6, 6, 6, 6} end tell on error myError set myReturnString to myError end try end tell end tell return true end apply end script end ProcessType
224
to ProcessDevice() script ProcessDevice property name : "ProcessDevice" property xpath : "//device[@type = 'VCO']" on apply(myXMLElement, myRuleProcessor) global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" set myDocument to document 1 tell myDocument try set myContainerElement to XML element -1 of XML element -1 of XML element 1 tell myContainerElement set myNewElement to make XML element with properties {markup tag:"Row"} end tell on error myError set myReturnString to myError end try end tell end tell return false end apply end script end ProcessDevice
Successive rules move and format their content into container elements inside the row XML element.
to ProcessPrice() script ProcessPrice property name : "ProcessPrice" property xpath : "//device[@type = 'VCO']/price" on apply(myXMLElement, myRuleProcessor) tell myGlueCode __skipChildren(myRuleProcessor) end tell global myReturnString set myReturnString to "OK" tell application "Adobe InDesign CS5" set myDocument to document 1 tell myDocument try set myRootElement to XML element 1 set myVCOs to XML element -1 of myRootElement set myTable to XML element -1 of myVCOs set myContainerElement to XML element -1 of myTable tell myContainerElement set myNewElement to make XML element with properties {markup tag:"Column"}
225
end tell set myXMLElement to move myXMLElement to beginning of myNewElement tell myXMLElement insert text as content using "$" position before element end tell on error myError set myReturnString to myError end try end tell end tell return true end apply end script end ProcessPrice
Once all of the specified XML elements have been wrapped, we can convert the container element to a table.
tell myContainerElement set myTable to convert to table row tag myRowTag cell tag myColumnTag end tell
226
set myXPath to {"/devices/device"} set myXMLMatches to mySimulateXPath(myXPath) --At this point, myXMLMatches contains all of the XML elements --that matched the XPath expression provided in myXPath. --In a real script, you could now process the elements. --For this example, however, we'll simply display a message. display dialog ("Found " & (count myXMLMatches) & " matching XML elements.") on mySimulateXPath(myXPath) set myMatchingElements to {} tell application "Adobe InDesign CS5" set myRuleProcessor to make XML rule processor with properties {rule paths:myXPath} set myDocument to document 1 set myRootXMLElement to XML element 1 of myDocument tell myRuleProcessor set myMatchData to start processing rule set start element myRootXMLElement repeat until myMatchData is nothing local myMatchData local myMatchingElements set myXMLElement to item 1 of myMatchData set myMatchingElements to myMatchingElements & myXMLElement set myMatchData to find next match end repeat end tell return myMatchingElements end tell end mySimulateXPath
14
Track Changes
Writers can track, show, hide, accept, and reject changes as a document moves through the writing and editing process. All changes are recorded and visualized to make it easier to review a document. This tutorial shows how to script the most common operations involving tracking changes. We assume you already read Chapter 2, Getting Started and know how to create, install, and run a script. We also assume you have some knowledge of working with text in InDesign and understand basic typesetting terms.
Tracking Changes
This section shows how to navigate tracked changes, accept changes, and reject changes using scripting. Whenever anyone adds, deletes, or moves text within an existing story, the change is marked in galley and story views.
227
Track Changes
Tracking Changes
228
tell application "Adobe InDesign CS5" set myDocument to document 1 tell myDocument set myStory to story 1 tell myStory set myChange = myStory change 1 tell myChange accept end tell end tell end tell end tell
In the following script, the change is rejected (for the complete script, refer to RejectChange):
tell application "Adobe InDesign CS5" set myDocument to document 1 tell myDocument set myStory to story 1 tell myStory set myChange = myStory change 1 tell myChange reject end tell end tell end tell end tell
Track Changes
229
--Shows how to get track change informations. tell application "Adobe InDesign CS5" set myDocument to document 1 tell myDocument set myStory to story 1 tell myStory set myChange to change 1 tell myChange -- change type (inserted text/deleted text/moved text, r/o) set myTypes to change type set myCharacters to characters set myDate to date set myInsertionPoints to insertion points set myLines to lines -- paragraphs A collection of paragraphs. set myParagraphs to paragraphs set myStoryOffset to story offset set myTextColumns to text columns set myTextStyleRanges to text style ranges set myTextsetiableInstances to text variable instances -- The user who made the change. Note: Valid only when changes is true. set myUserName to user name -- Words A collection of words set myWords to words end tell end tell end tell end tell
Track Changes
230
text, specified as an InCopy UI color. Note: Valid only when deleted background color choice is change background uses change pref color. set myBackgroundColorForDeletedText to background color for deleted text set background color for deleted text to red --background color for moved text (any) : The background color for moved text, specified as an InCopy UI color. Note: Valid only when moved background color choice is change background uses change pref color. set myBackgroundColorForMovedText to background color for moved text set background color for moved text to pink --change bar color (any) : The change bar color, specified as an InCopy UI color. set myChangeBarColor to change bar color set change bar color to charcoal --deleted background color choice (change background uses galley background color/change background uses user color/change background uses change pref color) : The background color option for deleted text. set myDeletedBackgroundColorChoice to deleted background color choice set deleted background color choice to change background uses change pref color --deleted text color choice (change uses galley text color/change uses change pref color) : The color option for deleted text. set myDeletedTextColorChoice to deleted text color choice set deleted text color choice to change uses change pref color --location for change bar (left align/right align) : The change bar location. set myLocationForChangeBar to location for change bar set location for change bar to left align --marking for added text (none/strikethrough/underline single/outline) : The marking that identifies added text. set myMarkingForAddedText to marking for added text set marking for added text to strikethrough --marking for deleted text (none/strikethrough/underline single/outline) : The marking that identifies deleted text. set myMarkingForDeletedText to marking for deleted text set marking for deleted text to underline single --marking for moved text (none/strikethrough/underline single/outline) : The marking that identifies moved text. set myMarkingForMovedText to marking for moved text set marking for moved text to outline --moved background color choice (change background uses galley background color/change background uses user color/change background uses change pref color) : The background color option for moved text. set myMovedBackgroundColorChoice to moved background color choice set moved background color choice to change background uses galley background color -- moved text color choice (change uses galley text color/change uses change pref color) : The color option for moved text. set myMovedTextColorChoice to moved text color choice set moved text color choice to change uses change pref color -- If true, displays added text. set myShowAddedText to show added text set show added text to true -If true, displays change bars.
Track Changes
231
set myShowChangeBars to show change bars set show change bars to true -- If true, displays deleted text. set myShowDeletedText to show deleted text set show deleted text to true -- If true, displays moved text. set myShowMovedText to show moved text set show moved text to true -- If true, includes deleted text when using the Spell Check command. set mySpellCheckDeletedText to spell check deleted text set spell check deleted text to true --The color for added text, specified as an InCopy UI color. Note: Valid only when added text color choice is change uses change pref color. set myTextColorForAddedText to text color for added text set text color for added text to blue -- text color for deleted text (any) : The color for deleted text, specified as an InCopy UI color. Note: Valid only when deleted text color choice is change uses change pref color. set myTextColorForDeletedText to text color for deleted text set text color for deleted text to yellow -- The color for moved text, specified as an InCopy UI color. Note: Valid only when moved text color choice is change uses change pref color. set myTextColorForMovedText to text color for moved text set text color for moved text to green end tell end tell