Edit: These goals are still valid, but I did add more scripting support to Bike for the 1.0 release than I initially expected. Bike 1.0 has a pretty good AppleScript dictionary for “external” scripting. I still plan to add “internal” JavaScript based scripting at some later time, will probably refer to it as “plugins” instead of scripting to distinguish from current AppleScript support.
Bike Scripting Goals
Bike doesn’t have much scripting support yet, and it likely won’t until after the 1.0 release. At the same time scripting is a very important part of Bike’s future. I’m going to sketch out some scripting goals and ideas here so you’ll know how I hope it will work and so you can give me ideas on how you hope it will work
Like TaskPaper scripting will be javascript based. Scripts are run in a javascript context that’s embedded in Bike.
TaskPaper scripts are limited to the current document. I hope to expand Bike’s scripting environment to include entire app, Windows, Documents, etc. Basically everything you can do via AppleScript I want you to be able to do within TaskPaper’s script context. I think my goal is to create something similar to Omni Automation.
Plugins will be the preferred way to run scripts. They will be loaded into Bike’s scripting context at startup. They will have ability to observer changes and add commands. Scripting will also be possible through AppleScript in a similar way that TaskPaper scripting is done… use AppleScript to submit code that is then run within Bike’s internal javascript context
Stretch goal, plugins will be able to present web view based UI’s in a sidebar “Inspector” view. This plugin view code will run in a different scripting context from default plugin code. A plugin that wants to display a view will have multiple script files… one that runs in main scripting context and can access TaskPaper model. And another that runs in WebView context. They may communicate by sending text messages back and forth.
A million details to fill in, but I think that covers the big picture.
Inspiration
Here’s a list of existing scriptable apps that use the same underlying JavaScript context based design. I’m sure I’ve missed some, please let me know about other apps to add.
It seems like there’s a fair amount of common infrastructure code that could be shared between scriptable apps, especially if you are building a document based app.
I’m on the lookout for an existing Swift “scripting” package that I could use. Omni used to have a lot of open source frameworks, but I can’t find anything for Omni-Automation. Is anyone aware of a package/lib/framework to help with building a javascript context based scripting environment? If so please let me know.
Since I haven’t been able to find anything so far I’ve started my own “ScriptLib” package here:
There’s nothing Bike specific there yet, but it’s currently the foundation that I plan to build Bike scripting support on assuming I don’t find an existing library. Please take a look and try out the little that’s there. I’m unlikely to work much on it for the time being and would welcome anyone to start looking at the code and pushing it forward with pull requests.
I’m updating some old thread with new info. I think the latest preview release of Bike 2 meets these scripting goals, except for the stretch goal of including a web view… and I hope to get that into a Bike 2.x point release.
Things go very slowly, but do make progress over time!
WebView will need to run in own context. So the API (from Bike extension code) will look a little like a web worker I think. You’ll create a WebView passing it a index.html. You will then post/receive messages to communicate with it. So the web view code won’t have direct access to outline view (not possible with modern web view APIs I think) … instead your extension code will need to read outline data, pack it up into a message, and then post to web view.
I “think” that’s likely what I’ll do.
Generally I expect this web view to be visible in an inspector pane to the right of the outline editor… though also possible to push a modal web view for a temporary visualization.
That plan does have some downside in consistency and complexity … all plugins displaying in a free for all in a web view.
Alternative plan would be maybe something like react native. Then extension code could communicate directly with view code. System would be more consistent, maybe faster and more efficient in some ways, but also more limited.
Thoughts or potential use cases (and needed functionality) would be welcome.
One representation which helps me see and adjust the shape of an emerging argument – grouping large sibling runs into maxima of 3-5 for example – is a nested table using colspan and rowspan to allow any table cell to have multiple children.
The outline/argument tables are
Rotatable
collapsible to varying degrees
clickable, with a clicked node becoming the focal parent, hiding its ancestors
An ideal requirement of the webview would be to able to trap some kind of commands, clicks or events to trigger rotations, focal changes, expansion and collapses for interactive use during presentations, or while thinking.
Also, of course, CSS to change color of focal table cells on hover, allow for a visual indication that a particular leaf of a table is not fully expanded, etc.
Possible, but you would need to do some extra work.
Your extension code can post messages to your web code, and your web code and post messages back to the extension code. Messages are JSON. So the web code would need to detect any edit you make. Send that edit back to the extension code as a message. And then the extension code would apply the actual edit to the outline.
Another thing that I need to do in some context – I’ve been experimenting with Mathematica, but now wondering whether Bike 2 might be an option – is to click on argument table cells in some arbitrary sequence, recording that sequence as a series of ids, and storing it somewhere.
(Partial custom traversals of an argument tree, providing a serialisation into linear text. The linear text you get depends on the path you take through the tree. I would need to record more than one such custom path through a give outline/tree, storing each path under a key name.
(I would also like, ideally, to be able to display one or more of these paths, complete or incrementally, as arrows in a canvas layer above the graphic representation of the tree)
If the state were held in a Bike file, I suppose it could be a sequence of children under a special node, or perhaps a comma-delimited value of a data- attribute somewhere ?
(Do user attributes stored in the root <ul> get written out and read back in, for example ?)
Generally attributes should be round tripped for the <ul> and all other rows… except I just noticed a bug that was causing the <ul> (root row case) to get lost. I’ve fixed that for next release.
Bike files also have <meta> elements, I think I will try to expose read/write of those to extension API, that might be the best place to store.