csshtmlheader.py
85 lines
| 3.2 KiB
| text/x-python
|
PythonLexer
Jonathan Frederic
|
r10674 | """Module that pre-processes the notebook for export to HTML. | ||
""" | ||||
Jonathan Frederic
|
r16819 | # Copyright (c) IPython Development Team. | ||
Jonathan Frederic
|
r10674 | # Distributed under the terms of the Modified BSD License. | ||
import os | ||||
import io | ||||
Jonathan Frederic
|
r16849 | import hashlib | ||
Jonathan Frederic
|
r10674 | |||
from IPython.utils import path | ||||
Jake Vanderplas
|
r11123 | from IPython.utils.traitlets import Unicode | ||
Jonathan Frederic
|
r16851 | from IPython.utils.py3compat import str_to_bytes | ||
Jonathan Frederic
|
r16819 | from .base import Preprocessor | ||
Jonathan Frederic
|
r10437 | |||
Paul Ivanov
|
r12219 | class CSSHTMLHeaderPreprocessor(Preprocessor): | ||
Jonathan Frederic
|
r10674 | """ | ||
Paul Ivanov
|
r12219 | Preprocessor used to pre-process notebook for HTML output. Adds IPython notebook | ||
Jonathan Frederic
|
r10674 | front-end CSS and Pygments CSS to HTML output. | ||
""" | ||||
Jake Vanderplas
|
r11140 | highlight_class = Unicode('.highlight', config=True, | ||
Jake Vanderplas
|
r11123 | help="CSS highlight class identifier") | ||
Jonathan Frederic
|
r16849 | def __init__(self, *pargs, **kwargs): | ||
Preprocessor.__init__(self, *pargs, **kwargs) | ||||
self._default_css_hash = None | ||||
Paul Ivanov
|
r12219 | def preprocess(self, nb, resources): | ||
Jonathan Frederic
|
r10674 | """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 | ||||
Paul Ivanov
|
r12219 | preprocessors to pass variables into the Jinja engine. | ||
Jonathan Frederic
|
r10437 | """ | ||
resources['inlining'] = {} | ||||
Jonathan Frederic
|
r16819 | resources['inlining']['css'] = self._generate_header(resources) | ||
Jonathan Frederic
|
r10437 | return nb, resources | ||
Jonathan Frederic
|
r16819 | def _generate_header(self, resources): | ||
Jonathan Frederic
|
r10674 | """ | ||
MinRK
|
r11046 | Fills self.header with lines of CSS extracted from IPython | ||
Jonathan Frederic
|
r10674 | and Pygments. | ||
""" | ||||
MinRK
|
r14042 | from pygments.formatters import HtmlFormatter | ||
Jonathan Frederic
|
r10437 | header = [] | ||
Jonathan Frederic
|
r10674 | |||
Jonathan Frederic
|
r16819 | # Construct path to IPy CSS | ||
Julian Taylor
|
r14750 | from IPython.html import DEFAULT_STATIC_FILES_PATH | ||
sheet_filename = os.path.join(DEFAULT_STATIC_FILES_PATH, | ||||
'style', 'style.min.css') | ||||
Jonathan Frederic
|
r10674 | |||
Jonathan Frederic
|
r16819 | # Load style CSS file. | ||
with io.open(sheet_filename, encoding='utf-8') as f: | ||||
header.append(f.read()) | ||||
Jonathan Frederic
|
r16849 | # Add pygments CSS | ||
formatter = HtmlFormatter() | ||||
pygments_css = formatter.get_style_defs(self.highlight_class) | ||||
header.append(pygments_css) | ||||
Jonathan Frederic
|
r16819 | # 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. | ||||
profile_dir = resources['profile_dir'] | ||||
custom_css_filename = os.path.join(profile_dir, 'static', 'custom', 'custom.css') | ||||
if os.path.isfile(custom_css_filename): | ||||
Jonathan Frederic
|
r16849 | if 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()) | ||||
Jonathan Frederic
|
r16819 | return header | ||
Jonathan Frederic
|
r10437 | |||
Jonathan Frederic
|
r16849 | def _hash(self, filename): | ||
"""Compute the hash of a file.""" | ||||
md5 = hashlib.md5() | ||||
with open(filename) as f: | ||||
Jonathan Frederic
|
r16851 | md5.update(str_to_bytes(f.read())) | ||
Jonathan Frederic
|
r16849 | return md5.digest() | ||