Your prescription for increased productivity and profitability
In writing a script for InDesign requiring user input, a simple dialog can be written using a number of methods in AppleScript. The demonstration script in our previous blog post used CHOOSE FROM LIST to have the user select a document preset with which to create a new document.
set presetPrompt to "Select preset for new document" try set myList to getPresets(1) set presetName to getNameFromList(myList, presetPrompt) on error errStr display alert ("Error: " & errStr) end try (*Returns list of names for document presets having intnet designated by list index*) on getPresets(intentIndex) tell application "Adobe InDesign CC 2019" set intentType to item intentIndex of {print intent, web intent, mobile intent} set fullList to (name of document presets where intent is intentType) end tell end getPresets (*dialog for user to select item from list*) on getNameFromList(theList, thePrompt) set userChoice to choose from list theList with prompt thePrompt if userChoice is not false then return item 1 of userChoice else error "User cancelled" end if end getNameFromList
A second dialog was needed to have the user choose a file. When a script requires two or more dialog inputs from the user, rather than using multiple dialogs, it may be better to have one dialog window using a custom dialog. For this, InDesign provides the ability to create a custom dialog with a number of widgets for user interaction including entry fields, dropdowns, checkboxes and radio buttons. For instance, instead of using choose from list you could have a dropdown in a custom dialog provide the same capability.
To simplify the creation of a custom dialog the template provided here can be used:
set dlgName to "Document Preferences" set canCancel to true set dlgLabel to "DocPrefs" set dlgRef to customDialog(dlgName, canCancel, dlgLabel) on customDialog(dlgName, canCancel, dlgLabel) tell application "Adobe InDesign CC 2019" activate set origPrefs to user interaction level of script preferences set user interaction level of script preferences to interact with all set dialogRef to make dialog with properties {name:dlgName, can cancel:canCancel, label:dlgLabel} tell dialogRef tell (make dialog column) --set up dialog widgets here tell (make dialog row) end tell --row end tell --column end tell --dialog set userResponse to show dialogRef set returnList to {} if userResponse is true then --get user responses here end if destroy dialogRef set user interaction level of script preferences to origPrefs end tell return returnList end customDialog
Running this code will create a dialog window with buttons for OK and Cancel only.
Building on the code for the custom dialog, our “Create Document” script will use a dropdown to have the user select an item from a list. To provide the list of document presets from which to choose, the following getPresets handler will be used. Add this at the bottom of the script.
(*Returns list of names for document presets having intent designated by list index*) on getPresets(intentIndex) tell application "Adobe InDesign CC 2019" set intentType to item intentIndex of {print intent, web intent, mobile intent} set fullList to (name of document presets where intent is intentType) return rest of fullList end tell end getPresets
The handler returns a list of document presets having intent indicated by the value (1, 2, or 3) passed. Change the top of the script to add global variable declarations and the call to the handler.
global gPresetList global gFileList set dlgName to "Document Preferences" set canCancel to true set dlgLabel to "DocPrefs" set gPresetList to getPresets(1) set dlgRef to customDialog(dlgName, canCancel, dlgLabel)
To add the dropdown to the custom dialog, change the code inside the tell dialogRef statement block to read as follows:
tell (make dialog column) --set up dialog widgets here tell (make dialog row) make static text with properties {static label:"Choose document preset:"} set presetDrop to make dropdown with properties{string list:gPresetList, selected index:0} end tell --row end tell --column
The custom dialog also needs a dropdown to allow the user to select the file from which to import styles. Instead of using a CHOOSE FILE command, the dialog will provide the user a list of files found in a sub-folder of the “Styles” folder named “Print.” For our purpose here, the “Styles” folder will be in the user’s Library folder. With style files in this folder, get the file list using the following:
set folderPath to path to library folder from user domain as string set styleFolder to folderPath & "Styles:Print:" set gFileList to getStyleFiles(styleFolder)
Add the following getStyleFiles handler to the bottom of the script.
(*Returns list of files in Styles folder designated*) on getStyleFiles(styleFolder) set fileList to list folder styleFolder without invisibles return fileList end getStyleFiles
With the style file list (gFileList<) as part of the script, the dropdown can be added. The custom dialog will also allow the user to determine if styles are to be added to the document or not. This will be done by placing the interface objects (widgets) having to do with importing styles inside an enabling group. Add the following just below the end tell–row statement that creates the first dropdown.
set eGroup to make enabling group with properties {static label:"Import Styles", checked state:true} tell eGroup tell (make dialog column) tell (make dialog row) make static text with properties {static label:"Select style file:"} set fileDrop to make dropdown with properties {string list:gFileList, selected index:0} end tell --row end tell --column end tell --enabling group
The script we developed in our previous blog post assumed that the user would want to import Paragraph and Object Styles. In this version, the custom dialog will allow the user to select from two radio buttons to indicate the styles to be imported. For this, change the tell eGroup block to read:
tell eGroup tell (make dialog column) tell (make dialog row) make static text with properties {static label:"Select style file:"} set fileDrop to make dropdown with properties {string list:gFileList, selected index:0} end tell --row set styleList to {"Text and Object Styles", "All Styles"} set radioGroup to make radiobutton group tell radioGroup make radiobutton control with properties {static label:item 1 of styleList, checked state:true} make radiobutton control with properties {static label:item 2 of styleList} end tell end tell --column end tell --enabling group
Now that the user interface objects (widgets) have been added to the dialog, we can add the code to get the values chosen by the user and pass them back to the call to customDialog at the top of the script. Inside the if statement near the bottom of the script, change the code to read:
--get user responses here set fileChoice to missing value set styleChoice to missing value set presetChoice to item ((selected index of presetDrop) + 1) of gPresetList if checked state of eGroup is true then set fileChoice to item ((selected index of fileDrop) + 1) of gFileList set styleIndex to selected button of radioGroup set styleChoice to item (styleIndex + 1) of styleList end if set returnList to {presetChoice, fileChoice, styleChoice}
The code for the Custom Dialog portion of our script in its entirety is listed below:
global gPresetList global gFileList set dlgName to "Document Preferences" set canCancel to true set dlgLabel to "DocPrefs" set gPresetList to getPresets(1) set folderPath to path to library folder from user domain as string set styleFolder to folderPath & "Styles:Print:" set gFileList to getStyleFiles(styleFolder) set dlgResult to customDialog(dlgName, canCancel, dlgLabel) on customDialog(dlgName, canCancel, dlgLabel) tell application "Adobe InDesign CC 2019" activate set origPrefs to user interaction level of script preferences set user interaction level of script preferences to interact with all set dialogRef to make dialog with properties {name:dlgName, can cancel:canCancel, label:dlgLabel} tell dialogRef tell (make dialog column) tell (make dialog row) make static text with properties {static label:"Select document preset:"} set presetDrop to make dropdown with properties {string list:gPresetList, selected index:0} end tell --row set eGroup to make enabling group with properties {static label:"Import Styles", checked state:true} tell eGroup tell (make dialog column) tell (make dialog row) make static text with properties {static label:"Select style file:"} set fileDrop to make dropdown with properties {string list:gFileList, selected index:0} end tell --row set radioGroup to make radiobutton group set styleList to {"Text and Object Styles", "All Styles"} tell radioGroup make radiobutton control with properties {static label:item 1 of styleList, checked state:true} make radiobutton control with properties {static label:item 2 of styleList} end tell end tell --column end tell --enabling group end tell --column end tell -- dialog set userResponse to show dialogRef set returnList to {} if userResponse is true then --get user responses here set fileChoice to missing value set styleChoice to missing value set presetChoice to item ((selected index of presetDrop) + 1) of gPresetList if checked state of eGroup is true then set fileChoice to item ((selected index of fileDrop) + 1) of gFileList set styleIndex to selected button of radioGroup set styleChoice to item (styleIndex + 1) of styleList end if set returnList to {presetChoice, fileChoice, styleChoice} end if destroy dialogRef set user interaction level of script preferences to origPrefs end tell return returnList end customDialog (*Returns list of names for document presets having intent designated by list index*) on getPresets(intentIndex) tell application "Adobe InDesign CC 2019" set intentType to item intentIndex of {print intent, web intent, mobile intent} set fullList to (name of document presets where intent is intentType) return rest of fullList end tell end getPresets (*Returns list of files in Styles folder designated*) on getStyleFiles(styleFolder) set fileList to list folder styleFolder without invisibles return fileList end getStyleFiles
The code above provides the information needed to create the InDesign document. To complete the script, add the following to the top of the script as follows: This will test the value for dlgResult and call one of two handlers to create a document based on the value for fileChoice returned from the custom dialog.
if dlgResult is not {} then copy dlgResult to {presetChoice, fileChoice, styleChoice} if fileChoice is not missing value then set styleSourceFile to (styleFolder & fileChoice) as alias set docRef to createDocWithStyles(presetChoice, styleSourceFile, styleChoice) else set docRef to createDocWithPreset(presetChoice) end if end if
The handlers for creating the document are as follows:
(*Creates document using document preset and imports styles from style file*) on createDocWithStyles(presetChoice, styleSourceFile, styleChoice) tell application "Adobe InDesign CC 2019" set docPreset to document preset presetChoice set docRef to make document with properties {document preset:docPreset} tell docRef if styleChoice = "All Styles" then import styles format table styles format from styleSourceFile import styles format text styles format from styleSourceFile import styles format object styles format from styleSourceFile else if styleChoice = "Text and Object Styles" then import styles format text styles format from styleSourceFile import styles format object styles format from styleSourceFile end if end tell end tell return styleChoice end createDocWithStyles (*Creates document using document preset*) on createDocWithPreset(presetName) tell application "Adobe InDesign CC 2019" set docRef to make document with properties {document preset:presetName} end tell return docRef end createDocWithPreset
You may want to enclose the code at the top of the script with a try/on error/end try trap. This could be used to notify the user in the event the user clicks the Cancel button for the custom dialog. Other errors will be generated if you attempt to use the getPresets handler with any value for intentIndex other than 1. Our next blog post will discuss some of the problems in working with document presets and intent. Meanwhile, think of other properties for the document that you might want to add to the script. How would you modify the script above to add this functionality?
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.