Continuing my love affair with OmniOutliner, this script demonstrates how to generate HTML from an outline for a specific purpose.
The Script Debugger 7 Feature Comparison page on the LNS web site is generated from an OmniOutliner outline using AppleScript. While OmniOutliner provides its own HTML export facilities, the results don’t suite my purpose so I used AppleScript to create the HTML I need. In my outline, each top-level entry represents a separate HTML table within my feature comparison page. The items within each table are indented to follow the structure defined within my outline document.
Here is how my outline appears within OmniOutliner:
And the resulting HTML output looks like this:
As you can see, the resulting HTML follows the structure of my outline document but uses styling that matches my site.
Here is the AppleScript code that accomplishes all of this:
NOTE: MarksLib is needed to compile and run this script.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use MarksLib : script "MarksLib" version "1.0"
property nbspaces : {" ", " ", " ", " ", " ", " ", " ", " ", " "}
property checkedColor : "#d9ecd0"
property uncheckedColor : "#e06377"
-- Begin the HTML output. A list is used to collect the output because its faster than string concatination in AppleScript
set theOutput to {"<html><body>", ¬
"<style>
td.centered {
text-align: center;
}
th {
background-color:black;
color:white;
vertical-align: bottom;
}
th.centered {
text-align: center;
}
td.checked {
background-color:" & checkedColor & ";
text-align: center;
}
td.unchecked {
background-color:" & uncheckedColor & ";
text-align: center;
}
</style>"}
tell application "OmniOutliner"
-- Iterate over the level 1 items (these will become seperate HTML tables)
repeat with aTableTopic in (get children of document 1)
set tableTitle to name of aTableTopic
set tableRows to my collectChildren(aTableTopic)
set end of theOutput to my makeTable(tableTitle, tableRows)
end repeat
end tell
-- Finish the output, and write it to a file on the Desktop
set end of theOutput to "</body></html>"
set theOutput to MarksLib's |join|(theOutput, return)
MarksLib's writeToFile("~/Desktop/SD7FeatureComparison.html", theOutput)
on collectChildren(theChild)
-- Iterate over the children of a node, generating table rows as we go. If a child has children of its
-- own we recur and indent the table rows.
set tableRows to {}
tell application "OmniOutliner"
repeat with aRow in children of theChild
set rowLevel to level of aRow
set rowText to name of aRow
set rowIsInSD6 to (state of cell "6" of aRow) is checked
set rowIsInSD7 to (state of cell "7" of aRow) is checked
set rowIsInSD7Lite to (state of cell "7 Lite" of aRow) is checked
if rowLevel > 2 then ¬
set rowText to MarksLib's |join|(items 1 thru (rowLevel - 2) of my nbspaces, "") & rowText
set end of tableRows to {level:rowLevel, text:rowText, isInSD6:rowIsInSD6, isInSD7:rowIsInSD7, isInSD7Lite:rowIsInSD7Lite}
if (count of children of aRow) > 0 then ¬
set tableRows to tableRows & my collectChildren(aRow)
end repeat
end tell
return tableRows
end collectChildren
on makeTable(tableTitle, tableRows)
-- Generate an HTML table for a list of rows
local theResult
set theResult to {"", "<h2>" & tableTitle & "</h2>", ¬
"<table width=\"100%\"><tr><th>Feature</th><th width=\"40px\" class=\"centered\">7.0</th><th width=\"40px\" class=\"centered\">7.0<br />Lite</th><th width=\"40px\" class=\"centered\">6.0</th></tr>"}
repeat with aRow in tableRows
if isInSD6 of aRow then
set sd6Text to "•"
set sd6Class to "checked"
else
set sd6Text to ""
set sd6Class to "unchecked"
end if
if isInSD7 of aRow then
set sd7Text to "•"
set sd7Class to "checked"
else
set sd7Text to ""
set sd7Class to "unchecked"
end if
if isInSD7Lite of aRow then
set sd7LiteText to "•"
set sd7LiteClass to "checked"
else
set sd7LiteText to ""
set sd7LiteClass to "unchecked"
end if
set end of theResult to "<tr><td>" & text of aRow & "</td><td class=\"" & sd7Class & "\">" & sd7Text & "</td><td class=\"" & sd7LiteClass & "\">" & sd7LiteText & "</td><td class=\"" & sd6Class & "\">" & sd6Text & "</td></tr>"
end repeat
set end of theResult to "</table>"
set end of theResult to ""
-- Convert theResult from a list of strings to a single string and return it
return MarksLib's |join|(theResult, return)
end makeTable
Here’s an excerpt from my OmniOutliner document you can use to test the script:
Script Debugger Feature Comparison Excerpt.zip (5.4 KB)
To use this code, open the excerpt OmniOutliner document in OmniOutliner, and then run the code above. The result will be a file named SD7FeatureComparison.html
located on your desktop.