Your prescription for increased productivity and profitability
This is the fourth in our series to demonstrate how a simple ePub document can be created using scripts. To create the skeleton for our document, a script named ePubDocFromPreset was used. This script depended on a stylesheet and a document preset having been created prior to running the script. When the script is run, the user is given a dialog box in which to enter a name for the project, and designate the document preset and the stylesheet to be used. The script then creates the document using the document preset and imports styles from the stylesheet. The document is saved in a folder named the same as the project name residing in the Documents folder for the user. If this folder does not exist, it is created.
The project folder needs to have a plain text file containing a single story flow for the document. For the images, there needs to be a folder named “images” with an image for each page of the document, and optionally a cover image. The images are expected to be jpeg and named using the following convention: “pg01.jpg” thru “pg99.jpg”. It is not anticipated that the completed book would be more than 99 pages long. The cover page needs to be named Cover.jpg.
When your book’s resources are in the project folder, the script PopulateWRepeatingStyles is used to place the text and images. To determine the paragraph styles to use for styling the text and for placing the image, a dialog box is presented to the user. Here the user also designates the object style to use for the image anchor.
The text is styled using an interesting algorithm within a repeating loop (see last week’s blog). This is possible because the text follows a standard pattern throughout.
The subroutine that places the text gets the name of all image files in the Images folder. Because image files are named consistent with its target page (pg01.jpg, and so on), the script is able to place the files using the insertion point for the paragraph having the designated paragraph style.
As its last step, the subroutine assigns the object style to the images using the style designated by the user in the custom dialog.
The function placeImages requires a reference to the active document, the name of the imageFolder (images), and the name of the object style that will apply the anchor settings. If there is no object style (No Style), a default anchor style is created.
(*Places images found in imageFolder and anchors using object style*) on placeImages(docRef, imageFolder, anchorStyleName) --get name of all jpeg files in folder named images tell application "Finder" if not (exists folder (imageFolder)) then error "Image folder not found in Users Directory" else set projectFolder to folder (imageFolder) set fileList to name of every file of projectFolder whose file type = {"jpg"} or name extension = "jpg" end if end tell tell application "Adobe InDesign CS6" tell docRef --get reference to object style; if it does not exist, then create the style try set anchoredStyle to object style anchorStyleName on error activate display alert ("creating anchor style " & anchorStyleName) set anchoredStyle to my createAnchorStyle(docRef) end try --repeat through the pages and place the images using the first insertion point of the defined paragraph repeat with i from 1 to count of pages set thisName to "pg" & (text 1 thru -1 of "0" & i) & ".jpg" if thisName is in fileList then set fileRef to imageFolder & ":" & thisName set frameRef to text frame 1 of page i set paraRef to object reference of paragraph targetStyleIndex of frameRef tell insertion point 1 of paraRef set placedList to place file fileRef set imageRef to item 1 of placedList end tell set containerRef to parent of imageRef set applied object style of containerRef to anchoredStyle end if end repeat end tell end tell end placeImages
/*Places images found in imageFolder and anchors using object style*/ function placeImages (docRef, imageFolder, anchorStyleName) { var pageRef = docRef.pages.item(0); //returns array of image files using function listFiles_FolderRef var imageList = listFiles_FolderRef (imageFolder, fileExt); //checks for anchored style; creates default style if not found if (docRef.objectStyles.item(anchorStyleName).isValid) { var anchoredStyle = docRef.objectStyles.item(anchorStyleName); } else { alert ("Creating anchor style " + anchorStyleName); var anchoredStyle = createAnchorStyle (docRef); } //parse imageList and get list of names only var imageNameList = []; var imageName; var lastIdx; for (var i = 0; i < imageList.length; i++) { imageName = imageList[i].toString(); lastIdx = imageName.lastIndexOf("/"); imageNameList.push(imageName.substr(lastIdx + 1)); } //repeat through pages and place image named for page number var pageCount = docRef.pages.count(); var thisPageRef; for (var i = 0; i < pageCount; i++) { var thisName = "pg" + ("0" + (i+1)).substr(-2) + ".jpg"; thisPageRef = docRef.pages.item(i); var frameRef = thisPageRef.textFrames.item(0); var paraRef = frameRef.paragraphs.item(targetStyleIndex); try { var placedList = paraRef.insertionPoints.item(0).place(File(imageFolder + "/" + thisName)); var imageRef = placedList[0]; var containerRef = imageRef.parent; containerRef.appliedObjectStyle = anchoredStyle; } catch(e){ //do nothing; add functionality here if desired } } }
The placeImage function in ExtendScript requires two helper functions:
AppleScript only requires createAnchorStyle(). This is one place you will find a big difference between AppleScript and ExtendScript. With ExtendScript, having to support both Windows’ and Apple’s file system adds a fair amount of code to the script. That is the price one pays for a script supporting both platforms. The code for listFiles_FolderRef follows:
//returns list of files found in folder referenced based on file extension function listFiles_FolderRef (filePath, fileExt){ //get folder reference using value for filePath variable var folderRef = Folder(filePath); //determine system you are running on if (File.fs == "Windows") { var fileList = folderRef.getFiles("*" + fileExt); } else { checkExt = fileExt.toUpperCase(); var fileList = folderRef.getFiles (listByExt); } if (fileList.length == 0) { throw ("No files found"); } return fileList; /*filter function for getFiles on Macintosh; checking for extension*/ function listByExt (objRef) { if (objRef instanceof File) { return objRef.name.toUpperCase().indexOf(checkExt)!= -1; } else { return false; } } }
In contrast, AppleScript can get the file list with a one-line statement addressed to the Finder:
tell application "Finder" set fileList to name of every file of projectFolder whose file type = {"jpg"} or name extension ="jpg" end tell
Make sure you understand the functionality for the placeImages subroutine. You are sure to use much of its code in scripts of your own. All that is left at this point is to bullet-proof the script. Among the processes you might add would be to have the user select image files if not found.