Automating Adobe InDesign 2019 - AppleScript


Beginning XML

Tuesday, July 30, 2019

XML Basics

There is nothing mysterious about working with XML. The hard part of working with XML is getting contents and structure to work together. This is done using a tagging system similar to working with HTML. XML elements are defined by tags enclosed in angle brackets as in:

<headline>This is a headline </headline>

Because there can be more than one story to a document, you will want to enclose all elements for a story within a story tag.

<story1>
   <headline>This is a headline</headline>
</story1>

All of the XML is then placed within a Root element and identified by a file header:

<!--?xml version="1.0" encoding="UTF-8" standalone="yes"?-->
<root>
<story1>
<headline>Headline Here</headline>
<byline>My Byline</byline>
<body>This is my story</body>
</story1>
</root>

You can put this much into a plain text file and save it with an .xml extension for testing.

Normally when an XMl file is imported into a document, its XML tags are matched with containers in the document having the same XML tag. However, If the XML import consists of nothing more than a story that will populate a single text frame (or single set of threaded text frames) there is no need to tag containers. You can simply import the XML and have a page (or spread) place it using Place XML as in the following example script. You can choose the file you created above to test.

Place XML

(*Assumes import XML preferences are set correctly for the document*)
set filePrompt to "Select XML file for placing"
set fileRef to choose file with prompt filePrompt
tell application "Adobe InDesign CC 2019"
   set measurement unit of script preferences to points
   tell document 1
	set elementRef to import XML from fileRef
   end tell
   set XMLElement to XML element 1 of document 1
   tell page 1 of document 1
	place XML using XMLElement place point {72, 36} with autoflowing
   end tell
end tell 

Take note that the list for place point is opposite than the normal horizontal before vertical list items. Here, the vertical coordinate is placed first.

When this script is run the file is placed but there is no styling applied to the text. To add styling, the XML tags from the import need to be matched with paragraph styles in the document. Below, our script is modified to import paragraph and character styles from a template. Next, the XML tags are mapped to paragraph styles by name to apply styling. If your templates have styles named consistently to match XML tags, you should be able to use any one of your templates for this purpose. If not, when prompted make sure to select a template that defines paragraph styles for "Headline", "Byline" and "Body."

Place XML Map Tags

set filePrompt to "Select XML file for placing"
set temPrompt to "Select template from which to import text styling"
set fileRef to choose file with prompt filePrompt
tell application "Adobe InDesign CC 2019"
	set measurement unit of script preferences to points
	set docRef to document 1
	set appPath to file path as string
	set dLoc to (appPath & "Templates") as alias
	set temRef to choose file with prompt temPrompt default location dLoc
	my importStyles(docRef, temRef)
	tell docRef
	   import XML from fileRef
	end tell
	--tag to paragraph style mapping
	my mapTags (docRef)
	set elementRef to XML element 1 of docRef
	tell page 1 of docRef
	   place XML using elementRef place point {72, 36} with autoflowing
	end tell
end tell

(*Uses XML tag to style to map styles.*)
on mapTags(docRef)
   tell application "Adobe InDesign CC 2019"
	tell docRef
	   set tagList to XML tags
	   repeat with i from 1 to length of tagList
		set tagName to name of item i of tagList
		if (exists paragraph style tagName) then
		   set styleRef to paragraph style tagName
		   make XML import map with properties {mapped style:styleRef, markup tag:item i of tagList}
		end if
	   end repeat
	   map XML tags to styles
	end tell
   end tell
end mapTags

(*Imports styles from stylesheet referenced given boolean values for object, text, and/or table styles*)
on importStyles(docRef, stylesheetRef)
   tell application "Adobe InDesign CC 2019"
	tell docRef
	   import styles format text styles format from stylesheetRef
	end tell
   end tell
end importStyles 

Add Images

The process becomes a little more complex when there is more than one XML element to be imported. For demonstration, our imported XML file needs to have an XML element added for an image.

XML images do not have literal text so there is no text between the beginning and ending tags. Instead the beginning tag includes the URL for the image. This reference can be either an absolute or relative path as in HTML. The more flexible relative reference refers to the image in reference to the location of the XML file.

Use the name of your image file name in place of the name above and add it as a line to your XML text file directly below the element.

<root>
   <photo href="file://Images/Photo1.png"></photo>
   ...
</root>

Because there now is more than one XML element, your InDesign document will need to have a tagged page item for the image as well as the text. These elements will need to be tagged "Photo" and "Story1" respectively.

Tagging

To tag a page item, select it, and open the Tags panel (Window > Utilities > Tags).

Shows menu for opening tag panel...Open tag panel froom Utilities menu

With the page item selected, Click on the hamburger icon (top right in the Tag panel) and select new tag from the menu. Enter the name for the tag and choose a color.

Shows dialog for entering name for tag and selecting color...Enter name and choose color for tag

Add a tag named Photo for the image page item and Story1 for the text page item.

With Show Tagged Frames selected (View > Structure > Hide Tagged Frames) your page should look similar to the screen capture below:

Prepared page showing tagged page items...Page with tagged frames

Save the document as a template in the Templates folder inside InDesign's application folder. Maybe name it "Photo-Story1.indt".

The Image File

For our example, the file for the image, named appropriately ("Photo1.png") needs to be placed in a folder named "Images" inside the same folder as the XML text file.

Now that all the pieces are in place, the following script will:

  • have the user choose a template from the list of templates
  • create the document from the template chosen
  • set up XML import preferences for the document
  • have the user choose the XMl file to place
  • import the XML file chosen
  • map paragraph styles to tags

XML Import With Photo

set filePrompt to "Choose XML File"
set doRepeat to false
try
   set docRef to docFromTemplateChosen()
   --set up xml import preferences
   xmlImportPrefs(docRef, doRepeat)
   set filePath to choose file with prompt filePrompt
   importXMLFile(docRef, filePath)
   mapTags(docRef)
on error errStr
   display alert errStr
end try

(*Sets up xml import preferences for merge import*)
on xmlImportPrefs(doRepeat)
   tell application "Adobe InDesign CC 2019"
	set docRef to document 1
	tell XML import preferences of docRef
	   set create link to XML to false
	   set allow transform to false
	   set import style to merge import
	   set repeat text elements to doRepeat
	   set import to selected to false
	   set ignore whitespace to false
	   set ignore unmatched incoming to false
	   set import CALS tables to false
	   set import text into tables to false
	end tell
   end tell
   return docRef
end xmlImportPrefs

(*User chooses XML file for import; Document imports file*)
on importXMLFile(docRef, fileRef)
   set theInfo to info for fileRef
   if name extension of theInfo is not "xml" then
	error "xml file not chosen"
   end if
   tell application "Adobe InDesign CC 2019"
	tell docRef
	   import XML from fileRef
	end tell
   end tell
end importXMLFile
(*Uses XML tag to style to map styles*)
on mapTags(docRef)
   tell application "Adobe InDesign CC 2019"
	tell docRef
	   set tagList to XML tags
		repeat with i from 1 to length of tagList
		   set tagName to name of item i of tagList
		   if (exists paragraph style tagName) then
		      set styleRef to paragraph style tagName
		      make XML import map with properties ¬
{mapped style:styleRef, markup tag:item i of tagList}
		   end if
		end repeat
	   map XML tags to styles
	end tell
   end tell
end mapTags

(*Presents user list of templates found in Templates folder for application. 
Creates document from template chosen.*)
on docFromTemplateChosen()
   set temPrompt to "Select template from list"
   tell application "Adobe InDesign CC 2019"
	set appPath to file path as string
	set templatePath to appPath & "Templates:"
   end tell
   set templateNames to list folder templatePath without invisibles
   set userChoice to choose from list templateNames ¬
with prompt temPrompt without multiple selections allowed
   if userChoice is not false then
      set fileChoice to item 1 of userChoice
      tell application "Adobe InDesign CC 2019"
	set docRef to open file (templatePath & fileChoice)
      end tell
      return docRef
    else
      error "No file chosen"
    end if
end docFromTemplateChosen

Onward and Upward

Now that you have the basics for creating an XML file for import and preparing the target document, try setting up a more complex document with several images and stories. Should be "a walk in the park."

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.

Trackback Link
http://www.yourscriptdoctor.com/BlogRetrieve.aspx?BlogID=18424&PostID=1529478&A=Trackback
Trackbacks
Post has no trackbacks.

Recent Posts


Tags


Archive