omniJS – the rudiments of format conversion

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

  1. Copy the whole of the source code, and paste it into Script Editor,
  2. check that the Script Editor language selector (top left) is set to JavaScript
  3. 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
    );
})();