Using a command line script to export from OmniGraffle
21 August 2018
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.
Eventually 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 there is no access to the export functionality from JavaScript, so I relied on the AppleScript route instead.
I'm not familiar with AppleScript, and didn't like it much when I have used 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 exports the current front document. It assumes there's only one canvas in the file, which is true for files I'm working with.
omni2png.scpt…
on convertGraffleFile(outputFile)
tell application "OmniGraffle"
export front document scope "all graphics" as "SVG" to file outputFile
close front document
end tell
end convertGraffleFile
on run argv
convertGraffleFile(item 1 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_file folder, name
input = folder + (name + ".graffle")
return unless input.exist?
output = folder + (name + ".svg")
return if FileUtils::uptodate?(output.to_s, [input.to_s])
system "open #{input}"
call_conversion(macpath(output))
end
def self.convert_rgram folder
convert_file folder, "rgram2"
end
def self.call_conversion output
cmd = "osascript lib/omni2png.scpt #{output}"
result = system cmd
puts "error processing #{output}" unless result
end
def self.convert_all_rgrams
Pathname('catalog').children
.select {|p| p.directory?}
.each {|p| convert_rgram 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.
You might find it odd that I open the file using a command line call
(system) rather opening the file within the AppleScript script.
The reason I do that is that sometimes I get irritating errors opening an
OmniGraffle document from within AppleScript (it says there's a permission
error, but has no trouble if I open it manually or by the command line)
Significant Revisions
21 August 2018: Updated as OmniGraffle changed its export approach to use the new “export” verb (instead of using save)
31 October 2017: Original post

