Automating Adobe InDesign 2017

Automating a Heart in InDesign

Saturday, February 11, 2017

Just in Time for Valentine

So you want to make a quick valentine to post on line. Because you are an InDesign specialist, you might want to demonstrate some of your skills while trying out Publish Online. And, with your final output to be from InDesign, you have some definite advantages in creating your graphic. Top of the list is the fact that you don't have to worry about finding the image to import. And, if you are concerned about the size of your final project, a graphic defined natively has a very small footprint (under the hood, it's just text after all). Once the graphic is defined, it can copied, pasted, and transformed to your liking. Stroke and fill with different colors, or gradients, or use to frame an imported image. You get the picture.

Creating Graphics With a Script

Remembering that a shape in InDesign is nothing more than paths defined by points within geometric space, you may decide that a script may be the best way to create a graphic. This is especially true if the graphic can be described using a bit of geometry. Without going into the details of creating a heart shape (that's for those nerd brains out there), the following script will create the shape for you.


The script needs a little explanation in addition to its comments. The script calculates the points on the path for the graphic (testPath) based on the height and width defined (variables hgt and wid). These dimensions can be the same but I prefer the width to be slightly smaller than the height. The reason a calculation is used to define the path points is to allow the heart to be any size (within reason). 

Surprisingly, it takes only five points to define for the path for a heart. Each point is a bezier curve point that takes three values (each a list of two values for x--horizontal and y--vertical): one for the point, and one for each of the point's direction handles. The values that define where the shape will be positioned on the page (xoset and yoset) are currently set at zero which places the shape in the upper left corner of the page. For now, use the values provided.

You will need to have a document open that has the color "red" defined. (That's with a lowercase "r".) With that, copy the script and paste it into the AppleScript editor. Press the button to compile, and then run the script from within the editor.

Heart Shape

   (*Define properties for the heart*)
   set nameValue to "heart"
   --set width to 95% of height
   set hgt to 200
   set wid to (hgt * .95)
   --offset is to top left of heart geometric bounds
   set xoset to 0
   set yoset to 0
   --make sure document has color swatch red 
   set strokeColor to "red"
   set fillColor to "red"
   set strokeWt to 2

   --ePath is percentages used to create path points
   set ePath to {{{0.672, 0.985}, {0.672, 0.985}, {0.737, 0.919}}, {{1.328, 0.555}, {1.185, 0.231}, {1.027, -0.077}}, {{0.672, 0.077}, {0.672, 0.209}, {0.672, 0.209}}, {{0.672, 0.208}, {0.672, 0.202}, {0.674, 0.094}}, {{0.327, -0.088}, {0.159, 0.23}, {0.008, 0.552}}}
   --calculate actual path points from ePath values
   set testPath to {}
   repeat with i from 1 to length of ePath
      set thisPt to item i of ePath
      set ptList to {}
      repeat with j from 1 to length of thisPt
         set x0 to ((item 1 of item j of thisPt) * wid) + xoset
         set y0 to ((item 2 of item j of thisPt) * hgt) + yoset
         set end of ptList to {x0, y0}
      end repeat
	set end of testPath to ptList
      end repeat
      --set geometric bounds for graphic
      set gBounds to {1, 1, wid, hgt}
      --have InDesign create the graphic
   tell application "Adobe InDesign CC 2017"
      set measurement unit of script preferences to points
      tell document 1
         tell page 1
	    set polyRef to make polygon with properties {geometric bounds:gBounds, stroke weight:strokeWt, fill color:fillColor, stroke color:strokeColor}
	    tell path 1 of polyRef
		set entire path to testPath
		set path type to closed path
	    end tell
		set name of polyRef to nameValue
	    end tell
	end tell
   end tell

heart graphic created with script

Change the values for xoset (horizontal offset), yoset (vertical offset), and maybe also for hgt (height). Run the script again.

Of course, once you have one heart created, you can copy, paste, and resize to your liking. A simple way to copy a graphic is to click on it and hold the shift and option keys down as you drag to a new position on the page. To resize, grab on a corner of the bounding box and hold the shift key down while pulling on the corner.

Make The Script User Friendly

You can make the script user friendly by adding a custom dialog. The script below is a good start for you. It creates fields for entering a name for the graphic, its size (height), and colors for fill and stroke. You will need to add fields for any of the other properties you want to have the user define.

It is always a good idea to create your dialog in a separate script until you get it working the way you want it. If, in the target script, you define all of the variables that need to be set at its top (as was done above), it becomes an easy matter to add a call to a custom dialog.

Custom Dialog

   set defaultColor to 7
	tell application "Adobe InDesign CC 2015"
	   tell document 1
	      set colorList to name of swatches
	   end tell
	end tell
	set userResponse to ¬
       userDialog ("Graphic Preferences", true, "Dialog Label", colorList, defaultColor)
	copy userResponse to {nameValue, sizeValue, fillIndex, strokeIndex}
	set fillColor to item fillIndex of colorList
	set strokeColor to item fillIndex of colorList
	{nameValue, sizeValue, fillColor, strokeColor}
   on error errStr
	display alert "Error: " & errStr
   end try
   (*The handler requires dialog name, true, a label, and a reference to colors in the document, 
   and an index for the default color*)
   on userDialog(dlgName, cancelIt, dlgLabel, colorList, defaultColor)
      tell application "Adobe InDesign CC 2015"
	 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:dlgName, canCancel:cancelIt, label:dlgLabel}
	 tell dlgRef
	    set dlgColumn to make dialog column
	    tell dlgColumn
		tell (make dialog row)
		   make static text with properties {static label:"Name graphic:"}
		   set nameField to make text editbox with properties {min width:200}
		end tell
		tell (make dialog row)
		   make static text with properties {static label:"Size (in points)"}
		   set sizeField to make measurement editbox with properties¬
                   {min width:60, minimum value:72, maximum value:1000, edit units:points}
		end tell
		tell (make dialog row)
		   make static text with properties {static label:"Choose fill color"}
		   set fillField to make dropdown with properties ¬
                  {string list:colorList, selected index:defaultColor, min width:144}
		end tell
		tell (make dialog row)
		   make static text with properties {static label:"Choose stroke color"}
		   set strokeField to make dropdown with properties¬
                  {string list:colorList, selected index:defaultColor, min width:144}
		end tell
	   end tell
	end tell
	set userResponse to show dlgRef
	set wasCancelled to false
	if userResponse = true then
	   set nameValue to edit contents of nameField
	   set sizeValue to edit value of sizeField
	   set fillIndex to (selected index of fillField) + 1
	   set strokeIndex to (selected index of strokeField) + 1
	else --user cancelled
	   set wasCancelled to true
	end if
	destroy dlgRef
	set user interaction level of script preferences to origLevel
	   --if cancelled, throw error; otherwise return values
	   if wasCancelled then error "User cancelled"
	return {nameValue, sizeValue, fillIndex, strokeIndex}
	end tell --application
   end userDialog

The script creates a text field for the graphic name, drop downs for fill and stroke color, and a measurement editbox for entering the size of the graphic (in points). 

The custom dialog created from script above Custom dialog created from script

Notice that the variables for nameValue, sizeValue, fillColor, and strokeColor are placed in a list at the end of the script (before the on error statement). When you run the script, check the values for these variables in the Result panel for Script Editor.

Now Combine the Scripts

Copy the custom dialog script into a new script After the End Try statement, add a new handler: "makeHeart". It will have arguments for each of the properties which you will be passing from your user dialog. If you included values for the four properties in our sample script the wrapper for the handler will look like the following:

   on makeHeart (nameValue, sizeValue, fillColor, strokeColor)

   end makeHeart 

Then, after the on makeHeart statement, define variables for hgt, wid, and gBounds using the size Value which is passed as part of the arguments:

   set hgt to sizeValue
   set wid to 0.95 * sizeValue
   set gBounds to {1, 1, hgt, wid}

If your custom dialog has the user define the values for the variables xOset, yOset, and strokeWt make sure you pass these values to the makeHeart handler. Otherwise, you will need to define them here. (Be aware in this latter event the user will not be able to change these values.) 

   set xoset to 0  
   set yoset to 0
   set strokeWt to 2

Now paste in the script that creates the heart starting with the comment that introduces the values for ePath:

--ePath is percentages used to create path points

Lastly, you need to call the makeHeart handler. Just before the on error statement (at the top of the script) change the statement that checks the values returned from the dialog to a call to the makeHeart handler:


{nameValue, sizeValue, fillColor, strokeColor}

Change to:

   makeHeart(nameValue, sizeValue, fillColor, strokeColor)

Notice that parentheses are placed around the variables passed to the handler instead of the original curly braces.

Compile and test your script. Notice that the dialog currently allows the minimum size for the heart to be 72 points with a maximum size of 1000. You may want to set these values differently. When you are happy with the script, save it to a folder inside InDesign's script folder for User. Now all you need to do is double-click on the script to create your perfect heart (or more).

The script in InDesign's Script panel

Get Creative and Have Fun.


Scripts are provided to give users a starting point from which they can create their own scripts. No representation is made to their completeness. Users are advised to use as written at their own risk

Trackback Link
Post has no trackbacks.

Recent Posts