Inline variable insertion in markdown

To clarify my position (which is just that, only my opinion!), I’m considering the following axioms:

  • Notebooks should be viewable both on-line (with a kernel) and off-line (using nbviewer, etc)
  • Notebook frontends should avoid favouring a particular kernel (e.g. the original IPython kernel)

I don’t actually think this is impossible to do by any means, but I do think it will require some big changes (which can be done outside of the core). I stand by my earlier conclusions that we want to decouple the variable-loading from the Markdown rendering (to support the above points).

@stefanv et al. have convinced me to rethink the problem, and I think a Jupyter-first solution is actually possible, it just requires a little more work.

Here’s what I think we might be able to try:

  1. Add a new cell type (e.g. IMarkdown).
  2. Create a new “execution” mode that treats IMarkdown execution as an instruction to ask the kernel for variable mimebundles (e.g. via the DAP, if possible)
  3. Create an output mimebundle that effectively contains the variable mimebundles + the original markdown
  4. Create a Markdown renderer that can compose these mime-bundles into a rendered result.

This approach puts the burden of tokenizing the markdown into a single place — the frontend.
It would probably be straightforward to create a plugin that finds the variable templates {{ x }}, and stores the information. This information can then be retrieved to query the kernel. Once the results are available, the final composite mimebundle can be stored in the cell outputs, and the renderer invoked.

It is tempting to just do this in a near-single pass — parse the markdown, and store the rendered HTML output (with expanded template strings), but I don’t know if I like the idea of storing text/html in the output of the cell. Instead, I’d prefer to store the constituent parts, so that we can support widgets, and also avoid filling the notebook with generated output!

With this approach, the notebook document maintains the reproducible rich output, but whilst being easy to author.

I don’t have time to work on this right now, but I am interested.

Related but off-topic

In this thread I was thinking about custom cell types, and suggested replacing the non–code-cell types with a single MIME cell that specifies its MIME type. I wonder now whether the more bold proposal to make all cells MIME cells and use a kind of execution registry that invokes an executor for a given MIME type would be workable. In the context of inline variable insertion, we’d just register an executor for text/markdown that queries the backend as outlined above, and returns the processed results.

Hmm, I really want to work on this now!

3 Likes