##// END OF EJS Templates
Merge pull request #4979 from minrk/clear-output-msgspec...
Merge pull request #4979 from minrk/clear-output-msgspec add versioning notes to small message spec changes

File last commit:

r13834:39de1467
r15001:cf7b62ae merge
Show More
exporter.py
275 lines | 9.6 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 """
#-----------------------------------------------------------------------------
# Copyright (c) 2013, 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
# Stdlib imports
import io
import os
import copy
import collections
import datetime
# IPython imports
from IPython.config.configurable import LoggingConfigurable
from IPython.config import Config
from IPython.nbformat import current as nbformat
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
#-----------------------------------------------------------------------------
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
Jonathan Frederic
Rebase changes made by hand
r12505 _preprocessors = None
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',
'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()
Thomas Kluyver
Decorator for docstrings referring to objects imported from nbformat.current
r13627 @nbformat.docstring_nbformat_mod
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
----------
Thomas Kluyver
Decorator for docstrings referring to objects imported from nbformat.current
r13627 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
Thomas Kluyver
More fixes to doc formatting
r13598 Notebook node
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)
# 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:
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
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.
"""
return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
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.
"""
Jonathan Frederic
Rebase changes made by hand
r12505 if self._preprocessors is None:
self._preprocessors = []
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Jonathan Frederic
Rebase changes made by hand
r12505 #Load default preprocessors (not necessarly enabled by default).
if self.default_preprocessors:
for preprocessor in self.default_preprocessors:
self.register_preprocessor(preprocessor)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
Jonathan Frederic
Rebase changes made by hand
r12505 #Load user preprocessors. Enable by default.
if self.preprocessors:
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