Prosemirror-py server side ProseMirror plug

I need to edit ProseMirror documents in JSON format both in headless batch processes and on the server side of web browser requests. I’ve been working with the prosemirror-py generously ported by Shen Li. So far it looks really good, much better than trying to execute Javascript from a Python WSGI process.

At first I was put off by the thought that I’d need to maintain separate versions of the document schema for browser and server-side use because prosemirror-py chokes on toDOM functions in my custom node types. Then I discovered that evaluating the schema with a small server-side Javascript interpreter such as quickjs or dukpy and then dumping it as JSON strips out the code and leaves the rest of the schema spec. This places far fewer demands on the Javascript interpreter than trying to load all of ProseMirror, and there’s then no need for the server-side code to be just strings of Javascript. Here’s what I do:

import quickjs, json
from prosemirror.model import Node, Schema
from prosemirror.transform import Transform

c = quickjs.Context()
schema = Path('schema_file_path').read_text()
schema_json = c.eval('JSON.stringify(this.schema.nodes)')
spec = dict(nodes=json.loads(schema_json), marks={})
sch = Schema(spec)
doc_node = Node.from_json(sch, doc_json)
tr = Transform(doc_node)

With the resulting Transform object I can manipulate the document in Python. Before storing the doc away I can check its validity with tr.doc.check() to avoid nasty surprises when my users bring the doc up in ProseMirror in their browsers.

Many thanks to Marijn, Shen Li, Fabrice Bellard, Alessandro Molina, and all others who have contributed to ProseMirror and the other code that supports this mode of use. The view is great from up here on the shoulders of giants.