##// END OF EJS Templates
Fixed missed line, made fix win specific
Fixed missed line, made fix win specific

File last commit:

r12219:60e06808
r12385:0d6b7e45
Show More
exporter.py
518 lines | 18.9 KiB | text/x-python | PythonLexer
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """This module defines Exporter, a highly configurable converter
that uses Jinja2 to export notebook files into different formats.
Matthias BUSSONNIER
starting templates
r9578 """
Matthias BUSSONNIER
fix some relative path issues
r9819
Matthias BUSSONNIER
starting templates
r9578 #-----------------------------------------------------------------------------
Matthias BUSSONNIER
document
r9665 # Copyright (c) 2013, the IPython Development Team.
Matthias BUSSONNIER
starting templates
r9578 #
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
Jonathan Frederic
Cleanup and refactor of API, almost complete....
r10677
Jonathan Frederic
Refactoring for the rename of ConverterTemplate to Exporter.
r10430 from __future__ import print_function, absolute_import
Matthias BUSSONNIER
document
r9665
# Stdlib imports
import io
Matthias BUSSONNIER
fix some relative path issues
r9819 import os
Jonathan Frederic
Fixed problem with data type filter construction.
r10631 import inspect
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 import copy
import collections
import datetime
Matthias BUSSONNIER
document
r9665
Brian E. Granger
Fixing import for nbconvert.
r11089 # other libs/dependencies
Jonathan Frederic
Catch specific error instead of all errors.
r11751 from jinja2 import Environment, FileSystemLoader, ChoiceLoader, TemplateNotFound
Brian E. Granger
Fixing import for nbconvert.
r11089
Matthias BUSSONNIER
document
r9665 # IPython imports
MinRK
don't reload template on every export...
r11844 from IPython.config.configurable import LoggingConfigurable
Matthias BUSSONNIER
start tinkerign with config system
r10862 from IPython.config import Config
Matthias BUSSONNIER
document
r9665 from IPython.nbformat import current as nbformat
MinRK
don't reload template on every export...
r11844 from IPython.utils.traitlets import MetaHasTraits, DottedObjectName, Unicode, List, Dict, Any
Jonathan Frederic
Added writers and supporting code.
r11367 from IPython.utils.importstring import import_item
Jonathan Frederic
Removed uneccessary jinja_filters class. Merged code into exporter class....
r10432 from IPython.utils.text import indent
Jonathan Frederic
Fixes for Py3.3
r11547 from IPython.utils import py3compat
Matthias BUSSONNIER
do a markdown converter
r9701
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 from IPython.nbconvert import preprocessors as nbpreprocessors
Brian E. Granger
Fixing import for nbconvert.
r11089 from IPython.nbconvert import filters
Jonathan Frederic
Refactoring for the rename of ConverterTemplate to Exporter.
r10430
Jonathan Frederic
Create exceptions file to house all of the convert specific exceptions....
r10431 #-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------
Matthias BUSSONNIER
document
r9665
Jonathan Frederic
Create exceptions file to house all of the convert specific exceptions....
r10431 #Jinja2 extensions to load.
JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
Matthias BUSSONNIER
fix filters documentation....
r10838 default_filters = {
'indent': indent,
Jonathan Frederic
Filter names cleanup
r11685 'markdown2html': filters.markdown2html,
Brian E. Granger
Fixing import for nbconvert.
r11089 'ansi2html': filters.ansi2html,
'filter_data_type': filters.DataTypeFilter,
'get_lines': filters.get_lines,
Jonathan Frederic
Filter names cleanup
r11685 'highlight2html': filters.highlight2html,
Brian E. Granger
Fixing import for nbconvert.
r11089 'highlight2latex': filters.highlight2latex,
MinRK
convert IPython syntax to Python syntax in nbconvert python template...
r11711 'ipython2python': filters.ipython2python,
MinRK
add posix_path filter...
r11972 'posix_path': filters.posix_path,
Brian E. Granger
Fixing import for nbconvert.
r11089 'markdown2latex': filters.markdown2latex,
'markdown2rst': filters.markdown2rst,
Jonathan Frederic
Filter names cleanup
r11685 'comment_lines': filters.comment_lines,
'strip_ansi': filters.strip_ansi,
'strip_dollars': filters.strip_dollars,
'strip_files_prefix': filters.strip_files_prefix,
'html2text' : filters.html2text,
MinRK
add html_text and add_anchor filters...
r11302 'add_anchor': filters.add_anchor,
Brian E. Granger
Fixing import for nbconvert.
r11089 'ansi2latex': filters.ansi2latex,
Jonathan Frederic
Filter names cleanup
r11685 'strip_math_space': filters.strip_math_space,
'wrap_text': filters.wrap_text,
MinRK
add posix_path filter...
r11972 'escape_latex': filters.escape_latex,
Matthias BUSSONNIER
fix filters documentation....
r10838 }
Jonathan Frederic
Create exceptions file to house all of the convert specific exceptions....
r10431 #-----------------------------------------------------------------------------
Jonathan Frederic
Cleanup and refactor of API, almost complete....
r10677 # Class
Matthias BUSSONNIER
document
r9665 #-----------------------------------------------------------------------------
Jonathan Frederic
Cleanup and refactor of API, almost complete....
r10677
Jonathan Frederic
Forgot to checkin new ResourcesDict class...
r11398 class ResourcesDict(collections.defaultdict):
def __missing__(self, key):
return ''
MinRK
don't reload template on every export...
r11844 class Exporter(LoggingConfigurable):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Exports notebooks into other file formats. Uses Jinja 2 templating engine
to output new formats. Inherit from this class if you are creating a new
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 template type along with new filters/preprocessors. If the filters/
preprocessors provided by default suffice, there is no need to inherit from
Jonathan Frederic
Finished rename/refact on API namespace
r10690 this class. Instead, override the template_file and file_extension
traits via a config file.
Jonathan Frederic
Fixed, accidental deletion of format string specifier.
r11750
Matthias BUSSONNIER
fix filters documentation....
r10838 {filters}
"""
Matthias BUSSONNIER
finish up config merging
r10874
# finish the docstring
Matthias BUSSONNIER
fix filters documentation....
r10838 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
Jonathan Frederic
flavor=template
r11745 template_file = Unicode(u'default',
Jonathan Frederic
Part way through adding 'flavor' support
r11733 config=True,
Jonathan Frederic
Create exceptions file to house all of the convert specific exceptions....
r10431 help="Name of the template file to use")
Jonathan Frederic
flavor=template
r11745 def _template_file_changed(self, name, old, new):
if new=='default':
self.template_file = self.default_template
else:
self.template_file = new
MinRK
clear template when template_file changes
r11860 self.template = None
MinRK
don't reload template on every export...
r11844 self._load_template()
Jonathan Frederic
flavor=template
r11745 default_template = Unicode(u'')
MinRK
don't reload template on every export...
r11844 template = Any()
environment = Any()
Jonathan Frederic
Added datetime access to Jinja
r9768
Jonathan Frederic
Added latexexporter
r10587 file_extension = Unicode(
Jonathan Frederic
Removed "profiles"... Templates that are shipped with nbconvert by default should...
r10435 'txt', config=True,
help="Extension of the file that should be written to disk"
)
Jonathan Frederic
s/templat_paths/templat_path
r11655 template_path = List(['.'], config=True)
MinRK
don't reload template on every export...
r11844 def _template_path_changed(self, name, old, new):
self._load_template()
Jonathan Frederic
Add cwd to default templates search path.
r11648
default_template_path = Unicode(
os.path.join("..", "templates"),
Jonathan Frederic
Finished rename/refact on API namespace
r10690 help="Path where the template files are located.")
template_skeleton_path = Unicode(
Jonathan Frederic
Add cwd to default templates search path.
r11648 os.path.join("..", "templates", "skeleton"),
Jonathan Frederic
Finished rename/refact on API namespace
r10690 help="Path where the template skeleton files are located.")
#Jinja block definitions
Jonathan Frederic
Fixed error due to Unicode traitlets not supporting None type.
r10693 jinja_comment_block_start = Unicode("", config=True)
jinja_comment_block_end = Unicode("", config=True)
jinja_variable_block_start = Unicode("", config=True)
jinja_variable_block_end = Unicode("", config=True)
jinja_logic_block_start = Unicode("", config=True)
jinja_logic_block_end = Unicode("", config=True)
Jonathan Frederic
Finished rename/refact on API namespace
r10690
Jonathan Frederic
Fixed all broken references, refactored some stuff here and there,...
r10624 #Extension that the template files use.
Jonathan Frederic
Finished rename/refact on API namespace
r10690 template_extension = Unicode(".tpl", config=True)
Jonathan Frederic
Fixed all broken references, refactored some stuff here and there,...
r10624
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 #Configurability, allows the user to easily add filters and preprocessors.
preprocessors = List(config=True,
help="""List of preprocessors, by name or namespace, to enable.""")
Matthias BUSSONNIER
stateless converter
r9640
Jonathan Frederic
Added writers and supporting code.
r11367 filters = Dict(config=True,
help="""Dictionary of filters, by name and namespace, to add to the Jinja
environment.""")
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 default_preprocessors = List([nbpreprocessors.coalesce_streams,
nbpreprocessors.SVG2PDFPreprocessor,
nbpreprocessors.ExtractOutputPreprocessor,
nbpreprocessors.CSSHTMLHeaderPreprocessor,
nbpreprocessors.RevealHelpPreprocessor,
nbpreprocessors.LatexPreprocessor,
nbpreprocessors.SphinxPreprocessor],
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 config=True,
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 help="""List of preprocessors available by default, by name, namespace,
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 instance, or type.""")
Jonathan Frederic
Moved default transformer registration into base
r11429
Jonathan Frederic
Added writers and supporting code.
r11367 def __init__(self, config=None, extra_loaders=None, **kw):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Public constructor
Jonathan Frederic
Post code-review, extended refactor.
r10485
Jonathan Frederic
Finished rename/refact on API namespace
r10690 Parameters
----------
config : config
User configuration instance.
Matthias BUSSONNIER
Allow custom nbconvert template loaders...
r11279 extra_loaders : list[of Jinja Loaders]
MinRK
more default_config into Exporter._config_changed
r11845 ordered list of Jinja loader to find templates. Will be tried in order
before the default FileSystem ones.
Jonathan Frederic
flavor=template
r11745 template : str (optional, kw arg)
Template to use when exporting.
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
MinRK
don't allow 'template' to specify 'template_file'...
r11852 if not config:
config = self.default_config
Jonathan Frederic
Finished rename/refact on API namespace
r10690
MinRK
more default_config into Exporter._config_changed
r11845 super(Exporter, self).__init__(config=config, **kw)
Matthias BUSSONNIER
document
r9665
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 #Init
MinRK
don't allow 'template' to specify 'template_file'...
r11852 self._init_template()
Matthias BUSSONNIER
Allow custom nbconvert template loaders...
r11279 self._init_environment(extra_loaders=extra_loaders)
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 self._init_preprocessors()
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 self._init_filters()
Matthias BUSSONNIER
create configurable preprocessors
r9624
Matthias BUSSONNIER
start tinkerign with config system
r10862
@property
def default_config(self):
Matthias BUSSONNIER
fix config inheriting
r10963 return Config()
MinRK
more default_config into Exporter._config_changed
r11845
def _config_changed(self, name, old, new):
MinRK
docstrings
r11848 """When setting config, make sure to start with our default_config"""
MinRK
more default_config into Exporter._config_changed
r11845 c = self.default_config
if new:
c.merge(new)
MinRK
don't allow 'template' to specify 'template_file'...
r11852 if c != old:
MinRK
more default_config into Exporter._config_changed
r11845 self.config = c
MinRK
don't allow 'template' to specify 'template_file'...
r11852 super(Exporter, self)._config_changed(name, old, c)
MinRK
more default_config into Exporter._config_changed
r11845
Matthias BUSSONNIER
fix config inheriting
r10963
MinRK
don't reload template on every export...
r11844 def _load_template(self):
MinRK
docstrings
r11848 """Load the Jinja template object from the template file
This is a no-op if the template attribute is already defined,
or the Jinja environment is not setup yet.
This is triggered by various trait changes that would change the template.
"""
MinRK
don't reload template on every export...
r11844 if self.template is not None:
return
# called too early, do nothing
if self.environment is None:
return
# Try different template names during conversion. First try to load the
# template by name with extension added, then try loading the template
# as if the name is explicitly specified, then try the name as a
# 'flavor', and lastly just try to load the template by module name.
module_name = self.__module__.rsplit('.', 1)[-1]
MinRK
don't try template names we know to be invalid...
r11952 try_names = []
if self.template_file:
try_names.extend([
self.template_file + self.template_extension,
self.template_file,
module_name + '_' + self.template_file + self.template_extension,
])
try_names.append(module_name + self.template_extension)
MinRK
don't reload template on every export...
r11844 for try_name in try_names:
self.log.debug("Attempting to load template %s", try_name)
try:
self.template = self.environment.get_template(try_name)
MinRK
catch IOError loading templates...
r11951 except (TemplateNotFound, IOError):
MinRK
don't reload template on every export...
r11844 pass
MinRK
catch IOError loading templates...
r11951 except Exception as e:
self.log.warn("Unexpected exception loading template: %s", try_name, exc_info=True)
MinRK
don't reload template on every export...
r11844 else:
self.log.info("Loaded template %s", try_name)
break
Jonathan Frederic
Finished a rough draft of the exporters.
r10588
Jonathan Frederic
Fixes "bugs with mutable defaults args", thanks @Carreau
r11376 def from_notebook_node(self, nb, resources=None, **kw):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Convert a notebook from a notebook node instance.
Parameters
----------
nb : Notebook node
Jonathan Frederic
Added writers and supporting code.
r11367 resources : dict (**kw)
of additional resources that can be accessed read/write by
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 preprocessors and filters.
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 nb_copy = copy.deepcopy(nb)
resources = self._init_resources(resources)
Jonathan Frederic
Changes after in person review with @ellisonbg including TODO tags
r11379
Jonathan Frederic
flavor=template
r11745 # Preprocess
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 nb_copy, resources = self._preprocess(nb_copy, resources)
Matthias BUSSONNIER
starting templates
r9578
MinRK
don't reload template on every export...
r11844 self._load_template()
Jonathan Frederic
flavor=template
r11745
MinRK
don't reload template on every export...
r11844 if self.template is not None:
Jonathan Frederic
flavor=template
r11745 output = self.template.render(nb=nb_copy, resources=resources)
else:
raise IOError('template file "%s" could not be found' % self.template_file)
Jonathan Frederic
Added writers and supporting code.
r11367 return output, resources
Matthias BUSSONNIER
starting templates
r9578
Jonathan Frederic
Added writers and supporting code.
r11367
Jonathan Frederic
Changes after in person review with @ellisonbg including TODO tags
r11379 def from_filename(self, filename, resources=None, **kw):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Convert a notebook from a notebook file.
Parameters
----------
filename : str
Full filename of the notebook file to open and convert.
"""
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383
#Pull the metadata from the filesystem.
Jonathan Frederic
Fixed case where no resources are provided
r11425 if resources is None:
resources = ResourcesDict()
if not 'metadata' in resources or resources['metadata'] == '':
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 resources['metadata'] = ResourcesDict()
basename = os.path.basename(filename)
notebook_name = basename[:basename.rfind('.')]
resources['metadata']['name'] = notebook_name
modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
Jörgen Stenarson
Fix for #3719...
r11622 resources['metadata']['modified_date'] = modified_date.strftime("%B %d, %Y")
Jonathan Frederic
Finished rename/refact on API namespace
r10690
Jonathan Frederic
Create exceptions file to house all of the convert specific exceptions....
r10431 with io.open(filename) as f:
Jonathan Frederic
Added writers and supporting code.
r11367 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources,**kw)
Jonathan Frederic
Create exceptions file to house all of the convert specific exceptions....
r10431
Jonathan Frederic
Removed uneccessary jinja_filters class. Merged code into exporter class....
r10432
Jonathan Frederic
Fixes "bugs with mutable defaults args", thanks @Carreau
r11376 def from_file(self, file_stream, resources=None, **kw):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Convert a notebook from a notebook file.
Parameters
----------
file_stream : file-like object
Notebook file-like object to convert.
"""
Jonathan Frederic
Added writers and supporting code.
r11367 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
Jonathan Frederic
More clean-up. Nomenclature changes
r10578
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 def register_preprocessor(self, preprocessor, enabled=False):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 Register a preprocessor.
Preprocessors are classes that act upon the notebook before it is
passed into the Jinja templating engine. Preprocessors are also
Jonathan Frederic
Finished rename/refact on API namespace
r10690 capable of passing additional information to the Jinja
templating engine.
Parameters
----------
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 preprocessor : preprocessor
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 if preprocessor is None:
raise TypeError('preprocessor')
isclass = isinstance(preprocessor, type)
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 constructed = not isclass
Jonathan Frederic
Added writers and supporting code.
r11367
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 #Handle preprocessor's registration based on it's type
if constructed and isinstance(preprocessor, py3compat.string_types):
#Preprocessor is a string, import the namespace and recursively call
#this register_preprocessor method
preprocessor_cls = import_item(preprocessor)
return self.register_preprocessor(preprocessor_cls, enabled)
Jonathan Frederic
Finished rename/refact on API namespace
r10690
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 if constructed and hasattr(preprocessor, '__call__'):
#Preprocessor is a function, no need to construct it.
#Register and return the preprocessor.
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 if enabled:
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 preprocessor.enabled = True
self._preprocessors.append(preprocessor)
return preprocessor
Jonathan Frederic
Added writers and supporting code.
r11367
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 elif isclass and isinstance(preprocessor, MetaHasTraits):
#Preprocessor is configurable. Make sure to pass in new default for
Jonathan Frederic
Added writers and supporting code.
r11367 #the enabled flag if one was specified.
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 self.register_preprocessor(preprocessor(parent=self), enabled)
Jonathan Frederic
Added writers and supporting code.
r11367
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 elif isclass:
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 #Preprocessor is not configurable, construct it
self.register_preprocessor(preprocessor(), enabled)
Jonathan Frederic
Added writers and supporting code.
r11367
Jonathan Frederic
Added latexexporter
r10587 else:
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 #Preprocessor is an instance of something without a __call__
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 #attribute.
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 raise TypeError('preprocessor')
Jonathan Frederic
Added latexexporter
r10587
Jonathan Frederic
Fixes for Py3.3
r11547 def register_filter(self, name, jinja_filter):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Register a filter.
A filter is a function that accepts and acts on one string.
The filters are accesible within the Jinja templating engine.
Parameters
----------
name : str
name to give the filter in the Jinja engine
filter : filter
"""
Jonathan Frederic
Fixes for Py3.3
r11547 if jinja_filter is None:
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 raise TypeError('filter')
Jonathan Frederic
Fixes for Py3.3
r11547 isclass = isinstance(jinja_filter, type)
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 constructed = not isclass
#Handle filter's registration based on it's type
Jonathan Frederic
Fixes for Py3.3
r11547 if constructed and isinstance(jinja_filter, py3compat.string_types):
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 #filter is a string, import the namespace and recursively call
#this register_filter method
Jonathan Frederic
Fixes for Py3.3
r11547 filter_cls = import_item(jinja_filter)
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 return self.register_filter(name, filter_cls)
Jonathan Frederic
Fixes for Py3.3
r11547 if constructed and hasattr(jinja_filter, '__call__'):
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 #filter is a function, no need to construct it.
Jonathan Frederic
Fixes for Py3.3
r11547 self.environment.filters[name] = jinja_filter
return jinja_filter
Jonathan Frederic
Fixed logic for register filter and transformer
r11428
Jonathan Frederic
Fixes for Py3.3
r11547 elif isclass and isinstance(jinja_filter, MetaHasTraits):
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 #filter is configurable. Make sure to pass in new default for
#the enabled flag if one was specified.
Jonathan Frederic
Fixes for Py3.3
r11547 filter_instance = jinja_filter(parent=self)
self.register_filter(name, filter_instance )
Jonathan Frederic
Fixed logic for register filter and transformer
r11428
elif isclass:
#filter is not configurable, construct it
Jonathan Frederic
Fixes for Py3.3
r11547 filter_instance = jinja_filter()
self.register_filter(name, filter_instance)
Jonathan Frederic
Fixed logic for register filter and transformer
r11428
Jonathan Frederic
More clean-up. Nomenclature changes
r10578 else:
Jonathan Frederic
Fixed logic for register filter and transformer
r11428 #filter is an instance of something without a __call__
#attribute.
raise TypeError('filter')
Jonathan Frederic
More clean-up. Nomenclature changes
r10578
Jonathan Frederic
Finished a rough draft of the exporters.
r10588
MinRK
don't allow 'template' to specify 'template_file'...
r11852 def _init_template(self):
Jonathan Frederic
Part way through adding 'flavor' support
r11733 """
Make sure a template name is specified. If one isn't specified, try to
build one from the information we know.
"""
Jonathan Frederic
flavor=template
r11745 self._template_file_changed('template_file', self.template_file, self.template_file)
Jonathan Frederic
Part way through adding 'flavor' support
r11733
Matthias BUSSONNIER
Allow custom nbconvert template loaders...
r11279 def _init_environment(self, extra_loaders=None):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Create the Jinja templating environment.
"""
MinRK
fix path prefix in nbconvert...
r11197 here = os.path.dirname(os.path.realpath(__file__))
Matthias BUSSONNIER
Allow custom nbconvert template loaders...
r11279 loaders = []
if extra_loaders:
loaders.extend(extra_loaders)
Jonathan Frederic
s/templat_paths/templat_path
r11655 paths = self.template_path
Jonathan Frederic
Add cwd to default templates search path.
r11648 paths.extend([os.path.join(here, self.default_template_path),
os.path.join(here, self.template_skeleton_path)])
loaders.append(FileSystemLoader(paths))
Matthias BUSSONNIER
Allow custom nbconvert template loaders...
r11279
self.environment = Environment(
loader= ChoiceLoader(loaders),
Jonathan Frederic
Post code-review, extended refactor.
r10485 extensions=JINJA_EXTENSIONS
)
Jonathan Frederic
Finished rename/refact on API namespace
r10690
#Set special Jinja2 syntax that will not conflict with latex.
Jonathan Frederic
Fixed error due to Unicode traitlets not supporting None type.
r10693 if self.jinja_logic_block_start:
Jonathan Frederic
Finished rename/refact on API namespace
r10690 self.environment.block_start_string = self.jinja_logic_block_start
Jonathan Frederic
Fixed error due to Unicode traitlets not supporting None type.
r10693 if self.jinja_logic_block_end:
Jonathan Frederic
Finished rename/refact on API namespace
r10690 self.environment.block_end_string = self.jinja_logic_block_end
Jonathan Frederic
Fixed error due to Unicode traitlets not supporting None type.
r10693 if self.jinja_variable_block_start:
Jonathan Frederic
Finished rename/refact on API namespace
r10690 self.environment.variable_start_string = self.jinja_variable_block_start
Jonathan Frederic
Fixed error due to Unicode traitlets not supporting None type.
r10693 if self.jinja_variable_block_end:
Jonathan Frederic
Finished rename/refact on API namespace
r10690 self.environment.variable_end_string = self.jinja_variable_block_end
Jonathan Frederic
Fixed error due to Unicode traitlets not supporting None type.
r10693 if self.jinja_comment_block_start:
Jonathan Frederic
Finished rename/refact on API namespace
r10690 self.environment.comment_start_string = self.jinja_comment_block_start
Jonathan Frederic
Fixed error due to Unicode traitlets not supporting None type.
r10693 if self.jinja_comment_block_end:
Jonathan Frederic
Finished rename/refact on API namespace
r10690 self.environment.comment_end_string = self.jinja_comment_block_end
Jonathan Frederic
Post code-review, extended refactor.
r10485
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 def _init_preprocessors(self):
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 """
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 Register all of the preprocessors needed for this exporter, disabled
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 unless specified explicitly.
"""
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 self._preprocessors = []
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 #Load default preprocessors (not necessarly enabled by default).
if self.default_preprocessors:
for preprocessor in self.default_preprocessors:
self.register_preprocessor(preprocessor)
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 #Load user preprocessors. Enable by default.
if self.preprocessors:
for preprocessor in self.preprocessors:
self.register_preprocessor(preprocessor, enabled=True)
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383
def _init_filters(self):
"""
Register all of the filters required for the exporter.
"""
#Add default filters to the Jinja2 environment
Jonathan Frederic
Fixes for Py3.3
r11547 for key, value in default_filters.items():
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 self.register_filter(key, value)
#Load user filters. Overwrite existing filters if need be.
if self.filters:
Jonathan Frederic
Fixes for Py3.3
r11547 for key, user_filter in self.filters.items():
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 self.register_filter(key, user_filter)
def _init_resources(self, resources):
Jonathan Frederic
Post code-review, extended refactor.
r10485
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383 #Make sure the resources dict is of ResourcesDict type.
if resources is None:
resources = ResourcesDict()
if not isinstance(resources, ResourcesDict):
new_resources = ResourcesDict()
new_resources.update(resources)
resources = new_resources
#Make sure the metadata extension exists in resources
if 'metadata' in resources:
if not isinstance(resources['metadata'], ResourcesDict):
resources['metadata'] = ResourcesDict(resources['metadata'])
else:
resources['metadata'] = ResourcesDict()
Jonathan Frederic
Only set name if it doesn't exist!
r11402 if not resources['metadata']['name']:
Jonathan Frederic
Added commit accidently removed...
r11403 resources['metadata']['name'] = 'Notebook'
Jonathan Frederic
Transformers in traitlet lists now, new _init_ methods,...
r11383
#Set the output extension
resources['output_extension'] = self.file_extension
return resources
Jonathan Frederic
Post code-review, extended refactor.
r10485
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 def _preprocess(self, nb, resources):
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Preprocess the notebook before passing it into the Jinja engine.
To preprocess the notebook is to apply all of the
Parameters
----------
nb : notebook node
notebook that is being exported.
Matthias BUSSONNIER
allow to pass a resource dict with notebook...
r10837 resources : a dict of additional resources that
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 can be accessed read/write by preprocessors
Matthias BUSSONNIER
allow to pass a resource dict with notebook...
r10837 and filters.
Jonathan Frederic
Finished rename/refact on API namespace
r10690 """
Jonathan Frederic
Changed copy import to be explicit in code
r11399 # Do a copy.deepcopy first,
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 # we are never safe enough with what the preprocessors could do.
Jonathan Frederic
Changed copy import to be explicit in code
r11399 nbc = copy.deepcopy(nb)
resc = copy.deepcopy(resources)
Jonathan Frederic
Added writers and supporting code.
r11367
Paul Ivanov
replace 'transformer' with 'preprocessor'
r12219 #Run each preprocessor on the notebook. Carry the output along
#to each preprocessor
for preprocessor in self._preprocessors:
nbc, resc = preprocessor(nbc, resc)
Jonathan Frederic
Added writers and supporting code.
r11367 return nbc, resc