Workshop is a canvas based end user programming environment. It allows the user to create boxes of either CodeMirror or ProseMirror editors and manipulate them on an artboard style canvas. The live demo demonstrates a mouse tracking widget as well as tabbed workspaces both of which are coded within the environment itself. Workshop is a rought prototype of a self-hosted end user programming environment in the web. In other words, it is a small application intended to provide the minimum functionality to allow the user to extend it with features as they see fit, during the use of the application. It’s “primitives” in this sense are the CodeMirror and ProseMirror editors along with mouse events to control them.
This project is the third part in a multiyear exploration of programming tools. I have parallel pursuits at different levels of the stack focusing on OS interactions (tiling wms) and programmer ergonomics (fliesystem watchers), here we will focus on what I like to think of broadly as “digital” tools. These projects have grown into the domain of the digital medium and involve collaboration, media and computation. The ultimate problem of the digital medium is of context. How are things accessed and related? How are static assets and compute made available? How are many more than one screen’s worth of content displayed on one screen, or three screens? Human computer interaction design is the practice of unifying information architecture with an invisible periphery structure through which a human navigates a simulation interface.
The first part was the result of an interaction design class project about education. We set out to study and improve computer science class lectures. The design we found was a dual editor live coding environment. We positioned instructor code alongside a local environment on each students laptop such that they could run class code in the instruction environment as well as modify, test and ask questions of a local environment simultaneously. The project mostly focused on the domain of large lectures, but also found relevance in small coding groups as well as pair programming. It was validating, a year later, to see Atom and VSCode simultaneously release pair programming tooling.
The second part was an experiment turned research project of a creative coding environment making explicit parallel design funcitonality. Features included an inline canvas, execution control and parallel design controls. I extended the computational notebook style column of cells towards creative coding. An experimental execution control environment provided an escape hatch to logical errors in code: a solution to longstanding issues in creative coding education running back to the beginnings of p5js. The experimental controls allowed exploring alternatives in real time coding sessions, allowing cells to be duplicated in place without losing past context. The repo is available at https://www.github.com/jaspertravers/codeshop.
This workshop project is the latest iteration. Breaking out of the computational notebook single column, workshop is a canvas based programming environment. Inspired by functionality developed by other CAD communities and applying it to programming, as well as realizing small parts of the long history of research in personal computing. There are numerous infinite canvas based programming environments, all of which inspired this exploration. One of the key design goals was to step past intermediate configuration, right to the code itself. Many iterations of workshop were a small file which simply bound an execute functionality to a keybind or button and utilized localStorage to provide interface end user programming. Various results include custom creative coding environments, custom widget control to interface functionality and rapid prototyping of presentation content. Workshop is an attempt at fusing Ward Cunningham’s all encompasing “card” metaphor with Ivan Sutherland’s initial realization of OOP as control of the entire application.
These projects span three years of my time at UCSD and a part of my summer in lockdown after graduation. I owe so much to the experience of being around the CSE deparment and the Design Lab and being exposed to so much of the prior art by professors who took an interest in me. There is still so much I have missed and so much more I want to do.
- Jasper
—
Communication, computation, work.
What follows is a short time working-dashboard I used during development, it is without explanation and meant to be used in emacs org mode. It does contain the build setup for the project and links to dependencies. You can run this by cloning the repo and running.
The majority of the thinking and prototyping work was ‘dogfooded’ and took place within various prototypes of Workshop itself, as the first complete functionality was manipulating cards and editors.
npm install
npm run dev
Two older versions are online at these links. They lack instructions and content. This repo will be deployed soon with at least some small instructions.
- https://www.stopify.org/
- https://codemirror.net/
- https://prosemirror.net/
- https://rollupjs.org/guide/en/
npm init
npm install @stopify/stopify
npm install @codemirror/next # this will change on v1.0.0 release
npm install prosemirror-model
npm install prosemirror-state
npm install prosemirror-view
npm install prosemirror-transform
# going to need a few more prosmirror modules; yes these can be space separated
npm install rollup --global
mkdir src public
touch src/main.js
touch rollup.config.js
npm install rollup --save-dev # being thorough about building
# building: npm run build
Need a bundler: either rollup, parcel, webpack, snowpack
# to catch up with rollup-starter-app
npm install serve --save-dev
npm install @rollup/plugin-commonjs --save-dev
npm install @rollup/plugin-node-resolve --save-dev
npm install rollup-plugin-terser --save-dev
npm install npm-run-all --save-dev
npm install webpack --save-dev # trying to tame warnings
npm install --save-dev @rollup/plugin-json
npm install --save-dev rollup-plugin-node-polyfills
Babel Issues:
npm install @rollup/plugin-babel --save-dev
npm install @babel/core --save-dev
npm install ajv --save-dev
npm install babel-loader @babel/core --save-dev
I’m going to give up on importing stopify and will instead include the bundle. Uninstalling myriad npm packages I used to try to fix the problem.
npm uninstall babel-loader @babel/core @rollup/plugin-babel ajv
Copying bundle into place and including in public/index.html
, I suppose I could very well remove @stopify/stopify
but I’ll leave it for now for followup investigation.
npm run build
script set in package.json
npm install --save-dev rollup-plugin-serve
npm install --save-dev rollup-plugin-livereload
editing config file to match
npm install prosemirror-keymap prosemirror-history prosemirror-commands prosemirror-dropcursor prosemirror-gapcursor prosemirror-menu prosemirror-inputrules prosemirror-schema-list prosemirror-schema-basic
npm install prosemirror-example-setup
backspace on empty editor throws “RangeError”
view.state.doc.toString()
to get string in editor for stopify
time for prosemirror
taken most things from prosemirror-example-setup
and the basic editor example.
Block | ||
---|---|---|
content | ||
position | ||
top | ||
left | ||
width | ||
height | ||
Block will be a div that has a child div to fill with content.
https://www.npmjs.com/package/chrome-devtools-frontend
npm install chrome-devtools-frontend
https://martinfowler.com/articles/micro-frontends.html
https://chrome-devtools-frontend.appspot.com/serve_file/@9c7912d3335c02d62f63be2749d84b2d0b788982/devtools_app.html auchenberg/devtools-remote#5
Dev Tools links that “work” https://chrome-devtools-frontend.appspot.com/serve_file/@9c7912d3335c02d62f63be2749d84b2d0b788982/devtools_app.html https://chrome-devtools-frontend.appspot.com/serve_file/@9c7912d3335c02d62f63be2749d84b2d0b788982/devtools_app.html https://chrome-devtools-frontend.appspot.com/serve_file/@010ddcfda246975d194964ccf20038ebbdec6084/audits2_worker/audits2_worker_module.js
- https://git-scm.com/book/
- https://rollupjs.org/guide/en/
- https://github.com/rollup/rollup-starter-app
- https://rollupjs.org/guide/en/#quick-start
The “thing” this all sits on. Where the components go.
Code editor.
Towards a live sandbox.
Content editor.
Prosemirror does not have a package out of the box that supports live markdown editing. It does, however, support some markdown features. Specifically, the ones where symbols start at the beginning of the line. Headers (#), lists (-), ordered lists (1.), code fences (“`), and blockquotes (>).
These are the “easier” set of input rules to transform as they all require starting at the beginning of the line. Markdown styles within a line, such as bold, italics, underline, strikethrough, and link styling require relatively more complicated regex to describe and have many edge cases when combined.
These are setup under the inputrules
module.
I wonder if it would be easy to have a markdown-code view within a leaf and rendered outside of the current focus.
The key here is going to be rulebuilders.js
in prosemirror-inputrules
We have a relatively broken markdown input set in inputrules.js
. For now I’ll leave it as it, it’ll take a deep dive to figure out how to fix it.
- Backspacing into a marked section sets the mark to the current cursor.
- Both styles cannot be set.
- I think there is a better way to do this within nodes and using the
prosemirror-markdown
package.
Might be able to figure out what gitlab did to make their editor work.
https://prosemirror.net/docs/ref/#inputrules
- https://prosemirror.net/docs/guide/
- https://prosemirror.net/docs/ref/#inputrules
- https://gitlab.com/gitlab-org/gitlab-foss/-/tree/master/app/assets/javascripts/behaviors/markdown
- https://github.com/ueberdosis/tiptap/tree/master/packages/tiptap-extensions
- https://github.com/ueberdosis/tiptap
There’s a big opportunity to make this work correctly. Searching the tiptap issue list for “mark” yielded multiple open issues regarding markdown ergonomics.
debug/repl style output; printing from code
- https://eloquentjavascript.net/code/
- https://github.com/marijnh/Eloquent-JavaScript/tree/master/html/js
-
creative coding output
Tech to check out; capabilities to explore
- git; this repo
- *mirror nodes for variolite local versioning. This is exactly the architecture these systems are built to explore.
- Write a
prosemirror-full-markdown
package… maybe.
- https://github.com/yjs/yjs
- https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API
- https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
- https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps
Yes, again… As always, incomplete.
- https://github.com/hundredrabbits/Ronin
- https://github.com/damelang/nile
- http://worrydream.com/refs/Sutherland-Sketchpad.pdf
- https://paper.dropbox.com/doc/Stamper-An-Artboard-Oriented-Programming-Environment–A4V0v1SHSKMwJb74PRF4eBnPAg-QXtfMXshBFBNCu6iCtx2J
- https://makespace.fun/
- http://www.joelotter.com/kajero/
Note: Github does not render .org
files entirely correctly. This file is edited and read in emacs with org mode.
Every editor hooked up to local storage. Every editor named and attached to a browser. Every editor tagged. See tiddlywiki tags and filters.
execution order and setting of that order will be a fascinating problem
var script = document.createElement('script');
script.type = 'text/javascript'; //could this be module?
script.src = 'script.js'; //can be cdn source
document.head.appendChild(script);
Boot | Viewport | Library | Workspace |
Boot: Initializes Primitives
- cm, pm, console, card, stopify
Initializes visual interface via Viewport
Viewport: Initializes Visual Interface
- tabs bar
Storage:
workspace [space] [card] content content: cm | pm | console | canvas | iframe | webrtc