pythonjupyter-notebookgoogle-colaboratorynbconvert

how to programmatically add slides cell metadata in jupyter notebooks?


Jupyter notebooks has a way of visualizing cell metadata so that you are able to parametrize how will cells look like when you export the notebook into slides using nbconvert.

Example: enter image description here

For instance, I would like to programmatically add that metadata into cells without using the GUI, so that I can automate slide creation, specially from google colaboratory as it doesn't support the Edit Cell Metadata tool.

I've come across this reference

https://jupyterbook.org/en/stable/content/metadata.html#add-tags-using-python-code

which programmatically adds metadata to hide cell code. I would like to be able to do the same but adding slideshow metadata. For instance I am not sure what {tags:values} or syntax I should follow.


Solution

  • You can use nbformat to do this like the example you point to.

    "The nbformat package allows you to programmatically read and parse notebook files." - SOURCE, Tony Hirst's description

    nbformat comes as part as Jupyter so it runs wherever you have your notebooks running.

    I use nbformat to do something similar to your goal here (in a work-in-progress state). The most pertinent part is here where I set the meta data for cells in the notebook to be a slide show. Here's the gist of that section:

    import nbformat as nbf
    a = nbf.v4.new_notebook()
    for p in image_fn_pairs:
        content_for_md_cell = slideshow_cell_stub_text.replace(
            "THE_IMAGE1_PLACEHOLDER_TEXT_GOES_HERE",p[0]).replace(
            "THE_IMAGE2_PLACEHOLDER_TEXT_GOES_HERE",p[1])
        a.cells.append(nbf.v4.new_markdown_cell(content_for_md_cell))
    # fix the metadata for each cell to be for a slide
    slide_show_meta = {"slideshow": {"slide_type": "slide"}}
    # a.cells = [c["metadata"] = slide_show_meta for c in a.cells]
    meta_fixed_cells = []
    for c in a.cells:
        c["metadata"] = slide_show_meta
        meta_fixed_cells.append(c)
    a.cells = meta_fixed_cells
    

    In your case, it sounds like you already have the content in your notebook, and so in your case you'll want to read in the notebook, like this first:

    import nbformat as nbf
    ntbk = nbf.read("old_notebook.ipynb", nbf.NO_CONVERT)
    

    And then fix the metadata like my example. Something along these lines:

    new_ntbk = ntbk
    # fix the metadata for each cell to be for a slide
    slide_show_meta = {"slideshow": {"slide_type": "slide"}}
    meta_fixed_cells = []
    for c in ntbk.cells:
        c["metadata"] = slide_show_meta
        meta_fixed_cells.append(c)
    new_ntbk.cells = meta_fixed_cells
    nbf.write(new_ntbk, "notebook_with_slide_metadata.ipynb", version=nbf.NO_CONVERT)
    

    You can try the automated, work-in-progress slide building process I set up and referred to above by going there and clicking launch binder. I think if you just run things in the notebook that comes up it will guide you through making slides with some filled rectangles side-by-side on each slide as stand-in for images.

    You'll also see I use a stub of a notebook in the script, that is based on a notebook stub to add in metadata for the entire notebook here so that it will play the slideshow automatically when the notebook is opened, i.e., the "livereveal": {"autolaunch": true, "scroll": true} section.



    nbconvert includes a preprocessor that will edit metadata, see here where it looks like it will add the metadata.



    If you use JupyterLab as your slide development tool, you can install jupyterlab-deck which will add a 'deck' icon to the toolbar that allows you to toggle in and out of the slidedeck viewing. See Usage here. (In deck mode of sessions served via MyBinder, I see the toolbar if I move the mouse towards the top of screen. I assume this is because shift+esc doesn't work. Or the documentation just hasn't been updated.)