template.py
188 lines
| 6.4 KiB
| text/x-python
|
PythonLexer
/ converters / template.py
|
r8994 | """Base classes for the notebook conversion pipeline. | ||
This module defines Converter, from which all objects designed to implement | ||||
a conversion of IPython notebooks to some other format should inherit. | ||||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# Copyright (c) 2012, the IPython Development Team. | ||||
# | ||||
# Distributed under the terms of the Modified BSD License. | ||||
# | ||||
# The full license is in the file COPYING.txt, distributed with this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
from __future__ import print_function, absolute_import | ||||
|
r9302 | import converters.transformers as trans | ||
|
r9303 | from converters.jinja_filters import (python_comment, indent, | ||
rm_fake, remove_ansi, markdown, highlight, | ||||
|
r9424 | ansi2html, markdown2latex, escape_tex, FilterDataType) | ||
|
r9302 | |||
|
r9333 | from converters.utils import markdown2rst | ||
|
r8994 | |||
|
r9307 | |||
|
r8994 | # Stdlib imports | ||
import io | ||||
|
r9490 | |||
|
r9307 | from IPython.utils.traitlets import MetaHasTraits | ||
|
r8994 | |||
|
r9183 | from jinja2 import Environment, FileSystemLoader | ||
|
r9049 | env = Environment( | ||
|
r9230 | loader=FileSystemLoader([ | ||
'./templates/', | ||||
'./templates/skeleton/', | ||||
]), | ||||
|
r9049 | extensions=['jinja2.ext.loopcontrols'] | ||
) | ||||
|
r8994 | |||
|
r9212 | texenv = Environment( | ||
|
r9230 | loader=FileSystemLoader([ | ||
'./templates/tex/', | ||||
'./templates/skeleton/tex/', | ||||
]), | ||||
|
r9212 | extensions=['jinja2.ext.loopcontrols'] | ||
) | ||||
|
r8994 | # IPython imports | ||
from IPython.nbformat import current as nbformat | ||||
|
r9183 | from IPython.config.configurable import Configurable | ||
|
r9491 | from IPython.utils.traitlets import ( Unicode, List, Bool) | ||
|
r8994 | |||
#----------------------------------------------------------------------------- | ||||
# Class declarations | ||||
#----------------------------------------------------------------------------- | ||||
class ConversionException(Exception): | ||||
pass | ||||
|
r9303 | |||
|
r9212 | |||
texenv.block_start_string = '((*' | ||||
texenv.block_end_string = '*))' | ||||
|
r9424 | |||
|
r9212 | texenv.variable_start_string = '(((' | ||
texenv.variable_end_string = ')))' | ||||
|
r9424 | |||
|
r9212 | texenv.comment_start_string = '((=' | ||
texenv.comment_end_string = '=))' | ||||
|
r9424 | |||
|
r9212 | texenv.filters['escape_tex'] = escape_tex | ||
|
r9218 | |||
|
r8994 | class ConverterTemplate(Configurable): | ||
|
r9332 | """ A Jinja2 base converter templates | ||
Preprocess the ipynb files, feed it throug jinja templates, | ||||
and spit an converted files and a data object with other data | ||||
shoudl be mostly configurable | ||||
""" | ||||
|
r8994 | |||
|
r9332 | pre_transformer_order = List(['haspyout_transformer'], | ||
|
r9237 | config=True, | ||
|
r9304 | help= """ | ||
An ordered list of pre transformer to apply to the ipynb | ||||
file befor running through templates | ||||
|
r9214 | """ | ||
) | ||||
|
r9218 | |||
|
r9234 | tex_environement = Bool(False, | ||
config=True, | ||||
help=""" is this a tex environment or not """) | ||||
template_file = Unicode('', | ||||
config=True, | ||||
|
r9332 | help=""" Name of the template file to use """ ) | ||
|
r8994 | #------------------------------------------------------------------------- | ||
# Instance-level attributes that are set in the constructor for this | ||||
# class. | ||||
#------------------------------------------------------------------------- | ||||
|
r9214 | |||
|
r8994 | |||
|
r9332 | preprocessors = [] | ||
def __init__(self, preprocessors={}, jinja_filters={}, config=None, **kw): | ||||
|
r9424 | """ Init a new converter. | ||
config: the Configurable confgg object to pass around | ||||
|
r9184 | |||
|
r9424 | preprocessors: dict of **availlable** key/value function to run on | ||
ipynb json data before conversion to extract/inline file, | ||||
jinja_filter : dict of supplementary jinja filter that should be made | ||||
availlable in template. If those are of Configurable Class type, they | ||||
will be instanciated with the config object as argument. | ||||
|
r9184 | |||
""" | ||||
|
r9229 | super(ConverterTemplate, self).__init__(config=config, **kw) | ||
|
r9234 | self.env = texenv if self.tex_environement else env | ||
self.ext = '.tplx' if self.tex_environement else '.tpl' | ||||
|
r9307 | |||
|
r9302 | for name in self.pre_transformer_order: | ||
|
r9332 | transformer = getattr(preprocessors, name, getattr(trans, name, None)) | ||
if isinstance(transformer, MetaHasTraits): | ||||
transformer = transformer(config=config) | ||||
self.preprocessors.append(transformer) | ||||
## for compat, remove later | ||||
|
r9492 | self.preprocessors.append(trans.coalesce_streams) | ||
|
r9424 | self.preprocessors.append(trans.ExtractFigureTransformer(config=config)) | ||
|
r9401 | self.preprocessors.append(trans.RevealHelpTransformer(config=config)) | ||
|
r9490 | self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config)) | ||
|
r9229 | |||
|
r9332 | ## | ||
|
r9424 | self.env.filters['filter_data_type'] = FilterDataType(config=config) | ||
|
r9229 | self.env.filters['pycomment'] = python_comment | ||
self.env.filters['indent'] = indent | ||||
self.env.filters['rm_fake'] = rm_fake | ||||
self.env.filters['rm_ansi'] = remove_ansi | ||||
self.env.filters['markdown'] = markdown | ||||
self.env.filters['highlight'] = highlight | ||||
self.env.filters['ansi2html'] = ansi2html | ||||
self.env.filters['markdown2latex'] = markdown2latex | ||||
|
r9333 | self.env.filters['markdown2rst'] = markdown2rst | ||
|
r9424 | for key, filtr in jinja_filters.iteritems(): | ||
if isinstance(filtr, MetaHasTraits): | ||||
self.env.filters[key] = filtr(config=config) | ||||
else : | ||||
self.env.filters[key] = filtr | ||||
|
r9229 | |||
|
r9234 | self.template = self.env.get_template(self.template_file+self.ext) | ||
|
r9214 | |||
|
r8994 | |||
|
r9332 | def process(self, nb): | ||
|
r9209 | """ | ||
|
r9218 | preprocess the notebook json for easier use with the templates. | ||
will call all the `preprocessor`s in order before returning it. | ||||
|
r9209 | """ | ||
|
r9184 | |||
|
r9229 | # dict of 'resources' that could be made by the preprocessors | ||
# like key/value data to extract files from ipynb like in latex conversion | ||||
resources = {} | ||||
|
r9184 | for preprocessor in self.preprocessors: | ||
|
r9303 | nb, resources = preprocessor(nb, resources) | ||
|
r9184 | |||
|
r9229 | return nb, resources | ||
|
r8994 | |||
|
r9332 | def convert(self, nb): | ||
|
r9182 | """ convert the ipynb file | ||
return both the converted ipynb file and a dict containing potential | ||||
other resources | ||||
""" | ||||
|
r9332 | nb, resources = self.process(nb) | ||
|
r9490 | return self.template.render(nb=nb, resources=resources), resources | ||
|
r8994 | |||
|
r9332 | def from_filename(self, filename): | ||
|
r8994 | "read and parse notebook into NotebookNode called self.nb" | ||
|
r9014 | with io.open(filename) as f: | ||
|
r9332 | return self.convert(nbformat.read(f, 'json')) | ||
|
r9307 | |||
|
r9424 | |||
|
r9490 | |||