InDesign scripting : lesson 32

there’s quite a farcical discussion going on over at the InDesign forum — Is there really no way to export PDFs as separate pages? as is so often the case in these forums, a person asks HOW to do something and then there’s an extended, often heated, discussion about WHY you would/wouldn’t or should/shouldn’t do it that way.

but the argy-bargy is unnecessary because there are some truly legitimate workflows that would benefit from this capability — like the guy at comment 39 — and because exporting each InDesign page as a separate PDF is really easy with Applescript.

today we’ll be looking at a simplified version of the script from lessons 11 and 12. we start by collecting the filename and file path of the active document. then we shorten the filename to exclude the extension — so “this file.indd” becomes “this file” (mgShortName):

tell application id "com.adobe.InDesign"
  set mgFolder to file path of active document
  set mgName to name of active document
  set text item delimiters of AppleScript to {"."}
  set mgShortName to text item 1 of mgName
  set text item delimiters of AppleScript to ""
end tell

next we’ll create a subfolder for the pdfs to be saved into. you do this through the finder by first checking if the subfolder already exists and, if not, creating it. we’re calling this subfolder “the pdfs” and it will be created in the same folder as the indesign file :

tell application "Finder"
  if (exists folder "the pdfs" of folder mgFolder) is false then
    make folder at mgFolder with properties {name:"the pdfs"}
  end if
end tell

then it’s just a matter of a simple repeat loop, cycling through each page in the document. we’re using the page number (name of page) as part of the filename so, using the example above, we’ll end up with “this file_1.pdf”, “this file_2.pdf”, etc. and we complete the script with a simple dialog to let us know when it has done its thing :

tell application id "com.adobe.InDesign"
  repeat with x from 1 to count pages of active document
    set mgPageName to name of page x of active document
    set page range of PDF export preferences to mgPageName
    set mgFilePath to mgFolder & "the pdfs:" & mgShortName & "_" & mgPageName & ".pdf" as string
    tell active document
      export format PDF type to mgFilePath using "macgrunt offset" without showing options
    end tell
  end repeat
  display dialog "ALL DONE!" buttons {"OK"} default button 1 giving up after 2
end tell

notice that when we specify mgFilepath we add a colon to “the pdfs” — this is what designates it as a folder. the full file path might be something like this “Macintosh HD:Users:macgrunt:Documents:the pdfs:this file_1.pdf” — this shows a hierarchy of five folders — everything after that last colon is the name of the file. so, if we didn’t add the colon after “the pdfs” the filename would have been “the pdfsthis file_1.pdf” (hopefully that makes sense).
note also that “macgrunt offset” is the name of the PDF export preset — you would need to substitute your own preset name here.

so that’s the basic functionality for exporting every page as a separate PDF. copy those three sections into a single script in applescript editor and you’re away. there are a bunch of macgrunt lessons showing other PDF export workflows and considerations — just enter “export pdf” up there in the search field.

the next lesson will look at a couple of other, more complex, ways we could approach the naming of these separate page PDFs.

until then, keep grunting.

macgrunt icon

Advertisements

InDesign scripting : lesson 31

in lesson 30 we looked at an applescript to change rows of a particular height to a new height throughout an entire InDesign table. here’s an example of slightly more complex table formatting.

no doubt you would use table and cell styles when setting up your own tables — to assist with formatting changes further down the track. but sometimes you need to work on tables that other, less diligent InDesign users have set up. and if you’re doing that on a regular basis, or if the tables are extensive, it makes sense to automate the tedium.

we’ll look again at the table from the last lesson :
screen grab of table before formatting

in this table, all cells have the same settings :
screen grab of control panel showing table settings

but now we want the reversed row heights to be a little wider and the blank rows to be narrower. first we need to change all the rows to a specific height before working on the other rows. to do this we change the ‘at least’ specifier to ‘exactly’ by changing auto grow to false :

tell application id "com.adobe.InDesign"
  tell active document
    tell table 1 of selection
      set auto grow of every row to false
      set height of every row to 5
      -- rest of script to go here
    end tell
  end tell
end tell

then we can use the cell fill colour to address the reversed rows only :

set height of (every row whose name of fill color is "C=0 M=100 Y=100 K=50") to 6.5

we need to use a different tactic for the blank rows. here’s one way — address every row that comes before a reversed row :

repeat with x in (every row whose name of fill color is "C=0 M=100 Y=100 K=50")
  set mgName to name of x
  try
    set height of row (mgName - 1) to 2
  end try
end repeat

the ‘name’ of a row is its number — so the first row in a table is row 1. that’s why we need the try statement — the first reversed row is row 1 and there is no row 0 to change to a height of 2 — so the script would throw an error without that try.

if we run that script the table will look like this :
screen grab of table after initial script run

the only remaining problem, as the observant will notice, is that there is at least one cell (and probably more) which is now too small and has overset text. an extra line in the script will fix that :

set height of every cell whose overflows is true to 9

the compiled script is short and simple :
screen grab of compiled script

… and the completed table looks like this :
screen grab of completed table

this is just a taster for what can be done with table formatting through applescript. whether or not you end up using scripting with your own tables depends on your workflow, how big your tables are, how often you work with tables, etc, etc. sometimes table are just too small to justify the time it takes to write or edit a script. but table scripting could be another powerful tool in your production arsenal — anything to minimise the monkey-work.

macgrunt icon

InDesign scripting : lesson 30

here’s a little quickie script to help those of you who like to specify exact row heights in your InDesign tables. changing column widths is easy, but changing row heights throughout a table is a pita.

let’s say you want to change all the reversed rows in a table like this, from 9mm high to 6mm high :
screen grab of original table

ordinarily you’d have to select each row, one after another, and set it to the new height manually, but with applescript we can automate it.

first we’ll create a dialog for the user to enter row heights into :

tell application id "com.adobe.InDesign"
  
  set mgDialog to make dialog
  tell mgDialog
    tell (make dialog column)
      tell (make dialog row)
        make static text with properties {static label:"Enter row height you'd like to change."}
      end tell
      tell (make dialog row)
        set mgOldHeightField to make text editbox with properties {edit contents:"current row height", min width:250}
      end tell
      tell (make dialog row)
        make static text with properties {static label:""}
      end tell
      tell (make dialog row)
        make static text with properties {static label:"Enter height you'd like it changed to."}
      end tell
      tell (make dialog row)
        set mgNewHeightField to make text editbox with properties {edit contents:"new row height", min width:250}
      end tell
      tell (make dialog row)
        make static text with properties {static label:""}
      end tell
    end tell
  end tell
  
  set mgResult to show mgDialog

  if mgResult is true then
    set mgOldHeight to edit contents of mgOldHeightField as number
    set mgNewHeight to edit contents of mgNewHeightField as number
    destroy mgDialog
  else
    error number -128
    destroy mgDialog
  end if

  -- rest of script to go here
  
end tell

first the specifications for the dialog are created, then the dialog is displayed to the user, then the results are captured into two variables — mgOldHeight and mgNewHeight. notice these variables are forced into numbers — for obvious reasons — so, if the user enters non-numerical data the script throws an error.

the resulting dialog looks like this :
screen grab of generated dialog

the rest of the script is simple as :

  tell active document
    tell table 1 of selection
      set height of (every row whose height is mgOldHeight) to mgNewHeight
    end tell
  end tell

here you’ll notice we’re addressing “table 1 of selection” which means that, for the script to work in this form, the first text frame containing the table must be selected (as shown in the screen grab above). you can also have all the text frames selected, but if you have nothing selected, or only the second frame selected, you’ll get an error.

that’s it. run the script, fill in your details, and all matching rows throughout the table will be changed almost instantaneously :
screen grab of filled dialog

screen grab of altered table

of course there are other ways to write the script — so that no selection is necessary, or every table in the document is addressed, or whatever — this is just the simplest form for this functionality.

the next scripting lesson will look a bit more at formatting InDesign tables with applescript.

til then, keep grunting.

macgrunt icon

InDesign scripting : lesson 29

the original version of this script was created, like so many scripts, in response to a problem. a necessary third-party export plugin was changing InDesign’s colour settings to a default custom set whenever it was used.

obviously, this is not an ideal situation for a colour-managed workflow and required each user to manually change the settings back every time the plug-in was run. needless to say, sometimes a user forgot to do this.

ordinarily, a script is not going to be of much use in this situation, because the user still needs to remember to run it. but this one takes advantage of yet another handy scripting feature supported by InDesign — the startup script. as you can probably guess, a startup script runs automatically whenever InDesign starts up — not an absolutely perfect solution to this problem, but at least a useful safeguard.

the structure of the script itself is quite simple :

tell application id "com.adobe.InDesign"
  
  set CMS settings of color settings to "macgrunt colour settings"
  
end tell

well, having gone that far, why not also reset a couple of other things, that might be periodically changed during the day, back to your preferred defaults at the start of the next day? this version of the script also resets some display preferences and the workspace :

tell application id "com.adobe.InDesign"
  
  set CMS settings of color settings to "macgrunt colour settings"
  set properties of display settings to {raster:proxy, vector:high resolution, transparency:medium quality}
  
  -----------------------------
  -- thanks to milligramme — adobe forums
  -- http://forums.adobe.com/message/3822734
  do script "app.applyWorkspace('macgrunt');" language javascript
  -----------------------------
  
end tell

that last command is an interesting one. if you look at the scripting dictionary for InDesign, you’ll see there’s an apply workspace command specified for applescript. problem is, it doesn’t work. but, as shown above, it’s possible to call the equivalent javascript using the do script command.

the finished compiled script looks like this :
screen grab of reset settings script

of course, you would need to substitute your own colour settings and workspace names.

well, that’s all very interesting, but how do you make this thing run every time InDesign starts up? rather than the scripts panel folder — just save it using the script file format into this folder :
Applications > Adobe InDesign CS6 > Scripts > startup scripts

what other things could you use a startup script for to help make your day a little easier?

macgrunt icon

InDesign scripting : lesson 28

we’ve already looked a fair bit at how to export pdfs from InDesign using applescript. see lessons 08, 09, 10, 11, and 12 plus InDesign scripting : bringing it together. but these scripts have relied on pdf export presets and, as it turns out, there’s a really good reason NOT to use an export preset when creating a pdf.

presets invariably export a ‘print’ pdf, but these often have tiny white lines criscrossing the screen. this is an unfortunate side effect of transparency flattening and is quite off-putting to clients, who incessantly ask “is it going to print like that?”. but if you export an ‘interactive’ pdf, you don’t get the dreaded white criscrossy lines (strange but true — who knows why?).

now, at this stage, you can’t save interactive pdf settings as export presets. but that don’t matter none — cause we got applescript.

this script is a stripped back version of a much larger one — with additional export options and email generation. this post will focus mainly on the syntax for exporting interactive pdfs — so refer back to the posts listed above if any of the other bits are confusing.

the first part of the script generates a dialog like this :

  set mgDialog to make dialog with properties {name:"How you want this exported then?"}
  tell mgDialog
    tell (make dialog column)
      tell (make border panel)
        tell (make dialog column)
          make static text with properties {static label:"PDF export setting : ", min width:140}
        end tell
        tell (make dialog column)
          set mgResolutionButtons to make radiobutton group
          tell mgResolutionButtons
            make radiobutton control with properties {static label:"72ppi layout", checked state:true}
            make radiobutton control with properties {static label:"96ppi layout", min width:180}
            make radiobutton control with properties {static label:"144ppi layout"}
          end tell
        end tell
      end tell
      tell (make border panel)
        tell (make dialog column)
          make static text with properties {static label:"Document option : ", min width:140}
        end tell
        tell (make dialog column)
          set mgDocumentsButtons to make radiobutton group
          tell mgDocumentsButtons
            make radiobutton control with properties {static label:"active document only", checked state:true}
            make radiobutton control with properties {static label:"all open documents", min width:180}
          end tell
        end tell
      end tell
      
      set mgResult to show mgDialog
      if mgResult is true then
        set mgResolution to selected button of mgResolutionButtons
        set mgDocuments to selected button of mgDocumentsButtons
        destroy mgDialog
      else
        error number -128
      end if
    end tell
  end tell

that gives you a dialog that looks something like this :
screen grab of script dialog

and captures the results into two variables : mgResolution and mgDocuments

it’s important to remember that a radiobutton group returns an integer – starting at 0 – not the label assigned to the selected button. for example, if you select the second option in the top radio button group you will get ‘1’ as the result (not “96ppi layout”)

so, the next thing we need to do is assign variables depending on the choices made in the dialog :

  if mgDocuments is 0 then
    set mgDocList to name of active document as list
  else if mgDocuments is 1 then
    set mgDocList to name of every document
  end if
  if mgResolution is 0 then
    set mgResolution to seventy two ppi
  else if mgResolution is 1 then
    set mgResolution to ninety six ppi
  else if mgResolution is 2 then
    set mgResolution to one hundred forty four ppi
  end if
  
  my mgExportInteractive(mgResolution, mgDocList)

you’ll notice here that when re-specifying the variable mgResolution we don’t use quotation marks (it’s seventy two ppi not “seventy two ppi”). this is because the three options shown above are constants defined by the developers. if you want a different resolution you can use an integer between 72 and 300 (eg. set mgResolution to 200).

that last line passes the two final variables (mgResolution and mgDocList) to the subroutine that does the actual work (mgExportInteractive).

now, it’s not really necessary to use subroutines, but they are a great way to make scripts modular. it makes it easy to cut and paste whole chunks of reusable functionality into a future script (and you WILL do this as you get more and more into scripting).

there are two subroutines in this script, the second one is called from within the first one :

on mgExportInteractive(mgResolution, mgDocList)
  tell application id "com.adobe.InDesign"
    set properties of interactive PDF export preferences to {interactive PDF interactive elements option:include all media, generate thumbnails:true, pdf magnification:fit page, pdf page layout:single page, flip pages:false, PDF JPEG quality:maximum, open in full screen:false, page transition override:from document, PDF raster compression:JPEG compression, include structure:false, page range:all pages, export layers:false, export reader spreads:false, view PDF:false}
    set raster resolution of interactive PDF export preferences to mgResolution
    repeat with i from 1 to (count of mgDocList)
      set active document to (every document whose name is item i of mgDocList)
      my mgProcess()
      tell active document
        export format interactive PDF to mgFilePath without showing options
      end tell
    end repeat
  end tell
end mgExportInteractive

on mgProcess()
  tell application id "com.adobe.InDesign"
    set mgFolder to file path of active document
    set mgDocName to name of active document
    set text item delimiters of AppleScript to {"."}
    set mgDocName to text item 1 of mgDocName
    set text item delimiters of AppleScript to ""
    set mgFilePath to mgFolder & mgDocName & ".pdf" as string
  end tell
end mgProcess

now, if you scroll all the way out to the right, you’ll see an interesting thing. oh, all right, you don’t have to scroll all the way out — I’ll tell you — there’s a piece of code there that says “… export reader spreads:false …”. why is this interesting? because, in CS5 (the version this script was written for), exporting reader spreads in an interactive pdf is the default and there’s no option to change it in the standard export dialog box (this has been rectified by CS6). but you CAN change it through applescript — a rare case of something you can do with applescript which cannot be done with the native program. running a script containing that piece of code will change all future exports as well — so you may want to add another line to your final script to reset it back to the default “true” — it’s up to you.

so, that’s the basic syntax for exporting ‘interactive’ pdfs rather than ‘print’ pdfs. check the dictionary for all the other settings you can adjust through applescript.

to download the complete functioning script, you can go here.

have a good one

macgrunt icon