If you're used to writing in Word or Google Docs, there's a chance that writing long-form texts in Nextjournal didn't feel quite right – until now. I’m happy to say that we just released a new version of our editor that provides a much more fluid writing experience. This has been six months in the making and we’re looking forward to release more frequent, incremental improvements from here on.
Read on for a rationale and an overview what's new and improved.
Previously, each text node was its own encapsulated editor instance. We decided on this approach early-on because it was simple to implement and it was a good fit to the functional model that is used in Nextjournal’s front-end architecture. This was most obvious when trying to make a text selection that spans multiple paragraphs:
Trying to extend the selection beyond the first paragraph was impossible. This never felt right and, especially when editing longer documents, was downright cumbersome.
Besides that, there were also less obvious shortcomings, for example: We couldn’t reliably synchronize cursor positions between between undos and redos and our change model would only provide a simple form of real-time collaboration ("first write wins"). Features like offline text editing were off the table.
ProseMirror and OT
We decided to fix these problems by rebuilding our underlying editing foundation with ProseMirror and Operational Transforms. ProseMirror is a solid, widely-used toolkit for rich-text editing and OT will provide us with better real-time collaboration features and support for offline text editing. Read on for the improvements that come out of this release.
The most obvious improvement is that we moved from per-node text editing to a fully integrated document editor. This allows making spanning selections across any type of node:
Cut, Copy & Paste Across Selections
Selections over multiple nodes can now also be cut, copied and pasted as you would expect:
This also works between notebooks, e.g. copying a code cell from one notebook and pasting it into another moves the runtime along with the code cell.
Drag To Re-Arrange Content
Previously the only way to re-arrange content was to open the global menu and go into outline mode which gives a compressed version of the document that can be re-ordered via drag and drop. This is way too much work for cases where you just want to quickly re-arrange some paragraphs.
For this, nodes can now be dragged to move them to other places in the document. Simply drag the ••• button on the left-hand side of a node and drop wherever you like:
When you press the Alt key while dragging a heading, it will move the heading’s content along with the drag. (The heading’s content will be everything that’s between the heading and the next heading at the same, or higher-up, level.)
Simpler Section Model
Previously, we had a nested section model that enforced heading levels based on the previous heading. We now dropped this behavior in favor of a flat model that allows any heading level to be followed by any other. This fits in better with the full-document editing experience that people are used from e.g. Google Docs and makes it easier on new authors. Instead of "Section" and "Subsection", the insert menu will now show "Heading 1", "Heading 2", etc.
We still believe that structured text editing is useful, especially for long-form documents that have lots of sections. So we plan to follow this change up soon with a document linting feature that provides hints and FIXMEs for headings levels that don’t match up (e.g. H1 followed by H3).
While we tested the new editor thoroughly, there’s a chance that we missed something. So please get in touch if you find anything that previously worked and now doesn’t or with any feedback you have on the new editor.