92 lines
3.2 KiB
Python
92 lines
3.2 KiB
Python
|
"""Module that pre-processes the notebook for export to HTML.
|
||
|
"""
|
||
|
|
||
|
# Copyright (c) Jupyter Development Team.
|
||
|
# Distributed under the terms of the Modified BSD License.
|
||
|
|
||
|
import os
|
||
|
import io
|
||
|
import hashlib
|
||
|
import nbconvert.resources
|
||
|
|
||
|
from traitlets import Unicode, Union, Type
|
||
|
from pygments.style import Style
|
||
|
from jupyterlab_pygments import JupyterStyle
|
||
|
|
||
|
from .base import Preprocessor
|
||
|
|
||
|
try:
|
||
|
from notebook import DEFAULT_STATIC_FILES_PATH
|
||
|
except ImportError:
|
||
|
DEFAULT_STATIC_FILES_PATH = None
|
||
|
|
||
|
|
||
|
class CSSHTMLHeaderPreprocessor(Preprocessor):
|
||
|
"""
|
||
|
Preprocessor used to pre-process notebook for HTML output. Adds IPython notebook
|
||
|
front-end CSS and Pygments CSS to HTML output.
|
||
|
"""
|
||
|
highlight_class = Unicode('.highlight',
|
||
|
help="CSS highlight class identifier"
|
||
|
).tag(config=True)
|
||
|
|
||
|
style = Union([Unicode('default'), Type(klass=Style)],
|
||
|
help='Name of the pygments style to use',
|
||
|
default_value=JupyterStyle
|
||
|
).tag(config=True)
|
||
|
|
||
|
def __init__(self, *pargs, **kwargs):
|
||
|
Preprocessor.__init__(self, *pargs, **kwargs)
|
||
|
self._default_css_hash = None
|
||
|
|
||
|
def preprocess(self, nb, resources):
|
||
|
"""Fetch and add CSS to the resource dictionary
|
||
|
|
||
|
Fetch CSS from IPython and Pygments to add at the beginning
|
||
|
of the html files. Add this css in resources in the
|
||
|
"inlining.css" key
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
nb : NotebookNode
|
||
|
Notebook being converted
|
||
|
resources : dictionary
|
||
|
Additional resources used in the conversion process. Allows
|
||
|
preprocessors to pass variables into the Jinja engine.
|
||
|
"""
|
||
|
resources['inlining'] = {}
|
||
|
resources['inlining']['css'] = self._generate_header(resources)
|
||
|
return nb, resources
|
||
|
|
||
|
def _generate_header(self, resources):
|
||
|
"""
|
||
|
Fills self.header with lines of CSS extracted from IPython
|
||
|
and Pygments.
|
||
|
"""
|
||
|
from pygments.formatters import HtmlFormatter
|
||
|
header = []
|
||
|
|
||
|
formatter = HtmlFormatter(style=self.style)
|
||
|
pygments_css = formatter.get_style_defs(self.highlight_class)
|
||
|
header.append(pygments_css)
|
||
|
|
||
|
# Load the user's custom CSS and IPython's default custom CSS. If they
|
||
|
# differ, assume the user has made modifications to his/her custom CSS
|
||
|
# and that we should inline it in the nbconvert output.
|
||
|
config_dir = resources['config_dir']
|
||
|
custom_css_filename = os.path.join(config_dir, 'custom', 'custom.css')
|
||
|
if os.path.isfile(custom_css_filename):
|
||
|
if DEFAULT_STATIC_FILES_PATH and self._default_css_hash is None:
|
||
|
self._default_css_hash = self._hash(os.path.join(DEFAULT_STATIC_FILES_PATH, 'custom', 'custom.css'))
|
||
|
if self._hash(custom_css_filename) != self._default_css_hash:
|
||
|
with io.open(custom_css_filename, encoding='utf-8') as f:
|
||
|
header.append(f.read())
|
||
|
return header
|
||
|
|
||
|
def _hash(self, filename):
|
||
|
"""Compute the hash of a file."""
|
||
|
md5 = hashlib.md5()
|
||
|
with open(filename, 'rb') as f:
|
||
|
md5.update(f.read())
|
||
|
return md5.digest()
|