POWER WITH PURPOSE

An overpowering reason for using scripts to automate working with XML comes from the wide variety of methods that can be used for importing as well as placing the XML. Much depends on the type of document you will be working with. How InDesign works with images depends largely on the type of document being created.

With InDesign there are two distinct types of documents created with XML:

  • autoflow document – page layout is based on a master page that includes a Primary Text Frame. Pages are created automatically to accommodate a single story that flows between the pages’ text frames associated with the Primary Text Frame. With this type of document, images are attached to the text flow using text or text frame anchors.
  • paginated document – pages may have unique layouts. A Primary Text Frame is not used and pages are defined by the document. XML content for the pages can be controlled in a number of ways. With this type of document, images do not need to be anchored to text or text frames. We will cover an example of the paginated document in a later blog post. For now, we will concentrate on the autoflow document.

WORKING WITH AUTOFLOW

In our previous blog post, the XML text was flowed into the document’s most recent story (story -1). This worked simply because there was no other story in the document at the time the XML was placed. Of course, if the user adds other story elements to the document prior to placing the XML, this will break the script. To prevent this, the container for the story needs to be defined by its name or id. What is interesting is the fact that the parent story of the Primary Text Frame (on the master page) is different from the parent story of the Primary Text Frame on a page of the document. Be sure to use the text frame on the document’s page (not the master page) when giving the frame a name. (Use our handy NameIt script or provide a name for the reference to the frame in the Layers panel.)

With the frame named, a script can use the following code for placing the XML.

   --inside tell block to the application
   tell document 1
      set frameRef to text frame "masterFrame"
      set storyRef to parent story of frameRef
      set rootElement to XML element 1
   end tell
   tell rootElement to place XML using storyRef with autoflow

If running the script does not produce multiple pages in the document to accommodate the text, you need to make sure smart text reflow is set to true and add pages of text preferences is set to end of document. This can be done programmatically by adding the following to your script:

   --inside tell statement to the document
   set properties of text preferences to {smart text reflow:true, add pages: end of document, limit to master text frames:true}

If this is a setting you want for the majority of your documents, you can set this in the Text Preferences panel for InDesign (Application menu > Preferences > Type).

If the placed text is not styled as a result of running your script, you will want to add XML tag to style mapping in your script (see March 23 blog post). Alternatively, you can map tags to styles manually in InDesign’s Tags panel (Window > Utilities > Tags). 

ADDING IMAGES

In adding XML tags to text, remember that the text is enclosed within a beginning and an ending XML tag.

<text>Actual text for the element goes here.</text>

The tag for an image is a little different as there is no text to place between the tags. Instead of text, the image tag defines the file location of the image as an attribute within the beginning tag.

Attributes are “metadata” that can be associated with an XML element. An attribute has a name and a value. The value is placed inside quotes following the name and an equal sign. An XML element can have any number of XML attributes, but each attribute name must be unique within the element. You cannot have two attributes named “id”, for instance.

The attribute for an image file is named href. This value can be either a fixed or a relative path to where the image is found (its URL locator). For the most part, your scripts will be using a relative locator which is relative to the location of the XML file. If the image and the XML file are in the same folder, the reference would be written similar to:

<image href="file:///filename.jpg"></image>

More often you will want your images to be located in a separate folder, with the folder at the same level as the XML file. In this instance, you precede the image filename with the name of the folder and a slash:

<image href="file:///images/filename.jpg"></image>

You can also use a shorthand method for writing a relative XML reference to a file:

<image href="file:///images/filename.jpg"/>

PREPARE DOCUMENT

If the XML for the document includes images, and you want to use autoflow, there is a little more work that needs to be done to make sure images import and place with the text as needed. The trick is in how the the document is created.

How much of the process you may want to automate will determine the extent of your script. We include some code to get you started.

  1. Start with a document that includes a Primary Text Frame
    1. Import XML tags from the XML file
      Select Load tags from InDesign’s Tags panel context menu
      or use the following code as part of a script that automates the process
tell application "Adobe InDesign CC 2015"
   set docRef to document 1
   my loadXMLTags(docRef)
end tell
on loadXMLTags(docRef)
   set fileRef to choose file with prompt ("Select XML file for placing")
   set fileInfo to info for fileRef
   if name extension of fileInfo is not "XML" then
      error ("wrong file type chosen")
   end if
   tell application "Adobe InDesign CC 2015"
      tell docRef
	load XML tags from fileRef
      end tell
   end tell
end loadXMLTags
  1. Import text styles from a template or style sheet as needed
  2. Resize the Primary Text Frame in the Master A Spread to accommodate the text
  3. Create placeholder text inside the Primary Text Frame on the first page for the text flow and Style using paragraph styles
  4. Associate XML tags to text that has been styled
    It is best to do this within the Story Editor (Command+Y with text highlighted). You do not want to include paragraph returns inside the tags as shown below:
    1. or
      use the following code as part of a script that automates the process
(*Associates styled text with XML tags, names the Primary Text Frame and
creates tag to paragraph style import map.
assumes Primary Text Frame on first page of document is selected and
placeholder text is created using the name of the associated paragraph style and
tags exist in document that match the name of the paragraph style*)
tell application "Adobe InDesign CC 2015"
   set docRef to document 1
   set frameRef to item 1 of selection
      tell frameRef
         set name to "page"
	 set paraCount to count of paragraphs
	 repeat with i from paraCount to 1 by -1
            set paraRef to object reference of paragraph i
	    set styleName to name of applied paragraph style of paraRef
            set styleRef to paragraph style styleName of docRef
	    set tagRef to XML tag styleName of docRef
	    tell parentElement
		set elementRef to make XML element with properties {markup tag:tagRef}
	    end tell
	    set textRef to object reference of text from character 1 to character -2 of paraRef
	    tell elementRef
		markup using textRef
	    end tell
	    tell docRef
		make XML import map with properties {mapped style:styleRef, markup tag:tagRef}
	    end tell
	 end repeat
      end tell --frameRef
   end tell
  1. If you do not use the script, you will need to name the text frame for reference. We used the same name as its associated tag (“page”) for our example.
  2. On the same page as the Primary Text Frame (page 1), create an image container for the image
  3. Anchor the image to the text frame or text as needed by dragging the small box (upper right corner of the container) to the text frame.
    Our sample anchors the image to the frame. For this, care must be taken to select the frame and not the text.
  4. Create an object style for the anchored frame (this could be imported from a template or style sheet). Associate the anchored frame to the “image” tag.

Once you have completed the steps your document should look similar to the following:

You might want to save the document at this point. To place the XML on the document, the following code can be used. The script assumes that you have named the Primary Text Frame on page 1 (“page”).

Place XML_TextFrame

This script uses the named text frame on page 1 (Primary Text Frame) to place the XML from an XML file chosen by the user. This is the same XML file used for importing XML tags in Step 2 of the Prepare Document process above.

   set frameName to "page" --change this value if the frame is named differently
   try
	set fileRef to getXMLFile()
	tell application "Adobe InDesign CC 2015"
	   set docRef to document 1
	   my setImportPrefs(docRef)
	   tell docRef
		import XML from fileRef
		set rootElement to XML element 1
		set elementRef to XML element 1 of rootElement
		set frameRef to text frame frameName
		set storyRef to parent story of frameRef
	   end tell
	   tell frameRef
		place XML using elementRef with autoflowing
	   end tell
	   tell docRef to map XML tags to styles
	end tell
   on error errStr
	activate
	display alert errStr
   end try
   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 false 
		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
   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 

ON YOUR OWN

Code provided in this blog post is cut down to the bare minimum using hard-coded values instead of dialogs for user input, It assumes names of styles and tags to be associated (mapped) are the same.Very little is done as far as error checking. The fine points we will leave up to the user. What we have provided here is just an introduction to what can be done with XML. 

Our final document

Our little demo is only a few pages long which gives little advantage for using a script. Consider, on the other hand, a document having many pages. In our next blog we will look at using XML to create an eight-up business card layout that could be used for any number of entries.

Check out our AppleScript page for resources you can use to make your own masterpiece. Our sample document has been posted as a Publish Online document at https://indd.adobe.com/view/05f652ba-6925-4ac2-ad3f-1046ee902173