Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTMLExporter: Add a new output filter that excludes widgets if there is no state #1643

Merged
merged 1 commit into from Oct 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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',
SylvainCorlay marked this conversation as resolved.
Show resolved Hide resolved
'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