Abstract

You can edit a Jupyter notebook as markdown without ever leaving text mode. This can work around accessibility issues or be used on non-graphical machines.

Introduction

Trying to use Orca with Jupyter is nigh on impossible. It doesn’t even let you open a file without using the mouse, and mouse routing buttons don’t seem to work for me. The same applies to JupyterLab, and I’ve heard similar stories for them under JAWS.

A lot of great work was started to improve this1, but at the moment I wasn’t able to make any headway, and I couldn’t find any sign of ongoing work with a quick search.

Using VSCodium may be an alternative but didn’t work for me. I heard it was heavy and slow to navigate, but your mileage may vary.

I wanted to find a different way to use and author Jupyter notebooks with different a screen reader and keyboard navigation. This is likely to be less accessible to many people, but by introducing more options, more people will find something that suits them.

I found a plethora of tooling for Jupyter2 which led to the discovery of Bookbook, a tool that sounded cool but one-way and unmaintained. JupyText is a very cool two-way converter, but it doesn’t seem to include cell outputs by default so would preclude easy access to data results. I also found Notedown and its de facto successor nbconvert.

Solution

This covers the end-to-end workflow of downloading and modifying a notebook from a JupyterLab instance, using nbconvert and pandoc.

  1. Install dependencies
  2. Download all the files from the JupyterLab server
  3. Convert notebook to markdown
  4. Edit and convert back again to execute
  5. Iterate as usual

Dependency installation

Downloading notebooks

This code converts an online Jupyter notebook into a zip file that you can download. To run it, you need to launch a Python interpreter in the inaccessible web interface and paste this code, then press Shift+Enter. There will probably be no output that a screen reader can understand, but a file named “lab.zip” will appear in the “file explorer” in the web interface, which you can download by right-clicking and choosing Download.

import zipfile, os
zf = zipfile.ZipFile("lab.zip", "w")
os.chdir("..")
for dp, _, fns in os.walk("."):
  for fn in fns:
    if fn == "lab.zip":
      continue
    zf.write(os.path.join(dp, fn))
zf.close()

Now decompress the files by double-clicking them (or using a terminal as below).

mkdir lab
cd lab
unzip ../lab.zip

Note that if you don’t entirely trust the files, you’ll need to remove the --execute in the next section. If you really don’t trust them at all, don’t download them!

Converting to markdown

The magic command is:

jupyter nbconvert --execute --allow-errors --inplace notebook.ipynb && pandoc --extract-media=images notebook.ipynb -o notebook.md

This will run the code (--execute) and save the readable file into notebook.md which you can edit using your favourite text editor. Images such as graphs will be saved into the images directory.

If you don’t entirely trust the code, remove the --execute flag (technically you can skip the entire first part of the pipeline but that’s harder to explain)

Converting back to Jupyter format

To test your code, first turn it back into a Jupyter notebook:

pandoc notebook.md -o notebook.ipynb

Then just turn it back into Markdown like before, and any errors will show up below the corresponding code (you can search “.output .error” to find them). You could also remove the –allow-errors to have the errors show up without updating the Markdown file, but I think this would be more confusing.

Limitations

The Jupyter web interfaces allow re-running individual blocks of code. I haven’t looked into this for nbconvert, but this feature can accelerate development, so finding a way to add it would be useful. One can imagine that only cells that have changed since the last run would be evaluated by default by a tool incorporating this feature.

The process described is quite clunky and requires considerable technical knowledge. Markdown is a fairly easy language to learn, so with the advent of less expensive multi-line Braille displays3 there is scope for a simple application that ties the whole workflow together into a simple editor with sensible keyboard shortcuts and search functionality.

Conclusion

This workflow can help with Jupyter usage for some people whose accessibility needs are not met by the existing solutions, but it’s not perfect. People who just love their machines in text-mode may prefer jut. People who want to commit plain-text versions of Jupyter files may fare better with Jupytext.

P.S.

Wondering why the writing style is so weird? Reading too many academic papers while trying to write casually at one in the morning don’t mix well.

  1. See the grant roadmap 

  2. Under the name Awesome Jupyter 

  3. Like the Canute 360