Your prescription for increased productivity and profitability
In our last post we developed an XML solution starting from ‘scratch” using a template specifically for just importing paragraph and object styles. On the other side of the spectrum, a template can provide all of the elements required for an automated XML workflow. This is paeticularly useful for documents that have a repeating publication schedule such as newsletters and product sales sheets where the page layout is consistent.
Consider a typical XML template. It can define XML tags, paragraph and object styles, and possibly structure in addition to the normal the document parameters of size and margins. All that is needed to complete the process is to import an XML text file which has been prepared to comply with the document tags and structure. Let’s see how a template like this can be created.
Your template should be ready for use.
To use the template, images for the document will need to be sized and saved in a folder named Images. This folder is placed in the same folder as the XML text file.
All that needs to be done to complete the project is for the user to open the template, save it as an InDesign document, and import the XML file that has been prepared for import.
Of the seven steps above that are listed for creating a template for XML import, five can be automated with a script. The page items for this template will be a grid of rectangles each of which will house an xML item. The containing area for the grid will be defined by creating and selecting a rectangle on the active page before running the script. The script will have some resemblance to the sample script that was created in our previous blog post but will present some new wrinkles. For simplicity, the values for our variables are placed at the top of the script.
global numRows, numCols, gut, gap set numRows to 2 set numCols to 3 set gut to 12 set gap to 12 set choosePrompt to "Choose dummy XML file for import" try set selRef to getSelection() on error errStr activate display alert ("Error: " & errStr) end try (*Returns reference to page item selected if text frame/insertion point or rectangle*) on getSelection() tell application "Adobe InDesign CC 2019" set selList to selection if selList is not {} and class of item 1 of selList is in {text frame, insertion point, rectangle} then set selItem to item 1 of selList else error "Requires text frame or rectangle selection" end if if class of selItem is insertion point then set storyRef to parent of selItem set frameRef to item 1 of text containers of storyRef else set frameRef to item 1 of selList end if return frameRef end tell end getSelection
Notice that here we are using global variables for our grid parameters. Normally, global variables are discoouraged, but in the event that the variables will not change within the script, they can be used effectively.
One way to get XML tags and structure is to import an XML file. This can be a dummy file, and doesn’t necessarily need to have the same structure you will be using. All you really need are the names of the elements defined by your XML text file. Add to the above after the call to getSelection():
set fileChoice to choose file with prompt choosePrompt
The reference returned will be used in the handler that sets up the page. Add the call to this handler directly below:
doSetup (selRef, fileChoice)
Do setup is the workhorse for this script. It imports the XML file, maps tags and creates a grid of containers complete with mark up.
(*Creates page items using boundsList returned from calcGridBounds*) on doSetup(selRef, fileChoice) tell application "Adobe InDesign CC 2019" set pageRef to parent of selRef set docRef to active document tell docRef import XML from fileChoice set rootElement to XML element 1 set tagList to name of XML tags end tell --map tags to styles my mapTagsToStyles (docRef, tagList) --calculate geometric bounds for page items to be created set measurement unit of script preferences to points copy geometric bounds of selRef to {y0, x0, y1, x1} set celWid to ((x1 - x0) - (numCols - 1) * gut) / numCols set celHgt to ((y1 - y0) - (numRows - 1) * gap) / numRows set boundsList to my calcGridBounds(x0, y0, celWid, celHgt) --create grid of page items of same class as selected item set selClass to class of selRef tell pageRef repeat with i from 1 to length of boundsList set thisBounds to item i of boundsList set thisItem to make selClass with properties {name:"Container", geometric bounds:thisBounds} set itemElement to XML element i of XML element 1 of rootElement markup thisItem using itemElement end repeat end tell end tell end doSetup
…A dummy XML file can provide needed XML tags
All the script needs now are the handlers called from the doSetup handler above: mapStylestoTags and CalcGridBounds.
(*checks to make sure a paragraph style exists for mapping each XML tag to style*) on mapTagsToStyles(docRef, tagList) --we only need to map tags to paragraph styles, the rest we can ignore set eList to {"Root", "Item", "Items", "Image"} tell application "Adobe InDesign CC 2019" tell docRef repeat with i from 1 to length of tagList set thisName to item i of tagList if thisName is not in eList then if not (exists paragraph style thisName) then set styleRef to make paragraph style with properties {name:thisName} else set styleRef to paragraph style thisName end if set tagRef to XML tag thisName make XML import map with properties {mapped style:styleRef, markup tag:tagRef} end if end repeat end tell end tell end mapTagsToStyles (*Calculates geometric bounds for items within a grid*) on calcGridBounds(x0, y0, celWid, celHgt) set boundsList to {} set firstX to x0 repeat with i from 1 to numRows repeat with j from 1 to numCols set x1 to x0 + celWid set y1 to y0 + celHgt copy {y0, x0, y1, x1} to the end of boundsList set x0 to x1 + gut end repeat set x0 to firstX set y0 to y1 + gap end repeat return boundsList end calcGridBounds
Compile and run the script. If you did not start with a template that defined paragraph styles, this would be a good time to do it. The styles have been created so, for the most part, you just need to define font, size, leading, justification and perhaps hyphenation.
Finally, add any page elements that are needed that do not change between versions of the document.
..Our template is ready to save
Save the document as an InDesign template giving it a descriptive name to indicate its purpose and perhaps any details such as grid or other.
You can make this script even more user friendly by providing a custom dialog for entering grid parameters: rows, columns, gutter, and gap. It may take a little extra time to put a script such as this together but the return on investment of time will grow measurably each time the template is used.
…Our document after adding real XML data
Disclaimer:
Scripts provided are for demonstration and educational purposes. No representation is made as to their accuracy or completeness. Readers are advised to use the code at their own risk.