DOCUMENT PRESETS

In our previous blog post, we included a handler that left the door wide open for errors. As written, the getPresets handler will only work if there is more than one document preset with the intent type being print intent. That’s a big assumption. In fact, using any value other than 1 for the variable intentIndex will error. For this blog we will look into the problem of working with document presets, especially in using intent. This handler is written to correct the following defects:

  1. Trying to get the name of every document preset will error if no document presets for the desired type are found
  2. Trying to use the rest property of an empty list will generate an error
  3. To date (version 4.0.1 InDesign does not support mobile intent.
  4. Only document presets having print intent will have a default named “[Default]” (the reason for using the rest property to delete this item from the list).

REWRITE FOR GETPRESETS()

1. Determine if there are any document presets for the intent defined;

   tell application "Adobe InDesign CC 2019"
      set fullList to document presets where intent is web intent
      if fullList is {} then 
         error "No document presets of intent indicated are found"
      end if
   end tell

2. If items are found, get a list of the preset names

   tell application "Adobe InDesign CC 2019"
      set fullList to document presets where intent is web intent
      if fullList is {} then 
         error "No document presets of intent indicated are found"
      end if
      set nameList to name of document presets where intent is web intent
   end tell

3. Check to see if the first item of the list is “[Default]” and, if so, determine if there is more than one item in the list. If the result is true, use rest to delete the [Default] item

   tell application "Adobe InDesign CC 2019"
      set fullList to document presets where intent is web intent
      if fullList is {} then 
         error "No document presets of intent indicated are found"
      end if
      set nameList to name of document presets where intent is web intent
      if item 1 of nameList is "[Default]" and length of fullList > 1 then
         set nameList to rest of nameList
      end if
   end tell

4. Write the code as a handler passing the intent type as a number. A property reference such as print intent (property of a document preset) can only be inside a tell statement to an application. For many reasons, you may not want to call a handler from within a tell statement to the application. If you know the application’s four letter code for the property, this can be used. Without access to the code, you can pass a number value that will correspond to the property in a list. For purpose of demonstration, we will use the latter.

Get Presets

   set intentIndex to 1
   try
      set presetList to getPresets (intentIndex)
   on error errStr
      activate
      display alert "Error: " & errStr
   end try
   (*Returns list of document presets having intent indicated by list iindex*)
   on getPresets (listIndex)
      tell application "Adobe InDesign CC 2019"
         set intentList to {print intent, web intent, mobile intent}
         set intentType to item listIndex of intentList
         set fullList to document presets where intent is intentType
         if fullList is {} then 
            error "No document presets of intent indicated are found"
         end if
         set nameList to name of document presets where intent is intentType
         if item 1 of nameList is "[Default]" and length of nameList > 1 then
            set nameList to rest of nameList
         end if
      end tell
      return nameList as list
   end getPresets 

DOCUMENT PRESET BUG?

Even with all these precautions, what is returned from the script above may not be as anticipated. First, and foremost, what shows up as document presets in InDesign’s New Document window will not necessarily be returned to your script. The New Document window can be used to create and save a document present manually as long as the intent is intended to be print. Because there is no provision for setting intent when saving document presets, all those created and saved in the New Document window are given print intent. Using a script, however, you can create a document preset having web intent.

As there is no apparent difference between web intent and mobile intent with the exception of page size, using web intent can work just fine for both. If you do want to differentiate between web and mobile document presets, you can use a label property such as “Web” or “Mobile”. With the label property added to a document preset, your getPresets handler could be modified to read as follows::

GetPresets_modified

   set intentIndex to 2
   try
      set presetList to getPresets(intentIndex)
      presetList
   on error errStr
      activate
      display alert "Error: " & errStr
   end try
   (*Returns list of document preset names with web or mobile intent indicated by list index*)
   on getPresets(intentIndex)
      tell application "Adobe InDesign CC 2019"
         set intentList to {print intent, web intent, mobile intent}
	 if intentIndex is 2 then
	    set fullList to document presets where label is "Web"
	 else if intentIndex is 3 then
	    set fullList to document presets where label is "Mobile"
	 else --all others would be print intent
	    set fullList to document presets where intent is print intent 
	 end if
	 if fullList is {} then
	    error "No document presets of intent indicated are found"
	 end if
	 if name of item 1 of fullList is "[Default]" and length of fullList > 1 then
	    set fullList to rest of fullList
	 end if
	 set nameList to {}
	 repeat with eachItem in fullList
	    set end of nameList to name of eachItem
	 end repeat
	 return nameList as list
      end tell
   end getPresets

CREATING DOCUMENT PRESETS

Because the difference between a document set with mobile intent is essentially the same as for web intent, a script for creating these two preset intent types can be the same. The New Document window for InDesign CC 2019 shows four presets for Mobile: iPhone X, iPhone 876 Plus, iPhone 8/7/6, iPad Pro (10.5 in).

If you get a list of all document preset names, these names will not be in the list.

   tell application "Adobe InDesign CC 2019"
      get name of document presets
   end tell

For demonstration, the following creates a document preset for the iPad Pro. Although web and mobile documents will both have web intent, the script will use the label property to differentiate between the two.

Make Document Preset

set presetName to "iPadPro_10"
set pgHgt to "1668 px"
set pgWid to "2224 px"
set autoFrame to true --create primary text frame
set intentIndex to 3
set pgOrient to 2 --1 is portrait 2 is landscape
set myPreset to makePreset(presetName, pgWid, pgHgt, autoFrame, intentIndex, pgOrient)
myPreset
on makePreset(presetName, pgWid, pgHgt, autoFrame, iIndex, pgOrient)
   tell application "Adobe InDesign CC 2019"
      set labelList to {"Print", "Web", "Mobile"}
      set orientList to {"portrait", "landscape"}
      set intentList to {print intent, web intent, web intent}
      set presetProps to {label:item iIndex of labelList, page width:pgWid, page height:pgHgt,¬
 create primary text frame:autoFrame, intent:item iIndex of intentList, page orientation:item pgOrient of orientList}
      if not (exists document preset presetName) then
	 set myPreset to make document preset with properties {name:presetName}
      else
	 set myPreset to document preset presetName
      end if
      set properties of document preset presetName to presetProps
      tell document preset presetName
	 set column count to 1
	 set column gutter to "12 px"
	 set bottom to "36 px"
	 set left to "36 px"
	 set right to "36 px"
	 set top to "36 px"
	 set pages per document to 1
	 set page orientation to portrait
	 set document bleed top offset to 0.0
	 set document bleed uniform size to true
	 set slug top offset to 0.0
	 set document slug uniform size to true
	 set start page number to 1
	 end tell
      end tell
      return myPreset
   end makePreset

Notice in the above that if a document preset exists with the name given, its properties will be overwritten. You may want to add code that gives the user a warning and the opportunity to choose whether to overwrite or not.

UPWARD AND ONWARD

The script above requires a limited number of values to be established by the user. For a user-friendly version of our Make Document Preset script, it should be fairly easy to add a custom dialog to provide the values for the following variables:

  • presetName – text editbox
  • intentIndex – string list for dropdown {“Print”, “Web”, “Mobile”}
  • pgWid – measurement editbox
  • pgHgt – measurement editbox
  • autoFrame – checkbox control
  • pgOrient – radiobutton group having radiobutton controls “Portrait” and “Landscape” with “Portrait” checked by default

Refer to our previous blog post for instructions for creating the dialog. It contains code for all the widgets (dialog elements) needed with exception of the text editbox, measurement editbox and checkbox control. For these three, refer to the code below:

Text Editbox

--inside tell statement that references a dialog column
tell (make dialog row)
   make static text with properties {static label:"Preset Name:"}
   set nameField to make text editbox with properties {min width:200, edit contents:"Name here"}
end tell --dialog row

Measurement Editbox

--inside tell statement that references a dialog column
tell (make dialog row)
   make static text with properties {static label: "Page Width:"}
   set widthField to make measurement editbox with properties {min width:100, minimum value:72, ¬
maximum value:2400, large nudge:12, small nudge:1, edit units:pixels}
end tell

Checkbox Control

--inside tell statement that references a dialog column
set checkField to make checkbox control with properties ¬
{static label:"create primary text frame", checked state: false}

Disclaimer:
Scripts provided are for demonstration and educational purposes. No representation is made as to their accuracy or completeness. Readers are advised to use the code at their own risk.