Add Studio Log to My Yahoo

More AppleScript and OmniOutliner: OmniOutliner as a Script Analysis and Management Tool

By: Jesse Shanks

Analyzing and managing programming code is a tough task in the best of circumstances. This article explores using OmniOutliner as a script analysis and management tool and, through xtensibility with adding AppleScripts to the Scripts Menu, using OmniOutliner as a script editor.

Outlining has always been an important part of using a computer, both as an application and as a component of applications. Utilizing well-developed outlining tools can help promote organization and output in line with some of the basic structures of hierarchial computer "thinking." Dave Winer of Userland Software wrote about the history of outliners on, "Outlining as a user interface, survives to this day. The expanding and collapsing file system viewer first appeared in Macintosh System 7, and now has become a common feature of all file system browsers. Word processors, presentation programs, script editors, project planners, personal information managers, all have outliners built into them now." Mac Net Journal has a page that describes some of the outliners available for Mac OS X.

My own introduction to outlining for programming came with my efforts to learn Userland's Frontier back in 1997. It was an interesting slant on writing AppleScripts with Frontier's outlining tools providing a different view of the structure of scripts. For me personally, it harkened back to the travails of symbolic logic in college. I suppose it is totally geeky to get a thrill when collapsing a complex outline into its parent rows and then expanding them into their layers of information. An application that I have been exploring lately is OmniOutliner from The Omni Group. I have occasionally used Microsoft Word's outline view or Powerpoint to prototype threaded ideas, but have never been satisfied with them as "real" outliners.

Working with the various features of OmniOutliner, I have found that it can be an excellent tool for many different tasks. One simple use is to quickly makes lists of steps to accomplish a task. I did some work on expanding some XML parsing scripts into generating outlines from XML source. The results of one such script is my The Life of Henry the Fifth by William Shakespeare outline. This puts the entire play into an outline format with each scene nested under its act and within each scene each characters speech is nested under his name. Using OminOutliner's tools, I can quickly work through various areas of the play and add notes and other analysis for the purpose of eventually creating a paper.

I was working with some tab-delimited documents, both text and RTF, and opening them as outlines. I used BBEdit's format command to turn some HTML in a consistent heirarchial format and opened that in OmniOutliner to get a very useful view of the structure of HTML documents. As I saved an AppleScript that wouldn't compile as text, in order to go over the code later and look for the mistake, I had a "gee whiz" moment and remembered that Script Editor saves it files with tabs to format the script.

Upon opening script text in OmniOutliner, the outline that appears is very useful in looking at the structure of code blocks and would certainly be familiar stylistically to anyone who has used Frontier or the outliner in their recent web log publishing tool, Radio. OmniOutliner has many tools for manipulating data stored in an outline. The "Sort" command re-orders the outline by columns. The "Hoist" command can be used to raise any block to the root level of the outline temporarily. Just this ability alone allows some level of usefulness in using OmniOutliner as a script analysis tool.

A scripter also has the option of selecting the text in a Script Editor window (with the compiled syntax colors) and pasting it into a TextEdit document. Then, when the file is saved with the syntax colored and the tabs preserved, that RTF file can be opened in OmniOutliner and a hierarchial outline of the script is displayed with full syntax coloration. Code blocks can be hoisted, expanded and collapsed at will.

Some advantages of viewing scripts (and other outlines) in OminOutliner include:

The capability of saving the script as:

Plain text with tabs
Plain text with fixed width
Plain Text (MORE 3.1)

Cocoa Spell checking of strings as you type (oh, how useful).
Extended Find and Replace.
Unlimited Undo.
Notes can be attached to any row in the script.
Availability of Services Menu.

Multiple columns can be added to provided more data or information about each row. The columns can contain different data types including Checkboxes, Dates, Durations, Numbers, Popup Lists. Below is an example of a script opened in OmniOutliner with columns for Date, a popup of Programmer Names and a Duration column. Two of the lines have notes attached, one of which is displayed in the Notes Window at the bottom. A Parent Row with calculated dates shows the most recent date of its children. A Parent row with calculated Popups shows the highest item on its list of its children. A Parent Row with calculated duration shows the total of the amounts entered into its children. So, in this fictional example, the collapsed code block would show the most recent date a code block was worked on, the highest level programmer to work on it and how long it has been worked on in total. When expanded, each of the children would show who worked on it, when and how long.

Alternate rows can have a background color for readability and other colors can be used for columns to mark off elements.

Outlines can be converted to Stationery Pad documents by checking "Stationery Pad" in the Get Info box in the Finder.

Once the script is in OmniOutliner, AppleScript can be used to send the script code to other processing such copied to the clipboard, written to a text file, send to BBEdit or compiled using the 'osacompile' shell command. The following script is heavily indebted to the OmniOutliner2OPML script written by Tim Jarrett of Jarrett House North. At this time, this script will only work on outlines that have no extra columns, but is being improved.

-- Check if a document is open
tell application "OmniOutliner" to set theOutlines to (count of documents)

if theOutlines is 0 then
display dialog "There are no documents open." with icon stop
end if
-- Get the top level rows
tell application "OmniOutliner"
set theDoc to document 1
set theRows to (every child of theDoc)
set theTitle to name of front document
end tell

if (count of theRows) is 0 then
display dialog "This document contains no code." with icon stop
end if

set theScriptCode to ""

-- Get the text from the rows
tell application "OmniOutliner"
repeat with currentRow in theRows
set theRowText to my rowText(currentRow)
set theScriptCode to theScriptCode & theRowText
end repeat
end tell

-- For this example, put the script code in a BBEdit document
-- Could be written to a file, put on clipboard or compiled
tell application "BBEdit 6.5"
make new document
set name of window 1 to "Contents of: " & theTitle
set contents of window 1 to theScriptCode
end tell

on rowText(theRow)
tell application "OmniOutliner"
set theCells to cells of theRow
repeat with theCurrentCell in theCells
set theCellText to (get text of theCurrentCell)
set thisRowText to theCellText & return
-- get child rows If those exist
set bSubTopics to (get has subtopics of theRow)
if bSubTopics then
set theChildren to my getChildData(theRow)
set thisRowText to thisRowText & theChildren
end if
end repeat
end tell
return thisRowText
end rowText

on getChildData(theRow)
set theChildren to ""
tell application "OmniOutliner"
set theRowC to (the children of theRow)
repeat with thisChild in theRowC
set theChildElement to my rowText(thisChild)
set theChildren to theChildren & theChildElement
end repeat
end tell
return theChildren
end getChildData

There are many enhancements that could be added to this script like the addition of notes as comments, the use of other columns to enhance the output and more. With the ability to export the outlined code as compilable text, we now have OmniOutliner into a well-featured script editor. The extensibility of the program through adding script to the Scripts Menu can only add to these capabilities.

Another aspect of using OmniOutliner which will bear further investigation is the opening of outlined scripts in OmniGraffle. I have opened a few and the results are quite interesting. The following was done quickly and did not spring fully layed-out from the outline. It is mostly the default styles for the shapes and I had to do quite a bit of shuffling to get it into something that resembled the structure of the script. But, still could be useful documentation purposes in a project and one AppleScript task I have on my list is to create a script that reformats an outline into something that would produce the visual appearance I want in OmniGraffle.

The possibilities of using OmniOutliner as a management and analysis tool, especially using AppleScript to extend its features and link it with other programs, seems literally endless. Rather than using one mega-application that has poorly implemented features, one can create a suite of multiple applications working together each doing its own job excellently.

May 18, 2002


Applescript Language Guide
Applescript Language Guide; English Dialect