Here’s a powerful example of app-to-app automation. An outline in OmniOutliner is used as the source material for a set of slides created in OmniGraffle.
Note the use of link-backs so that simply tapping an object on an OmniGraffle slide reveals the source item in the OmniOutliner outline.
Also note that when the outline is updated, the changes can be sent to the OmniGraffle document!
Retrieving Data
The example function (shown below) is designed to extract the properties of every item of the current OmniOutliner outline, and return them as an array of individual JavaScript objects.
function outlineToObjectsArray(){
var array = new Array()
items = rootItem.descendents
for(i = 0; i < items.length; i++){
item = items[i]
obj = new Object()
obj.level = item.level
obj.index = item.index
obj.topic = item.topic
array.push(obj)
}
return array
}
Outline to Objects Array
01
functionoutlineToObjectsArray(){
02
vararray = newArray()
03
items = rootItem.descendents
04
for(i = 0; i < items.length; i++){
05
item = items[i]
06
obj = newObject()
07
obj.level = item.level
08
obj.index = item.index
09
obj.topic = item.topic
10
array.push(obj)
11
}
12
returnarray
13
}
The function uses the OmniOutliner descendents property of the rootItem class to generate an ordered list of every item of the outline. This list is then iterated in order to create an array of JavaScript objects, each of which contains the values of the level, index, and topic properties of the outline item.
The result of function is an array similar in structure to this:
To convert the resulting array of JavaScript objects into a data format suitable for passing from the function to the main script, the returning line of the function (line 12) is changed so that the array is converted into a string by using the stringify() method of the JSON class, and then the resulting string is encoded using the standard JavaScript encodeURIComponent() method. The encoded function result will be decoded in the main script (below: line 23).
Outline to JSON String
12
returnencodeURIComponent(JSON.stringify(array))
Retrieve and Build
Here’s a script that uses Call and Response to create a set of slides in OmniGraffle based upon the contents of the current OmniOutliner document.
var alert = new Alert("Confirmation", "This script will import the topics from the current OmniOutliner document to OmniGraffle as canvas slides.\n\nShould the script continue?")
alert.addOption("Continue")
alert.addOption("Stop")
alert.show(function(result){
if (result == 1){
throw new Error('script cancelled')
} else {
function outlineToObjectsArray(){
var array = new Array()
items = rootItem.descendents
for(i = 0; i < items.length; i++){
item = items[i]
obj = new Object()
obj.level = item.level
obj.index = item.index
obj.topic = item.topic
array.push(obj)
}
return encodeURIComponent(JSON.stringify(array))
}
var scriptURL = URL.tellScript("omnioutliner", outlineToObjectsArray.toString() + '\n' + 'outlineToObjectsArray()')
scriptURL.call(function(reply){
reply = decodeURIComponent(reply)
reply = JSON.parse(reply)
// title and body size and position are based upon current canvas dimensions
var cnvs = document.windows[0].selection.canvas
var cnvsSize = cnvs.size
var cW = cnvsSize.width
var cH = cnvsSize.height
var vM = Math.round(cH/12)
var hM = Math.round(cW/12)
var boxOffset = Math.round(cH/32)
var titleSize = Math.round(cW/14)
var bodySize = Math.round(cW/20)
var lineHeightPercentage = 1.25
var titleBoxRect = new Rect(hM, vM, cW - hM*2, titleSize * lineHeightPercentage)
var bodyBoxRect = new Rect(hM, vM + titleBoxRect.height + boxOffset, cW - hM*2, cH - vM*2 - boxOffset - titleBoxRect.height)
// font family defaults
var titleFontPSName = 'HelveticaNeue-Medium'
var bodyFontPSName = 'HelveticaNeue'
for(i = 0; i < reply.length; i++){
// retrieve item data
obj = reply[i]
objIndex = obj.index
objLevel = obj.level
objTopic = obj.topic
// create new canvas for each top-level item
if (objLevel == 1){
cnvs = addCanvas()
cnvs.size = cnvsSize
cnvs.canvasSizingMode = CanvasSizingMode.Fixed
// create a slide title box
shape = cnvs.addShape('Rectangle',titleBoxRect)
shape.name = 'Slide Title'
shape.textHorizontalPadding = 0
shape.textVerticalPadding = 0
shape.text = objTopic
shape.fontName = titleFontPSName
shape.autosizing = TextAutosizing.Overflow
shape.textHorizontalAlignment = HorizontalTextAlignment.Left
shape.textVerticalPlacement = VerticalTextPlacement.Middle
shape.textSize = titleSize
shape.fillColor = null
shape.shadowColor = null
shape.strokeColor = null
// create a slide body box
shape = cnvs.addShape('Rectangle',bodyBoxRect)
shape.name = 'Slide Body'
shape.textHorizontalPadding = 0
shape.textVerticalPadding = 0
shape.text = ' '
shape.fontName = bodyFontPSName
shape.autosizing = TextAutosizing.Overflow
shape.textHorizontalAlignment = HorizontalTextAlignment.Left
shape.textVerticalPlacement = VerticalTextPlacement.Top
shape.textSize = bodySize
shape.fillColor = null
shape.shadowColor = null
shape.strokeColor = null
} else if (objLevel == 2){
bodyShape = cnvs.graphicWithName('Slide Body')
bodyText = bodyShape.text
if (bodyText == '' || bodyText == ' '){
bodyShape.text = '•' + ' ' + objTopic
} else {
bodyShape.text = bodyText + '\n' + '•' + ' ' + objTopic
}
bodyShape.textSize = bodySize
}
}
})
}
})
varalert = newAlert("Confirmation", "This script will import the topics from the current OmniOutliner document to OmniGraffle as canvas slides.\n\nShould the script continue?")
Here’s a short video demonstrating App-to-App scripting between OmniGraffle and OmniOutliner (macOS). In the shown example, the topics from an OmniOutliner document are used to create slides in the current OmniGraffle document.
TIP: the video shows the use of Omni Automation scripts implemented as actions for the “Presentation Tools” OmniGraffle plug-in. TAP|CLICK to download the plug-in, and TAP|CLICK to download the demo outline.
UNDER CONSTRUCTION
This webpage is in the process of being developed. Any content may change and may not be accurate or complete at this time.