The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniGraffle General (http://forums.omnigroup.com/forumdisplay.php?f=10)
-   -   'unattended' export / file conversion? (http://forums.omnigroup.com/showthread.php?t=106)

af3556 2006-04-12 06:18 PM

'unattended' export / file conversion?
 
Hello,

I find OmniGraffle very easy to use and certainly my preferred vector drawing editor. However for one of my acitvities I need to publish lots of small diagrams in a more standard (web-friendly) format (GIF/PNG, maybe PDF or SVG). It is a pain to have to 'make a change, select export, complete the export dialog, repeat". I'd love to set up an automator workflow or similar (even a launchd supervised shell script watching a directory full of graffle files) that would automatically generate a corresponding GIF/PNG/whatever every time it saw a change in the source graffle file. i.e. the workflow becomes: 'make a change, Save, wait a few seconds'.

Alas, I can't find any such functionality in the current OmniGraffle - am I asking too much?

Thanks,
Ben

Greg Titus 2006-04-13 06:03 AM

[QUOTE=af3556]Alas, I can't find any such functionality in the current OmniGraffle - am I asking too much?[/QUOTE]

Hi Ben,

This isn't available built-in to OmniGraffle itself, but it is possible to do it via Graffle's AppleScript support. In fact, it made for a nice little scripting project last night. Just paste the following into Script Editor, and follow the instructions.

[CODE]
-- Here is an AppleScript that will watch a folder for changes to Graffle files and automatically convert them to another format. Before use you should:
-- 1. Change the properties at the beginning to match the behavior you would like as far as where to watch and what type to export as.
-- 2. Towards the bottom there is a "here is where you set the export settings" section where you can do the AppleScript equivalent of setting various controls on Graffle's export panel. You may want to change the export settings here. See Graffle's AppleScript dictionary for details on the setting names, and et cetera.
-- 3. Finally, you may also need to change the application name from "OmniGraffle Professional" to just "OmniGraffle" in process_item if you have the standard version instead of pro.
-- Then just run the script. It will keep running forever until you manually stop it. You could set it up as a startup item if desired.

-- a file extension which Graffle supports for export
property new_extension : "png"
-- the folder to watch
property watch_folder : "Macintosh HD:Users:toon:Desktop"
-- the subfolder inside the watch folder where the exported documents should go
property export_foldername : "Images"
-- amount of time to wait in between checking for file changes
property seconds_between_checks : 30

tell application "Finder"
-- set up the watch folder and create the export folder inside
tell application "Finder"
set watch_folder to watch_folder as alias
if not (exists folder export_foldername of watch_folder) then
make new folder at watch_folder with properties {name:export_foldername}
end if
set the export_folder to (folder export_foldername of watch_folder) as alias
end tell

-- repeat forever
repeat
-- get all the graffle files in the watch folder
set fileList to files of watch_folder whose kind is "OmniGraffle document"
repeat with aFile in fileList
-- figure out what the new exported name would be
set new_name to my rename(aFile, new_extension)
set the target_path to (((export_folder as string) & new_name) as string)

-- if there isn't an export file or if the graffle file is newer, do the export
if (not (exists document file new_name of export_folder)) or modification date of aFile > modification date of document file new_name of export_folder then
my process_item(aFile as alias, new_name, export_folder)
end if
end repeat

-- wait before we look again
delay seconds_between_checks
end repeat
end tell

-- this sub-routine just comes up with the new name
on rename(this_item, new_extension)
tell application "Finder"
set the file_name to the name of this_item
set file_extension to the name extension of this_item
if the file_extension is "" then
set the trimmed_name to the file_name
else
set the trimmed_name to text 1 thru -((length of file_extension) + 2) of the file_name
end if
set target_name to (the trimmed_name & "." & new_extension) as string
end tell
return the target_name
end rename

-- this sub-routine does the export
on process_item(source_file, new_name, results_folder)
set the source_item to the POSIX path of the source_file
set the target_path to (((results_folder as string) & new_name) as string)
with timeout of 900 seconds
tell application "OmniGraffle Professional"
-- save the current export settings so we can replace them later
set oldAreaType to area type of current export settings
set oldBorder to include border of current export settings

-- here is where you set the export settings you want
set area type of current export settings to all graphics
set include border of current export settings to true

-- open the file if it isn't already open
set needToOpen to (count (documents whose path is source_item)) is 0
if needToOpen then
open source_file
end if

-- do the export
set docsWithPath to documents whose path is source_item
set theDoc to first item of docsWithPath
save theDoc in file target_path

-- if the file wasn't already open, close it again
if needToOpen then
close theDoc
end if

-- put the original export settings back
set area type of current export settings to oldAreaType
set include border of current export settings to oldBorder
end tell
end timeout
end process_item
[/CODE]

af3556 2006-04-15 04:35 AM

[edited to replace my "v0.1" semi-broken hackery of Greg's script]

Woohoo! Thanks Greg!

This just about does the trick.

I modified the script to a 'droplet', which remembers lists of files and folders to watch and exports the new versions alongside the graffle files (e.g. foo.graffle -> foo.graffle.png). I just drag the graffle files I want auto-exported to this script app, and start the script after I start OG. If OG isn't running when the script is launched, it will 'batch update' any watched files/folders and then exit.

[AS rant: I've got years of experience in C, Perl, and other assorted languages, yet AppleScript is just so damned opaque to me.... I wanted to test if OG had any open, modified docs, but I could only get the expression "count (document's modified)" to work - my old English teacher would crucify me :-) I also found weirdness with AppleScript's handling of the quit statement (see comments in the code below), and it took me ages of fiddling to figure out the difference between the alias and 'object' (Finder?) file reference types... I can say for sure Greg that without your script to work from I would've given up in dismay]


BTW, I played with calling the script via a Folder Action ('items added'), and via launchd (WatchPaths), and found that in both these cases the script will only be called for *new* files, not modifications to existing files. Presumably OG opens and overwrites the same file when saving, rt. creating a new one and unlinking the old, and thus neither launchd's WatchPaths nor the Folder Action pick up the change (as the file modification doesn't change the containing directory). Pity, as this would be a neat way of on-demand launching the script.


Thanks very much for the script! (Omni got a sale out of it - I had OG 3.2, which didn't support the export applescript function, and this was the last straw for me to upgrade :-)

Thanks,
Ben

[CODE]
-- Watch and auto-export OmniGraffle files to web-friendly versions
-- files/folders to watch are to be dropped onto this script (saved as a Stay Open application)
-- if a folder is watched all OG files in the folder will be monitored
-- exported files are created alongside the originals, named with the new_extension
-- based on / hacked from the original from Greg Titus (http://forums.omnigroup.com/showthread.php?p=537)

-- a file extension which Graffle supports for export
property new_extension : "png"

-- amount of time to wait in between checking for file changes
property seconds_between_checks : 15

-- evidently there are two kinds of file references in AS: a Finder file reference, and an alias
-- apparently aliases are "more useful"
-- list of 'aliases' (folders, files) to watch (added to via 'on open')
property watch_files : {}
property watch_folders : {}

on run
set t to "OmniGraffle Auto-Exporter" & return & ¬
"Drop files/folders to be monitored on this script and they'll be automatically exported to " & new_extension & ¬
" versions." & return & return & ¬
"This script will stay open whilst OmniGraffle is running." & return
set t to t & "Currently monitoring " & (count watch_files) & " file(s) and " & (count watch_folders) & " folder(s). "
if (count watch_files) > 0 or (count watch_folders) > 0 then
set r to button returned of (display dialog t & "Keep these?" buttons {"Yes", "No", "Show"} default button "Yes" with icon note)
if r is "Show" then
tell application "Finder"
activate
reveal {watch_files, watch_folders} -- one hit, so they're all selected
end tell
end if
if r is "No" then
set watch_files to {}
set watch_folders to {}
end if
else
display dialog t buttons {"Ok"} with icon note
end if
end run

on open item_list
tell application "Finder"

repeat with this_item in item_list
-- need to be careful of the list operations on watch_files, watch_folders - make sure only to add aliases
-- e.g. 'copy this_item to end of watch_files' corrupts the list on the second iteration, whereas
-- 'copy (this_item as alias) to end of watch_files' works fine
-- think you can find documentation on this? hah! (the Wikipedia AppleScript page was the
-- only reference I found that actually stated that 'on open' returns a list of aliases!)

if kind of this_item is "OmniGraffle document" then
if this_item is not in watch_files then copy (this_item as alias) to end of watch_files
else if kind of this_item is "folder" then
if this_item is not in watch_folders then copy (this_item as alias) to end of watch_folders
end if

end repeat

(*
set s to ""
set s to s & "files: (" & (count of watch_files) & "): " & return
repeat with i in watch_files
set s to s & " [" & (i as string) & "]" & return
end repeat
set s to s & "folders: (" & (count of watch_folders) & "): " & return
repeat with i in watch_folders
set s to s & " [" & (i as string) & "]" & return
end repeat
display dialog s
*)

end tell
end open

on idle

-- if omnigraffle's not already running, close it after exporting the new files
tell application "System Events"
set isRunning to (name of processes) contains "OmniGraffle Professional"
end tell

tell application "Finder"
-- gather list of files to update
set file_list to watch_files
repeat with this_folder in watch_folders
-- display dialog "processing " & (this_folder as string) & "|" & class of this_folder
-- 'files of' ... returns 'class docf' (file?) objects, not aliases
set folder_files to (files of this_folder whose kind is "OmniGraffle document")
repeat with this_file in folder_files
set this_file to (this_file as alias)
--display dialog "f: " & this_file & "|" & class of this_file
if this_file is not in file_list then copy this_file to end of file_list
--beep 1
end repeat
end repeat
(*
set s to ""
set s to s & "file_list: (" & (count of file_list) & "): " & return
repeat with i in file_list
set s to s & " [" & (i as string) & "]" & return
end repeat
display dialog s
*)

-- ok, now have list of candidate OG files

set processed_items to false
repeat with this_file in file_list

-- figure out what the new exported name would be
set new_name to (this_file as string) & "." & new_extension

-- if there isn't an export file or if the graffle file is newer, do the export
if (not (exists document file new_name)) or modification date of this_file > modification date of document file new_name then
my process_item(this_file, new_name)
set processed_items to true
end if

end repeat -- file_list

end tell

if isRunning then
-- wait before we look again
return seconds_between_checks
else
if processed_items then -- will have started up OG, so close it
tell application "OmniGraffle Professional"
-- close the app (if there are no open files, which there shouldn't be, as OG wasn't running before we started it)
--display dialog "ndocs: " & (count (document's modified))
if (count (document's modified)) is 0 then
quit
end if
end tell
end if
quit -- me too
-- it seems the 'quit' statement merely sends a Quit event/signal to the script/app,
-- and further this signal isn't processed until after the handler returns and the idle time expires
-- reduce the idle time to some small, non-0 value to minimise the delay before exiting (0 = no change)
return 0.1
end if

end idle


-- this sub-routine does the export
on process_item(source_file, exported_file)
set the source_item to the POSIX path of the source_file

with timeout of 900 seconds
tell application "OmniGraffle Professional"
-- if the file's being actively edited, a random object may be selected when we come to
-- do the export, and with an object selected the export will default to 'selected graphics' - oops!
-- sooo, override the 'default' (and return it later)
set oldAreaType to area type of current export settings
set area type of current export settings to all graphics

-- open the file if it isn't already open
set needToOpen to (count (documents whose path is source_item)) is 0
if needToOpen then
open source_file
end if

-- do the export
set docsWithPath to documents whose path is source_item
set theDoc to first item of docsWithPath
save theDoc in file exported_file

-- if the file wasn't already open, close it again
if needToOpen then
close theDoc
end if

set area type of current export settings to oldAreaType
end tell
end timeout
end process_item
[/CODE]

af3556 2006-04-18 09:24 PM

The latest, latest, version.

Oh, and it now is meant to run continuously, and will slow down the polling interval when OG isn't running, and when no changes are detected (i.e. you're off doing something else).

[CODE]
-- Watch and auto-export OmniGraffle files to web-friendly versions
-- files/folders to watch are to be dropped onto this script (saved as a Stay Open application)
-- if a folder is watched all OG files in the folder will be monitored
-- exported files are created alongside the originals, named with the export_format extension
-- multiple-canvas documents are exported as per the 'Entire Document' (subdirectory named after the OG file)
-- based on / hacked from the original from Greg Titus (http://forums.omnigroup.com/showthread.php?p=537)
-- Changelog:
-- 2006-04-19 BDL added multiple canvases
-- 2006-04-21 BDL removed per-canvas exporting (window flipping is too intrusive), replaced
-- with export area = entire document; much mucking about with 'save in file'/folder business

-- a file extension which Graffle supports for export
property export_format : "png"

-- amount of time to wait in between checking for file changes
-- this is adaptive, and is reset to 10s when a change is detected and will ramp up to 300s
property idle_time : 10
property idle_time_min : 10
property idle_time_max : 300
property idle_time_inc : 5

-- evidently there are two kinds of file references in AS: a Finder file reference, and an alias
-- apparently aliases are "more useful"
-- list of 'aliases' (folders, files) to watch (added to via 'on open')
property watch_files : {}
property watch_folders : {}

on run
set t to "OmniGraffle Auto-Exporter" & return & ¬
"Drop files/folders to be monitored on this script and they'll be automatically exported to " & export_format & ¬
" versions." & return & return & ¬
"This script will stay open whilst OmniGraffle is running." & return
set t to t & "Currently monitoring " & (count watch_files) & " file(s) and " & (count watch_folders) & " folder(s). "
if (count watch_files) > 0 or (count watch_folders) > 0 then
set r to button returned of (display dialog t & "Keep these?" buttons {"Yes", "No", "Show"} default button "Yes" with icon note)
if r is "Show" then
tell application "Finder"
activate
reveal {watch_files, watch_folders} -- one hit, so they're all selected
end tell
end if
if r is "No" then
set watch_files to {}
set watch_folders to {}
end if
else
display dialog t buttons {"Ok"} with icon note
end if
end run

on open item_list

tell application "Finder"

repeat with this_item in item_list
-- need to be careful of the list operations on watch_files, watch_folders - make sure only to add aliases
-- e.g. 'copy this_item to end of watch_files' corrupts the list on the second iteration, whereas
-- 'copy (this_item as alias) to end of watch_files' works fine
-- think you can find documentation on this? hah! (the Wikipedia AppleScript page was the
-- only reference I found that actually stated that 'on open' returns a list of aliases!)

if kind of this_item is "OmniGraffle document" then
if this_item is not in watch_files then copy (this_item as alias) to end of watch_files
else if kind of this_item is "folder" then
if this_item is not in watch_folders then copy (this_item as alias) to end of watch_folders
end if

end repeat

(*
set s to ""
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to {return & tab}
set s to s & "files: (" & (count of watch_files) & "): " & return
set s to s & tab & (watch_files as string) & return
set s to s & "folders: (" & (count of watch_folders) & "): " & return
set s to s & tab & (watch_folders as string) & return
display dialog s
set AppleScript's text item delimiters to tid
*)

end tell
end open

on idle

-- if omnigraffle's not already running, close it after exporting the new files
tell application "System Events"
set isRunning to (name of processes) contains "OmniGraffle Professional"
end tell

tell application "Finder"
-- gather list of files to update
set file_list to watch_files
repeat with this_folder in watch_folders
-- display dialog "processing " & (this_folder as string) & "|" & class of this_folder
-- 'files of' ... returns 'class docf' (file?) objects, not aliases
set folder_files to (files of this_folder whose kind is "OmniGraffle document")
repeat with this_file in folder_files
set this_file to (this_file as alias)
--display dialog "f: " & this_file & "|" & class of this_file
if this_file is not in file_list then copy this_file to end of file_list
end repeat
end repeat

(*
set s to ""
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to {return & tab}
set s to s & "file_list: (" & (count of file_list) & "): " & return
set s to s & tab & (file_list as string) & return
display dialog s
set AppleScript's text item delimiters to tid
*)

end tell

-- ok, now have list of candidate OG files
set processed_items to false
repeat with this_file in file_list
set processed_items to my process_item(this_file, export_format)
end repeat


if not isRunning and processed_items then -- will have started up OG, so close it
tell application "OmniGraffle Professional"
-- close the app (if there are no open files, which there shouldn't be, as OG wasn't running before we started it)
--display dialog "ndocs: " & (count (document's modified))
if (count (document's modified)) is 0 then
quit
end if
end tell
end if

-- if files are being changed drop back to a fast idle time, otherwise decay
if processed_items then
set idle_time to idle_time_min
else
set idle_time to idle_time + idle_time_inc
if idle_time > idle_time_max then
set idle_time to idle_time_max
end if
end if

return idle_time

end idle

on process_item(source_file, export_format)

set processed_items to false

-- file extension must be added to the destination filename, and must match the export
-- type (i.e. 'save doc as "png" in file "figure.graffle.png"')
-- Note when saving a multi-page document, the destination filename will have the
-- export type extension removed, but *will not* have the .graffle extension removed. The
-- result will be created as the directory to hold the exported canvas files.
-- e.g. if destination = figure.graffle.png => OG will try to create figure.graffle/, but will fail as
-- this is the name of the source file!
-- OG strips the .graffle extension for the directory name automatically via the GUI, but not via AS
-- simple solution: double up the extension (figure.graffle.png.png => figure.graffle.png/...) when saving

-- don't double up yet, as we want to test the directory's modification time
set new_name to (source_file as string) & "." & export_format


-- test if the target (new_name) needs to be updated
tell application "Finder"
-- combining the test (exists AND mod date) fails when destination doesn't exist
-- why does AS execute the second statement when the first is false?
-- worse, why did that logic work earlier? (ref. Omni forum's original)

-- if doesn't exist, need to update
set need_update to not (exists item new_name)

if not need_update then -- exists, but is it stale?
-- display dialog "target mod date: " & (modification date of item new_name)
set need_update to modification date of source_file > modification date of item new_name
end if
end tell

if need_update then
my export_item(source_file, new_name, export_format)
set processed_items to true
end if

return processed_items

end process_item



-- this sub-routine does the export
on export_item(source_file, new_name, export_format)

-- if there isn't an export file or if the graffle file is newer, do the export
with timeout of 900 seconds
tell application "OmniGraffle Professional"
-- if the file's being actively edited, a random object may be selected when we come to
-- do the export, and with an object selected the export will default to 'selected graphics' - oops!
-- sooo, we will explicitly set the area type (and return it later)
set oldAreaType to area type of current export settings


-- open the file if it isn't already open
-- 1. convert the source_file alias to a POSIX path ("/path/to/file.graffle")
-- - OG's 'document path' property is a POSIX path
-- 2. see if a file with that path is currently open
-- 3. if not, open it
-- 4. get a reference to the document object
set the source_item to the POSIX path of the source_file
set needToOpen to (count (documents whose path is source_item)) is 0
if needToOpen then
open source_file
end if
-- you'd think open would return the document you just opened, no?
set theDocument to first item of (documents whose path is source_item)

-- single or multipage?
if (count of canvases of theDocument) = 1 then
set area type of current export settings to all graphics
else
set area type of current export settings to entire document
-- double up target directory name
set new_name to new_name & "." & export_format
end if

save theDocument as export_format in file new_name

-- if the file wasn't already open, close it again
if needToOpen then
close theDocument
end if

set area type of current export settings to oldAreaType
end tell
end timeout

end export_item
[/CODE]

stevef 2006-04-19 09:38 PM

Exporting Individual (Selected) Objects
 
Hi,
I have also been working on an export script, but with a little different flavor. I use OG 4 to draw a bunch of buttons/icons in one canvas.
Then, in the "Note" for each object I want to export I put the
text "ExportTo[filename]"

Anyway, this seems to work, and as it wasn't very obvious to me (an intermittent Applescripter at best) I post it here in case its useful:
(ps. if anyone has a simple way to do regular expressions in Applescript
on the note contents would be nice to simplify into
filename = first group of match regex "exportTo[.*?]" on string this_note
or something like that!

[CODE]tell application "OmniGraffle Professional"
set myWindow to front window
set myDoc to document of myWindow
set export_folder to (choose folder with prompt "Pick the folder to export icons to process") as string

set exportType to "PNG"
set exportFileExtension to "png"

--copy current export settings to mySettings but I cant restore...
set allProps to properties of current export settings

set include border of current export settings to false
set copy linked images of current export settings to false
set area type of current export settings to selected graphics

tell front document

activate

repeat with i from 1 to number of items in every canvas
set this_canvas to item i of every canvas
set canvas of myWindow to this_canvas
tell canvas i
set allGraphics to (every graphic whose notes contains "ExportTo[")
repeat with i from 1 to number of items in allGraphics
set this_item to item i of allGraphics
set this_note to notes of this_item
set this_userData to user data of this_item
set this_tag to tag of this_item

-- Check if regex ExportTo[xxxx] exists in the note
-- and set file name to export to that name
set startIndex to offset of "ExportTo[" in this_note
set subString to texts from (startIndex + 9) to length of this_note
set endIndex to offset of "]" in subString
set fileName to texts 1 thru (endIndex - 1) of subString
set selection of myWindow to {this_item}
set exportFileName to export_folder & fileName & "." & exportFileExtension
save myDoc as exportType in exportFileName
end repeat

end tell
end repeat
end tell

end tell


[/CODE]

af3556 2006-05-17 05:32 AM

New version - handles package files
 
The previous version of the script did not handle package files. There were two problems:[LIST][*] a package is basically a folder (trailing ":" or "/"), so exported files were created as file.graffle/.png, and [*] OG 4.1.2 has a "bug" in that its 'documents whose path ...' strips the trailing "/", which confuses the find-the-document-we-just-opened logic. I just loooove Applescript.[/LIST]
I've had to strip some comments to keep under the 10,000 character limit. Does Omni have a better place to contribute AS code to?

[CODE]
-- Watch and auto-export OmniGraffle files to web-friendly versions
-- files/folders to watch are to be dropped onto this script (saved as a Stay Open application)
-- if a folder is watched all OG files in the folder will be monitored
-- exported files are created alongside the originals, named with the export_format extension
-- multiple-canvas documents are exported as per the 'Entire Document' (subdirectory named after the OG file)
-- based on / hacked from the original from Greg Titus (http://forums.omnigroup.com/showthread.php?p=537)
-- Changelog:
-- 2006-04-19 BDL added multiple canvases
-- 2006-04-21 BDL removed per-canvas exporting (window flipping is too intrusive), replaced
-- with export area = entire document; much mucking about with 'save in file'/folder business
-- 2006-05-17 BDL added "support" for OG package files


-- a file extension which Graffle supports for export
property export_format : "png"

-- amount of time to wait in between checking for file changes
-- this is adaptive, and is reset to 10s when a change is detected and will ramp up to 300s
property idle_time : 10
property idle_time_min : 10
property idle_time_max : 300
property idle_time_inc : 5

-- list of 'aliases' (folders, files) to watch (added to via 'on open')
property watch_files : {}
property watch_folders : {}

on run
set t to "OmniGraffle Auto-Exporter" & return & ¬
"Drop files/folders to be monitored on this script and they'll be automatically exported to " & export_format & ¬
" versions." & return & return & ¬
"This script will stay open whilst OmniGraffle is running." & return
set t to t & "Currently monitoring " & (count watch_files) & " file(s) and " & (count watch_folders) & " folder(s). "
if (count watch_files) > 0 or (count watch_folders) > 0 then
set r to button returned of (display dialog t & "Keep these?" buttons {"Yes", "No", "Show"} default button "Yes" with icon note)
if r is "Show" then
tell application "Finder"
activate
reveal {watch_files, watch_folders} -- one hit, so they're all selected
end tell
end if
if r is "No" then
set watch_files to {}
set watch_folders to {}
end if
else
display dialog t buttons {"Ok"} with icon note
end if
end run

on open item_list

tell application "Finder"

repeat with this_item in item_list

-- need to be careful of the list operations on watch_files, watch_folders - make sure only to add aliases
-- e.g. 'copy this_item to end of watch_files' corrupts the list on the second iteration, whereas
-- 'copy (this_item as alias) to end of watch_files' works fine
-- think you can find documentation on this? hah! (the Wikipedia AppleScript page was the
-- only reference I found that actually stated that 'on open' returns a list of aliases!)

if kind of this_item is "OmniGraffle document" then
if this_item is not in watch_files then copy (this_item as alias) to end of watch_files
else if kind of this_item is "folder" then
if this_item is not in watch_folders then copy (this_item as alias) to end of watch_folders
end if

end repeat

end tell
end open

on idle

-- if omnigraffle's not already running, close it after exporting the new files
tell application "System Events"
set isRunning to (name of processes) contains "OmniGraffle Professional"
end tell

tell application "Finder"
-- gather list of files to update
set file_list to watch_files
repeat with this_folder in watch_folders
-- display dialog "processing " & (this_folder as string) & "|" & class of this_folder
-- 'files of' ... returns 'class docf' (file?) objects, not aliases
set folder_files to (files of this_folder whose kind is "OmniGraffle document")
repeat with this_file in folder_files
set this_file to (this_file as alias)
--display dialog "f: " & this_file & "|" & class of this_file
if this_file is not in file_list then copy this_file to end of file_list
end repeat
end repeat

end tell

-- ok, now have list of candidate OG files (aliases)
set processed_items to false
repeat with this_file in file_list
set processed_items to my process_item(this_file, export_format)
end repeat


if not isRunning and processed_items then -- will have started up OG, so close it
tell application "OmniGraffle Professional"
-- close the app (if there are no open files, which there shouldn't be, as OG wasn't running before we started it)
--display dialog "ndocs: " & (count (document's modified))
if (count (document's modified)) is 0 then
quit
end if
end tell
end if

-- if files are being changed drop back to a fast idle time, otherwise decay
if processed_items then
set idle_time to idle_time_min
else
set idle_time to idle_time + idle_time_inc
if idle_time > idle_time_max then
set idle_time to idle_time_max
end if
end if

return idle_time

end idle

on process_item(source_file, export_format)

set processed_items to false

-- file extension must be added to the destination filename, and must match the export
-- type (i.e. 'save doc as "png" in file "figure.graffle.png"')
-- Note when saving a multi-page document, the destination filename will have the
-- export type extension removed, but *will not* have the .graffle extension removed. The
-- result will be created as the directory to hold the exported canvas files.
-- e.g. if destination = figure.graffle.png => OG will try to create figure.graffle/, but will fail as
-- this is the name of the source file!
-- OG strips the .graffle extension for the directory name automatically via the GUI, but not via AS
-- simple solution: double up the extension (figure.graffle.png.png => figure.graffle.png/...) when saving
-- (see export_item())

-- ok, now to really complicate matters: some OG files are folders (packages) i.e. file.graffle may
-- actually be ":path:to:file.graffle:"
-- - this stuffs up the export naming, so need to chomp any trailing path separators for package files
-- note that there's no point trying to do chomp the alias, as AS will gleefully put back the ":"

if package folder of (info for source_file) is true then
-- package, chomp trailing ':'
set new_name to (characters 1 through -2 of (source_file as string)) as string
set new_name to new_name & "." & export_format
else
-- plain file
set new_name to (source_file as string) & "." & export_format
end if

-- test if the target (new_name) needs to be updated
tell application "Finder"
-- if doesn't exist, need to update
set need_update to not (exists item new_name)

if not need_update then -- exists, but is it stale?
--display dialog "target mod date: " & (modification date of item new_name)
set need_update to modification date of source_file > modification date of item new_name
end if
end tell

if need_update then
my export_item(source_file, new_name, export_format)
set processed_items to true
end if

return processed_items

end process_item



-- this sub-routine does the export
on export_item(source_file, new_name, export_format)

with timeout of 900 seconds
tell application "OmniGraffle Professional"
set oldAreaType to area type of current export settings

-- open the file if it isn't already open
-- 1. convert the source_file alias to a POSIX path ("/path/to/file.graffle")
-- - OG's 'document path' property is a POSIX path
-- 2. see if a file with that path is currently open
-- 3. if not, open it
-- 4. get a reference to the document object
set the source_item to the POSIX path of the source_file

-- OG 4.1.2 returns 'path of...' WITHOUT the trailing slash for package files, need to
-- chomp before we compare ('documents whose path is ...')
if (package folder of (info for source_file) is true) and (character -1 of source_item is "/") then
-- package, chomp trailing '/'
set source_item to (characters 1 through -2 of source_item) as string
end if

set needToOpen to (count (documents whose path is source_item)) is 0
if needToOpen then
open source_file
end if

set theDocument to first item of (documents whose path is source_item)

-- single or multipage?
if (count of canvases of theDocument) = 1 then
set area type of current export settings to all graphics
else
set area type of current export settings to entire document
-- double up target directory name
set new_name to new_name & "." & export_format
end if

save theDocument as export_format in file new_name

-- if the file wasn't already open, close it again
if needToOpen then
close theDocument
end if

set area type of current export settings to oldAreaType
end tell
end timeout

end export_item
[/CODE]


All times are GMT -8. The time now is 04:01 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.