InDesign scripting : bringing it together

this post is a response to a question from Tom :

I am working towards a compilation of scripts to take customer supplied Indd documents – Drop them on applet or automator – Print 1 laser / create 3 PDF files (different settings) / email the low res proof to CSR. … What I picture in my head is getting the email PDF proof script running the way I want – Put it into automator as part of a larger workflow. Then get the other elements as scripts – put those into the same workflow – ??

two things to note straight up — you don’t need separate scripts and you don’t need automator. but this is a great little example because all we need to do is pull together a bunch of script snippets already scattered around this site. as you read through you’ll see highlighted bits that link back to posts with more details.

let’s go … first things first — we want this to be a droplet (so you can drag and drop files onto the app for processing) so the whole script will be wrapped in an on open handler. and you’ll need to wrap it in a repeat loop so it can handle more than one dropped file at a time. and it would be a good idea to alert the user when the script has finished doing its thing. so the initial bits will look something like this :

on open mgItems
  repeat with mgThisItem in mgItems
    -- rest of script here
  end repeat
  display dialog "some kind of confirmation message here"
end open

then we need InDesign to open and process each file. but we should put this in a try block to ensure the script doesn’t crash if a different file type is dropped on it inadvertently :

on open mgItems
  repeat with mgThisItem in mgItems
    tell application id "com.adobe.InDesign"
      try
        open mgThisItem
        tell active document
          -- do printing and pdf stuff in InDesign
        end tell
        close active document
      on error
        -- decide what kind of error handling you want to include if the file won't open
      end try
    end tell
    -- rest of script for email processing here
  end repeat
  display dialog "some kind of confirmation message here"
end open

the observant will notice that the tell application command is different from previous scripts on this site. this is the way to address any version of InDesign — but be aware that other parts of this script may have terms or syntax that may need to be adjusted for your particular version of InDesign.

ok — next comes the printing bit. if you’re using only one print preset for this workflow you’d use a simple line :

print using "name_of_print_preset" without print dialog

but if you need to change the print preset based on the file specs you’d need something more complex like in InDesign scripting : lesson 24.

exporting pdfs is covered in lessons 08, 09, 10, 11, and 12 and cover a few different ways to approach the problem. three basic things need to be determined : the export preset to be used, the name of the pdf and the location to save it to.

the simplest version of this part of the workflow might look like this (but depends on Tom’s specific needs) :

set mgDocName to name of active document
set text item delimiters of AppleScript to " "
set mgShortName to text item 1 of mgDocName
set text item delimiters of AppleScript to ""
set mgHRFilePath to "path:to:highres:folder:" & mgShortName & "_HR.pdf" as string
set properties of PDF export preferences to properties of PDF export preset "HighRes"
tell active document
  export format PDF type to mgHRFilePath without showing options
end tell
set mgHRDigitalFilePath to "path:to:highresdigital:folder:" & mgShortName & "_HRD.pdf" as string
set properties of PDF export preferences to properties of PDF export preset "HighResDigital"
tell active document
  export format PDF type to mgHRDigitalFilePath without showing options
end tell
set mgProofFilePath to "path:to:proof:folder:" & mgShortName & "_proof.pdf" as string
set properties of PDF export preferences to properties of PDF export preset "Proof"
tell active document
  export format PDF type to mgProofFilePath without showing options
end tell

that’s it for the InDesign bits. now to email that third pdf. first get a reference to the file, then create the message — Tom’s using Entourage (thanks to Ben Waldie at MacTech for the Entourage code) :

tell application "Finder"
  set mgFile to mgProofFilePath as alias
end tell
set mgSubject to "proof of job " & mgShortName as string
tell application "Microsoft Entourage"
   set theRecipients to {{address:{display name:"CSR Name", address:"CSR@tomsplace.com"}, recipient type:to recipient}}
   set theMessage to make new outgoing message with properties {recipient:theRecipients, subject:"mgSubject", content:"here's your proof dude", attachments:mgFile}
   send theMessage
end tell

again, this is pretty much the simplest form this part of the workflow could take. Tom will need to expand it to encompass his particular requirements.

the final basic structure could look something like this :

on open mgItems
  repeat with mgThisItem in mgItems

    tell application id "com.adobe.InDesign"
      try
        open mgThisItem
        tell active document
          print using "name_of_print_preset" without print dialog
        end tell
        set mgDocName to name of active document
        set text item delimiters of AppleScript to " "
        set mgShortName to text item 1 of mgDocName
        set text item delimiters of AppleScript to ""
        set mgHRFilePath to "path:to:highres:folder:" & mgShortName & "_HR.pdf" as string
        set properties of PDF export preferences to properties of PDF export preset "HighRes"
        tell active document
          export format PDF type to mgHRFilePath without showing options
        end tell
        set mgHRDigitalFilePath to "path:to:highresdigital:folder:" & mgShortName & "_HRD.pdf" as string
        set properties of PDF export preferences to properties of PDF export preset "HighResDigital"
        tell active document
          export format PDF type to mgHRDigitalFilePath without showing options
        end tell
        set mgProofFilePath to "path:to:proof:folder:" & mgShortName & "_proof.pdf" as string
        set properties of PDF export preferences to properties of PDF export preset "Proof"
        tell active document
          export format PDF type to mgProofFilePath without showing options
        end tell
        close active document
      on error
        -- decide what kind of error handling you want to include if the file won't open
      end try
    end tell

    tell application "Finder"
      set mgFile to mgProofFilePath as alias
    end tell
    set mgSubject to "proof of job " & mgShortName as string
    tell application "Microsoft Entourage"
      set theRecipients to {{address:{display name:"CSR Name", address:"CSR@tomsplace.com"}, recipient type:to recipient}}
      set theMessage to make new outgoing message with properties {recipient:theRecipients, subject:"mgSubject", content:"here's your proof dude", attachments:mgFile}
      send theMessage
    end tell

  end repeat
  display dialog "some kind of confirmation message here"
end open

of course, this isn’t a definitive solution — it’s simply a demonstration of one possible approach to the problem.

once you’re done compiling the perfect script, save it as an app and drag it onto your sidebar so it’s easily accessible — then start dropping those indd files.

macgrunt icon

InDesign scripting : lesson 24

waaay back in lesson 04 we looked at a script to automate printing (and lessons 05 and 06 explained how some of the script elements worked).

well, finally, it’s time to take printing automation to the next level. the original script prompts the user to select a print preset from a list. but that’s too much like hard work. what if the script could automatically decide which preset to use based on the document specs?

apologies to you lovely people in the States — we’re going to be using metric for this example because, well, it is the twenty first century after all and anything referred to as ‘imperial’ should be long dead.

the first part of the script captures a few bits of information from the document preferences. facing pages is boolean, so it returns true or false. page orientation returns landscape or portrait (square pages return portrait too). page height and width return real numbers in whatever measurement unit you’re using :

tell application "Adobe InDesign CS6"
  tell active document
    set mgPgFace to facing pages of document preferences as string
    set mgPgOrnt to page orientation of document preferences as string
    set mgPgHght to page height of document preferences
    set mgPgWdth to page width of document preferences
  end tell
end tell

display dialog (mgPgHght as string) & " : " & (mgPgWdth as string) & " : " & mgPgOrnt & " : " & mgPgFace

so, for a single A4 page the resulting dialog will look something like this :
screen grab of initial dialog

now, if you’re a neat freak (and aren’t we all?) you may prefer your real numbers converted to integers. notice that you can’t coerce a real to an integer as it is captured — the conversion has to be done separately :

tell application "Adobe InDesign CS6"
  tell active document
    set mgPgFace to facing pages of document preferences as string
    set mgPgOrnt to page orientation of document preferences as string
    set mgPgHght to page height of document preferences
    set mgPgWdth to page width of document preferences
    set mgPgHght to mgPgHght as integer
    set mgPgWdth to mgPgWdth as integer
  end tell
end tell

display dialog (mgPgHght as string) & " : " & (mgPgWdth as string) & " : " & mgPgOrnt & " : " & mgPgFace

then you’ll have neat (not necessary, but neat) :
screen grab of revised dialog
…and you can get rid of that display dialog line now — dialogs are a handy way to check your progress when developing a script.

ok, now, the complexity of the next bit is dependant on the complexity of your workflow. the workflow this script was developed for has only eight possible scenarios, roughly like so :
table showing print preset options for various document types

so, all we need to do is find out which of the scenarios our document falls into and select the corresponding print preset (which we’ll capture into the variable mgPrintPreset). let’s start with the two facing pages options (printed as spreads) :

if mgPgFace is "true" then --print document as spreads
  if mgPgHght is greater than 277 or mgPgWdth is greater than 200 then --use A3 fit preset
    set mgPrintPreset to "A3S fit"
  else --use A3 100% preset
    set mgPrintPreset to "A3S 100%"
  end if
else --print document as single pages
  --(scripting bits for single page options go here)
end if

this shows the basic approach to these kinds of problems — if/then/else. if something is true, then do this thing, else (otherwise) do this other thing. we just need to break the problem down into pairs of options.

and we can still use this method for eight different scenarios because if statements can also be nested — ifs within ifs. the full code for dealing with all eight possibilities looks like this :

if mgPgFace is "true" then --print document as spreads
  if mgPgHght is greater than 277 or mgPgWdth is greater than 200 then --use A3 fit preset
    set mgPrintPreset to "A3S fit"
  else --use A3 100% preset
    set mgPrintPreset to "A3S 100%"
  end if
else --print document as single pages
  if mgPgOrnt is "portrait" then --use one of the vertical presets
    if mgPgHght is greater than 277 or mgPgWdth is greater than 200 then --use one of the A3 presets
      if mgPgHght is greater than 400 or mgPgWdth is greater than 277 then --use A3 fit preset
        set mgPrintPreset to "A3V fit"
      else --use A3 100% preset
        set mgPrintPreset to "A3V 100%"
      end if
    else --use A4 vertical preset
      set mgPrintPreset to "A4V"
    end if
  else --use one of the horizontal presets
    if mgPgHght is greater than 200 or mgPgWdth is greater than 277 then --use one of the A3 presets
      if mgPgHght is greater than 277 or mgPgWdth is greater than 400 then --use A3 fit preset
        set mgPrintPreset to "A3H fit"
      else --use A3 100% preset
        set mgPrintPreset to "A3H 100%"
      end if
    else --use A4 horizontal preset
      set mgPrintPreset to "A4H"
    end if
  end if
end if

but it’s easier to understand in a screen grab of the code in script editor :
screen grab of this section of code in script editor

the bits in quotation marks are the names of the InDesign print presets, the green elements are the variables (remember you can name variables anything you like, just as long as it’s not a term reserved by applescript), and the other coloured bits are comments to help us keep track of what we’re doing. comments are preceded by two hyphens and are not actually part of the code — they’re little reminders that are especially helpful when revisiting the script sometime in the future.

the last line of code simply tells the document to print using the selected print preset :

print using (mgPrintPreset as string) without print dialog

cobble all those bits together and the complete script for this workflow looks something like this :
screen grab of complete script in script editor

now, obviously you’re not going to be able to use this one straight out of the box — you’ll have to do a little work to update it to your page sizes and print presets and whatnot to suit your workflow.

but once you’ve set it up you can do all your printing with a double click — rather than cmnd-p, click, choose, click, click …

OR, even better, reassign the cmnd-p shortcut to run your script.

bonza.

macgrunt icon

InDesign scripting : lesson 06

the printing script from lesson 04 and lesson 05 is very simple, but there’s still one more thing to explain about it before we move onto the next script in lesson 07. here’s the printing script again :

Screen grab of Print All Files script

when creating a script to perform a particular task, you need to consider all the possibilities that may arise when the script is run. for example, the script from lesson 03 was written to delete all the guides throughout an entire document. will it still perform this task if the guides are on a locked layer? ; if the guides themselves are locked? ; if the guides are on a master page? (in CS2 at least the answers are : yes ; yes ; and no)

sometimes it’s not a problem if your script doesn’t perform exactly as expected — it simply fails to complete the task and you have to either fix it or live with it. but sometimes it IS a problem because an error can stop a complex process mid-script. sometimes an error can even crash InDesign. sometimes you learn this the hard way.

error handling involves anticipating potential problems and building safeguards into your script. the printing script has error handling in the form of an if/then statement. the script works fine without it, right up until the first time you hit the ‘cancel’ button in the choose from list dialog box — that’s when the script will crash InDesign. why? because the script will go on to ask InDesign to print every document using an undefined printer preset — this is confusing for InDesign, so it gives up and goes berko.

so, we need something in there which will ask InDesign to print ONLY if a printer preset has been selected. the easiest way to do this is to check that the ‘cancel’ button WAS NOT selected. that is, if the ‘cancel’ button was not selected, then the ‘ok’ button MUST have been selected (and the ‘ok’ button cannot be selected until a preset is chosen from the list). make sense?

whenever ‘cancel’ is selected in a dialog box it returns the result ‘false’. so, all we need to do is check that the result of the choose from list dialog box is not false. hence the command : if result is not false then {go on and print those little beauties} end if

ok — now for your homework. what will the script do if the result IS false (the cancel button is selected)? would that behaviour bother you? if so, how could you improve the script?

macgrunt icon

InDesign scripting : lesson 05

let’s revisit a couple of the elements of the script from lesson 04 so you have a better understanding of how they work and how you can integrate them into other scripts. here’s the script again :

Screen grab of Print All Files script

the first thing we’re asking the script to do is place the names of all of InDesign’s current printer presets into a variable which we’ve called mgPresetList. having studied lesson 03 you’ll know that the variable can be called anything you like, as long as it doesn’t clash with standard applescript terminology. mgPresetList is a list of names being generated by InDesign every time the script is run. if printer presets are added or deleted in InDesign, the list will change next time the script is run.

in applescript a list looks like this : {“[Default]”, “A4 landscape”, “A4 portrait”, “A4 landscape (spreads)”, “A3 landscape”, “A3 portrait”, “A3 landscape (spreads)”, “A4 no crops”}. curly braces delineate the start and end of the list, and the elements of the list are contained within double-quotes and separated by commas. if it suited the workflow, we could restrict the list to just the A3 landscape presets by ‘hard-coding’ the list :

set mgPresetList to {"A3 landscape", "A3 landscape (spreads)"}

ok, that’s a quick introduction to lists. we’ll look at other things you can do with lists in future lessons.

next — the choose from list command. this command is an example of a user interface — a way for the script to interact with the user (you) during the running of the script. sometimes user interfaces get input from the user, as in this case. sometimes they merely communicate with the user, as in the display dialog command at the end of the script.

the last part of the choose from list command was explained in lesson 04. let’s look at the first part. the most fundamental example of this command takes the form :

choose from list {SomeList}

our script could have skipped placing the printer preset list into a separate variable like this :

choose from list (name of every printer preset as list)

this is mostly a matter of style. placing data into variables is a good way to keep track of things when you’re starting out. please yourself.

speaking of variables, this is where our second variable comes into play :

set mgPrintPreset to choose from list ...

the mgPrintPreset variable will contain the result of the choose from list command. there are other ways to capture the result of this command, but “set [VariableName] to …” is the easiest.

in the next lesson we’ll look at another important aspect of this script — error handling. so many important elements packed into one simple little script aren’t there?

meanwhile — check out the difference to the second user interface if you delete the second half of the command and just write :

display dialog "ALL DONE!"

macgrunt icon

InDesign scripting : lesson 04

the first scripting lesson – lesson 01 – suggested you save your InDesign applescripts in script file format (.scpt). but there’s a very good reason why you should ignore such nonsensical advice and save them in text file format (.applescript) instead :

Script Editor screen grab. shows saving in text file format

both file formats work equally well from the InDesign scripts panel, but the fact is you cannot search the contents of .scpts through spotlight, but you CAN search through the contents of .applescript files because they are essentially text files. why is searchability important? because when you get more involved in scripting and you have dozens and dozens of scripts and script snippets lying around, it helps to be able to search for that little bit of code that you used somewhere in some kind of script a couple of months ago but can’t quite remember which one.

ok? cool. on with the lesson. here’s a script for just about everyone who uses InDesign. everyone, that is, except those who never need to print an InDesign file. one very cool thing about this script is that it will work for every version of InDesign from CS2 through to CS5.5 (it may even work with earlier versions). usually scripts have to be adapted between versions due to changing syntax rules and whatnot. the only thing you may need to change with this one is your version number in the first line :

Screen grab of Print All Files script

you can get the complete script here — PrintAllFiles

now, having diligently studied the first three lessons, you’ll instantly see that this script has two ‘tell’ blocks. the first addresses the application and the second addresses ‘every document’. between the two ‘tell’ statements we’re capturing some information. (by the way, if you don’t understand why those bits of text are green you should review lesson 03) first, we’re getting a list of all of InDesign’s printer presets. then, we’re using a handy applescript command – ‘choose from list’ – to create a dialog box from which the user can make a selection :

screen grab showing printer preset list

we’ve included two optional parameters with the ‘choose from list command’ – ‘with prompt’ and ‘with title’. you can change those two bits of black text between the quotation marks to whatever takes your fancy. or you can get rid of those optional parameters altogether – see what happens.

the guts of the script is, of course, in the next ‘tell’ block. now, we could have just written :

tell every document
  print
end tell

but that would give us the same result as hitting command-p for every document – no benefit there at all, because we have to click OK for every print dialog window. curiously, the same would happen even if we added the “using (name of printer preset)” bit.

the real magic is in the last part – “without print dialog”. as well as suppressing the usual print dialog, this part of the command also kills the usual ‘missing links’ dialog as well. for the workflow this script was developed for, this is perfect because that bloody dialog is just a pain. ymmv.

you’ll find this script will save time even if you have a single document to print — just two double-clicks and you’re done. but it really kicks arse when you need to print multiple documents using the same preset.

macgrunt icon