Here is a simple (no-frills) example of deriving a textual outline (tab-indented text) from an OmniOutliner outline, using the ‘omniJS’ or ‘Omni Automation’ JSContext included in current builds of OO 5.3 Pro.
Works with: OO 5.3 test (v189.2 r305308)
To test on macOS
- Copy the whole of the source code, and paste it into Script Editor,
- check that the Script Editor language selector (top left) is set to JavaScript
- check that an outline is open in OO, and run.
The tab-indented version will be placed in the clipboard, and displayed in Script Editor.
(() => {
const ooJSContext = () => {
// replicateString :: Int -> String -> String
const replicateString = (n, s) =>
''.concat.apply('', Array.from({
length: n
}, () => s));
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
// TAB-INDENTED TEXT VIA FOLDTREEOO ----------------------------------
// foldTreeOO :: (OOItem -> [b] -> b) -> OOItem -> b
const foldTreeOO = f => ooItem => {
const go = node => f(node, node.children.map(go));
return go(ooItem);
};
// tabIndented :: OOItem -> [String] -> String
const tabIndented = (item, xs) => unlines([
replicateString(item.level - 1, '\t') + item.topic,
...xs
]);
// MAIN -------------------------------------------------------------
return unlines(
document.outline.rootItem.children
.map(foldTreeOO(tabIndented))
);
};
// JXA JSCONTEXT ---------------------------------------------------------
ObjC.import('AppKit');
// String copied to general pasteboard
// copyText :: String -> IO Bool
const copyText = s => {
const pb = $.NSPasteboard.generalPasteboard;
return (
pb.clearContents,
pb.setStringForType(
$(s),
$.NSPasteboardTypeString
)
);
};
const strClip = Application('OmniOutliner')
.evaluateJavascript(
'(' + ooJSContext + ')()'
);
return (
copyText(strClip),
strClip
);
})();