Using CSS and the InDesign DOM to format HTML

 

To enable CSS support, edit the field options and press the  … button next to the HTML option:

This opens a dialog with a set of options, one of which is CSS and provides the ability to edit the stylesheet. A stylesheet contains declarations that map to properties and supported methods in InDesign’s scripting DOM properties.

Working with Text

The InsertionPoint DOM object is used for text based tags to process the CSS. Writable properties can be set where EasyCatalog supports conversion of their value type. Collections are supported as shown in the following example:

If the HTML contained no formatting:

Use a stylesheet to apply properties via a basic CSS parser. For example, nth-of-typeis used here to pick out each of the first 3 paragraphs:

Some properties, such as appliedFont, use a tab to separate parts of a value. Use the ^t meta-character sequence for the tab:

Working with Images

The Rectangle DOM object is used for <img> tags:

In addition to the DOM properties, EasyCatalog also adds width, height and fit as writable properties. fit accepts contentproportionally and frametocontent.

It’s also possible to manipulate the text inside an image tag, such as forcing the image into a new page or column.

However because this manipulation is inside the link, the field content is changed so flagged as an error as it modifies content. Modifying link content is generally not recommended for this reason. The following example turns the Rectangle object into a TextFrame and inserts text into it. Meta character sequences are used to insert a paragraph break:

Working with Tables

When working with tables, the <table> tag uses a Table object. The <tr> tag uses a Row object and the <td><th> tag uses a Cell object.

Row Properties

To color the header and alternating rows, the following stylesheets can be defined. The properties here belong to a Row DOM object. Any property that takes a color can also take a css style color name in addition to a named swatch. These are automatically created by EasyCatalog:

Cell Properties

For <td> and <th> tags, a Cell object is used, so properties for the Cell DOM object can be assigned. If the HTML contained a class attribute, eg:

Then a stylesheet can pick this out:

Setting a cell width:

Table Properties

The following HTML contains 2 tables with id attributes to identify them:

The following stylesheet targets specific tables using their ID:

This produces the following output:

An HTML style attribute may contain browser CSS values that are unsuitable for the InDesign DOM, such as:

To stop the properties defined by the style node getting applied you can target the node and use the following:

Calling DOM Methods

Supported DOM methods can be called using the method name as the CSS property name. Put the arguments after the colon, separated by commas. Do not add parentheses around the method name or its arguments.

For example, this stores a label on each body cell:

This corresponds to calling cell.insertLabel("source", "catalogue") in a script. Property and method names are matched without regard to case. If a property and a method share a name, the property takes precedence.

Double quotes preserve commas and spaces within a string. Use \" for a quote inside a quoted argument, and "" to pass an empty string. An empty value passed to the method-argument converter means no arguments; omit trailing optional arguments to let InDesign use their defaults. An empty CSS declaration is ignored by the stylesheet parser, so it cannot be used to call a method with no arguments.

Arguments are converted according to the method’s declared parameter types. Supported conversions include strings, booleans, integers, real numbers, numeric unit values, dates represented numerically, file paths, enums, supported arrays, and records. Parameters declared as Any are passed as strings; EasyCatalog does not infer a number or boolean from their text.

For an enum argument, use its DOM value name, such as right_align, without the enum class prefix. DOM object references, such as a Page or InsertionPoint object, are not currently supported as method arguments. If a parameter also accepts a supported alternative, that alternative can be used. Structs, callbacks and streams are not supported.

Array Values

An array groups several values into one property value or one method argument. Use square brackets and separate the elements with commas.

Arrays in Method Arguments

For example, the move method on a rectangle can take a two-element coordinate array:

The array is one argument containing the new [x, y] position. This is equivalent to rectangle.move([72, 144]). The target object must permit the move; placement and anchoring restrictions still apply.

Arrays may contain quoted text, including commas, where the declared element type accepts strings. For example, ["one", "two, three", ""] contains three strings. Use [] for an empty array where the parameter permits it. Fixed-length method arrays must contain the required number of elements. Numeric unit arguments currently require plain numbers; method conversion does not interpret unit strings such as "10mm".

Arrays in Properties

Existing unit, real-number and tab-stop position arrays accept either comma-separated values or an optional outer pair of brackets. For example, these declarations are equivalent for a cell’s gradient starting point:

The gradient starting point is relevant when the cell has a gradient fill. Existing unbracketed CSS continues to use its original conversion behaviour.

Additional supported property-array types include strings, integers, booleans, dates, files, enums and Any. Use bracketed syntax for these types. Elements are converted according to the property’s declared type; Any elements remain strings. These additional array conversions validate fixed lengths and reject the assignment if an element cannot be converted. The existing unit, real-number and tab-stop position handlers retain their previous validation behaviour.

Records and Tab Stops

A record groups named properties using braces. An array of records uses square brackets around a comma-separated list of records. Field names must be unquoted DOM property names. Values use the existing property converters, including units and enum values.

For example, set tab stops in the paragraphs of HTML table cells:

The second tab stop right-aligns text at 24 mm. Quoted strings may contain commas, colons, semicolons or braces. Record fields can be separated by commas or semicolons; do not leave a trailing separator before the closing brace.

For a native table stylesheet using EasyCatalog’s table, row, column and cell selectors, use cell instead of td, th.

The simpler position-only syntax remains supported:

The positions can also be written as [12mm, 24mm, 36mm]. Use either the position-only form or records throughout a tab list; do not mix the two forms.

Record fields are checked against the governing DOM object. Unknown, read-only and duplicate fields are rejected. Records are supported only where the DOM declares a record-compatible type; braces are not a general way to create DOM objects. Struct conversion is not currently supported.

Lua Based Property Content

When a property includes [[ and ]], the text enclosed is treated as Lua code, and the result of the code is substituted into the property. A field function can be used within this Lua code to access the contents of any field associated with the current table, cell, row, text range. If the field does not exist, the field function will return nil.

For example, the following code checks the content of the availability field and applies colors to body cells based on its value:

Lua Based DOM manipulation

A special lua property exists that enables execution of lua based manipulation of the DOM. The self object is the DOM object that matches the CSS target, so Cell, Table, Row, Column or Text.
For example, here we want a table to be 120 mm wide, with the last column always 35 mm. All other column widths are distributed evenly in the remaining space.

The following applies color to a text field using the field function, but also uses the lua property to apply an underline using self. All enhanced HTML formatted fields get a surrounding <body> tag by default.

Sharing CSS between fields

If the CSS just contains the name of a file in the data source’s scripts folder, this is loaded and used.

Supported Selectors

The CSS parser is basic and evaluates whether a single HTML-like node matches a given CSS selector. The following selector types are supported:

1. Tag Selector

  • Matches elements by their tag name.
  • Examples:
    • div — matches all <div> elements
    • * — wildcard, matches any element

2. ID Selector

  • Matches elements by their id attribute.
  • Syntax: #idName
  • Example: #main — matches element with id="main"

3. Class Selector

  • Matches elements by their class attribute.
  • Syntax: .className
  • Multiple classes can be chained: .foo.bar
  • Matches elements containing all specified classes.

4. Attribute Selectors

  • Match elements based on attribute values.
  • Supported operators:
    • [attr=value] — exact match
    • [attr~=value] — whitespace-separated list contains value
    • [attr|=value] — equals value or starts with value-
    • [attr^=value] — starts with value
    • [attr$=value] — ends with value
    • [attr*=value] — contains value

5. Structural Pseudo-Classes

Target elements based on their position or type among siblings:

Pseudo-ClassDescription
:first-childMatches the first child of its parent
:last-childMatches the last child of its parent
:nth-child(n)Matches the nth child (1-based) of its parent
:nth-last-child(n)Matches the nth child from the end
:first-of-typeMatches the first element of its type among siblings
:last-of-typeMatches the last element of its type among siblings
:nth-of-type(n)Matches the nth element of its type among siblings
:nth-last-of-type(n)Matches the nth element of its type from the end
:only-childMatches the only child of its parent
:only-of-typeMatches the only element of its type among siblings
:emptyMatches elements with no children (no elements, text, or comments)

Note: nth-child and similar selectors support numeric positions, odd, even and supported an+b formulas. For tag selectors, use forms such as td:nth-child(2), td:nth-child(even) or td:nth-child(2n-1). Formulas containing spaces or a plus sign are supported only through the single-class matching path, for example .price:nth-child(2n + 1).

6. Selector Combinations

  • table td — descendant selector.
  • table > tbody — direct child selector.
  • tr + tr — adjacent sibling selector.
  • tr ~ tr — general sibling selector.
  • td, th — applies the same declarations to either selector.

Selector Limitations

This is a limited CSS parser, not a browser CSS implementation. Each simple selector supports one attribute selector and one structural pseudo-class. Multiple attribute selectors, chained pseudo-classes, pseudo-elements such as ::before, namespace selectors and escaped selector names are not supported. Attribute comparison modifiers such as [name="value" i] and empty-string comparisons are also unsupported.

The limited :not() support applies to a single class selector containing a supported pseudo-class, for example .price:not(:first-child). It is not a general-purpose selector negation. At-rules such as @media and @keyframes are skipped.

Finding CSS Errors and Warnings

When EasyCatalog logging is enabled, search EasyCatalog Log.txt for these identifiers:

  • [CSS ERROR] — reported CSS parsing problems, invalid or unsupported selectors, DOM property and method failures, and method results whose status could not be checked.
  • [CSS WARNING] — permissive conversions that accept questionable input while retaining the existing result.

Parser messages include available context such as the property name, selector, or byte offset. Declaration-block offsets are relative to the block being parsed. Stylesheet offsets refer to the parser’s current stylesheet text, which may already have comments removed.

Selector diagnostics are produced when the stylesheet is loaded, with repeated invalid selectors reported once per load. A valid selector that simply matches no objects is not an error. Logging does not change selector matching or the parser’s existing recovery behaviour, and it is not exhaustive CSS validation.

Method-argument conversion errors identify the method, target object, parameter name and position, expected type, and supplied value. If an object type is involved, the message explains that DOM object references cannot be supplied as CSS method arguments. Errors returned by InDesign methods are also reported. If a method supplies an unexpected number of result entries, this is logged without changing the existing success return behaviour.

Conversion warnings include numeric text such as 12abc being accepted as 12, a value outside the 16-bit integer range being narrowed, non-finite real arguments, and an unrecognised boolean such as tru becoming false. These warnings do not cause the conversion to fail. Explicit boolean values include true, false, yes, no, on, off, 1 and 0.