innovationOUtside / nb_extension_empinken

Jupyter notebook extension for background colouring selected cells
MIT License
1 stars 0 forks source link

Creating a custom template around tagged cells #4

Open psychemedia opened 4 years ago

psychemedia commented 4 years ago

If we tag cells, the nbconvert docs describe a way for customising templates that can add additional style based on the cell tags.

For example:

%%writefile mytemplate.tpl

{% extends 'full.tpl'%}
{% block any_cell %}
{% if 'Hard' in cell['metadata'].get('tags', []) %}
    <div style="border:thin solid red">
        {{ super() }}
    </div>
{% elif 'Medium' in cell['metadata'].get('tags', []) %}
    <div style="border:thin solid orange">
        {{ super() }}
    </div>
{% elif 'Easy' in cell['metadata'].get('tags', []) %}
    <div style="border:thin solid green">
        {{ super() }}
    </div>
{% else %}
    {{ super() }}
{% endif %}
{% endblock any_cell %}

And then run with:

example = !jupyter nbconvert --to html 'example.ipynb' --template=mytemplate.tpl --stdout

In the jupyter_contrib_nbextensions package, template files are in the jupyter_contrib_nbextensions/templates/ directory.

We can define in an init.py file something like:

def templates_directory():
    """Return path to the jupyter_contrib_nbextensions nbconvert templates."""
    return os.path.join(
        os.path.dirname(os.path.dirname(__file__)), 'templates')
# each application of os.path.dirname returns one step higher up the path

As an example, in jupyter_contrib_nbextensions, the toc2 exporter has a template file toc2.tpl in the templates directory. Exporters are defined in a nbconvert_support directory according the form:

## toc2.py
from nbconvert.exporters.html import HTMLExporter
from traitlets.config import Config

# -----------------------------------------------------------------------------
# Classes
# -----------------------------------------------------------------------------

class TocExporter(HTMLExporter):
    """
    :mod:`nbconvert` HTMLExporter which embeds the toc2 nbextension.
    Export table of contents nbextension functionality to html. The idea is to
    link a relevant part of the javascript nbextension and the css, and add a
    small script in the html file.
    Example usage::
        jupyter nbconvert --to html_toc FILE.ipynb
    """

    # If this custom exporter should add an entry to the
    # "File -> Download as" menu in the notebook, give it a name here in the
    # `export_from_notebook` class member
    export_from_notebook = "HTML + ToC"

    def _file_extension_default(self):
        return '.html'

    # This is presumably the filename without the .tpl suffix?
    def _template_file_default(self):
        return 'toc2'

    output_mimetype = 'text/html'

    def _raw_mimetypes_default(self):
        return ['text/markdown', 'text/html', '']

    @property
    def default_config(self):
        c = Config({'ExtractOutputPreprocessor': {'enabled': False}})
        #  import here to avoid circular import
        from jupyter_contrib_nbextensions.nbconvert_support import (
            templates_directory)
        c.merge(super(TocExporter, self).default_config)

        c.TemplateExporter.template_path = [
            '.',
            templates_directory(),
        ]

        return c

and imported via the __init__.py in the same directory as that file using eg from .toc2 import TocExporter.

The package setup.py then has an entry point defined as:

entry_points={
            'nbconvert.exporters': [
                'html_toc = jupyter_contrib_nbextensions.nbconvert_support.toc2:TocExporter'
            ],
        },

which supports the CLI call: jupyter nbconvert --to html_toc FILE.ipynb

Ah.. docs for writing a custom exporter.

psychemedia commented 4 years ago

This framework for creating new templates could be handy?

https://github.com/timkpaine/nbcx

UPDATE: from a recent tweet, it looks like this may be about to be deprecated.

Also, changes moving to nbconvert 6: https://blog.jupyter.org/the-templating-system-of-nbconvert-6-47ea781eacd2