Your prescription for increased productivity and profitability
In writing a script the major task often relies on a number of dependencies that must be resolved before the script can be successful. This is true of the script that we began in the previous blog, “TextFrameInfo”. This script is designed to collect information about the text frames in a document. The information will be written to a text file in the same folder as the document.
The script, as currently written, depends on the following:
The first two dependencies can be handled by a single subroutine: getDocRef()
try set docRef to getDocRef() on error errStr display alert errStr return end try --======== --HANDLERS --======== (*Returns reference to active document; otherwise generates error.*) on getDocRef() tell application "Adobe InDesign CS6" if modal state = true then error "Please close dialogs before running script" end if if not (exists document 1) then error "Requires active document" end if if saved of document 1 is false then error "Please save document before running script" end if return document 1 end tell end getDocRef
/*Returns reference to active document; otherwise throws exception; place call to function inside try/catch block */ try { var docRef = getDocRef() ; } catch (e) { alert (e); } //returns reference to active document; otherwise throws exception function getDocRef(){ //if a variable is not assigned a value, its value is undefined if (app.modalState == true) { throw ("Please close dialogs before running script"); } if (app.documents.length == 0) { throw ("No documents open"); } var docRef = app.documents.item(0); if (docRef.saved == false) { throw ("Please save document before running script"); } //returns value for variable docRef back to call statement return docRef; }
For the next two dependencies, we will rely on the user to define the layer for the script. First, the script gets a list of the names of all layers in the document with the subroutine getLayerNames().
set layerNames to getLayerNames (docRef) (*Returns list of names of layers for the document referenced*) on getLayerNames(docRef) tell application "Adobe InDesign CS6" tell docRef set layerNames to name of every layer end tell end tell return layerNames end getLayerNames
var layerNames = getLayerNames (docRef) /*Returns list of names of layers for the document referenced*/ function getLayerNames (docRef) { var layerNames = docRef.layers.everyItem().name; return layerNames; }
Next, the user is asked to choose the layer all of the text frames rely on using the subroutine chooseFromList (). With AppleScript, this is fairly simple using the choose from list command.
set docRef to getDocRef() set layerList to getLayerNames(docRef) set multipleItems to false set promptStr to "Choose text frame layer" try set userChoice to chooseFromList(layerList, promptStr, multipleItems) on error errStr activate display alert errStr return end try set layerName to item 1 of userChoice (*Throws error if user Cancels, otherwise returns user choice from list*) on chooseFromList (layerList, promptStr, multipleItems) set userChoice to choose from list layerList with prompt promptStr multiple selections allowed multipleItems if userChoice = false then error "User Cancelled" end if return userChoice end chooseFromList
For ExtendScript it is necessary to create a custom dialog from which the user can select the name of the script.
var docRef = getDocRef() var layerNames = getLayerNames (docRef) var dlgName = "Layer List"; var dlgLabel = "Layer List Choice"; var cancelIt = true; var promptStr = "Choose text frame layer"; var defaultItem = 0; var choiceList = layerNames; try { var userChoice = chooseFromList_Index (dlgName, cancelIt, dlgLabel, promptStr, choiceList, defaultItem); userChoice; } catch (e) { alert (e); } var layerName = layerNames[userChoice]; var layerRef = docRef.layers.itemByName(layerName); //returns index of item chosen from dropdown function chooseFromList_Index (dlgName, cancelIt, dlgLabel, labelText, dropList, defaultChoice) { //make sure that user interaction levels will allow a dialog var origLevel = app.scriptPreferences.userInteractionLevel; app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL; //create the dialog var dlgRef = app.dialogs.add(); //create master column with a single row var dlgMColumn = dlgRef.dialogColumns.add(); var dlgMRow = dlgMColumn.dialogRows.add(); //add a container for your items; we are providing two dialog columns: one for a label and one for the widget var dlgColumn1 = dlgMRow.dialogColumns.add(); var dlgColumn2 = dlgMRow.dialogColumns.add(); //add your items for your container (use container reference for parent dlgColumn1.staticTexts.add({staticLabel:labelText}); var choiceField = dlgColumn2.dropdowns.add({stringList:dropList, selectedIndex:defaultChoice, minWidth:144}); //show the dialog and capture the result if (dlgRef.show() == true) { var userChoice = choiceField.selectedIndex; dlgRef.destroy(); //restore script preference app.scriptPreferences.userInteractionLevel = origLevel; return userChoice; } else { //destroy the dialog before throwing exception dlgRef.destroy(); //restore script preference app.scriptPreferences.userInteractionLevel = origLevel; throw ("User cancelled"); } }
All that is left at this point is to add these subroutines to the script that was started in our previous blog. The complete script will be used in a project designed to create a fixed layout document for iPad. That will be in the final installment for this series.