Last active
January 18, 2024 20:22
-
-
Save mprat/a843b08e315621d91a667124a243abeb to your computer and use it in GitHub Desktop.
nbconvert configuration for converting a Jupyter notebook into an HTML output with images saved separately, intended to be embedded into a Jekyll site.
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
{%- extends 'display_priority.tpl' -%} | |
{% block codecell %} | |
<div class="cell border-box-sizing code_cell rendered"> | |
{{ super() }} | |
</div> | |
{%- endblock codecell %} | |
{% block input_group -%} | |
<div class="input"> | |
{{ super() }} | |
</div> | |
{% endblock input_group %} | |
{% block output_group %} | |
<div class="output_wrapper"> | |
<div class="output"> | |
{{ super() }} | |
</div> | |
</div> | |
{% endblock output_group %} | |
{% block in_prompt -%} | |
<div class="prompt input_prompt"> | |
{%- if cell.execution_count is defined -%} | |
In [{{ cell.execution_count|replace(None, " ") }}]: | |
{%- else -%} | |
In [ ]: | |
{%- endif -%} | |
</div> | |
{%- endblock in_prompt %} | |
{% block empty_in_prompt -%} | |
<div class="prompt input_prompt"> | |
</div> | |
{%- endblock empty_in_prompt %} | |
{# | |
output_prompt doesn't do anything in HTML, | |
because there is a prompt div in each output area (see output block) | |
#} | |
{% block output_prompt %} | |
{% endblock output_prompt %} | |
{% block input %} | |
<div class="inner_cell"> | |
<div class="input_area"> | |
{{ cell.source | highlight_code(metadata=cell.metadata) }} | |
</div> | |
</div> | |
{%- endblock input %} | |
{% block output %} | |
<div class="output_area"> | |
{% block output_area_prompt %} | |
<div class="prompt output_prompt"> | |
{%- if cell.execution_count is defined -%} | |
Out[{{ cell.execution_count|replace(None, " ") }}]: | |
{%- else -%} | |
Out[ ]: | |
{%- endif -%} | |
</div> | |
{% endblock output_area_prompt %} | |
{{ super() }} | |
</div> | |
{% endblock output %} | |
{% block markdowncell scoped %} | |
<div class="cell border-box-sizing text_cell rendered"> | |
{{ self.empty_in_prompt() }} | |
<div class="inner_cell"> | |
<div class="text_cell_render border-box-sizing rendered_html"> | |
{{ cell.source | markdown2html | strip_files_prefix }} | |
</div> | |
</div> | |
</div> | |
{%- endblock markdowncell %} | |
{% block unknowncell scoped %} | |
unknown type {{ cell.type }} | |
{% endblock unknowncell %} | |
{% block execute_result -%} | |
{%- set extra_class="output_execute_result" -%} | |
{% block data_priority scoped %} | |
{{ super() }} | |
{% endblock %} | |
{%- set extra_class="" -%} | |
{%- endblock execute_result %} | |
{% block stream_stdout -%} | |
<div class="output_subarea output_stream output_stdout output_text"> | |
<pre> | |
{{- output.text | ansi2html -}} | |
</pre> | |
</div> | |
{%- endblock stream_stdout %} | |
{% block stream_stderr -%} | |
<div class="output_subarea output_stream output_stderr output_text"> | |
<pre> | |
{{- output.text | ansi2html -}} | |
</pre> | |
</div> | |
{%- endblock stream_stderr %} | |
{% block data_svg scoped -%} | |
<div class="output_svg output_subarea {{ extra_class }}"> | |
{%- if output.svg_filename %} | |
<img src="{{ output.svg_filename | jekyllimgurl }}" | |
{%- else %} | |
{{ output.data['image/svg+xml'] | svg_filter }} | |
{%- endif %} | |
</div> | |
{%- endblock data_svg %} | |
{% block data_html scoped -%} | |
<div class="output_html rendered_html output_subarea {{ extra_class }}"> | |
{{ output.data['text/html'] }} | |
</div> | |
{%- endblock data_html %} | |
{% block data_markdown scoped -%} | |
<div class="output_markdown rendered_html output_subarea {{ extra_class }}"> | |
{{ output.data['text/markdown'] | markdown2html }} | |
</div> | |
{%- endblock data_markdown %} | |
{% block data_png scoped %} | |
<div class="output_png output_subarea {{ extra_class }}"> | |
{%- if 'image/png' in output.metadata.get('filenames', {}) %} | |
<img src="{{ output.metadata.filenames['image/png'] | jekyllimgurl }}" | |
{%- else %} | |
<img src="data:image/png;base64,{{ output.data['image/png'] }}" | |
{%- endif %} | |
{%- set width=output | get_metadata('width', 'image/png') -%} | |
{%- if width is not none %} | |
width={{ width }} | |
{%- endif %} | |
{%- set height=output | get_metadata('height', 'image/png') -%} | |
{%- if height is not none %} | |
height={{ height }} | |
{%- endif %} | |
{%- if output | get_metadata('unconfined', 'image/png') %} | |
class="unconfined" | |
{%- endif %} | |
> | |
</div> | |
{%- endblock data_png %} | |
{% block data_jpg scoped %} | |
<div class="output_jpeg output_subarea {{ extra_class }}"> | |
{%- if 'image/jpeg' in output.metadata.get('filenames', {}) %} | |
<img src="{{ output.metadata.filenames['image/jpeg'] | jekyllimgurl }}" | |
{%- else %} | |
<img src="data:image/jpeg;base64,{{ output.data['image/jpeg'] }}" | |
{%- endif %} | |
{%- set width=output | get_metadata('width', 'image/jpeg') -%} | |
{%- if width is not none %} | |
width={{ width }} | |
{%- endif %} | |
{%- set height=output | get_metadata('height', 'image/jpeg') -%} | |
{%- if height is not none %} | |
height={{ height }} | |
{%- endif %} | |
{%- if output | get_metadata('unconfined', 'image/jpeg') %} | |
class="unconfined" | |
{%- endif %} | |
> | |
</div> | |
{%- endblock data_jpg %} | |
{% block data_latex scoped %} | |
<div class="output_latex output_subarea {{ extra_class }}"> | |
{{ output.data['text/latex'] }} | |
</div> | |
{%- endblock data_latex %} | |
{% block error -%} | |
<div class="output_subarea output_text output_error"> | |
<pre> | |
{{- super() -}} | |
</pre> | |
</div> | |
{%- endblock error %} | |
{%- block traceback_line %} | |
{{ line | ansi2html }} | |
{%- endblock traceback_line %} | |
{%- block data_text scoped %} | |
<div class="output_text output_subarea {{ extra_class }}"> | |
<pre> | |
{{- output.data['text/plain'] | ansi2html -}} | |
</pre> | |
</div> | |
{%- endblock -%} | |
{%- block data_javascript scoped %} | |
{% set div_id = uuid4() %} | |
<div id="{{ div_id }}"></div> | |
<div class="output_subarea output_javascript {{ extra_class }}"> | |
<script type="text/javascript"> | |
var element = $('#{{ div_id }}'); | |
{{ output.data['application/javascript'] }} | |
</script> | |
</div> | |
{%- endblock -%} | |
{%- block data_widget_state scoped %} | |
{% set div_id = uuid4() %} | |
{% set datatype_list = output.data | filter_data_type %} | |
{% set datatype = datatype_list[0]%} | |
<div id="{{ div_id }}"></div> | |
<div class="output_subarea output_widget_state {{ extra_class }}"> | |
<script type="text/javascript"> | |
var element = $('#{{ div_id }}'); | |
</script> | |
<script type="{{ datatype }}"> | |
{{ output.data[datatype] | json_dumps }} | |
</script> | |
</div> | |
{%- endblock data_widget_state -%} | |
{%- block data_widget_view scoped %} | |
{% set div_id = uuid4() %} | |
{% set datatype_list = output.data | filter_data_type %} | |
{% set datatype = datatype_list[0]%} | |
<div id="{{ div_id }}"></div> | |
<div class="output_subarea output_widget_view {{ extra_class }}"> | |
<script type="text/javascript"> | |
var element = $('#{{ div_id }}'); | |
</script> | |
<script type="{{ datatype }}"> | |
{{ output.data[datatype] | json_dumps }} | |
</script> | |
</div> | |
{%- endblock data_widget_view -%} | |
{%- block footer %} | |
{% set mimetype = 'application/vnd.jupyter.widget-state+json'%} | |
{% if mimetype in nb.metadata.get("widgets",{})%} | |
<script type="{{ mimetype }}"> | |
{{ nb.metadata.widgets[mimetype] | json_dumps }} | |
</script> | |
{% endif %} | |
{{ super() }} | |
{%- endblock footer-%} |
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
def jekyllurl(path): | |
""" | |
Take the filepath of an image output by the ExportOutputProcessor | |
and convert it into a URL we can use with Jekyll | |
""" | |
return path.replace("../..", "") | |
def svg_filter(svg_xml): | |
""" | |
Remove the DOCTYPE and XML version lines from | |
the inline XML SVG | |
""" | |
svgstr = "".join(svg_xml) | |
start_index = svgstr.index("<svg") | |
end_index = svgstr.index("</svg>") | |
return svgstr[start_index:end_index + 6] | |
c = get_config() | |
c.NbConvertApp.export_format = 'html' | |
c.NbConvertApp.output_files_dir = '../../assets/imgs/{notebook_name}' | |
c.HTMLExporter.preprocessors = [ | |
'nbconvert.preprocessors.ExecutePreprocessor', | |
'nbconvert.preprocessors.coalesce_streams', | |
'nbconvert.preprocessors.ExtractOutputPreprocessor'] | |
c.HTMLExporter.template_file = 'jekyll.tpl' | |
c.HTMLExporter.filters = {"jekyllimgurl": jekyllurl, "svg_filter": svg_filter} | |
c.ExecutePreprocessor.allow_errors = True | |
c.FilesWriter.build_directory = "_includes/notebooks/" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a comment!