Building OnThe Past

For the month of February our blog posts have been working toward the completion of a script that would create a web document from a selected document preset (preset with web intent). Our post for February 22 introduced using a custom dialog to have the user select a document preset and determine if layers were to be added to the document.

The amount of code needed for the project expanded considerably with the addition of the custom dialog. The upside of this is that by having the user choose from pre-defined lists and dialog control elements, the code that would be required to support and follow through with the user’s choices is significantly reduced.

Custom Dialogs

Although putting a custom dialog does require a fair amount of code, it need not pose a stumbling block for your automation efforts. In fact, creating a custom dialog can be simplified by following a few basic rules:

  • Start with a simple dialog
    The dialog we created for the February 22 post was limited in functionality, but it did demonstrate how to create some of the more common dialog elements: a dropdown, an enabling group, and checkbox controls.
  • Copy and Paste
    Add more controls using copy and paste on existing code
  • Modify Pasted Code
    Change names of variables and text for labels in the copied code as needed.

Step By Step

In this post we will add to the dialog created in the February 22 post. We will add controls to give the user the option of selecting a stylesheet and types of styles to import. The user will choose from a list of file names provided in a dropdown with checkbox controls to determine the styles to import. These will be within an enabling group to indicate if this functionality is needed. For the dropdown a list of stylesheet names will be needed. To create the checkboxes the script will also need a list of strings for the labels.

GET LIST OF STYLESHEET NAMES

Getting a list of file names from a predetermined folder location was covered in our blog post of February 14. However, with the custom doing much of the work, a handler to get the stylesheet folder and list of its files can be written as follows:

Get Stylesheet Information

(*Returns path to folder and list of style document names
Assumes stylesheets are saved in Styles folder inside InDesign's Presets folder*)
on getStylesheetInfo ()
tell application "Adobe InDesign CC 2018"
   set appPath to file path as string
   set stylePath to appPath & "Presets" & ":" & "Styles"
end tell
set styleList to list folder stylePath without invisibles
return {stylePath, styleList}
end getStylesheetInfo

Add call to Handler

With the getStylesheetInfo handler added to our script, the top portion can be written as follows to test the result returned from the dialog:

set layerList to {"DieLine", "Background", "Images", "Animation", "Text"}
set dlgName to "Document Setup"
tell application "Adobe InDesign CC 2018"
   set presetNames to name of document presets where intent is web intent
end tell
set {stylePath, styleList} to getStylesheetInfo()
try
   set userResponse to userDialog(dlgName, true, presetNames, layerList, styleList)
   userResponse
on error errStr
   activate
   display alert "Error: " & errStr
end try 

THE CURRENT DIALOG

The dialog written for the February 22 post reads as follows (watch out for continue line characters ¬):

(*Custom dialog allows user to determine document preset for document
and layers to be created*)
on userDialog(dlgName, cancelIt, presetList, layerList)
   tell application "Adobe InDesign CC 2018"
      set origLevel to user interaction level of script preferences
      set user interaction level of script preferences to interact with all
      set dlgRef to make dialog with properties {name:dlgName, canCancel:cancelIt}
      set checkObjects to {}
      tell dlgRef
	    tell (make dialog column)
		tell (make dialog row)
		   make static text with properties {static label:"Choose Preset for document"}
		   set filenameDrop to make dropdown with properties ¬
{string list:presetList, selected index:0, min width:144}
	        end tell
		set enable1 to make enabling group with properties {static label:"Add Layers", checked state:false}
		tell enable1
		   tell (make dialog column)
			tell (make dialog row)
			   repeat with i from 1 to length of layerList
				set end of checkObjects to make checkbox control with properties ¬
{static label:item i of layerList, checked state:false}
			   end repeat
			end tell
		   end tell
		end tell
	   end tell--dlgColumn
	end tell --dlgRef
	set userResponse to show dlgRef
	if userResponse = true then
	   set checkList to {}
	   set fileIndex to (selected index of filenameDrop) + 1
	   if checked state of enable1 = true then
		repeat with i from 1 to length of checkObjects
		   if checked state of item i of checkObjects is true then
		      set end of checkList to static label of item i of checkObjects
		   end if
		end repeat
	   end if
	end if
	destroy dlgRef
	set user interaction level of script preferences to origLevel
	--if cancelled, throw error; otherwise return values
	if userResponse = false then error "User cancelled"
	return {fileIndex, checkList}
   end tell --application
end userDialog

Update the Dialog

Our new script will use the dialog as written with the following changes:

    1. Add styleList to userDialog argument list
on userDialog(dlgName, cancelIt, presetList, layerList, styleList)
    1. Before tell dlgRef statement, add a list to hold the checkbox control references for the style checkbox controls
set styleChecks to {} --object list for style checkbox controls
    1. Immediately after line added in step 2, add a list of strings for the checkbox control labels (indicates styles to be imported)
set styleLabels to {"Text", "Object", "Table", "Swatches"}
    1. Add an enabling group with a dropdown and checkbox controls: copy the statements for enable1, paste after, and change to read as follows:
set enable2 to make enabling group with properties {static label:"Import Styles", checked state:false}
    tell enable2
       tell (make dialog column)
          tell (make dialog row)
             repeat with i from 1 to length of styleLabels
                set end of styleChecks to make checkbox control with properties ¬
{static label:item i of styleLabels, checked state:true}
             end repeat
          end tell--row
       end tell--column
    end tell--enabling group
    1. Now copy the dropdown code from above (“Choose Preset for document” element) , paste it into the enabling group “enable2” code, and modify it so the enable2 code now reads as follows  (watch for continue line characters ¬ ):
set enable2 to make enabling group with properties {static label:"Import Styles", checked state:false}
    tell enable2
       tell (make dialog column)
         tell (make dialog row)
	    make static text with properties {static label:"Choose Stylesheet for Style Import"}
	    set stylenameDrop to make dropdown with properties ¬
{string list:styleList, selected index:0, min width:144}
	 end tell --dialog row
	 tell (make dialog row)
	   repeat with i from 1 to length of styleLabels
		set end of styleChecks to make checkbox control with properties ¬
{static label:item i of styleLabels, checked state:true}
	   end repeat
	end tell--row
      end tell--column
   end tell--enabling group
    1. The rest of the dialog code remains the same with the exception of getting the result from the user’s choices. Again, copy and paste and modify. This time the code to modify is the userResponse and if statement block. Change it to read as follows:
set userResponse to show dlgRef
if userResponse = true then
   set checkList to {}
   set styleIndex to -1
   set styleChecklist to {}
   set fileIndex to (selected index of filenameDrop) + 1
   if checked state of enable1 = true then
      repeat with i from 1 to length of checkObjects
	   if checked state of item i of checkObjects is true then
	      set end of checkList to static label of item i of checkObjects
	  end if
      end repeat
   end if
   if checked state of enable2 = true then
       set styleIndex to (selected index of stylenameDrop) + 1
      repeat with i from 1 to length of styleChecks
	  if checked state of item i of styleChecks is true then
	      set end of styleChecklist to static label of item i of styleChecks
	  end if
      end repeat
   end if
end if
  1. Finally, modify the return statement to return the index for the stylefile (styleIndex) and styleCheckList
   return {fileIndex, checkList, styleIndex, styleCheckList}

TEST YOUR SCRIPT

Your script should now have the top portion of the script that calls the getStylesheetInfo() and userDialog() handlers.

Try your script with different combinations for user responses. Make sure the result of the dialog is as anticipated. Remember that the results from the dropdown controls is a number that points to the item in the list passed. The values returned should be as follows:

{index for Document Preset, {list of layers}, index for stylesheet file, {list of styles to import}}

…The finished custom dialog

CREATE THE DOCUMENT

Once you have the custom dialog working correctly, you can add code to the top portion of the script to call handlers to create the document, add layers, and import styling: After the code that calls the user dialog, add code to read as follows:

   set userResponse to userDialog(dlgName, true, presetNames, layerList, styleList)
   set presetIndex to item 1 of userResponse
   set presetName to item presetIndex of presetNames
   set layerNames to item 2 of userResponse
   set docRef to docFromPreset(presetName)
   if layerNames is not {} then
      createLayers(docRef, layerNames)
   end if
   set styleIndex to item 3 of userResponse
   if styleIndex > 0 then
      set stylefilePath to stylePath & ":" & item styleIndex of styleList
      importStyles(docRef, stylefilePath, styleList)
   end if

ImportStyles

Add a handler to import styles from the selected stylesheet.

(*Imports styles and loads swatches from file at stylefilePath
based on contents of styleList*)
on importStyles(docRef, stylefilePath, stylesToImport)
   set styleSheetRef to stylefilePath as alias
   tell application "Adobe InDesign CC 2018"
      tell docRef
	if stylesToImport contains "text" then
	   import styles format text styles format from styleSheetRef
	end if
	if stylesToImport contains "object" then
	   import styles format object styles format from styleSheetRef
	end if
	if stylesToImport contains "table" then
	   import styles format table styles format from styleSheetRef
	end if
	if stylesToImport contains "Swatches" then
	   load swatches from styleSheetRef
	end if
      end tell --document
   end tell --aapplication
end importStyles

Handlers

Make sure you also have the following handlers included in the script:

on getStylesheetInfo()
--see code above
end getStylesheetInfo
(*Creates web document using named preset*)
on docFromPreset(presetName)
	tell application "Adobe InDesign CC 2018"
		set presetRef to document preset presetName
		set docRef to make document with properties {document preset:presetRef}
	end tell
	return docRef
end docFromPreset
(*Creates layers with names as listed in layerList. 
The existing layer 1 is renamed using item 1 of the layerList as part of the process*)
on createLayers(docRef, layerList)
   tell application "Adobe InDesign CC 2018"
      tell docRef
	if length of layerList > 1 then
	   set name of layer 1 to item 1 of layerList
	   set layerList to rest of layerList
	end if
	repeat with i from 1 to length of layerList
	   set layerName to item i of layerList
	   if not (exists layer layerName) then
		make layer with properties {name:layerName}
	   end if
	end repeat
      end tell
   end tell
end createLayers

If you found yourself floundering and did not get your script to work, don’t fret. This scrpt will be the Featured Script for the month of March (Feature page). This will include a download for the entire script as currently written.

ONWARD AND UPWARD

Even with the power of the dialog, the script does make some assumptions. It assumes that you have saved document presets with web intent in your version of InDesign. Also, that you have saved InDesign stylesheet documents which exist at the folder path indicated (inside a folder named “Styles” inside InDesign’s Presets folder). Should your stylesheets exist at a different location, you will need to make that change. Of course, you will want to have stylesheets that include styles for text, objects, tables, and swatches. As an option, you might want to keep your stylesheets for swatches separate from your other stylesheets. This would require a fair amount of modification to the script above including adding another enabling group to the custom dialog.

Disclaimer:

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