Your prescription for increased productivity and profitability
Business cards, that is. In this week’s blog post we will use what we have learned about XML and Adobe InDesign to create a project for printing business cards 8-up on a page. The cards will be “butt-cut” meaning that there is no trim provided between the cards.
As we have seen in this blog series to date, the success of an XML automated project depends on two factors:
Although the process of setting up the InDesign document can be done manually, we will use a couple of scripts to automate some of the process.
To keep things simple, our XML file will define the following elements:
Root Employees Employee Name Title Cel
The Cel element is for the cell phone number of the employee. The XML file provided, reads similar to the following which shows a single entry:
<root><employees><employee><name>Rob Bray</name><title>Consultant</title><cel>Cel 000 000-0000</cel></employee> </employees></root>
This is slightly different than the XML file used in our previous example where each individual element for an entry was followed by a line return. Thankfully, this structure will not be a problem as InDesign’s XML import preferences can be set up to add the line returns.
Our document will be a single page document, set up for print intent with Primary Text Frame enabled.
Size will be 42 picas wide by 3 picas high, having 2 columns with a 4 pica gutter.
Margins for the document will be top: 1 pica, bottom: 1 pica, left: 2 picas, right: 2 picas
Most of the work will be on the master page. We will use three layers:
Lock Layer 1 to make it easier to work on the other two layers. Set up the Dieline layer as shown below:
nec ullamcorper mattis, pulvinar dapibus leo.
On page 1 of the master page, make sure you are on the Dieline layer. Create a rectangle starting in the upper left hand corner of the page (0,0). Make the rectangle 21 picas wide by 12 picas high. Give it an outline stroke of 1 pt.
Copy the following to a new script in AppleScript Editor:
set numCols to 2 set numRows to 4 set horiz to 252 set vert to 144 set y0 to 0 --top move to set x0 to 0 --left move to set beginX to 0 --reset value for x0 set counter to 0 tell application "Adobe InDesign CC 2015" set measurement unit of script preferences to points set docRef to document 1 set selList to selection set selItem to item 1 of selection tell docRef repeat with i from 1 to numRows repeat with j from 1 to numCols if counter > 0 then duplicate selItem move selItem to {x0, y0} end if set x0 to x0 + 252 set counter to counter + 1 end repeat set x0 to beginX set y0 to y0 + 144 end repeat end tell end tell
Save the script and run it with the rectangle selected.
Lock the Dieline layer and switch to the Static layer. Save the document.
Create the static items for your first business card as needed and group them.
Now, change the values of y0, x0, and beginX at the top of the Duplicate Grid script to the top y and left x values for your static text group. Settings for a group butting to the top and left margins would be as follows:
set y0 to 12 set x0 to 18 set beginX to 18
With the group selected, run the Duplicate Grid script again.
Lock the Static layer and unlock Layer 1. Save the document.
With Layer 1 active, resize the Primary Text Frame to accommodate your dynamic text items.
Change column count in Text Frame Options (Command+B) to 1.
On page 1 of the document (not the master page), you should have the Primary Text Frame available.
Add placeholder text for Name, Title, and Cel to the Primary Text Frame.
Add paragraph styles for Name, Title, and Cel.
Notice that the placeholder text and paragraph style names are exactly the same and correspond with the XML tags in the XML file.
Style the placeholder text. Make sure that the Name paragraph style includes Keep Option “Start Paragraph: In Next Frame”.
You can add XML tags manually or use our script LoadTags.scpt (introduced in our previous script blog). Using the script assures that tags will be named as needed, and all tags needed will be added. If using the script, select the XML file when prompted.
You should now have the following tags in InDesign’s Tags panel.
From the Context Menu for the Tags panel, select Map Tags to Styles.
Click on the Map by Name button.
ave the document.
Marking up your document for a multiple-item XML can be a tedious and error-prone process. To eliminate this, use our script XML_Tag Markup.scpt. The following code assumes that tags, paragraph styles, and all have been set up as described above. Little error checking is provided, so use with caution.
set tagName to "Employee" tell application "Adobe InDesign CC 2015" set docRef to document 1 tell docRef set mTagRef to my getTag(docRef, tagName) set selList to selection set frameRef to item 1 of selList set rootElement to XML element 1 end tell set parentElement to my tagFrame(docRef, frameRef, tagName) set paraCount to count of paragraphs of frameRef repeat with i from paraCount to 1 by -1 tell frameRef set paraRef to object reference of paragraph i set styleRef to applied paragraph style of paraRef set styleName to name of styleRef set tagRef to my getTag(docRef, styleName) set textRef to object reference of text from character 1 to character -2 of paraRef end tell tell parentElement set elementRef to make XML element with properties {markup tag:tagRef} markup textRef using elementRef end tell tell docRef to make XML import map with properties {mapped style:styleRef, markup tag:tagRef} end repeat end tell --application (*Tags the selected text frame. Use with Primary Text Frame selected on page 1*) on tagFrame(docRef, frameRef, tagName) set masterName to tagName & "s" set tagRef to getTag(docRef, tagName) set mTagRef to getTag(docRef, masterName) tell application "Adobe InDesign CC 2015" tell docRef set rootElement to XML element 1 set name of frameRef to tagName end tell tell rootElement set masterElement to make XML element with properties {markup tag:mTagRef} end tell tell masterElement set parentElement to make XML element with properties {markup tag:tagRef} end tell tell parentElement to markup using frameRef end tell return parentElement end tagFrame (*Checks for existence of tag. If it doesn't exist, it is created*) on getTag(docRef, tagName) set tagRef to missing value tell application "Adobe InDesign CC 2015" tell docRef if exists XML tag tagName then return XML tag tagName else set tagRef to make XML tag with properties {name:tagName} end if end tell end tell return tagRef end getTag
Select the text frame with the placeholder text and run the script. When prompted, enter “Employee”. This is the name for the parent element of the XML text elements.
If you did everything right to this point, the Structure panel (Command + Option + 1) and Story Editor (Command+Y with text selected) should look like the following.
If your Structure and Story Editor look correct, save the document. Switch to A-Master. Unlock Layer 1 if still locked.
Because you cannot duplicate the Primary Text Frame, you will use another script: Primary Grid.scpt. This gets the bounds of the chosen text frame (the Primary Text Frame on the master page) and creates multiple text frames for the remaining business cards on the page. As part of the script, the text frames are threaded.
set numCols to 2 set numRows to 4 set horiz to 252 set vert to 144 set counter to 0 tell application "Adobe InDesign CC 2015" set measurement unit of script preferences to points tell document 1 set frameStyle to "[Basic Text Frame]" set selList to selection set selItem to item 1 of selection set lastFrame to selItem copy geometric bounds of selItem to {y0, x0, y1, x1} set beginX to x0 set beginX1 to x1 tell page 1 of master spread "A-Master" repeat with i from 1 to numRows repeat with j from 1 to numCols if counter > 0 then set thisFrame to make text frame with properties {geometric bounds:{y0, x0, y1, x1}, applied object style:frameStyle} if counter < (numRows * numCols) then set previous text frame of thisFrame to lastFrame set lastFrame to thisFrame end if end if set x0 to x0 + 252 set x1 to x1 + 252 set counter to counter + 1 end repeat set x0 to beginX set x1 to beginX1 set y0 to y0 + 144 set y1 to y1 + 144 end repeat end tell end tell end tell
With the Primary Text frame selected, run the Primary Grid script. Activate Show Text Threads (Command+Option+Y). Your document should now look similar to the following:
If all went well, save the document.
Document after running Primary Grid script
The script ImportToRoot (below) sets up XML import preferences for an XML file that does not include paragraph returns after individual text elements. Notice that for this set ignore whitespace is set to true.
Make sure you have Smart Test Reflow and Limit to Primary Text Frames checked for InDesign’s Type Preferences. Add Pages should also be set to End of Document.
(*Relies on Primary Text Frame being named as defined in variable frameName*) set frameName to "Employee" try set fileRef to getXMLFile() tell application "Adobe InDesign CC 2015" set docRef to document 1 my setImportPrefs(docRef) set rootElement to XML element 1 of docRef tell rootElement to import XML from fileRef set frameRef to text frame frameName of docRef tell frameRef place XML using rootElement with autoflowing end tell tell docRef to map XML tags to styles end tell on error errStr activate display alert errStr end try (*Sets import prefeences for XML that does not include paragraph returns*) on setImportPrefs(docRef) tell application "Adobe InDesign CC 2015" tell XML import preferences of docRef set allow transform to false set import style to merge import set repeat text elements to true set create link to XML to false set import to selected to false set ignore whitespace to true set import CALS tables to false set import text into tables to false set ignore unmatched incoming to true set remove unmatched existing to true end tell end tell end setImportPrefs (*Has user select file and checks to make sure file is an XML file*) on getXMLFile() set fileRef to choose file with prompt ("Select XML file for placing") without invisibles and multiple selections allowed set fileInfo to info for fileRef if name extension of fileInfo is not "XML" then error "Wrong file type chosen" end if return fileRef end getXMLFile
Save the document.
There you have it. Business cards are created to conform to the XML file. This can include any number of XML entries.
Our final document.
You may have noticed that we saved the document after each major step above, that is, if all went well. If there was a problem, revert the document back to its last save. (File > Revert). Review your last step to discover the problem.
Again, to keep the code pared down to the bare essentials, values for variables in the scripts have been hard-coded. This should be replaced with a custom dialog. You will also want to add error handling to take care of a situation such as the user not having a text frame or rectangle selected when running a script that requires a selected item.
If creating business cards (or other multiple item documents) are something you do quite often, you may want to set keyboard shortcuts for your script (once you have replaced hard-coded values with a user dialog).
Again, the scripts used here as well as the XML file are provided in a download available from the AppleScript page of this site.
See if you can modify the business card layout to include an image of the employee. The image will need to be an anchored page item (see our blog post for March 28). The big caveat for this is that the images need to be sized at 100% and the text frame to which it will be anchored needs to be large enough to accommodate the image when it is first placed. Good luck.