Skip to content

Commit

Permalink
Merge pull request #101 from maartenbreddels/feature_render_images_in…
Browse files Browse the repository at this point in the history
…line

new: render image inline in html
  • Loading branch information
SylvainCorlay committed Apr 5, 2019
2 parents bc22a8d + 3e9a557 commit 74a186f
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 3 deletions.
24 changes: 24 additions & 0 deletions tests/app/image_inlining_test.py
@@ -0,0 +1,24 @@
# tests the --template argument of voila
import pytest
import base64
import os

@pytest.fixture
def voila_notebook(notebook_directory):
return os.path.join(notebook_directory, 'images.ipynb')


@pytest.mark.gen_test
def test_template_gridstack(http_client, base_url, notebook_directory):
response = yield http_client.fetch(base_url)
html_text = response.body.decode('utf-8')

assert 'data:image/svg+xml;base64,' in html_text
assert 'data:image/png;base64,' in html_text

# check if the external file is inline
with open(os.path.join(notebook_directory, notebook_directory, 'quantstack.svg'), 'rb') as f:
svg_data = f.read()
svg_data_base64 = base64.b64encode(svg_data).decode('ascii')
assert svg_data_base64 in html_text

62 changes: 62 additions & 0 deletions tests/notebooks/images.ipynb

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions tests/notebooks/quantstack.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions voila/handler.py
Expand Up @@ -5,14 +5,13 @@
# #
# The full license is in the file LICENSE, distributed with this software. #
#############################################################################

import tornado.web

from jupyter_server.base.handlers import JupyterHandler

import nbformat # noqa: F401
from .execute import executenb
from nbconvert import HTMLExporter
from .html import HTMLExporter


class VoilaHandler(JupyterHandler):
Expand Down Expand Up @@ -65,7 +64,8 @@ def get(self, path=None):
exporter = HTMLExporter(
template_file='voila.tpl',
template_path=self.nbconvert_template_paths,
config=self.exporter_config
config=self.exporter_config,
contents_manager=self.contents_manager # for the image inlining
)

if self.strip_sources:
Expand Down
29 changes: 29 additions & 0 deletions voila/html.py
@@ -0,0 +1,29 @@
import mimetypes

import nbconvert.exporters.html
from jinja2 import contextfilter
from nbconvert.filters.markdown_mistune import IPythonRenderer, MarkdownWithMath


class VoilaMarkdownRenderer(IPythonRenderer):
"""Custom markdown renderer that inlines images"""
def image(self, src, title, text):
contents_manager = self.options['contents_manager']
if contents_manager.file_exists(src):
content = contents_manager.get(src, format='base64')
data = content['content'].replace('\n', '') # remove the newline
mime_type, encoding = mimetypes.guess_type(src)
src = 'data:{mime_type};base64,{data}'.format(mime_type=mime_type, data=data)
return super(VoilaMarkdownRenderer, self).image(src, title, text)


class HTMLExporter(nbconvert.exporters.html.HTMLExporter):
"""Custom HTMLExporter that inlines the images using VoilaMarkdownRenderer"""
@contextfilter
def markdown2html(self, context, source):
cell = context['cell']
attachments = cell.get('attachments', {})
renderer = VoilaMarkdownRenderer(escape=False, attachments=attachments,
contents_manager=self.contents_manager,
anchor_link_text=self.anchor_link_text)
return MarkdownWithMath(renderer=renderer).render(source)

0 comments on commit 74a186f

Please sign in to comment.