##// END OF EJS Templates
Make quoting consistent in the new tests
Make quoting consistent in the new tests

File last commit:

r20619:66b1a252
r20924:0af29458
Show More
exporter.py
280 lines | 9.7 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
Jessica B. Hamrick
Inherit from Unicode traitlet
r19469 from IPython.utils.traitlets import MetaHasTraits, Unicode, List, TraitError
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 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 ''
Jessica B. Hamrick
Inherit from Unicode traitlet
r19469 class FilenameExtension(Unicode):
Jessica B. Hamrick
Add extension traitlet to force dotted names
r19460 """A trait for filename extensions."""
default_value = u''
info_text = 'a filename extension, beginning with a dot'
def validate(self, obj, value):
Jessica B. Hamrick
Inherit from Unicode traitlet
r19469 # cast to proper unicode
value = super(FilenameExtension, self).validate(obj, value)
Jessica B. Hamrick
Add extension traitlet to force dotted names
r19460
Jessica B. Hamrick
Inherit from Unicode traitlet
r19469 # check that it starts with a dot
Jessica B. Hamrick
Handle case where value is an empty string
r19471 if value and not value.startswith('.'):
Jessica B. Hamrick
More descriptive error messages
r19464 msg = "FileExtension trait '{}' does not begin with a dot: {!r}"
Jessica B. Hamrick
Add extension traitlet to force dotted names
r19460 raise TraitError(msg.format(self.name, value))
return value
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 """
Jessica B. Hamrick
Rename Extension to FilenameExtension
r19462 file_extension = FilenameExtension(
Thomas Kluyver
Add the . into file_extension
r19027 '.txt', config=True,
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 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()
Jessica B. Hamrick
Make the directory name be the default relpath
r20619 path, basename = os.path.split(filename)
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 notebook_name = basename[:basename.rfind('.')]
resources['metadata']['name'] = notebook_name
Jessica B. Hamrick
Make the directory name be the default relpath
r20619 resources['metadata']['path'] = path
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502
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):
Nicholas Bollweg
fixes #7360 by setting resources.metadata
r19904 new_metadata = ResourcesDict()
new_metadata.update(resources['metadata'])
resources['metadata'] = new_metadata
Jonathan Frederic
renamed: exporter.py -> template_exporter.py
r12502 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