Accessing the InDesign Scripting DOM via Lua

Overview

The InDesign Scripting DOM provides full access to the creation and manipulation of all content within InDesign. By combining this the speed of Lua with the data access and control facilities of EasyCatalog, it’s possible to create data driven content in virtually any format.

Accessing

The InDesign Scripting DOM can be accessed via Lua within Formatting Rules and Script Label contexts. The DOM is accessed by calling the getdom() method of a Frame or Formatting Rule. An optional parameter can be used to specify the object required, the default being the frame type. Options also include Document or Application. For formatting rules we recommend using getdom(“Document”) rather than navigating the hierarchy as there are instances where the rules are placed outside page bounds.

Once the DOM is acquired, properties and methods are accessed using the same naming conventions as Extendscript. However there are few language related differences:

Properties are functions

To set a property, provide a parameter. To get a property omit the parameter:

Enumeration are strings

Lua does not support typed enumerations. They are implemented as strings as shown the following example. Also notice the use of colors():add()ย (as properties are functions):

Compared this to the ExtendScript version:

Determining object types

The Javascript constructor.name method should be replaced with a string comparison on the object itself. For example:

Adding an Object With Properties

Some add methods allow the specification of properties. Lua tables can be used where the table entry key is the property name and the value is the value:

Working with Collections

Most of the available objects in the DOM have a collection counterpart. Regarded as a class, a collection is nothing but a generic interface giving an easy and ordered access to homogeneous InDesign objects that live together. Collections support the methods add, itemByName, itemByID, item, firstItem, lastItem, middleItem, anyItem, previousItem, nextItem, itemByRange, everyItem.

Accessing a collection is a case of accessing the property containing the collection. If the property method is passed a parameter, this is assumed to be an implied item() call. For example:

Special Collection Objects

All collections support theย everyItem() and theย itemByRange() methods. These return a single object containing references to multiple objects of the same type. Properties and methods which are exposed to this object apply to all contained objects. This gives a performance boost as it reduces the number of transactions in the document database. For example:

In addition to this method of access, an optional false boolean parameter can be supplied to return a table of objects rather than a special collection object:

Because collections offer a performance boost when setting properties a Collection.new allows the creation of singleton object from a table of objects(of the same type):

Examples

Formatting Rule Post Processing Example to iterate through the frames in a rule:

Creating a dialog box:

Creating a table and inserting text:

Populating Tables with Tabular Fields

In this example, a tabular field is used to populate a prototype table, which is repeated enough times to hold data for each row:

Template frame contains 4 column table with no data:

The Script label on the frame controls population of the data:

Result when populated:

The technique can also be applied to Formatting Rules, with the advantage of updating if the original data changes.

Accessing EasyCatalog Scripting Functions

With the scripting module installed, it’s possible to access methods exposed by EasyCatalog. The FIELD, DATASOURCE and RECORD objects are automatically converted to compatible types. The following example acquires a FIELD object and then inserts it using the ‘insertField’ method which is added by EasyCatalog to the InsertionPoint class:

Example using Formatting Rule Post Processing Logic to create a table that mirrors the contents of a named tabular field. The Formatting Rule is an empty text box.

Debugging

In CC 2018 and above remote debugging is supported using the ZeroBrane Studio IDE. Debugging is only available when “Enable Sockets” is set to true in Advanced preferences. Re-launch InDesign to apply this setting. To Debug:
Copy mobdebug.lua and socket.lua into any location checked by the ‘require’ command (A list is shown if the module cannot be found). These are available from the ZeroBrane download.
Launch the IDE. Go to Project | Start Debugger Server and start the debugger server (if this menu item is disabled, the server is already started)
Add the following to your script:

Test your script. You should see a green arrow pointing to the next statement after the start() call in the IDE and should be able to step through the code.