Skip to content

Commit

Permalink
Add a new output filter that excludes widgets if there is no state (#…
Browse files Browse the repository at this point in the history
…1643)

This allows showing a static mimetype instead of a blank widget
  • Loading branch information
martinRenou committed Oct 3, 2021
1 parent c663c75 commit 35c4d07
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 21 deletions.
34 changes: 19 additions & 15 deletions nbconvert/exporters/html.py
Expand Up @@ -21,6 +21,7 @@
from jinja2.loaders import split_template_path

from nbconvert.filters.highlight import Highlight2HTML
from nbconvert.filters.widgetsdatatypefilter import WidgetsDataTypeFilter
from nbconvert.filters.markdown_mistune import IPythonRenderer, MarkdownWithMath

from .templateexporter import TemplateExporter
Expand Down Expand Up @@ -98,22 +99,22 @@ def _template_name_default(self):
def default_config(self):
c = Config({
'NbConvertBase': {
'display_data_priority' : ['application/vnd.jupyter.widget-state+json',
'application/vnd.jupyter.widget-view+json',
'application/javascript',
'text/html',
'text/markdown',
'image/svg+xml',
'text/latex',
'image/png',
'image/jpeg',
'text/plain'
]
},
'display_data_priority': [
'application/vnd.jupyter.widget-view+json',
'application/javascript',
'text/html',
'text/markdown',
'image/svg+xml',
'text/latex',
'image/png',
'image/jpeg',
'text/plain'
]
},
'HighlightMagicsPreprocessor': {
'enabled':True
}
})
'enabled': True
}
})
c.merge(super().default_config)
return c

Expand All @@ -136,7 +137,10 @@ def from_notebook_node(self, nb, resources=None, **kw):
langinfo = nb.metadata.get('language_info', {})
lexer = langinfo.get('pygments_lexer', langinfo.get('name', None))
highlight_code = self.filters.get('highlight_code', Highlight2HTML(pygments_lexer=lexer, parent=self))
filter_data_type = WidgetsDataTypeFilter(notebook_metadata=nb.metadata, parent=self)

self.register_filter('highlight_code', highlight_code)
self.register_filter('filter_data_type', filter_data_type)
return super().from_notebook_node(nb, resources, **kw)

def _init_resources(self, resources):
Expand Down
69 changes: 69 additions & 0 deletions nbconvert/filters/widgetsdatatypefilter.py
@@ -0,0 +1,69 @@
"""Filter used to select the first preferred output format available,
excluding interactive widget format if the widget state is not available.
The filter contained in the file allows the converter templates to select
the output format that is most valuable to the active export format. The
value of the different formats is set via
NbConvertBase.display_data_priority
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------

from warnings import warn

from ..utils.base import NbConvertBase

__all__ = ['WidgetsDataTypeFilter']


WIDGET_VIEW_MIMETYPE = 'application/vnd.jupyter.widget-view+json'
WIDGET_STATE_MIMETYPE = 'application/vnd.jupyter.widget-state+json'


class WidgetsDataTypeFilter(NbConvertBase):
""" Returns the preferred display format, excluding the widget output if
there is no widget state available """

def __init__(self, notebook_metadata=None, **kwargs):
metadata = notebook_metadata or {}

self.widgets_state = (
metadata['widgets'][WIDGET_STATE_MIMETYPE]['state'] if
metadata.get('widgets') is not None else {}
)

super().__init__(**kwargs)

def __call__(self, output):
""" Return the first available format in the priority.
Produces a UserWarning if no compatible mimetype is found.
`output` is dict with structure {mimetype-of-element: value-of-element}
"""
for fmt in self.display_data_priority:
if fmt in output:
# If there is no widget state available, we skip this mimetype
if (
fmt == WIDGET_VIEW_MIMETYPE and
output[WIDGET_VIEW_MIMETYPE]['model_id'] not in self.widgets_state
):
continue

return [fmt]
warn("Your element with mimetype(s) {mimetypes}"
" is not able to be represented.".format(
mimetypes=output.keys())
)

return []
3 changes: 0 additions & 3 deletions share/jupyter/nbconvert/templates/base/display_priority.j2
Expand Up @@ -32,9 +32,6 @@
{%- elif type == 'application/javascript' -%}
{%- block data_javascript -%}
{%- endblock -%}
{%- elif type == 'application/vnd.jupyter.widget-state+json' -%}
{%- block data_widget_state -%}
{%- endblock -%}
{%- elif type == 'application/vnd.jupyter.widget-view+json' -%}
{%- block data_widget_view -%}
{%- endblock -%}
Expand Down
3 changes: 0 additions & 3 deletions share/jupyter/nbconvert/templates/latex/display_priority.j2
Expand Up @@ -36,9 +36,6 @@
((*- elif type == 'application/javascript' -*))
((*- block data_javascript -*))
((*- endblock -*))
((*- elif type == 'application/vnd.jupyter.widget-state+json' -*))
((*- block data_widget_state -*))
((*- endblock -*))
((*- elif type == 'application/vnd.jupyter.widget-view+json' -*))
((*- block data_widget_view -*))
((*- endblock -*))
Expand Down

0 comments on commit 35c4d07

Please sign in to comment.