Your prescription for increased productivity and profitability
When writing a script that sets InDesign application preferences it is always a good idea to capture the existing setting before changing. When the process that depends on the preference setting is completed, the script needs to return the value back to its original.
Lets look at a few examples.
Setting and resetting the script preference user interaction level is a common practice you may find in scripts that create a user dialog. In order for a user dialog window to show, the script preference user interaction level needs to be set to interact with all.
AppleScript
--call to dialog handler try set dlgResult to userDialog() on error errStr activate display alert "Error: " & errStr end try (*dialog handler sets and resets user interaction level; returns result or error*) on userDialog() set dialogName to "Name Here" tell application "Adobe InDesign CC 2017" 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:dialogName, can cancel:true, label:dialogName} tell dlgRef tell (make dialog column) --add dialog widgets here end tell --column end tell --dialog set userResponse to show dlgRef if userResponse = true then --put results from widgets into list set resultList to {} end if destroy dlgRef --reset preference back to original level set user interaction level of script preferences to origLevel --return captured values back to main part of script --handle error if user clicks Cancel button if (userResponse is false) then error ("User Cancelled") end if end tell --the script does not get here if user cancelled return resultList end userDialog
ExtendScript
try { var dlgResult = userDialog (); dlgResult; } catch (errMsg) { alert ("Error: "+ errMsg); } function userDialog() { var dialogName = "Name Here" var origLevel= app.scriptPreferences.userInteractionLevel; app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll; var dlgRef = app.dialogs.add({name:dialogName, canCancel:true, label:dialogName}) ; with(dlgRef){ with(dialogColumns.add()){ //add dialog widgets here } } userResponse = dlgRef.show(); if (userResponse == true){ //Place results iin array var resultArr = new Array; } //Remove the dialog window from memory. dlgRef.destroy(); app.scriptPreferences.userInteractionLevel = origLevel; if(userResponse == false) { throw ("User Cancelled"); } //script doesn't get here if user cancels return resultArr; }
Notice in the above examples that the dialog window is destroyed and the user interaction level of script preferences is reset irrespective of whether the user clicks OK or Cancel.
AppleScript
tell application "Adobe InDesign CC 2017" set origUnit to measurement unit of script preferences set measurement unit of script preferences to points --code that uses points for measurements set measurement unit of script preferences to origUnit end tell
ExtendScript
var origUnit = app.scriptPreferences.measurementUnit; app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS; //code that uses points for measurements app.scriptPreferences.measurementUnit = origUnit;
Another common practice is to set and reset the horizontal and vertical measurement units for view preferences.
AppleScript
--assumes document 1 exists tell application "Adobe InDesign CC 2017" set origH to horizontal measurement units of view preferences set origV to vertical measurement units of view preferences set horizontal measurement units of view preferences to points set vertical measurement units of view preferences to points tell page 1 of document 1 set rectRef to make rectangle with properties ¬ {geometric bounds:{100, 50, 36, 150}, fill color:"Black", fill tint:50, stroke weight:0} end tell set horizontal measurement units of view preferences to origH set vertical measurement units of view preferences to origV end tell
ExtendScript
var origH = app.viewPreferences.horizontalMeasurementUnits; var origV = app.viewPreferences.verticalMeasurementUnits; app.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.POINTS; app.viewPreferences.verticalMeasurementUnits = MeasurementUnits.POINTS; var pageRef = app.documents[0].pages[0]; var rectRef= pageRef.rectangles.add({geometricBounds: [100, 50, 36, 150], fillColor:"Black", fillTint:50, strokeWeight:0}); app.viewPreferences.horizontalMeasurementUnits = origH; app.viewPreferences.verticalMeasurementUnits = origV;
The advantage of this second method is that it allows the horizontal and vertical units to be set to different values.
Note:The measurement unit for script preferences overrides that for the view preferences. If you have a script that uses view preferences to set the measurement unit and the script preferences is set to a different unit you may have unexpected results or an error that reads Data is out of range. Make sure that the measurement unit for script preferences is set to auto value.
We can use code from the above examples as part of code that you might want to have handy as the start for a script that creates and names multiple page items consecutively.
AppleScript
set baseName to "Text" set numberItems to 4 set topBound to 30 set leftBound to 30 set boxWidth to 120 set boxHeight to 50 set spaceBetween to 20 --assumes document 1 exists with paragraph style "Title" tell application "Adobe InDesign CC 2017" set docRef to document 1 set fColor to swatch "Black" of docRef set pStyle to paragraph style "Title" of docRef set pageRef to page 1 of docRef set origUnit to measurement unit of script preferences set measurement unit of script preferences to points --arguments: parent reference, layer name, at top boolean set boxLayer to my makeLayer(docRef, "boxLayer", false) set rightBound to leftBound + boxWidth repeat with i from 1 to numberItems set thisName to (baseName & i) set gBounds to {topBound, leftBound, topBound + boxHeight, rightBound} (*arguments: parent reference, name, geometric bounds, fill color, fill tint, stroke weight, stroke color, stroke tint, layer reference)*) set rectRef to my makeRectangle¬ (pageRef, thisName, gBounds, fColor, 50, 0, "None", 100, boxLayer) set textLabel to ("Text " & i) set textRef to my makeTitlebox¬ (pageRef, thisName, gBounds, pStyle, textLabel, boxLayer) set topBound to topBound + boxHeight + spaceBetween end repeat end tell (*creates a text frame with title as defined by textLabel value passed Text frame has no fill or stroke*) on makeTitlebox(parentRef, itemName, gBounds, pStyle, textLabel, layerRef) tell application "Adobe InDesign CC 2017" tell parentRef set titleRef to make text frame with properties ¬ {name:itemName, geometric bounds:gBounds, itemlayer:layerRef, fill color:"None", stroke weight:0, stroke color:"None", contents:textLabel} set applied paragraph style of paragraph 1 of titleRef to pStyle set vertical justification of text frame preferences of titleRef to center align end tell end tell return titleRef end makeTitlebox (*creates rectangle using values passed in argument list*) on makeRectangle(parentRef, itemName, gBounds, fColor, fTint, sWeight, sColor, sTint, layerRef) tell application "Adobe InDesign CC 2017" tell parentRef set rectRef to make rectangle with properties {name:itemName, ¬ geometric bounds:gBounds, fill color:fColor, fill tint:fTint, stroke weight:sWeight, stroke color:sColor, stroke tint:sTint, item layer:layerRef} end tell end tell return rectRef end makeRectangle (*Creates layer if one named layerName does not exist; returns reference to layer*) on makeLayer(parentRef, layerName, atTop) tell application "Adobe InDesign CC 2017" tell parentRef if not (exists (layer layerName)) then if atTop then set layerRef to make layer with properties ¬ {name:layerName, locked:false, visible:true} else set layerRef to make layer with properties {name:layerName} move layerRef to after layer -1 end if else if locked of layer layerName is true then set locked of layer layerName to false end if set layerRef to layer layerName end if end tell end tell return layerRef end makeLayer
This script introduces a number of handlers (functions) that you might want to add to your handler library (see previous blog post).
..Page items created by the script
In the script above, notice the number of variables that have values hard coded at the top of the script. To make it user friendly you will want to add a custom dialog to have the user supply values for box fill color, tint, stroke weight, stroke color, stroke tint, paragraph style, base name, topBound, leftBound, rightBound, boxHeight, spaceBetween, and number of items.
Disclaimer: Code samples are to be used as a guide for users to create their own real world scripts and is provided “AS IS”. No representation is made as to the accuracy or completeness of the code. Use of the code and its operation is at the discretion and responsibility of the user.