-
Notifications
You must be signed in to change notification settings - Fork 505
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
295205d
commit cb28723
Showing
7 changed files
with
209 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 46 additions & 9 deletions
55
share/jupyter/voila/templates/base/voila_setup.macro.html.j2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,58 @@ | ||
{%- macro voila_setup_labextensions(base_url, labextensions) -%} | ||
{%- macro voila_setup(base_url) -%} | ||
{% if frontend == 'voila' %} | ||
<script src="{{ page_config['fullStaticUrl'] | e }}/voila.js"></script> | ||
{%- endmacro %} | ||
|
||
{# For backward compatibility #} | ||
{%- macro voila_setup(base_url, nbextensions) -%} | ||
{{ voila_setup_labextensions(base_url, labextensions) }} | ||
{% elif frontend == 'voilite' %} | ||
{{ resources.include_js("static/voilite.js") }} | ||
{% endif %} | ||
{%- endmacro %} | ||
|
||
{# Helper functions for updating the loading text #} | ||
{%- macro voila_setup_helper_functions() -%} | ||
<script> | ||
var voila_process = function(cell_index, cell_count) { | ||
var voila_heartbeat = function() { | ||
console.log('Ok, voila is still executing...'); | ||
} | ||
var update_loading_text = function(cell_index, cell_count) { | ||
var el = document.getElementById("loading_text"); | ||
el.innerHTML = `Executing ${cell_index} of ${cell_count}`; | ||
} | ||
var voila_heartbeat = function() { | ||
console.log('Ok, voila is still executing...'); | ||
var display_cells = function() { | ||
// remove the loading element | ||
var el = document.getElementById("loading"); | ||
el.parentNode.removeChild(el); | ||
// show the cell output | ||
el = document.getElementById("rendered_cells"); | ||
el.style.display = ''; | ||
} | ||
{% if frontend == 'voila' %} | ||
var voila_process = update_loading_text; | ||
var voila_finish = display_cells; | ||
{% elif frontend == 'voilite' %} | ||
var voila_process = function(cell_index, cell_count, cell_source) { | ||
if (!window.voiliteExecution) { | ||
window.voiliteExecution = Promise.resolve(); | ||
} | ||
{# TODO Wait for window.voiliteKernel to be defined #} | ||
window.voiliteExecution = window.voiliteExecution.then(async function () { | ||
update_loading_text(cell_index, cell_count); | ||
await window.voiliteKernel.ready; | ||
return window.voiliteKernel.requestExecute(cell_source).then(function(result) { | ||
console.log(result); | ||
if (cell_index === cell_count) { | ||
display_cells(); | ||
} | ||
}); | ||
}); | ||
}; | ||
var voila_finish = function() { | ||
// no-op | ||
} | ||
{% endif %} | ||
</script> | ||
{%- endmacro %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
############################################################################# | ||
# Copyright (c) 2022, Voilà Contributors # | ||
# Copyright (c) 2022, QuantStack # | ||
# # | ||
# Distributed under the terms of the BSD 3-Clause License. # | ||
# # | ||
# The full license is in the file LICENSE, distributed with this software. # | ||
############################################################################# | ||
|
||
import markupsafe | ||
|
||
from traitlets import default | ||
from traitlets.config import Config | ||
|
||
from jupyter_server.services.contents.largefilemanager import LargeFileManager | ||
|
||
from nbconvert.filters.highlight import Highlight2HTML | ||
from nbconvert.exporters import TemplateExporter | ||
from nbconvert.preprocessors import ClearOutputPreprocessor | ||
|
||
from voila.exporter import VoilaExporter | ||
from voila.configuration import VoilaConfiguration | ||
from voila.paths import collect_template_paths | ||
|
||
|
||
|
||
class VoiliteExporter(VoilaExporter): | ||
def __init__(self, *args, **kwargs): | ||
kwargs.setdefault("base_url", "/") | ||
kwargs.setdefault("contents_manager", LargeFileManager()) | ||
|
||
self.voila_configuration = VoilaConfiguration(parent=self) | ||
|
||
# TODO | ||
# page_config | ||
self.page_config = {} | ||
# config | ||
# template_name? | ||
# template_paths? | ||
|
||
super().__init__(*args, **kwargs) | ||
|
||
# TODO | ||
# Investigate why this doesnt work | ||
# jupyter nbconvert --to voilite_dashboard --VoilaConfiguration.strip_sources=False notebook.ipynb | ||
if self.voila_configuration.strip_sources: | ||
self.exclude_input = True | ||
self.exclude_output_prompt = True | ||
self.exclude_input_prompt = True | ||
|
||
@default("template_paths") | ||
def _template_paths(self, prune=True, root_dirs=None): | ||
return collect_template_paths(['voila', 'nbconvert'], self.template_name, prune=True) | ||
|
||
@property | ||
def default_config(self): | ||
config = super().default_config | ||
config["NbConvertBase"]["display_data_priority"] = [ | ||
"application/vnd.voilite.code+txt" | ||
] | ||
return config | ||
|
||
def from_notebook_node(self, nb, resources=None, **kwargs): | ||
# this replaces from_notebook_node, but calls template.generate instead of template.render | ||
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) | ||
) | ||
self.register_filter("highlight_code", highlight_code) | ||
|
||
# TODO: This part is already copied three times across | ||
# nbconvert and Voila, we should do something about it | ||
nb_copy, resources = super(TemplateExporter, self).from_notebook_node( | ||
nb, resources, **kwargs | ||
) | ||
resources.setdefault("raw_mimetypes", self.raw_mimetypes) | ||
resources["global_content_filter"] = { | ||
"include_code": not self.exclude_code_cell, | ||
"include_markdown": not self.exclude_markdown, | ||
"include_raw": not self.exclude_raw, | ||
"include_unknown": not self.exclude_unknown, | ||
"include_input": not self.exclude_input, | ||
"include_output": not self.exclude_output, | ||
"include_input_prompt": not self.exclude_input_prompt, | ||
"include_output_prompt": not self.exclude_output_prompt, | ||
"no_prompt": self.exclude_input_prompt and self.exclude_output_prompt, | ||
} | ||
|
||
extra_context = dict( | ||
frontend='voilite', | ||
kernel_start=self.kernel_start, | ||
cell_generator=self.cell_generator | ||
) | ||
|
||
html = [] | ||
for html_snippet in self.template.generate( | ||
nb=nb_copy, | ||
resources=resources, | ||
**extra_context, | ||
static_url=self.static_url, | ||
page_config=self.page_config | ||
): | ||
html.append(html_snippet) | ||
|
||
return "".join(html), resources | ||
|
||
def kernel_start(self, nb): | ||
# TODO WHAT | ||
kernel_id = '36' | ||
return kernel_id | ||
|
||
def cell_generator(self, nb, kernel_id): | ||
# self.cwd = os.path.dirname(notebook_path) ?? | ||
# nb, _ = ClearOutputPreprocessor().preprocess( | ||
# nb, {'metadata': {'path': self.cwd}} | ||
# ) | ||
nb, _ = ClearOutputPreprocessor().preprocess(nb, {}) | ||
for cell_idx, input_cell in enumerate(nb.cells): | ||
output = input_cell.copy() | ||
output["outputs"] = [dict( | ||
output_type="execute_result", | ||
data={ | ||
"application/vnd.voilite.code+txt": input_cell.source | ||
}, | ||
metadata={} | ||
)] | ||
yield output | ||
|
||
def _init_resources(self, resources): | ||
# VoilaExporter bypasses the nbconvert behavior of inlining the assets like CSS and JS | ||
# We do want to inline those assets though, so | ||
# we bypass this bypass by not calling VoilaExporter._init_resources | ||
resources = super(VoilaExporter, self)._init_resources(resources) | ||
|
||
def resources_include_js(name): | ||
env = self.environment | ||
code = """<script type="module">\n%s</script>""" % (env.loader.get_source(env, name)[0]) | ||
return markupsafe.Markup(code) | ||
|
||
resources["include_js"] = resources_include_js | ||
|
||
return resources |