Sunday, June 23, 2013

AppleScript to create a taxonomy chart

Update: 6/29/2013. Rewrote script. Now it places the outline into a hierarchical structure before it draws the tree.

Also, I've posted a script that produces the exact same output, but using a JSON source rather than an outline.

-----

Unlike most flow charts, taxonomy charts have a purely hierarchical structure. This script creates such a chart.

Below is a taxonomy of the genre Rock/Pop (according to the music service Rhapsody) created by this script.


Although it would have been nice (and would have made the scripting much simpler) to have used OmniOutliner to provide the data for this chart, I didn't want to spend the $30 it costs, and I figured most people who use OmniGraffle don't have OmniOutliner. 

Instead, the data is drawn from a file placed on your desktop. By default, this file is called drawtree.txt, but you can change that in the SETTINGS properties at the top of the script.

The text in that file to create the chart above:

o Rock/Pop
oo Roots
ooo Cajun/Zydeco
ooo Tex Mex
ooo Swamp Pop
oo Classic Rock
ooo Adult Oriented Rock
oo Art & Progressive Rock
ooo Rock Opera
ooo New Prog
ooo Krautrock
oo Blues & Boogie Rock
ooo Boogie Rock
ooo Southern Rock
oo Glam
oo Hard Rock
ooo Post-Grunge
ooo Instrumental Guitar Rock
ooo Acid Rock
oo Instrumental Rock
oo Pop
ooo Dance Pop
ooo Teen Beat
ooo Teen Idols
oo Jam Rock
oo Latin Pop
oo Country Rock
oo Funk Rock
oo Metal
ooo Progressive Metal
ooo Thrash/Speed Metal
ooo Stoner Rock
ooo Doom Metal
ooo Pop Metal
ooo New Wave of British Heavy Metal
ooo Black Metal
ooo Death Metal
ooo Funk Metal
ooo Industrial Metal
ooo Christian Metal
ooo Rapcore
ooo Alt Metal
ooo Metalcore
oo Folk-Rock
ooo Political Rock
ooo Celtic Rock
oo Adult Alternative
oo Adult Contemporary
ooo Blue-Eyed Soul
ooo Modern Folk
ooo Lite Rock
ooo Jazz Rock

The hierarchy level of each item is indicated by the length of the string proceeding it. I'm using the letter "o" to create this string; any letter will work. It must be string of letters, however, and not - say - a string of asterisks. (I'm using the AppleScript keyword "word" to grab that first string; only a string of letters is considered a word.) A single "o" is the top level, "oo" is the next level down, etc.

Note: there must be a space between the string of o's and the label following it. Also, children directly follow their parent in this list. If you compare the list above to the chart above, you'll get the gist of it.

There are customizable options at the top of this script. These all start with the prefix "SETTINGS_".

Note that this script doesn't do a whole lot of error checking. If there's a problem with the text (e.g., no space between the string of o's and the label, skipping a hierarchy level, etc.), the script will probably fail. I've tested this on several large charts with no error, so if the script errors out, verify your data.

If you've verified your data and there's still a problem, leave your data in a comment here and I'll investigate.

The script follows the jump. Copy it, paste it into AppleScript Editor, and run it.

Sunday, June 2, 2013

Script to generate a table of contents. Supports long documents.

There are a few great scripts out there that automatically create a table of contents for your OmniGraffle document.

This script does as well, but it will spread the table of contents over multiple pages if necessary, and it will also list section headers if you have canvases within your document that serve as section header pages.

It's also extremely customizable.You can pretty much make it look exactly like you want it to look, and you have precise control over almost every aspect of it by changing the properties listed at the top of the script that start with the prefix "SETTINGS_".

Here is one example of how the table of contents for a document with section headings might look, but again, you can customize it to look any number of ways.


The script currently has these limitations.
  • It does not gracefully support wrapping long canvas names; if a canvas name is so long it wraps, it's not going to look great.
  • Sections (the section header and its child pages) have no way to alter the default widow/orphan control. A section is alway kept together unless its height is greater than the canvas height
If additional table-of-content pages are required due to the document being too long to display the TOC on a single canvas, additional canvases will be created to accommodate additional TOC pages. Note: these will be placed at the front of the document and you will have to move them manually due to a bug in OmniGraffle's AppleScript implementation related to moving canvases. (That bug is explained in a post here.)

The script is after the jump. Copy it and paste it into AppleScript editor and run it.

I'm hoping the comments in the script are sufficient to describe the various customizable options. If you have any questions or find any bugs, or you want any new features, please leave a comment.

Omnigraffle AppleScript bug: moving a canvas removes all shared layers on that canvas

Just so you AppleScripters out there are aware, this bug exists in OmniGraffle's AppleScript implementation as of version 5.4.2.

Moving a canvas through AppleScript to the beginning or end of the canvas list removes all shared layers of the moved canvas, even shared layers that are the last instance of that layer.

For example, the following script will remove all shared layers from the second canvas when it is moved to the front of the document.

-- warning: running this script will remove shared layers
tell application id "OGfl"
    tell document of front window
        set c to item 2 of canvases
        move c to beginning of canvases
    end tell
end tell

Also, if any of the shared layers is the last instance of that shared layer, you won't be able to get it back (other than using Undo).

The folks at Omni Group have added this to their bug database.