Perhaps worth also creating such actions for 1Writer ? 1Writer is well designed, and a good plain text match for OmniOutliner. It also has a JS API which overlaps with that of Drafts.

I wasn’t quite sure why the omniJS component of examples was shown in a urlEncoded form ?

It seems a pity not to take advantage of the JS interpreters in 1Writer and Drafts, and show the JS code in legible form:

a bit less daunting,

an immediately clearer sense of what the code will do. (I was taken by surprise, for example, when I ran the tab-indented text to OO outline action (“Tabbed-Paragraphs to Outline”), and my OO document unexpectedly closed. Had the code been en clair, I would have spotted that and expected it,

and, more generally, much easier for users to read and adjust the code

But perhaps there is something I am missing here ?

( PS re the tab-indent to outline action – a possible complexity in Drafts 5 is that the distributed Indent action defaults to four spaces rather than tabs, so there could be some confusion when a user’s indents are not detected by the script )

The document.close() was added to work-around a drawing issue where the outline document does not show the changes until it is refreshed by closing and re-opening. When the bug has been addressed, I’ll update the posted action.

With regard to your suggestion to display the Omni Automation code as JavaScript vs. a script URL:

I see advantages/disadvantages to both the “clear” and “encapsulated” approaches and have chosen to pursue the strategy of using script URLs in the actions and posting the source for each of the script URL scripts on individual web pages at https://omni-automation.com/drafts-app/index.html. This allows for the opportunity to document each script’s strategy and (often line-by-line) explain what the scripts are doing Omni Automation-wise, and to provide a video showing the scripts in use.

When composing AppleScript scripts, it’s not unusual for the script to contain multiple tell blocks, each targeting a different application. Runs fine and the tell blocks clearly delineate what code targets which application.

With the example Drafts action, I still haven’t found the technique for targeting multiple apps in the same script that has the same simplicity and understand-ability of the AppleScript tell blocks.

In a simple form, using back tacks could help to delineate the JavaScript code meant for the target Omni app. And then the content from the Draft could be inserted, and then go through the process of creating an Omni Automation script URL for execution by the Drafts app:

When composing AppleScript scripts, it’s not unusual for the script to contain multiple tell blocks, each targeting a different application. Runs fine and the tell blocks clearly delineate what code targets which application.

We’re not actually targeting two apps in the same script here – we are writing two scripts, one of which submits the other for evaluation, to a different instance of the JS interpreter (A different JSContext).

The trick is simply to write the submitted script as a function, and make use of the fact that:

coercion of functions to the String type in JS yields properly quoted source code, and

You can bundle the submission of JS functions by [1Writer, Drafts] for evaluation in [OmniOutliner, OmniGraffle] by writing a more general function to cover all those permutations, and any number of optional arguments, as in:

So, for example, if we not only want to fill an OG shape with text from 1Writer or Drafts, but also want to provide any number of additional arguments, specifying, perhaps, font and font size, for a start:

My hesitation to embrace the suggestion has been based upon the complexity of the example as it features JS techniques, like arrow functions, and function encasement, that haven’t been included in the code examples on the website. Perhaps this scenario might provide an introduction to those concepts for readers?

Regardless, I thank you again for the attention you’ve dedicated to this.

… the complexity of the example as it features JS techniques, like arrow functions, and function encasement, that haven’t been included in the code examples

For the beginner, complexity lies not in novelty (everything is novel) but in the number of layers and moving parts.

(An ES6 arrow function, for example, has a simpler structure than an ES5 function declaration, and both are equally novel if we are starting from scratch.

The main constraint on using arrow functions derives from their simplicity – they are cut-down light-weight structures which, unlike the full-blown and more complex function () {} declarations, don’t bind values to the special names this and arguments. In the general function below, for example, we are using a function declaration because we want to make use of the array-like arguments value, which lets us call a function with any number of optional arguments)

The problem with approaches like .replace(‘XXX’, withManuallyPreProcessedArgumentString) is that they add complexity by increasing:

the number of operations and moving parts

the number of levels of indirection

the number of things that can go wrong

We can reduce all this to:

one function definition, and

automatic stringifications (by JS, rather than the user).

There may also be an argument for packaging even those mechanics into a general off-the-shelf function that users can copy and paste.