Your prescription for increased productivity and profitability
Our previous blog introduced a number of handlers (functions) that you might want to keep handy in a library for use in other scripts. These handlers were:
Similar to the makeTitleBox, you might want a handler that allows setting values for parameters such as fill color, tint, stroke weight, and fit. The beginnings for a suggested script follows.
set layerRef to missing value set gBounds to {100, 30, 150, 500} set textContent to "This is a test, only a test" set fitToContent to false set pStylename to "Heading1" set fillColor to "Black" set fillTint to 30 set strokeWeight to 2 set strokeColor to "Black" set strokeTint to 100 set frameName to "Test Frame" tell application "Adobe InDesign CC 2017" set measurement unit of script preferences to points set docRef to document 1 set vJust to center align set pStyle to paragraph style pStylename of docRef set pageRef to active page of active window set textFrame to my makeTextFrame(pageRef, frameName, ¬ gBounds, fillColor, fillTint, strokeWeight, strokeColor, strokeTint, pStyle, ¬ textContent, fitToContent, vJust, layerRef) end tell (*Expects actual text to be passed to text frame created. layerRef can be missing value, and itemName can be empty string ""*) on makeTextFrame(parentRef, itemName, gBounds, fillColor, fillTint, strokeWeight,¬ strokeColor, strokeTint, pStyle, textContent, fitToContent, vJust, layerRef) tell application "Adobe InDesign CC 2017" tell parentRef set myFrame to make text frame with properties {geometric bounds:gBounds,¬ fill color:fillColor, fill tint:fillTint, stroke weight:strokeWeight} if strokeWeight is not 0 then set stroke color of myFrame to strokeColor set stroke tint of myFrame to strokeTint end if if itemName is not "" then set name of myFrame to itemName end if set contents of insertion point 1 of myFrame to textContent tell text 1 of parent story of myFrame set applied paragraph style to pStyle end tell if fitToContent then tell myFrame to fit given frame to content else tell myFrame to set vertical justification of text frame preferences to vJust end if if layerRef is not missing value then set item layer of myFrame to layerRef end if return myFrame end tell end tell end makeTextFrame
//Expects document with paragraph and object styles as named var layerRef = undefined; var gBounds = [100, 30, 150, 500]; var textContent = "This is a test, only a test"; var fitToCont = false; var pStylename = "Heading1"; var myFillColor = "Black"; var myFillTint = 30; var myStrokeWeight = 2; var myStrokeColor = "Black" var myStrokeTint = 100; var frameName = "Text Frame"; app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS; var vJust = app.textFramePreferences.verticalJustification = VerticalJustification.CENTER_ALIGN; var docRef = app.documents[0]; var pStyle = docRef.paragraphStyles.item(pStylename); var pageRef = app.activeWindow.activePage; var myFrame = makeTextFrame(pageRef, frameName, gBounds, myFillColor, myFillTint, myStrokeWeight, myStrokeColor, myStrokeTint, pStyle, textContent, vJust, layerRef); function makeTextFrame (pageRef, frameName, gBounds, myFillColor, myFillTint, myStrokeWeight, myStrokeColor, myStrokeTint, pStyle, textContent, vJust, layerRef) { var myFrame = pageRef.textFrames.add({geometricBounds:gBounds, fillColor:myFillColor, fillTint:myFillTint, strokeWeight:myStrokeWeight}); if (myStrokeWeight != 0) { myFrame.strokeColor = myStrokeColor; myFrame.strokeTint = myStrokeTint; } if (frameName != "") { myFrame.name = frameName; } if (fitToCont != false) { myFrame.fit(FitOptions.FRAME_TO_CONTENT); } myFrame.texts.item(0).insertionPoints.item(0).contents = textContent; myFrame.texts.item(0).parentStory.appliedParagraphStyle=pStyle; myFrame.textFramePreferences.verticalJustification= vJust; if (layerRef != undefined){ myFrame.itemLayer = layerRef; } return myFrame; }
To complete the script, you will want to create a user interaction dialog (UI) to allow the user to define the values for the text frame. The problem with this handler, as with the handler to make a rectangle (makeRectangle) from our previous blog, is that there are a number of variables that need to be defined, requiring a fairly extensive user dialog.
By using a paragraph style, we were able to save having to establish a few more variables. Imagine the number of fields in the UI dialog that would be needed to have the user name the font, size, color, and justification for the text along with all of the other parameters. As you can see, using paragraph styles can simplify scripts with the added advantage of establishing styling consistency.
We can push the concept of using styles further, using object styles to enforce styling consistency while also simplifying an automation script. Let’s investigate.
Looking at the script above, we see that it requires 12 arguments to be passed to the makeTextFrame handler. (Don’t forget to count vJust which needs to be set inside the tell application block.)
By using an object style to style the text frame, we can cut that number back considerably. But first, let’s establish the style. The object style panel is one that I include as part of my workspace. With a new document open, make sure you have a paragraph style established named Heading1. You can set its properties to your liking. Next, open the object style panel. (To open it, select Window > Styles > Object Style from InDesign’s menu.)
…Object Style Panel
By default, InDesign gives us three object styes: [None], [Basic Graphics Frame], and [Basic Text Frame]. We will base our new text frame object style on [Basic Text Frame]. Click on [Basic Text Frame] and choose New Object Style from the panel’s context menu.
This dialog can be a little intimidating. Just remember, “with complexity, comes power.”
Give the style a name: “GrayFillWithBorder.” Start at the top of the Basic Attributes list, clicking on Fill and then Stroke. Set the appropriate values when the Fill/Stroke tab panel opens.
In the New Object Style window, Basic Attributes list, uncheck Stroke & Corner Options. Make sure Paragraph Styles is checked and click on it. Select Heading1 from the Paragraph Style dropdown.
For the object style, we will set Text Frame General Options to Vertical Justification: Align: Center. Click OK. Alternatively, if you had a text frame selected when you opened the Object Style Options dialog, you could select the Preview option in the lower left corner to preview your settings before dismissing the window.
Now, we will write a second script to create a text frame, this time using the object style.
AppleScript
set layerRef to missing value set gBounds to {30, 30, 80, 500} set textContent to "This is a second test using an object style" set pStylename to "Heading1" set oStylename to "GrayFillWithBorder" tell application "Adobe InDesign CC 2017" set measurement unit of script preferences to points set docRef to document 1 set oStyle to object style oStylename of docRef set pStyle to paragraph style pStylename of docRef set pageRef to active page of active window set textFrame to my makeTextFrame(pageRef, "testText", gBounds, oStyle, pStyle, textContent, layerRef) end tell on makeTextFrame(parentRef, itemName, gBounds, oStyle, pStyle, textContent, layerRef) tell application "Adobe InDesign CC 2017" tell parentRef set myFrame to make text frame with properties {geometric bounds:gBounds, applied object style:oStyle} if itemName is not "" then set name of myFrame to itemName end if set contents of insertion point 1 of myFrame to textContent tell text 1 of parent story of myFrame set applied paragraph style to pStyle end tell if layerRef is not missing value then set item layer of myFrame to layerRef end if return myFrame end tell end tell end makeTextFrame
ExtendScript
//Expects document with paragraph and object styles as named var layerRef = undefined; var gBounds = [30, 30, 80, 500]; var textContent = "This is a second test, using an object style"; var pStylename = "Heading1"; var oStylename = "GrayFillWithBorder"; var frameName = "Text Frame"; app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS; var docRef = app.documents[0]; var oStyle = docRef.objectStyles.item(oStylename); var pStyle = docRef.paragraphStyles.item(pStylename); var pageRef = app.activeWindow.activePage; var myFrame = makeTextFrame(pageRef, frameName, gBounds, oStyle, pStyle, textContent, layerRef); function makeTextFrame (pageRef, frameName, gBounds, oStyle, pStyle, textContent, layerRef) { var myFrame = pageRef.textFrames.add({geometricBounds:gBounds}); myFrame.texts.item(0).insertionPoints.item(0).contents = textContent; myFrame.appliedObjectStyle = oStyle; myFrame.texts.item(0).parentStory.appliedParagraphStyle=pStyle; if (layerRef != undefined){ myFrame.itemLayer = layerRef; } return myFrame; }
Now, instead of thirteen arguments, there are only 5 that need to be defined–quite the savings. But wait, there’s more!
Using styles, you get:
For the best HTML export, you will want to associate your paragraph styles with an HTML tag. We will associate our Heading1 style with H1.
A big advantage to using object styles is that InDesign will put the styling into the CSS file that it generates as part of the export. Try it. Export the sample document you created using the two scripts above.
If you check the View HTML after Exporting option, the page you created is displayed automatically.
As you can see, the displayed page lacks much as far as the page layout is concerned. If you look at the files created as part of the xport, you will see that InDesign has created an .html file and a TestDocument-web-resources folder. If your document had linked image, this folder would contain a folder for the images. For our test, there is only the css folder (Cascading Style Sheets folder). If you open the idGeneratedStyles.css document in a plain text or code editor, you can examine how the paragraph and object styles you created for your document were interpreted for the web.
Looking through the styles, you will find one named the same as your object style with “div.” prepended. Also, there is a style named for the Heading1 paragraph style with the associated HTML tag (h1) prepended. The attributes listed under these styles should be fairly self-explanatory. You can give the files to your HTML/CSS person for finalizing, or, feeling brave, add styling to a .css file to make the final product look exactly the way you want (see below). Alternatively, your HTML/CSS person may give you a .css file to add to your export HTML process.
To illustrate, we will create our own .css file to add to the HTML export. Using a plain text editor (or code editor), create the following file:
div.GrayFillWithBorder { width: 500px; height: 50px; margin: 30px auto 18px auto; padding: 30px 12px 12px 12px; }
Save the file as testCSS.css someplace handy. Make sure it has the .css extension, As a final option, when you export your document, click on the Advanced tab in the HTML Export Options dialog. In the panel that opens, click on the Add Style Sheet button and navigate to the css file created above.
This time, the display of the object-styled text frame is more what we are wanting. To do the same for the second text frame is not that easy as the name InDesign uses to reference the frame can change. Using an object-style, you can have a consistently named and styled text frame when exported to HTML.
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.