nbpresent

nbslides is the evolution of the work by the Jupyter community to make notebooks into authorable, presentable, designed assets for communicating.

  1. The problem that this enhancement addresses. If possible include code or anecdotes to describe this problem to readers.

Problem

Creating conference-quality presentations with the Notebook requires a good understanding of the limitations of the notebook, nbconvert, reveal.js, RISE and the publishing platform (nbconvert and hosting, or nbviewer). The user is forced into a particular mindset about how slides are structured and authored, based on the these limitations, and at the end is still left with a potentially fragile artifact that doesn't reflect the amount of effort that goes into its creation.

User Story: Jill

Jill is presenting in support of her journal paper at a conference. While performing her work in Jupyter notebooks, she has prepared some beautiful visualizations and meaningful code snippets, as well a number of content pieces which are included in the draft and final versions of her journal paper.

She has seen some example slide decks on nbviewer that use reveal.js, and they look pretty neat, so she decides to turn on the Slides cell metadata and starts a brand new document, copy-and-pasting the content from her notebooks, making some screenshots.

Going back and forth between some command line scripts, her local web server and her notebook, she finally has something she can present. The resulting presentation looks pretty ho-hum, and has some formatting issues, but gets the point across. Right before the presentation, the organizers tell her they need a ppt or pdf of her slides, as there are A/V issues, and she won't be able to connect her laptop directly or use the internet during her talk.

She decides to just use LibreOffice next time.

User Story: John

John maintains a family of presentations, which are frequently updated for customer courses. While the content is light, the format represents his corporate and personal brand, and is a selling tool for his organization. In addition to wanting to create printed take-home materials, he has slides that contain interactive features.

Jack has experimented with showoff, beamer, but keeps ending up with LibreOffice. He evaluates using the notebook for his presentations, but finds that it lacks a number of key features: reuse of slides, repeatable PDF output, slide numbering, branding for his company and others.

He tries using showoff, but still finds it requires a lot of knowledge of CSS and html, and even has to learn some ruby. He decides to just use LibreOffice.

A brief (1-2 sentences) overview of the enhancement you are proposing. If possible include hypothetical code sample to describe how the solution would work to readers.

Proposed Enhancement

We propse unifying a number of features in different parts of the ecosystem into a single installable package which contains authoring, conversion, and management of presentation-related features.

A detailed explanation covering relevant algorithms, data structures, an API spec, and any other relevant technical information

Logical Architecture

Using nbpresent, a user can seamlessly author, present and publish notebooks as fixed-viewport, regioned, themed, layered, composable, hierarchically-stated experiences.

...user

The key user is the author/presenter of technical findings and opinions involving code, prose and data. While we must assume a fair degree of technical competence, they should not need to learn many skills outside their area of interest.

...seamlessly

After deciding to author slides and getting npresent installed on their server, a user should not have to leave their area of comfort, whether that's the JS Notebook environment, a hydrogen session or the command line, to be able to see their presentation.

...author, present

The authoring and live presenting experience should dominate nbpresent design choices. A significant shortcoming of reveal, showoff, and beamer are required knowledge of some form of esoteric language(s) to get your presentaton to Look Good. LibreOffice has mostly succeeded here with its drag-and-drop UI, but makes it more difficult to achieve a designed, consistent layout, as you are given free reign to make pixel-level corrections, sapping productivity.

Somewhere in between is a system that achieves separation of content, composition, layout and style which allows the user (and eventually a team) to concentrate on the appropriate task at hand, evolving an outline into a delivered, polished, and rehearsed presentation.

For rapid authoring, an author needs to be able to drop in and out of the logical model of the traditional notebook view, the tooled slide authoring view, and a full-on presentation view, suitable for delivering presentations which include rich widgets and require execution.

...publish

At the end of the process, a user will need to be able to hit "publish", initially to some simple choices like PDF, a standalone HTML file, or a zip of their file ready to be hosted on a plain-old-host (github/google pages). Jupyter Notebook Viewer represents a specific publishing target, and will have to be able to provide a out-of-the-box compatibility.

....notebooks

At a granular level, cell inputs and outputs, and to an extent, widgets, will be the content that make up presentations, but there is seldom a one-to-one mapping of cell to slide, cell to part-of-slide, or part-of-cell to part-of-slide. Furthermore, presentations frequently represent the unification of a number of sources, and need to be remixable, suggesting there is not a one-to-one mapping between notebook and presentation.

We propose allow using per-cell metadata to allow mapping each cell's input (and outputs, for code cells) to a specific region of a slide. Since cross-notebook cell transclusion must be possible, we will need to be able to assign stable identifiers to cells, and by extension their inputs and outputs.

...fixed-viewport

One key aspect of presentations (as opposed the the incubating dashboards) is working within the boundaries of the presented screen... whichever screen: desktop, mobile, hi-res presentation. Pixel-based approaches to this are significantly limiting.

To work within this, a constraint-based system, built on a cassowary-derived engine such as kiwi.js is proposed.

...regioned

Within the confines of a particular slide, instead of a pure stream of slides, subslides and fragments as in the current slideshow mechanism, we need to be able to add cell (inputs and outputs) to different parts of a slide layout: even to multiple regions of multiple slides.

...themed

Today, it takes heroic effort to view a notebook-as-slides in anything other than the stock default. Unlike the notebook, where consistent UI is a feature, presentations need to represent the brand of the author and/or their organization.

Intertwined with regioned layouts is CSS, fonts, images (and potentially JS, such as typographic effects) that enables a specific branding of a presentation. These theme assets need to be referenced/embedded along with presentations, with effective fallback to a default brand (such as on nbviewer).

...layered

Backgrounds, headers and footers are important to presentations, but without a full z-index stack, managing these becomes very static.

Layers, a la inkscape, provide a useful solution to this design problem.

...composable

A huge advantage of showoff and beamer is the (technically adept) user's ability to reuse content.

A presentation notebook needs to be able to bring in one or more cells (inputs and outputs) from other slides. These guest cells would not be editable within the host notebook, and refreshing of guest cells should be as painless as possible (automatic on save, if possible, on keystroke, eventually).

...hierarchically-stated

Slides should participate in both a layout hierarchy, as well as a state hierarchy. This is a generalization of the reveal sub-slide and fragment constructs.

Additional dimensions of state include scroll position

Repo Architecture

  • setup.py
  • nbpresent
    • static
      • nbpresent

Web-Based Presentation

The most challenging part is the presentation system itself. The current choice, reveal.js, has gotten us very far, but is turning out to be challening to support: its CSS, build chain, and opinions make it a poor match for the kinds of complex HTML that come out of notebooks, as well as the design goals of many of our users.

The initial implementation would continue to use reveal, but would not try to directly translate cells to <section> content.

Web-based Presentation: Future

This feature would be packaged as a number of npm modules, using current Jupyter front-end development practices:

  • es6/typescript
  • browserify

PhosphorJS is a strong contender for the underlying layout engine, specifically the proposed constraint-based layout, and will be generally available in the notebook in a roadmapped version.

In addition to the core rendering functions, specific components would be packaged as plugin modules that carry their own JS and CSS:

  • layouts
  • themes

Several of these plugins would be packaged with the pip/conda-installable Jupyter package, but these could be added/upgraded by the user.

Notebook Authoring

The authoring environment

A list of pros that this implementation has over other potential implementations.

Pros

A list of cons that this implementation has.

Cons

A list of individuals who would be interested in contributing to this enhancement should it be accepted.

Interested Contributors

Data Model

graph LR nb[notebook] --> md[metadata] md --> nbp[present] nbp --> slide nbp --> layer slide --> region nb -- * --> cells cells --> c[cell] cp[cell part] c --> input c -- 0,1 --> outputs c -- 0,1 --> widgets input --- cp outputs --- cp widgets --- cp c --> cmd[cell metadata] cmd --> cnbp[cell present] cnbp -- 0,* --> cpm cp --> cpm layer --> cpm region --> cpm effect --> cpm

Mockups

UI won't change much vs RISE

New Slide should default to something useful


In [5]:
# these customize the environment 
from IPython.display import Javascript, display
foo = [display(Javascript(url=url)) for url in [
    "https://bollwyvl.github.io/nb-inkscapelayers/main.js",
    "https://bollwyvl.github.io/nb-mermaid/init.js"
]],