Convert Notebook to ThebeLab HTML

A watched issue on Github reminded of something I’d forgotten I’d started to look at — an nbconvert template to convert an .ipynb file to an HTML page that could execute the code against a specified MyBinder provided environment.

(Apparently, the Jupyter Book jupyter-book page path/to/notebook.ipynb command should achieve much the same thing, though I’m not sure where you have to set the Binder repo URL. In a config file?)

FWIW, here’s the nbconvert template I’d started to sketch.

{% extends 'full.tpl'%}

{% block header %}

{{ super() }}


  {
    requestKernel: true,
    binderOptions: {
      repo: "binder-examples/requirements",
    },
  }



{% endblock header %}


{%- block body %}
Activate

var bootstrapThebe = function() {
    thebelab.bootstrap();
}

document.querySelector("#activateButton").addEventListener('click', bootstrapThebe)


{{ super() }}
{%- endblock body %}

It doesn’t quite work at the moment because the <pre> code tag doesn’t carry the correct attributes (though a proposed patch to thebelab may address that).

Chris Holdgraf uses Javascript to rewrite the tags dynamically in a related Jupyter Book template:

            // Find all code cells, replace with Thebelab interactive code cells
            const codeCells = document.querySelectorAll('.input_area pre')
            codeCells.forEach((codeCell, index) => {
                codeCell.setAttribute('data-executable', 'true')
                // Figure out the language it uses and add this too
                var parentDiv = codeCell.parentElement.parentElement;
                var arrayLength = parentDiv.classList.length;
                for (var ii = 0; ii < arrayLength; ii++) {
                    var parts = parentDiv.classList[ii].split('language-');
                    if (parts.length === 2) {
                        // If found, assign dataLanguage and break the loop
                        var dataLanguage = parts[1];
                        break;
                    }
                }
                codeCell.setAttribute('data-language', dataLanguage)
                // If the code cell is hidden, show it
                var inputCheckbox = document.querySelector(`input#hidebtn${codeCell.id}`);
                if (inputCheckbox !== null) {
                    setCodeCellVisibility(inputCheckbox, 'visible');
                }
            });

This can be put in a <script> tag immediately before the Jinja {%- endblock body %} directive.

Example gist here.

Track this issue for more…

Author: Tony Hirst

I'm a Senior Lecturer at The Open University, with an interest in #opendata policy and practice, as well as general web tinkering...