Your prescription for increased productivity and profitability
Our last blog introduced you to a script that creates the framework for your ePub document. Here, we start another script that will populate the document and style the text. Each page for our sample document will have a similar structure consisting of three paragraphs:
The text contents will be imported from a plain text file with paragraphs defined by ending line returns reading, in part, as follows:
My Crazy Cat¶ This is a story about one crazy cat whose personality seems to change with each day of the week.¶ ¶ Monday¶ My cat carefully plans his week while lazying around the house all day.¶ ¶
And so on. Of course, depending on your text editor, you probably will not see the paragraph returns. We added the paragraph return character here just for illustration.
The interesting part of this script involves how the paragraphs are styled.
Because the styling repeats in a consistent pattern, it can use a unique looping algorithm that involves a modulus operation.
The mathematical operation modulus is similar to division with the exception that it returns only the remainder of a division operation, for example.
24 modulus 3 = 0 25 modulus 3 = 1
The symbol for modulus in AppleScript is mod; in ExtendScript it is the percent sign (%).
For demonstration, try the following script snippet:
AppleScript
set paraCount to 9 --number of paragraphs in text flow set applyParastyleList to {"Headline1", "Text", "CenterImage"} --names of styles set styleLen to length of applyParastyleList repeat with i from 1 to paraCount set parastyleIndex to ((i + paraCount - 1) mod styleLen) + 1 set styleName to item parastyleIndex of applyParastyleList display alert "paragraph style is now " & item parastyleIndex of applyParastyleList end repeat
ExtendScript
var paraCount = 9; //number of paragraphs in text flow var applyParastyleList = ["Headline1", "Text", "CenterImage"]; //names of styles to be applied var styleLen = applyParastyleList.length; for (var i = 0; i < paraCount; i ++) { var tempIndex = ((i + paraCount) % styleLen) ; var styleName = applyParastyles[tempIndex]; alert ("Paragraph style is now " + applyParastyleList[tempIndex] paraList[i].appliedParagraphStyle = docRef.paragraphStyles.item(styleName); }
In the script, references to the document’s paragraph styles are stored in a list (array) variable. This is returned from the getParagraphStyles subroutine.
AppleScript
tell application "Adobe InDesign CS6" set docRef to document 1 set parastyleList to my getParagraphStyles (docRef) end tell (*Handler returns list of names for paragraph styles in document*) on getParagraphStyles(docRef) tell application "Adobe InDesign CS6" tell docRef set allNames to name of paragraph styles end tell end tell set parastyleList to rest of allNames --discard the first style set item 1 of parastyleList to "No Style" --rename the style that is now first return parastyleList end getParagraphStyles
ExtendScript
//calls function var docRef = app.documents.item(0); var parastyleList = getParagraphStyles(docRef); /*Function returns list of names for paragraph styles in document*/ var localstyleList = docRef.paragraphStyles.everyItem().name; var localstyleLen = localstyleList.length; localstyleList = localstyleList.slice(2, localstyleLen); //remove first two items from array localstyleList.unshift("No Style"); //add this item as the first item return localstyleList; }
The list of available paragraph styles is passed to a custom dialog which allows the user to select, in order, the paragraph styles to use. The custom dialog provides five drop downs from which to choose the style for each of the paragraphs. For our sample document only the first three drop downs will be used. The others will default to “No Style”.
The styles are then applied to the paragraphs using our looping algorithm. This is done in the placeText subroutine that places the text inside the top/left margin for the first page of the document.
(*Places text for file defined by fileRef and styles the text using a list of paragraph styles*) on placeText(docRef, fileRef, applyParastyles) set styleLen to length of applyParastyles tell application "Adobe InDesign CS6" --set text import preferences set origImportPrefs to text import preferences tell text import preferences set strip returns between lines to false set strip returns between paragraphs to false set use typographers quotes to true set convert spaces into tabs to false end tell --get page and place point for placing the text set pageRef to page 1 of docRef tell margin preferences of pageRef set mTop to top set mLeft to left end tell set placePt to {mLeft, mTop} --place the file tell pageRef to place file fileRef place point placePt with autoflowing without showing options --get an object reference list of the paragraphs in the story set paraList to object reference of paragraphs of story -1 of docRef set paraCount to (length of paraList) --adjust the number of paragraphs if paraCount mod styleLen > 0 then set paraCount to (paraCount div styleLen) * styleLen end if --repeat through the paragraphs and apply the styles tell docRef repeat with i from 1 to paraCount set parastyleIndex to ((i + paraCount - 1) mod styleLen) + 1 set styleName to item parastyleIndex of applyParastyles set thisPara to item i of paraList set applied paragraph style of thisPara to paragraph style styleName end repeat --check for overflow condition for text frame on page 1 if overflows of text frame 1 of page 1 = true then set next text frame of text frame 1 of page 1 to text frame 1 of page 2 end if end tell --return text import preferences to original settings set text import preferences to origImportPrefs end tell end placeText
ExtendScript
/*Places text for the file defined; styles the text using list of paragraph styles*/ function placeText (docRef, fileRef, applyParastyles){ var styleLen = applyParastyles.length; //set text import preferences var origImportPrefs = app.textImportPreferences.properties; with (app.textImportPreferences) { stripReturnsBetweenLines = false; stripReturnsBetweenParagraphs = false; useTypographersQuotes = true; convertSpacesIntoTabs = false; } //define page and place point for text import var pageRef = docRef.pages.item(0); var mTop = pageRef.marginPreferences.top; var mLeft = pageRef.marginPreferences.left; var placePt = [mLeft, mTop]; //place the file; parameters: file, place point, layer reference, showing options, autoflow pageRef.place(fileRef, placePt, undefined, false, true); //get array of paragraphs in story placed var paraList = docRef.stories.item(-1).paragraphs; //adjust the number of paragraphs var paraCount = paraList.length; if (paraCount % styleLen > 0) { paraCount = (Math.floor(paraCount/styleLen)) * styleLen; } //style the paragraphs using the looping algorithm for (var i = 0; i < paraCount; i ++) { var tempIndex = ((i + paraCount) % styleLen) ; var styleName = applyParastyles[tempIndex]; paraList[i].appliedParagraphStyle = docRef.paragraphStyles.item(styleName); } //check for overflow condition for text frame on page 1 if (pageRef.textFrames.item(0).overflows == true) { var nextPage = docRef.pages.item(1); pageRef.textFrames.item(0).nextTextFrame = nextPage.textFrames.item(0); } //reset text import preferences app.textImportPreferences.properties = origImportPrefs; }
A procedure within this subroutine needs explanation. We need to make sure that the number of paragraphs to be styled conform to the number of styles being used. Otherwise an error with be raised if the script attempts to style a paragraph that does not exist. Some text editors will throw away the last paragraph of a story if it is empty. For our example, this is prevented by using end of story characters (hash characters) for the last paragraph.
The subroutine makes sure there is an evenly-divisible number of paragraphs by rounding the number of paragraphs (paraCount). This might result in the paragraphs on the last page being unstyled. Users would then need to style this page manually. Optionally, you could add paragraphs until the count is evenly divisible.
At first glance, going to all of this trouble to write a script to create one document, might seem to be counter-productive. On the other hand, consider the fact that most pages in a fixed layout will not require any more than five paragraphs. The order of styling for the pages is controlled by the paragraph style list (array). The paragraph that will hold the image is identified by an index value. Suppose you want to have the image for page 1 follow the second paragraph, but to follow the third paragraph on subsequent pages. Allow for empty paragraphs to shift the position, and remove empty paragraphs after images have been placed.
For example, allow for five paragraphs with the following pattern: {“Headline1”, “Text”, “Text”, “CenterImage”, “Text”}. When you want the text to follow the second paragraph, you make the second paragraph of the page an empty paragraph. When it needs to follow the third paragraph, both the first and second paragraphs have content. It works, believe me.
Tune in next week as we place the images for our pages.