使用命令列腳本從 OmniGraffle 匯出
2018 年 8 月 21 日
時不時我會在 OmniGraffle 中繪製一堆圖表,然後需要將它們全部轉換成可以在網頁中顯示的格式。如果我只有一或兩個,每次執行都可以。但是如果我有十幾個或更多,那麼我發現使用腳本會比較容易。這樣一來,我可以在需要時安全地匯出所有圖表。
幸運的是,Omnigraffle 提供自動化介面,讓我可以透過 AppleScript 與它對話,讓這件事成為可能。它會隨著時間而改變,今天早上我花了好幾個小時才讓它順利運作。因此,我想記下我的筆記,以防其他人也想這麼做。
最終可能會出現更好的方法來執行這項工作。Omni Group 正在建構一個更豐富的自動化環境,可以從 JavaScript 呼叫。在我撰寫這篇文章時,無法從 JavaScript 存取匯出功能,所以我改用 AppleScript 路徑。
我不熟悉 AppleScript,而且在使用時也不太喜歡它。因此,我喜歡將 AppleScript 中的任何程式碼保持在最低限度。我做了例行的 Google 搜尋,拼湊出一個小型腳本,用來匯出目前的前端文件。它假設檔案中只有一個畫布,這適用於我正在處理的檔案。
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
我想對符合特定名稱模式的特定資料夾中的所有檔案執行這項工作。我想要用熟悉的語言處理這大部分的邏輯,而我用 ruby 來執行此類腳本。
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
這段程式碼會查看catalog
的所有子目錄,對於每個包含ggram.graffle
的子目錄,會匯出成類似名稱的png
檔案。它只會在日期顯示需要重新撰寫png
檔案時執行。
你可能會覺得奇怪,我使用命令列呼叫 (system
) 開啟檔案,而不是在 AppleScript 腳本中開啟檔案。我這樣做的原因是,我有時會在 AppleScript 中開啟 OmniGraffle 文件時出現惱人的錯誤 (它說有權限錯誤,但如果我手動或透過命令列開啟,則沒有問題)
重大修訂
2018 年 8 月 21 日:更新為 OmniGraffle 已變更其匯出方法,以使用新的「匯出」動詞(而非使用儲存)
2017 年 10 月 31 日:原始文章