Finding Outline Items

It is common for scripts to perform their automation tasks by first locating a set of objects that meet a specified set of criteria, and then process the found items. This page contains examples and techniques of how to locate items in an outline document.

The apply(…) instance method of the Item class is very useful for locating items whose properties match specified criteria. The following example functions use this method to locate specific items.

The Item.ApplyResult Class

By default, the apply() method when used with the rootItem object, will iterate every item of the outline, processing each item with the processing code you provide. Optionally, you can use the properties of the Item.ApplyResult class to indicate if an iterated item should be ignored, or if the iteration process should stop.

rootItem.apply(function(item){ // process each item })
var thisIsTheOne = null rootItem.apply(function(item){ // stop the iteration process when a match is found if (item.topic.startsWith(stringToMatch)){ thisIsTheOne = item return Item.ApplyResult.Stop } }) if (thisIsTheOne){//process the matched item}
rootItem.apply(function(item){ // do not process if condition met if (item.topic.startsWith(stringToMatch)){ return Item.ApplyResult.Skip } else { // process the item } })

Using the apply() function to process every item in the outline document:

 02  Process each item individually

Using the apply() function to locate and process a specific item:

 01  The variable thisIsTheOne will be used to store the reference to the matched item. It is assigned an initial value of: null

 04-07  A conditional to determine if the item is the one to use. In this example, the topic text is examined for a match.

 05  Store the item reference in the variable

 06  Return Item.ApplyResult.Stop to halt further execution of the apply() method.

 09  Process the matched item.

Using the apply() function to process all items except those whose top-level ancestor matches specific requirements:

 03-07  A conditional to determine if the item is to be processed or skipped. In this example, the contents of the topic text are analyzed.

 04  Return Item.ApplyResult.Skip to not process this item’s descendent tree, but continue the apply() method with other items.

Finding by Identifier

For example, here is a function that returns an object reference to the outline item whose identifier matches the one passed into the function. The result will be null if no matching item is located.

function itemWithID(itemID){ var matchedItem = null rootItem.apply(function(item){ if (item.identifier == itemID){ matchedItem = item console.log(matchedItem.topic) return Item.ApplyResult.Stop } }) return matchedItem }

NOTE: although the previous example is a valid use of the apply() method, for this example, locating an item by ID is better accomplished using the the itemWithIdentifier() method of the Outline class:

item = document.outline.itemWithIdentifier(itemID)

The following function uses the itemWithIdentifier() method of the Outline class to select the item whose ID matches the provided ID string. Note that the reveal(…) function is called before using the select(…) function to ensure that the targeted item is visible before selecting it.

function selectItemWithID(itemID){ item = document.outline.itemWithIdentifier(itemID) if (item != null){ editor = document.editors[0] node = editor.nodeForItem(item) editor.reveal([node]) editor.select([node]) } }

Finding Items by Topic Contents

Locating items based upon their topics (text contents) is a common technique.

Here’s a function, incorporating the apply() method, that returns an object reference to the first item whose text matches the provided string:

function firstItemWhoseTopicMatchesString(str){ var matchedItem = null rootItem.apply(function(item){ if (item.topic == str){ matchedItem = item return Item.ApplyResult.Stop } }) return matchedItem }

A version of the function that returns an array of object references to all items whose topic matches the provided string:

function everyItemWhoseTopicMatchesString(str){ var matchedItems = new Array() rootItem.apply(function(item){ if (item.topic == str){ matchedItems.push(item) } }) return matchedItems }

Another search example that returns an object reference to the first item whose text begins with the indicated text:

function firstItemWhoseTopicBeginsWithString(str){ var matchedItem = null rootItem.apply(function(item){ if (item.topic.startsWith(str)){ matchedItem = item return Item.ApplyResult.Stop } }) return matchedItem }

A function for returning an array of object references to every item whose topic begins with the provided string:

function everyItemWhoseTopicBeginsWithString(str){ var matchedItems = new Array() rootItem.apply(function(item){ if (item.topic.startsWith(str)){ matchedItems.push(item) } }) return matchedItems }

Another search example that returns an object reference to the first item whose text ends with the indicated text:

function firstItemWhoseTopicEndsWithString(str){ var matchedItem = null rootItem.apply(function(item){ if (item.topic.endsWith(str)){ matchedItem = item return Item.ApplyResult.Stop } }) return matchedItem }

A function for returning an array of object references to every item whose topic ends with the provided string:

function everyItemWhoseTopicEndsWithString(str){ var matchedItems = new Array() rootItem.apply(function(item){ if (item.topic.startsWith(str)){ matchedItems.push(item) } }) return matchedItems }

A search example that returns an object reference to the first item whose text includes the indicated text. Notes the includes() method is case sensitive.

function firstItemWhoseTopicIncludesString(str){ var matchedItem = null rootItem.apply(function(item){ if (item.topic.includes(str)){ matchedItem = item return Item.ApplyResult.Stop } }) return matchedItem }

A function for returning an array of object references to every item whose topic includes the provided string:

function everyItemWhoseTopicIncludesString(str){ var matchedItems = new Array() rootItem.apply(function(item){ if (item.topic.includes(str)){ matchedItems.push(item) } }) return matchedItems }

Finding Items by State

Another common search is based upon the state of the item, or the status of it’s checkbox column. This is accomplished by scanning the nodes of the Editor’s rootNode object, since the visible state of items may not match the settings shown in the document window.

The result of the following routine is an array of outline items (rows) whose state matches the value provided as input to the handler.

function everyItemWhoseStateMatchesValue(stateValue){ var matchedItems = new Array() mainNode = document.editors[0].rootNode mainNode.apply(function(node){ nodeState = node.valueForColumn(document.outline.statusColumn) if (node != mainNode && nodeState == stateValue){ matchedItems.push(node.object) } }) return matchedItems }

And here is how the previous function could be called:

And here's a variation of the previous function for identifying items by state, that use the JavaScript filter() method:

function itemsByState(stateValue){ var editor = document.editors[0], status = document.outline.statusColumn; return rootItem.descendants.filter(function(row){ return editor.nodeForItem(row).valueForColumn(status) === stateValue; }) } itemsByState(State.Mixed)

Finding Items by Column Cell Value

Here’s an example script that will apply a named style to the row whose cell of a specified column has a value meeting certain requirements, in this case whose numeric value is greater than 100. Note that depending on the applied column format the cell’s value may be Text or Decimal:

var nStyles = document.outline.namedStyles var nStyle = nStyles.byName('Highlight 3') var targetColumn = columns.byTitle('STATS') var targetValue = 100 rootItem.apply(function(item){ var value = item.valueForColumn(targetColumn) if (value && value instanceof Text){ if (Number(textObj.string) > targetValue){ item.style.setStyle(nStyle) } } else if (value && value instanceof Decimal){ var compVal = Decimal.fromString(targetValue.toString()) if (value.compare(compVal) > 0){ item.style.setStyle(nStyle) } } })

Finding Items by Notes

Nulla vitae elit libero, a pharetra augue. Vestibulum id ligula porta felis euismod semper. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Maecenas sed diam eget risus varius blandit sit amet non magna. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Aenean lacinia bibendum nulla sed consectetur. Donec ullamcorper nulla non metus auctor fringilla.

function everyItemWhoseNoteIncludesString(str){ var matchedItems = new Array() rootItem.apply(function(item){ if (item.note.includes(str)){ matchedItems.push(item) } }) return matchedItems }
function everyItemWhoseNoteIsEmpty(){ var matchedItems = new Array() rootItem.apply(function(item){ if (item.note == ''){ matchedItems.push(item) } }) return matchedItems }
function everyItemWhoseNoteIsNotEmpty(){ var matchedItems = new Array() rootItem.apply(function(item){ if (item.note != ''){ matchedItems.push(item) } }) return matchedItems }
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.

DISCLAIMER