##// END OF EJS Templates
Remove version
Remove version

File last commit:

r18606:776d1fa8
r18645:26a7adc7
Show More
exporter.py
259 lines | 9.0 KiB | text/x-python | PythonLexer
MinRK
add raw_format to Exporter classes...
r13664 """This module defines a base Exporter class. For Jinja template-based export,
see templateexporter.py.
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
from __future__ import print_function, absolute_import
import io
import os
import copy
import collections
import datetime
from IPython.config.configurable import LoggingConfigurable
from IPython.config import Config
MinRK
Don't use nbformat.current in nbconvert
r18605 from IPython import nbformat
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
from IPython.utils.importstring import import_item
Jonathan Frederic
Rebase changes made by hand
r12505 from IPython.utils import text, py3compat
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
class ResourcesDict(collections.defaultdict):
def __missing__(self, key):
return ''
Jonathan Frederic
Rebase changes made by hand
r12505 class Exporter(LoggingConfigurable):
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
Jonathan Frederic
@MinRK fix suggestions
r12518 Class containing methods that sequentially run a list of preprocessors on a
NotebookNode object and then return the modified NotebookNode object and
accompanying resources dict.
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
file_extension = Unicode(
'txt', config=True,
help="Extension of the file that should be written to disk"
)
Thomas Kluyver
Make output_mimetype accessible from the class....
r13834 # MIME type of the result file, for HTTP response headers.
# This is *not* a traitlet, because we want to be able to access it from
# the class, not just on instances.
output_mimetype = ''
Thomas Kluyver
Add MIME types to nbconvert exporters
r13830
Jonathan Frederic
Rebase changes made by hand
r12505 #Configurability, allows the user to easily add filters and preprocessors.
preprocessors = List(config=True,
help="""List of preprocessors, by name or namespace, to enable.""")
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
MinRK
avoid loading preprocessors twice...
r15774 _preprocessors = List()
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Matthias BUSSONNIER
traits defauts are strings not object...
r12826 default_preprocessors = List(['IPython.nbconvert.preprocessors.coalesce_streams',
'IPython.nbconvert.preprocessors.SVG2PDFPreprocessor',
'IPython.nbconvert.preprocessors.ExtractOutputPreprocessor',
'IPython.nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
'IPython.nbconvert.preprocessors.LatexPreprocessor',
Julia Evans
Add preprocessor that clears cell outputs
r16295 'IPython.nbconvert.preprocessors.ClearOutputPreprocessor',
Julia Evans
Add preprocessor to execute notebooks
r17074 'IPython.nbconvert.preprocessors.ExecutePreprocessor',
Matthias BUSSONNIER
traits defauts are strings not object...
r12826 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 config=True,
Jonathan Frederic
Rebase changes made by hand
r12505 help="""List of preprocessors available by default, by name, namespace,
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 instance, or type.""")
def __init__(self, config=None, **kw):
"""
Public constructor
Parameters
----------
config : config
User configuration instance.
"""
MinRK
don't recursively reassign config in Exporter._config_changed
r13472 with_default_config = self.default_config
if config:
with_default_config.merge(config)
super(Exporter, self).__init__(config=with_default_config, **kw)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Jonathan Frederic
Rebase changes made by hand
r12505 self._init_preprocessors()
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
@property
def default_config(self):
return Config()
Jonathan Frederic
@MinRK fix suggestions
r12518 def from_notebook_node(self, nb, resources=None, **kw):
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
Convert a notebook from a notebook node instance.
Parameters
----------
MinRK
move NotebookNode to top-level...
r18606 nb : :class:`~IPython.nbformat.NotebookNode`
MinRK
Don't use nbformat.current in nbconvert
r18605 Notebook node (dict-like with attr-access)
Thomas Kluyver
More fixes to doc formatting
r13598 resources : dict
Additional resources that can be accessed read/write by
preprocessors and filters.
**kw
Ignored (?)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
nb_copy = copy.deepcopy(nb)
resources = self._init_resources(resources)
MinRK
allow highlighting language to be set from notebook metadata
r15672
if 'language' in nb['metadata']:
resources['language'] = nb['metadata']['language'].lower()
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
# Preprocess
Jonathan Frederic
@MinRK fix suggestions
r12518 nb_copy, resources = self._preprocess(nb_copy, resources)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
return nb_copy, resources
def from_filename(self, filename, resources=None, **kw):
"""
Convert a notebook from a notebook file.
Parameters
----------
filename : str
Full filename of the notebook file to open and convert.
"""
Jonathan Frederic
Rebase changes made by hand
r12505 # Pull the metadata from the filesystem.
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 if resources is None:
resources = ResourcesDict()
if not 'metadata' in resources or resources['metadata'] == '':
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))
Jonathan Frederic
Rebase changes made by hand
r12505 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Thomas Kluyver
Specify encoding for reading notebook file....
r13656 with io.open(filename, encoding='utf-8') as f:
MinRK
Don't use nbformat.current in nbconvert
r18605 return self.from_notebook_node(nbformat.read(f, as_version=4), resources=resources, **kw)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
def from_file(self, file_stream, resources=None, **kw):
"""
Convert a notebook from a notebook file.
Parameters
----------
file_stream : file-like object
Notebook file-like object to convert.
"""
MinRK
Don't use nbformat.current in nbconvert
r18605 return self.from_notebook_node(nbformat.read(file_stream, as_version=4), resources=resources, **kw)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Jonathan Frederic
Rebase changes made by hand
r12505 def register_preprocessor(self, preprocessor, enabled=False):
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
Jonathan Frederic
Rebase changes made by hand
r12505 Register a preprocessor.
Jonathan Frederic
@MinRK fix suggestions
r12518 Preprocessors are classes that act upon the notebook before it is
Jonathan Frederic
Rebase changes made by hand
r12505 passed into the Jinja templating engine. preprocessors are also
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 capable of passing additional information to the Jinja
templating engine.
Parameters
----------
Jonathan Frederic
Rebase changes made by hand
r12505 preprocessor : preprocessor
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
Jonathan Frederic
Rebase changes made by hand
r12505 if preprocessor is None:
raise TypeError('preprocessor')
isclass = isinstance(preprocessor, type)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 constructed = not isclass
Jonathan Frederic
Moved add_prompts into correct location.
r12708 # Handle preprocessor's registration based on it's type
Jonathan Frederic
Rebase changes made by hand
r12505 if constructed and isinstance(preprocessor, py3compat.string_types):
Jonathan Frederic
Moved add_prompts into correct location.
r12708 # Preprocessor is a string, import the namespace and recursively call
# this register_preprocessor method
Jonathan Frederic
Rebase changes made by hand
r12505 preprocessor_cls = import_item(preprocessor)
return self.register_preprocessor(preprocessor_cls, enabled)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Jonathan Frederic
Rebase changes made by hand
r12505 if constructed and hasattr(preprocessor, '__call__'):
Jonathan Frederic
Moved add_prompts into correct location.
r12708 # Preprocessor is a function, no need to construct it.
# Register and return the preprocessor.
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 if enabled:
Jonathan Frederic
Rebase changes made by hand
r12505 preprocessor.enabled = True
self._preprocessors.append(preprocessor)
return preprocessor
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Jonathan Frederic
Rebase changes made by hand
r12505 elif isclass and isinstance(preprocessor, MetaHasTraits):
Jonathan Frederic
Moved add_prompts into correct location.
r12708 # Preprocessor is configurable. Make sure to pass in new default for
# the enabled flag if one was specified.
Jonathan Frederic
Rebase changes made by hand
r12505 self.register_preprocessor(preprocessor(parent=self), enabled)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
elif isclass:
Jonathan Frederic
Moved add_prompts into correct location.
r12708 # Preprocessor is not configurable, construct it
Jonathan Frederic
Rebase changes made by hand
r12505 self.register_preprocessor(preprocessor(), enabled)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
else:
Jonathan Frederic
Moved add_prompts into correct location.
r12708 # Preprocessor is an instance of something without a __call__
# attribute.
Jonathan Frederic
Rebase changes made by hand
r12505 raise TypeError('preprocessor')
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Jonathan Frederic
Rebase changes made by hand
r12505 def _init_preprocessors(self):
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
Jonathan Frederic
Rebase changes made by hand
r12505 Register all of the preprocessors needed for this exporter, disabled
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 unless specified explicitly.
"""
MinRK
avoid loading preprocessors twice...
r15774 self._preprocessors = []
# Load default preprocessors (not necessarly enabled by default).
for preprocessor in self.default_preprocessors:
self.register_preprocessor(preprocessor)
# Load user-specified preprocessors. Enable by default.
for preprocessor in self.preprocessors:
self.register_preprocessor(preprocessor, enabled=True)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
def _init_resources(self, resources):
#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()
if not resources['metadata']['name']:
resources['metadata']['name'] = 'Notebook'
#Set the output extension
resources['output_extension'] = self.file_extension
return resources
Jonathan Frederic
@MinRK fix suggestions
r12518 def _preprocess(self, nb, resources):
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
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.
resources : a dict of additional resources that
Jonathan Frederic
Rebase changes made by hand
r12505 can be accessed read/write by preprocessors
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 """
# Do a copy.deepcopy first,
Jonathan Frederic
Rebase changes made by hand
r12505 # we are never safe enough with what the preprocessors could do.
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 nbc = copy.deepcopy(nb)
resc = copy.deepcopy(resources)
Jonathan Frederic
Rebase changes made by hand
r12505 #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
renamed: exporter.py -> template_exporter.py
r12502 return nbc, resc