Using a command line script to export from Omnigraffle

31 October 2017

From time to time I draw a bunch of diagrams in Omnigraffle, and then need to convert them all to a format I can show in a web page. If I only have one or two, then doing it each time works ok. But if I have a dozen or more, then I find it easier to have a script. That way I can safely export them all whenever I need to.

Fortunately Omnigraffle makes this possible by providing an automation interface which allows me to talk to it via AppleScript. It does change over the years, and needed a couple of hours fiddling to get it to work this morning. So I thought I'd jot down my notes in case anyone else wants to do it.

Soon there may be a better way to do this. The Omni Group is putting together a richer automation environment that will be callable from JavaScript. As I write this I wasn't sure if I could access the export functionality from it, so I relied on the AppleScript route instead.

I'm not familiar with AppleScript, and didn't like it much when I have played with it. So I like to keep any code in Applescript to a minimum. I did the usual googling around and cobbled together a small script that opens a single file and does the export. It assumes there's only one canvas in the file, which is true for files I'm working with.

omni2png.scpt…

  on convertGraffleFile(graffleFile, outputFile)
     tell application "OmniGraffle"
          set area type of current export settings to all graphics
          open graffleFile
          tell front document to save in file outputFile
          close front document
      end tell
  end convertGraffleFile
  
  on run argv
     convertGraffleFile(item 1 of argv, item 2 of argv)
  end run

I want to do all this to all files in a certain folder that match a certain name pattern. Much of this logic I want to have in a familiar language, and ruby is what I use for such scripting.

omni.rb…

  module Omni
    def self.convert_ggram folder
      input = folder + "ggram.graffle"
      return unless input.exist?
      output = folder + "ggram.png"
      return if FileUtils::uptodate?(output.to_s, [input.to_s])
      call_conversion(macpath(input), macpath(output))    
    end
  
    def self.call_conversion input, output
      system "osascript lib/omni2png.scpt #{input} #{output}"
    end
  
    def self.convert_all_ggrams
      Pathname('catalog').children
        .select {|p| p.directory?}
        .each {|p| convert_ggram p }
    end
  
    def self.macpath arg
      return arg.expand_path.to_s.tr("/", ":")[1..-1]
    end
  end

This code looks at all child directories of catalog, for each one that contains a ggram.graffle exports into a similarly named png file. It only does it if the dates indicate that the png file needs to be rewritten.


Share:
if you found this article useful, please share it. I appreciate the feedback and encouragement

For articles on similar topics…

…take a look at the tag: tools