diff --git a/IPython/testing/iptest.py b/IPython/testing/iptest.py index 0b17ced..094e928 100644 --- a/IPython/testing/iptest.py +++ b/IPython/testing/iptest.py @@ -146,7 +146,7 @@ have['zmq'] = test_for('zmq.pyzmq_version_info', min_zmq, callback=lambda x: x() test_group_names = ['core', 'extensions', 'lib', 'terminal', 'testing', 'utils', - 'html', 'nbconvert' + 'html', ] class TestSection(object): @@ -239,22 +239,9 @@ sec.exclude('static') sec.exclude('tasks') if not have['jinja2']: sec.exclude('notebookapp') -if not have['pygments'] or not have['jinja2']: - sec.exclude('nbconvert') if not have['terminado']: sec.exclude('terminal') -# nbconvert: -sec = test_sections['nbconvert'] -sec.requires('pygments', 'jinja2', 'jsonschema', 'mistune') -# Exclude nbconvert directories containing config files used to test. -# Executing the config files with iptest would cause an exception. -sec.exclude('tests.files') -sec.exclude('exporters.tests.files') -if not have['tornado']: - sec.exclude('nbconvert.post_processors.serve') - sec.exclude('nbconvert.post_processors.tests.test_serve') - #----------------------------------------------------------------------------- # Functions and classes diff --git a/jupyter_nbconvert/__init__.py b/jupyter_nbconvert/__init__.py deleted file mode 100755 index 9a915c8..0000000 --- a/jupyter_nbconvert/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Utilities for converting notebooks to and from different formats.""" - -from .exporters import * -from . import filters -from . import preprocessors -from . import postprocessors -from . import writers diff --git a/jupyter_nbconvert/__main__.py b/jupyter_nbconvert/__main__.py deleted file mode 100644 index 8f0dd72..0000000 --- a/jupyter_nbconvert/__main__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .nbconvertapp import launch_new_instance -launch_new_instance() diff --git a/jupyter_nbconvert/exporters/__init__.py b/jupyter_nbconvert/exporters/__init__.py deleted file mode 100644 index c3fee7c..0000000 --- a/jupyter_nbconvert/exporters/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from .export import * -from .html import HTMLExporter -from .slides import SlidesExporter -from .templateexporter import TemplateExporter -from .latex import LatexExporter -from .markdown import MarkdownExporter -from .notebook import NotebookExporter -from .pdf import PDFExporter -from .python import PythonExporter -from .rst import RSTExporter -from .exporter import Exporter, FilenameExtension diff --git a/jupyter_nbconvert/exporters/export.py b/jupyter_nbconvert/exporters/export.py deleted file mode 100644 index 4e78239..0000000 --- a/jupyter_nbconvert/exporters/export.py +++ /dev/null @@ -1,177 +0,0 @@ -"""Module containing single call export functions.""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from functools import wraps - -from IPython.nbformat import NotebookNode -from IPython.utils.decorators import undoc -from IPython.utils.py3compat import string_types - -from .exporter import Exporter -from .templateexporter import TemplateExporter -from .html import HTMLExporter -from .slides import SlidesExporter -from .latex import LatexExporter -from .pdf import PDFExporter -from .markdown import MarkdownExporter -from .python import PythonExporter -from .rst import RSTExporter -from .notebook import NotebookExporter -from .script import ScriptExporter - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -@undoc -def DocDecorator(f): - - #Set docstring of function - f.__doc__ = f.__doc__ + """ - nb : :class:`~IPython.nbformat.NotebookNode` - The notebook to export. - config : config (optional, keyword arg) - User configuration instance. - resources : dict (optional, keyword arg) - Resources used in the conversion process. - - Returns - ------- - tuple- output, resources, exporter_instance - output : str - Jinja 2 output. This is the resulting converted notebook. - resources : dictionary - Dictionary of resources used prior to and during the conversion - process. - exporter_instance : Exporter - Instance of the Exporter class used to export the document. Useful - to caller because it provides a 'file_extension' property which - specifies what extension the output should be saved as. - - Notes - ----- - WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT - """ - - @wraps(f) - def decorator(*args, **kwargs): - return f(*args, **kwargs) - - return decorator - - -#----------------------------------------------------------------------------- -# Functions -#----------------------------------------------------------------------------- - -__all__ = [ - 'export', - 'export_html', - 'export_custom', - 'export_slides', - 'export_latex', - 'export_pdf', - 'export_markdown', - 'export_python', - 'export_script', - 'export_rst', - 'export_by_name', - 'get_export_names', - 'ExporterNameError' -] - - -class ExporterNameError(NameError): - pass - -@DocDecorator -def export(exporter, nb, **kw): - """ - Export a notebook object using specific exporter class. - - Parameters - ---------- - exporter : class:`~jupyter_nbconvert.exporters.exporter.Exporter` class or instance - Class type or instance of the exporter that should be used. If the - method initializes it's own instance of the class, it is ASSUMED that - the class type provided exposes a constructor (``__init__``) with the same - signature as the base Exporter class. - """ - - #Check arguments - if exporter is None: - raise TypeError("Exporter is None") - elif not isinstance(exporter, Exporter) and not issubclass(exporter, Exporter): - raise TypeError("exporter does not inherit from Exporter (base)") - if nb is None: - raise TypeError("nb is None") - - #Create the exporter - resources = kw.pop('resources', None) - if isinstance(exporter, Exporter): - exporter_instance = exporter - else: - exporter_instance = exporter(**kw) - - #Try to convert the notebook using the appropriate conversion function. - if isinstance(nb, NotebookNode): - output, resources = exporter_instance.from_notebook_node(nb, resources) - elif isinstance(nb, string_types): - output, resources = exporter_instance.from_filename(nb, resources) - else: - output, resources = exporter_instance.from_file(nb, resources) - return output, resources - -exporter_map = dict( - custom=TemplateExporter, - html=HTMLExporter, - slides=SlidesExporter, - latex=LatexExporter, - pdf=PDFExporter, - markdown=MarkdownExporter, - python=PythonExporter, - rst=RSTExporter, - notebook=NotebookExporter, - script=ScriptExporter, -) - -def _make_exporter(name, E): - """make an export_foo function from a short key and Exporter class E""" - def _export(nb, **kw): - return export(E, nb, **kw) - _export.__doc__ = """Export a notebook object to {0} format""".format(name) - return _export - -g = globals() - -for name, E in exporter_map.items(): - g['export_%s' % name] = DocDecorator(_make_exporter(name, E)) - -@DocDecorator -def export_by_name(format_name, nb, **kw): - """ - Export a notebook object to a template type by its name. Reflection - (Inspect) is used to find the template's corresponding explicit export - method defined in this module. That method is then called directly. - - Parameters - ---------- - format_name : str - Name of the template style to export to. - """ - - function_name = "export_" + format_name.lower() - - if function_name in globals(): - return globals()[function_name](nb, **kw) - else: - raise ExporterNameError("template for `%s` not found" % function_name) - - -def get_export_names(): - """Return a list of the currently supported export targets - - WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT""" - return sorted(exporter_map.keys()) diff --git a/jupyter_nbconvert/exporters/exporter.py b/jupyter_nbconvert/exporters/exporter.py deleted file mode 100644 index 6787582..0000000 --- a/jupyter_nbconvert/exporters/exporter.py +++ /dev/null @@ -1,280 +0,0 @@ -"""This module defines a base Exporter class. For Jinja template-based export, -see templateexporter.py. -""" - - -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 -from IPython import nbformat -from IPython.utils.traitlets import MetaHasTraits, Unicode, List, TraitError -from IPython.utils.importstring import import_item -from IPython.utils import text, py3compat - - -class ResourcesDict(collections.defaultdict): - def __missing__(self, key): - return '' - - -class FilenameExtension(Unicode): - """A trait for filename extensions.""" - - default_value = u'' - info_text = 'a filename extension, beginning with a dot' - - def validate(self, obj, value): - # cast to proper unicode - value = super(FilenameExtension, self).validate(obj, value) - - # check that it starts with a dot - if value and not value.startswith('.'): - msg = "FileExtension trait '{}' does not begin with a dot: {!r}" - raise TraitError(msg.format(self.name, value)) - - return value - - -class Exporter(LoggingConfigurable): - """ - 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. - """ - - file_extension = FilenameExtension( - '.txt', config=True, - help="Extension of the file that should be written to disk" - ) - - # 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 = '' - - #Configurability, allows the user to easily add filters and preprocessors. - preprocessors = List(config=True, - help="""List of preprocessors, by name or namespace, to enable.""") - - _preprocessors = List() - - default_preprocessors = List(['jupyter_nbconvert.preprocessors.coalesce_streams', - 'jupyter_nbconvert.preprocessors.SVG2PDFPreprocessor', - 'jupyter_nbconvert.preprocessors.ExtractOutputPreprocessor', - 'jupyter_nbconvert.preprocessors.CSSHTMLHeaderPreprocessor', - 'jupyter_nbconvert.preprocessors.RevealHelpPreprocessor', - 'jupyter_nbconvert.preprocessors.LatexPreprocessor', - 'jupyter_nbconvert.preprocessors.ClearOutputPreprocessor', - 'jupyter_nbconvert.preprocessors.ExecutePreprocessor', - 'jupyter_nbconvert.preprocessors.HighlightMagicsPreprocessor'], - config=True, - help="""List of preprocessors available by default, by name, namespace, - instance, or type.""") - - - def __init__(self, config=None, **kw): - """ - Public constructor - - Parameters - ---------- - config : config - User configuration instance. - """ - with_default_config = self.default_config - if config: - with_default_config.merge(config) - - super(Exporter, self).__init__(config=with_default_config, **kw) - - self._init_preprocessors() - - - @property - def default_config(self): - return Config() - - def from_notebook_node(self, nb, resources=None, **kw): - """ - Convert a notebook from a notebook node instance. - - Parameters - ---------- - nb : :class:`~IPython.nbformat.NotebookNode` - Notebook node (dict-like with attr-access) - resources : dict - Additional resources that can be accessed read/write by - preprocessors and filters. - **kw - Ignored (?) - """ - nb_copy = copy.deepcopy(nb) - resources = self._init_resources(resources) - - if 'language' in nb['metadata']: - resources['language'] = nb['metadata']['language'].lower() - - # Preprocess - nb_copy, resources = self._preprocess(nb_copy, resources) - - 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. - """ - - # Pull the metadata from the filesystem. - if resources is None: - resources = ResourcesDict() - if not 'metadata' in resources or resources['metadata'] == '': - resources['metadata'] = ResourcesDict() - path, basename = os.path.split(filename) - notebook_name = basename[:basename.rfind('.')] - resources['metadata']['name'] = notebook_name - resources['metadata']['path'] = path - - modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename)) - resources['metadata']['modified_date'] = modified_date.strftime(text.date_format) - - with io.open(filename, encoding='utf-8') as f: - return self.from_notebook_node(nbformat.read(f, as_version=4), 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, as_version=4), resources=resources, **kw) - - - def register_preprocessor(self, preprocessor, enabled=False): - """ - Register a preprocessor. - Preprocessors are classes that act upon the notebook before it is - passed into the Jinja templating engine. preprocessors are also - capable of passing additional information to the Jinja - templating engine. - - Parameters - ---------- - preprocessor : preprocessor - """ - if preprocessor is None: - raise TypeError('preprocessor') - isclass = isinstance(preprocessor, type) - constructed = not isclass - - # 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) - - if constructed and hasattr(preprocessor, '__call__'): - # Preprocessor is a function, no need to construct it. - # Register and return the preprocessor. - if enabled: - preprocessor.enabled = True - self._preprocessors.append(preprocessor) - return preprocessor - - elif isclass and isinstance(preprocessor, MetaHasTraits): - # Preprocessor is configurable. Make sure to pass in new default for - # the enabled flag if one was specified. - self.register_preprocessor(preprocessor(parent=self), enabled) - - elif isclass: - # Preprocessor is not configurable, construct it - self.register_preprocessor(preprocessor(), enabled) - - else: - # Preprocessor is an instance of something without a __call__ - # attribute. - raise TypeError('preprocessor') - - - def _init_preprocessors(self): - """ - Register all of the preprocessors needed for this exporter, disabled - unless specified explicitly. - """ - 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) - - - 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): - new_metadata = ResourcesDict() - new_metadata.update(resources['metadata']) - resources['metadata'] = new_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 - - - def _preprocess(self, nb, resources): - """ - 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 - can be accessed read/write by preprocessors - """ - - # Do a copy.deepcopy first, - # we are never safe enough with what the preprocessors could do. - nbc = copy.deepcopy(nb) - resc = copy.deepcopy(resources) - - #Run each preprocessor on the notebook. Carry the output along - #to each preprocessor - for preprocessor in self._preprocessors: - nbc, resc = preprocessor(nbc, resc) - return nbc, resc diff --git a/jupyter_nbconvert/exporters/html.py b/jupyter_nbconvert/exporters/html.py deleted file mode 100644 index a4dbb02..0000000 --- a/jupyter_nbconvert/exporters/html.py +++ /dev/null @@ -1,57 +0,0 @@ -"""HTML Exporter class""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import os - -from jupyter_nbconvert.filters.highlight import Highlight2HTML -from IPython.config import Config - -from .templateexporter import TemplateExporter - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class HTMLExporter(TemplateExporter): - """ - Exports a basic HTML document. This exporter assists with the export of - HTML. Inherit from it if you are writing your own HTML template and need - custom preprocessors/filters. If you don't need custom preprocessors/ - filters, just change the 'template_file' config option. - """ - - def _file_extension_default(self): - return '.html' - - def _default_template_path_default(self): - return os.path.join("..", "templates", "html") - - def _template_file_default(self): - return 'full' - - output_mimetype = 'text/html' - - @property - def default_config(self): - c = Config({ - 'NbConvertBase': { - 'display_data_priority' : ['application/javascript', 'text/html', 'text/markdown', 'application/pdf', 'image/svg+xml', 'text/latex', 'image/png', 'image/jpeg', 'text/plain'] - }, - 'CSSHTMLHeaderPreprocessor':{ - 'enabled':True - }, - 'HighlightMagicsPreprocessor': { - 'enabled':True - } - }) - c.merge(super(HTMLExporter,self).default_config) - return c - - def from_notebook_node(self, nb, resources=None, **kw): - langinfo = nb.metadata.get('language_info', {}) - lexer = langinfo.get('pygments_lexer', langinfo.get('name', None)) - self.register_filter('highlight_code', - Highlight2HTML(pygments_lexer=lexer, parent=self)) - return super(HTMLExporter, self).from_notebook_node(nb, resources, **kw) diff --git a/jupyter_nbconvert/exporters/latex.py b/jupyter_nbconvert/exporters/latex.py deleted file mode 100644 index be6c7f8..0000000 --- a/jupyter_nbconvert/exporters/latex.py +++ /dev/null @@ -1,96 +0,0 @@ -"""LaTeX Exporter class""" - -#----------------------------------------------------------------------------- -# 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 -#----------------------------------------------------------------------------- - -# Stdlib imports -import os - -# IPython imports -from IPython.utils.traitlets import Unicode -from IPython.config import Config - -from jupyter_nbconvert.filters.highlight import Highlight2Latex -from .templateexporter import TemplateExporter - -#----------------------------------------------------------------------------- -# Classes and functions -#----------------------------------------------------------------------------- - -class LatexExporter(TemplateExporter): - """ - Exports to a Latex template. Inherit from this class if your template is - LaTeX based and you need custom tranformers/filters. Inherit from it if - you are writing your own HTML template and need custom tranformers/filters. - If you don't need custom tranformers/filters, just change the - 'template_file' config option. Place your template in the special "/latex" - subfolder of the "../templates" folder. - """ - - def _file_extension_default(self): - return '.tex' - - def _template_file_default(self): - return 'article' - - #Latex constants - def _default_template_path_default(self): - return os.path.join("..", "templates", "latex") - - def _template_skeleton_path_default(self): - return os.path.join("..", "templates", "latex", "skeleton") - - #Special Jinja2 syntax that will not conflict when exporting latex. - 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) - - #Extension that the template files use. - template_extension = Unicode(".tplx", config=True) - - output_mimetype = 'text/latex' - - - @property - def default_config(self): - c = Config({ - 'NbConvertBase': { - 'display_data_priority' : ['text/latex', 'application/pdf', 'image/png', 'image/jpeg', 'image/svg+xml', 'text/plain'] - }, - 'ExtractOutputPreprocessor': { - 'enabled':True - }, - 'SVG2PDFPreprocessor': { - 'enabled':True - }, - 'LatexPreprocessor': { - 'enabled':True - }, - 'SphinxPreprocessor': { - 'enabled':True - }, - 'HighlightMagicsPreprocessor': { - 'enabled':True - } - }) - c.merge(super(LatexExporter,self).default_config) - return c - - def from_notebook_node(self, nb, resources=None, **kw): - langinfo = nb.metadata.get('language_info', {}) - lexer = langinfo.get('pygments_lexer', langinfo.get('name', None)) - self.register_filter('highlight_code', - Highlight2Latex(pygments_lexer=lexer, parent=self)) - return super(LatexExporter, self).from_notebook_node(nb, resources, **kw) diff --git a/jupyter_nbconvert/exporters/markdown.py b/jupyter_nbconvert/exporters/markdown.py deleted file mode 100644 index 9c8abf5..0000000 --- a/jupyter_nbconvert/exporters/markdown.py +++ /dev/null @@ -1,43 +0,0 @@ -"""Markdown Exporter class""" - -#----------------------------------------------------------------------------- -# 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 IPython.config import Config - -from .templateexporter import TemplateExporter - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class MarkdownExporter(TemplateExporter): - """ - Exports to a markdown document (.md) - """ - - def _file_extension_default(self): - return '.md' - - def _template_file_default(self): - return 'markdown' - - output_mimetype = 'text/markdown' - - def _raw_mimetypes_default(self): - return ['text/markdown', 'text/html', ''] - - @property - def default_config(self): - c = Config({'ExtractOutputPreprocessor':{'enabled':True}}) - c.merge(super(MarkdownExporter,self).default_config) - return c diff --git a/jupyter_nbconvert/exporters/notebook.py b/jupyter_nbconvert/exporters/notebook.py deleted file mode 100644 index 20bf32a..0000000 --- a/jupyter_nbconvert/exporters/notebook.py +++ /dev/null @@ -1,32 +0,0 @@ -"""NotebookExporter class""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .exporter import Exporter -from IPython import nbformat -from IPython.utils.traitlets import Enum - -class NotebookExporter(Exporter): - """Exports to an IPython notebook.""" - - nbformat_version = Enum(list(nbformat.versions), - default_value=nbformat.current_nbformat, - config=True, - help="""The nbformat version to write. - Use this to downgrade notebooks. - """ - ) - def _file_extension_default(self): - return '.ipynb' - - output_mimetype = 'application/json' - - def from_notebook_node(self, nb, resources=None, **kw): - nb_copy, resources = super(NotebookExporter, self).from_notebook_node(nb, resources, **kw) - if self.nbformat_version != nb_copy.nbformat: - resources['output_suffix'] = '.v%i' % self.nbformat_version - else: - resources['output_suffix'] = '.nbconvert' - output = nbformat.writes(nb_copy, version=self.nbformat_version) - return output, resources diff --git a/jupyter_nbconvert/exporters/pdf.py b/jupyter_nbconvert/exporters/pdf.py deleted file mode 100644 index 4e5095c..0000000 --- a/jupyter_nbconvert/exporters/pdf.py +++ /dev/null @@ -1,149 +0,0 @@ -"""Export to PDF via latex""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import subprocess -import os -import sys - -from IPython.utils.py3compat import which -from IPython.utils.traitlets import Integer, List, Bool, Instance -from IPython.utils.tempdir import TemporaryWorkingDirectory -from .latex import LatexExporter - - -class PDFExporter(LatexExporter): - """Writer designed to write to PDF files""" - - latex_count = Integer(3, config=True, - help="How many times latex will be called." - ) - - latex_command = List([u"pdflatex", u"{filename}"], config=True, - help="Shell command used to compile latex." - ) - - bib_command = List([u"bibtex", u"{filename}"], config=True, - help="Shell command used to run bibtex." - ) - - verbose = Bool(False, config=True, - help="Whether to display the output of latex commands." - ) - - temp_file_exts = List(['.aux', '.bbl', '.blg', '.idx', '.log', '.out'], config=True, - help="File extensions of temp files to remove after running." - ) - - writer = Instance("jupyter_nbconvert.writers.FilesWriter", args=()) - - def run_command(self, command_list, filename, count, log_function): - """Run command_list count times. - - Parameters - ---------- - command_list : list - A list of args to provide to Popen. Each element of this - list will be interpolated with the filename to convert. - filename : unicode - The name of the file to convert. - count : int - How many times to run the command. - - Returns - ------- - success : bool - A boolean indicating if the command was successful (True) - or failed (False). - """ - command = [c.format(filename=filename) for c in command_list] - - # On windows with python 2.x there is a bug in subprocess.Popen and - # unicode commands are not supported - if sys.platform == 'win32' and sys.version_info < (3,0): - #We must use cp1252 encoding for calling subprocess.Popen - #Note that sys.stdin.encoding and encoding.DEFAULT_ENCODING - # could be different (cp437 in case of dos console) - command = [c.encode('cp1252') for c in command] - - # This will throw a clearer error if the command is not found - cmd = which(command_list[0]) - if cmd is None: - raise OSError("%s not found on PATH" % command_list[0]) - - times = 'time' if count == 1 else 'times' - self.log.info("Running %s %i %s: %s", command_list[0], count, times, command) - with open(os.devnull, 'rb') as null: - stdout = subprocess.PIPE if not self.verbose else None - for index in range(count): - p = subprocess.Popen(command, stdout=stdout, stdin=null) - out, err = p.communicate() - if p.returncode: - if self.verbose: - # verbose means I didn't capture stdout with PIPE, - # so it's already been displayed and `out` is None. - out = u'' - else: - out = out.decode('utf-8', 'replace') - log_function(command, out) - return False # failure - return True # success - - def run_latex(self, filename): - """Run pdflatex self.latex_count times.""" - - def log_error(command, out): - self.log.critical(u"%s failed: %s\n%s", command[0], command, out) - - return self.run_command(self.latex_command, filename, - self.latex_count, log_error) - - def run_bib(self, filename): - """Run bibtex self.latex_count times.""" - filename = os.path.splitext(filename)[0] - - def log_error(command, out): - self.log.warn('%s had problems, most likely because there were no citations', - command[0]) - self.log.debug(u"%s output: %s\n%s", command[0], command, out) - - return self.run_command(self.bib_command, filename, 1, log_error) - - def clean_temp_files(self, filename): - """Remove temporary files created by pdflatex/bibtex.""" - self.log.info("Removing temporary LaTeX files") - filename = os.path.splitext(filename)[0] - for ext in self.temp_file_exts: - try: - os.remove(filename+ext) - except OSError: - pass - - def from_notebook_node(self, nb, resources=None, **kw): - latex, resources = super(PDFExporter, self).from_notebook_node( - nb, resources=resources, **kw - ) - with TemporaryWorkingDirectory() as td: - notebook_name = "notebook" - tex_file = self.writer.write(latex, resources, notebook_name=notebook_name) - self.log.info("Building PDF") - rc = self.run_latex(tex_file) - if not rc: - rc = self.run_bib(tex_file) - if not rc: - rc = self.run_latex(tex_file) - - pdf_file = notebook_name + '.pdf' - if not os.path.isfile(pdf_file): - raise RuntimeError("PDF creating failed") - self.log.info('PDF successfully created') - with open(pdf_file, 'rb') as f: - pdf_data = f.read() - - # convert output extension to pdf - # the writer above required it to be tex - resources['output_extension'] = '.pdf' - - return pdf_data, resources - diff --git a/jupyter_nbconvert/exporters/python.py b/jupyter_nbconvert/exporters/python.py deleted file mode 100644 index e1218da..0000000 --- a/jupyter_nbconvert/exporters/python.py +++ /dev/null @@ -1,31 +0,0 @@ -"""Python script Exporter class""" - -#----------------------------------------------------------------------------- -# 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 .templateexporter import TemplateExporter - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class PythonExporter(TemplateExporter): - """ - Exports a Python code file. - """ - def _file_extension_default(self): - return '.py' - - def _template_file_default(self): - return 'python' - - output_mimetype = 'text/x-python' diff --git a/jupyter_nbconvert/exporters/rst.py b/jupyter_nbconvert/exporters/rst.py deleted file mode 100644 index 731e978..0000000 --- a/jupyter_nbconvert/exporters/rst.py +++ /dev/null @@ -1,40 +0,0 @@ -"""restructuredText Exporter class""" - -#----------------------------------------------------------------------------- -# 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 IPython.config import Config - -from .templateexporter import TemplateExporter - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class RSTExporter(TemplateExporter): - """ - Exports restructured text documents. - """ - - def _file_extension_default(self): - return '.rst' - - def _template_file_default(self): - return 'rst' - - output_mimetype = 'text/restructuredtext' - - @property - def default_config(self): - c = Config({'ExtractOutputPreprocessor':{'enabled':True}}) - c.merge(super(RSTExporter,self).default_config) - return c diff --git a/jupyter_nbconvert/exporters/script.py b/jupyter_nbconvert/exporters/script.py deleted file mode 100644 index 52d2638..0000000 --- a/jupyter_nbconvert/exporters/script.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Generic script exporter class for any kernel language""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .templateexporter import TemplateExporter - -from IPython.utils.traitlets import Dict - -class ScriptExporter(TemplateExporter): - - _exporters = Dict() - - def _template_file_default(self): - return 'script' - - def from_notebook_node(self, nb, resources=None, **kw): - langinfo = nb.metadata.get('language_info', {}) - - # delegate to custom exporter, if specified - exporter_name = langinfo.get('nbconvert_exporter') - if exporter_name and exporter_name != 'script': - self.log.debug("Loading script exporter: %s", exporter_name) - from .export import exporter_map - if exporter_name not in self._exporters: - Exporter = exporter_map[exporter_name] - self._exporters[exporter_name] = Exporter(parent=self) - exporter = self._exporters[exporter_name] - return exporter.from_notebook_node(nb, resources, **kw) - - self.file_extension = langinfo.get('file_extension', '.txt') - self.output_mimetype = langinfo.get('mimetype', 'text/plain') - return super(ScriptExporter, self).from_notebook_node(nb, resources, **kw) diff --git a/jupyter_nbconvert/exporters/slides.py b/jupyter_nbconvert/exporters/slides.py deleted file mode 100644 index c2e5d03..0000000 --- a/jupyter_nbconvert/exporters/slides.py +++ /dev/null @@ -1,43 +0,0 @@ -"""HTML slide show Exporter class""" - -#----------------------------------------------------------------------------- -# 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 jupyter_nbconvert import preprocessors -from IPython.config import Config - -from .html import HTMLExporter - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class SlidesExporter(HTMLExporter): - """Exports HTML slides with reveal.js""" - - def _file_extension_default(self): - return '.slides.html' - - def _template_file_default(self): - return 'slides_reveal' - - output_mimetype = 'text/html' - - @property - def default_config(self): - c = Config({ - 'RevealHelpPreprocessor': { - 'enabled': True, - }, - }) - c.merge(super(SlidesExporter,self).default_config) - return c diff --git a/jupyter_nbconvert/exporters/templateexporter.py b/jupyter_nbconvert/exporters/templateexporter.py deleted file mode 100644 index ca488c8..0000000 --- a/jupyter_nbconvert/exporters/templateexporter.py +++ /dev/null @@ -1,321 +0,0 @@ -"""This module defines TemplateExporter, a highly configurable converter -that uses Jinja2 to export notebook files into different formats. -""" - -#----------------------------------------------------------------------------- -# 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 os - -# other libs/dependencies are imported at runtime -# to move ImportErrors to runtime when the requirement is actually needed - -# IPython imports -from IPython.utils.traitlets import MetaHasTraits, Unicode, List, Dict, Any -from IPython.utils.importstring import import_item -from IPython.utils import py3compat, text - -from jupyter_nbconvert import filters -from .exporter import Exporter - -#----------------------------------------------------------------------------- -# Globals and constants -#----------------------------------------------------------------------------- - -#Jinja2 extensions to load. -JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols'] - -default_filters = { - 'indent': text.indent, - 'markdown2html': filters.markdown2html, - 'ansi2html': filters.ansi2html, - 'filter_data_type': filters.DataTypeFilter, - 'get_lines': filters.get_lines, - 'highlight2html': filters.Highlight2HTML, - 'highlight2latex': filters.Highlight2Latex, - 'ipython2python': filters.ipython2python, - 'posix_path': filters.posix_path, - 'markdown2latex': filters.markdown2latex, - 'markdown2rst': filters.markdown2rst, - '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, - 'add_anchor': filters.add_anchor, - 'ansi2latex': filters.ansi2latex, - 'wrap_text': filters.wrap_text, - 'escape_latex': filters.escape_latex, - 'citation2latex': filters.citation2latex, - 'path2url': filters.path2url, - 'add_prompts': filters.add_prompts, - 'ascii_only': filters.ascii_only, - 'prevent_list_blocks': filters.prevent_list_blocks, -} - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TemplateExporter(Exporter): - """ - 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 - template type along with new filters/preprocessors. If the filters/ - preprocessors provided by default suffice, there is no need to inherit from - this class. Instead, override the template_file and file_extension - traits via a config file. - - {filters} - """ - - # finish the docstring - __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys())) - - - template_file = Unicode(u'default', - config=True, - help="Name of the template file to use") - def _template_file_changed(self, name, old, new): - if new == 'default': - self.template_file = self.default_template - else: - self.template_file = new - self.template = None - self._load_template() - - default_template = Unicode(u'') - template = Any() - environment = Any() - - template_path = List(['.'], config=True) - def _template_path_changed(self, name, old, new): - self._load_template() - - default_template_path = Unicode( - os.path.join("..", "templates"), - help="Path where the template files are located.") - - template_skeleton_path = Unicode( - os.path.join("..", "templates", "skeleton"), - help="Path where the template skeleton files are located.") - - #Jinja block definitions - 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) - - #Extension that the template files use. - template_extension = Unicode(".tpl", config=True) - - filters = Dict(config=True, - help="""Dictionary of filters, by name and namespace, to add to the Jinja - environment.""") - - raw_mimetypes = List(config=True, - help="""formats of raw cells to be included in this Exporter's output.""" - ) - def _raw_mimetypes_default(self): - return [self.output_mimetype, ''] - - - def __init__(self, config=None, extra_loaders=None, **kw): - """ - Public constructor - - Parameters - ---------- - config : config - User configuration instance. - extra_loaders : list[of Jinja Loaders] - ordered list of Jinja loader to find templates. Will be tried in order - before the default FileSystem ones. - template : str (optional, kw arg) - Template to use when exporting. - """ - super(TemplateExporter, self).__init__(config=config, **kw) - - #Init - self._init_template() - self._init_environment(extra_loaders=extra_loaders) - self._init_filters() - - - def _load_template(self): - """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. - """ - from jinja2 import TemplateNotFound - - 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. - try_names = [] - if self.template_file: - try_names.extend([ - self.template_file + self.template_extension, - self.template_file, - ]) - 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) - except (TemplateNotFound, IOError): - pass - except Exception as e: - self.log.warn("Unexpected exception loading template: %s", try_name, exc_info=True) - else: - self.log.debug("Loaded template %s", try_name) - break - - def from_notebook_node(self, nb, resources=None, **kw): - """ - Convert a notebook from a notebook node instance. - - Parameters - ---------- - nb : :class:`~IPython.nbformat.NotebookNode` - Notebook node - resources : dict - Additional resources that can be accessed read/write by - preprocessors and filters. - """ - nb_copy, resources = super(TemplateExporter, self).from_notebook_node(nb, resources, **kw) - resources.setdefault('raw_mimetypes', self.raw_mimetypes) - - self._load_template() - - if self.template is not None: - output = self.template.render(nb=nb_copy, resources=resources) - else: - raise IOError('template file "%s" could not be found' % self.template_file) - return output, resources - - - def register_filter(self, name, jinja_filter): - """ - 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 - """ - if jinja_filter is None: - raise TypeError('filter') - isclass = isinstance(jinja_filter, type) - constructed = not isclass - - #Handle filter's registration based on it's type - if constructed and isinstance(jinja_filter, py3compat.string_types): - #filter is a string, import the namespace and recursively call - #this register_filter method - filter_cls = import_item(jinja_filter) - return self.register_filter(name, filter_cls) - - if constructed and hasattr(jinja_filter, '__call__'): - #filter is a function, no need to construct it. - self.environment.filters[name] = jinja_filter - return jinja_filter - - elif isclass and isinstance(jinja_filter, MetaHasTraits): - #filter is configurable. Make sure to pass in new default for - #the enabled flag if one was specified. - filter_instance = jinja_filter(parent=self) - self.register_filter(name, filter_instance ) - - elif isclass: - #filter is not configurable, construct it - filter_instance = jinja_filter() - self.register_filter(name, filter_instance) - - else: - #filter is an instance of something without a __call__ - #attribute. - raise TypeError('filter') - - - def _init_template(self): - """ - Make sure a template name is specified. If one isn't specified, try to - build one from the information we know. - """ - self._template_file_changed('template_file', self.template_file, self.template_file) - - - def _init_environment(self, extra_loaders=None): - """ - Create the Jinja templating environment. - """ - from jinja2 import Environment, ChoiceLoader, FileSystemLoader - here = os.path.dirname(os.path.realpath(__file__)) - loaders = [] - if extra_loaders: - loaders.extend(extra_loaders) - - paths = self.template_path - paths.extend([os.path.join(here, self.default_template_path), - os.path.join(here, self.template_skeleton_path)]) - loaders.append(FileSystemLoader(paths)) - - self.environment = Environment( - loader= ChoiceLoader(loaders), - extensions=JINJA_EXTENSIONS - ) - - #Set special Jinja2 syntax that will not conflict with latex. - if self.jinja_logic_block_start: - self.environment.block_start_string = self.jinja_logic_block_start - if self.jinja_logic_block_end: - self.environment.block_end_string = self.jinja_logic_block_end - if self.jinja_variable_block_start: - self.environment.variable_start_string = self.jinja_variable_block_start - if self.jinja_variable_block_end: - self.environment.variable_end_string = self.jinja_variable_block_end - if self.jinja_comment_block_start: - self.environment.comment_start_string = self.jinja_comment_block_start - if self.jinja_comment_block_end: - self.environment.comment_end_string = self.jinja_comment_block_end - - - def _init_filters(self): - """ - Register all of the filters required for the exporter. - """ - - #Add default filters to the Jinja2 environment - for key, value in default_filters.items(): - self.register_filter(key, value) - - #Load user filters. Overwrite existing filters if need be. - if self.filters: - for key, user_filter in self.filters.items(): - self.register_filter(key, user_filter) diff --git a/jupyter_nbconvert/exporters/tests/__init__.py b/jupyter_nbconvert/exporters/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_nbconvert/exporters/tests/__init__.py +++ /dev/null diff --git a/jupyter_nbconvert/exporters/tests/base.py b/jupyter_nbconvert/exporters/tests/base.py deleted file mode 100644 index efc2ae5..0000000 --- a/jupyter_nbconvert/exporters/tests/base.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Base TestCase class for testing Exporters""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import os - -from ...tests.base import TestsBase - -all_raw_mimetypes = { - 'text/x-python', - 'text/markdown', - 'text/html', - 'text/restructuredtext', - 'text/latex', -} - -class ExportersTestsBase(TestsBase): - """Contains base test functions for exporters""" - - exporter_class = None - should_include_raw = None - - def _get_notebook(self, nb_name='notebook2.ipynb'): - return os.path.join(self._get_files_path(), nb_name) - - def test_raw_cell_inclusion(self): - """test raw cell inclusion based on raw_mimetype metadata""" - if self.should_include_raw is None: - return - exporter = self.exporter_class() - (output, resources) = exporter.from_filename(self._get_notebook('rawtest.ipynb')) - for inc in self.should_include_raw: - self.assertIn('raw %s' % inc, output, "should include %s" % inc) - self.assertIn('no raw_mimetype metadata', output) - for exc in all_raw_mimetypes.difference(self.should_include_raw): - self.assertNotIn('raw %s' % exc, output, "should exclude %s" % exc) - self.assertNotIn('never be included', output) diff --git a/jupyter_nbconvert/exporters/tests/cheese.py b/jupyter_nbconvert/exporters/tests/cheese.py deleted file mode 100644 index f4a42ce..0000000 --- a/jupyter_nbconvert/exporters/tests/cheese.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -Contains CheesePreprocessor -""" -#----------------------------------------------------------------------------- -# 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 ...preprocessors.base import Preprocessor - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class CheesePreprocessor(Preprocessor): - """ - Adds a cheese tag to the resources object - """ - - - def __init__(self, **kw): - """ - Public constructor - """ - super(CheesePreprocessor, self).__init__(**kw) - - - def preprocess(self, nb, resources): - """ - Sphinx preprocessing to apply on each notebook. - - Parameters - ---------- - nb : NotebookNode - Notebook being converted - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - """ - resources['cheese'] = 'real' - return nb, resources diff --git a/jupyter_nbconvert/exporters/tests/files/notebook2.ipynb b/jupyter_nbconvert/exporters/tests/files/notebook2.ipynb deleted file mode 100644 index 08fbd35..0000000 --- a/jupyter_nbconvert/exporters/tests/files/notebook2.ipynb +++ /dev/null @@ -1,178 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# NumPy and Matplotlib examples" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First import NumPy and Matplotlib:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].\n", - "For more information, type 'help(pylab)'.\n" - ] - } - ], - "source": [ - "%pylab inline" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we show some very basic examples of how they can be used." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "a = np.random.uniform(size=(100,100))" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(100, 100)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "evs = np.linalg.eigvals(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(100,)" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "evs.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is a cell that has both text and PNG output:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(array([95, 4, 0, 0, 0, 0, 0, 0, 0, 1]),\n", - " array([ -2.93566063, 2.35937011, 7.65440086, 12.9494316 ,\n", - " 18.24446235, 23.53949309, 28.83452384, 34.12955458,\n", - " 39.42458533, 44.71961607, 50.01464682]),\n", - " )" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAD9CAYAAAC2l2x5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEhdJREFUeJzt3X1olfX/x/HXtVbT8CZDmsK6KmrubEu3U2xnZOpxLBnG\nOqsIE7RoE3QRZkT/yEAjcIh/LIs6i/BEGSU1CkxT0+pkFp1zMmsxZ5uUTIXoxm95lmdlef3+8Nep\ndbtz7exs16fnAw7sXNs5n/c14nmurl3naDmO4wgAYJy8sR4AADA6CDwAGIrAA4ChCDwAGIrAA4Ch\nCDwAGOofA9/U1KTCwkLNnj07vS2ZTCoUCsm2bTU2NmpgYCD9vccee0zFxcUqKyvTgQMHRm9qAMC/\n+sfA33PPPdq9e/eQbeFwWLZtq6+vT0VFRero6JAkffXVV3ryySf15ptvKhwOa/Xq1aM3NQDgX/1j\n4OfNm6dp06YN2RaPx9Xc3KyCggI1NTUpFotJkmKxmOrr62XbthYsWCDHcZRMJkdvcgDAP8r4HHwi\nkZDP55Mk+Xw+xeNxSecDX1pamv65kpKS9PcAALmXn+kDMvlkA8uyhrUNAPDvMv1kmYyP4KuqqtTT\n0yNJ6unpUVVVlSQpEAjo8OHD6Z87cuRI+nt/NaRXb+vWrRvzGZh/7Odgfu/dvDy747j7yLCMAx8I\nBBSJRJRKpRSJRFRTUyNJqq6u1p49e9Tf369oNKq8vDxNnjzZ1VAAgJH7x8AvXbpUN9xwg3p7e3X5\n5ZfrmWeeUUtLi/r7+1VSUqKTJ09q1apVkqTCwkK1tLSotrZW9957rzZv3pyTHQAA/DXLcXvs73ZB\ny3L9vxvjQTQaVTAYHOsxXGP+scX8Y8fLs0vu2kngAcAD3LSTjyoAAEMReAAwFIEHAEMReAAwFIEH\nAEP9ZwM/Zcqlsixr1G9Tplw61rsK4D/qP3uZ5PnPxMnFHONjfwF4G5dJAgDSCDwAGIrAA4ChCDwA\nGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrA\nA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChXAf+6aef1g03\n3KDrr79ea9askSQlk0mFQiHZtq3GxkYNDAxkbVAAQGZcBf7UqVPasGGD9u7dq0Qiod7eXu3Zs0fh\ncFi2bauvr09FRUXq6OjI9rwAgGFyFfiJEyfKcRx9//33SqVSOnPmjC655BLF43E1NzeroKBATU1N\nisVi2Z4XADBMrgMfDod15ZVXasaMGZo7d64CgYASiYR8Pp8kyefzKR6PZ3VYAMDw5bt50Ndff62W\nlhYdPnxY06ZN0x133KEdO3bIcZxhPX79+vXpr4PBoILBoJsxAMBY0WhU0Wh0RM9hOcOt8u/s3LlT\nW7du1bZt2yRJ4XBYx44d09GjR9Xa2iq/36+DBw+qra1NnZ2dQxe0rGG/EIwmy7Ik5WKO8bG/ALzN\nTTtdnaKZN2+ePvzwQ506dUo//vijdu3apUWLFikQCCgSiSiVSikSiaimpsbN0wMAssBV4KdMmaLW\n1lbdeuutuvHGG1VRUaGFCxeqpaVF/f39Kikp0cmTJ7Vq1apszwsAGCZXp2hGtCCnaAAgYzk7RQMA\nGP8IPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEI\nPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAY\nisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYynXgf/jhB919992a\nNWuWysrKFIvFlEwmFQqFZNu2GhsbNTAwkM1ZAQAZcB34devWybZtdXV1qaurSz6fT+FwWLZtq6+v\nT0VFRero6MjmrACADLgO/L59+7R27VpNmDBB+fn5mjp1quLxuJqbm1VQUKCmpibFYrFszgoAyICr\nwJ84cUKDg4NqaWlRIBDQxo0blUqllEgk5PP5JEk+n0/xeDyrwwIAhi/fzYMGBwfV29urTZs2qa6u\nTitXrtRLL70kx3GG9fj169envw4GgwoGg27GAABjRaNRRaPRET2H5Qy3yn9QWlqqnp4eSdKuXbv0\n3HPP6aefflJra6v8fr8OHjyotrY2dXZ2Dl3Qsob9QjCaLMuSlIs5xsf+AvA2N+10fQ6+uLhYsVhM\n586d086dO1VXV6dAIKBIJKJUKqVIJKKamhq3Tw8AGCHXR/C9vb266667NDg4qLq6Oj388MM6d+6c\nli1bpkOHDum6667T888/r0mTJg1dkCN4AMiYm3a6DrxbBB4AMpfTUzQAgPGNwAOAoQg8ABiKwAOA\n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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "hist(evs.real)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/jupyter_nbconvert/exporters/tests/files/pngmetadata.ipynb b/jupyter_nbconvert/exporters/tests/files/pngmetadata.ipynb deleted file mode 100644 index b23ed69..0000000 --- a/jupyter_nbconvert/exporters/tests/files/pngmetadata.ipynb +++ /dev/null @@ -1,240 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": [ - "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\n", - "yXu7+0V77P9Cku7uixZ5/CxfVV2b5IM5ZGlfxRxlqGvaT063t+/e0d1fSvKRJE9Mst+asUWNwzCs\n", - "4vv5J7u2DN9Cz4uq+vokb07ylu7+jUUdJCu3qPPiuiRPSfIrSXq6hvm1VXW9dcujtKjz4u4kX0ly\n", - "dVU9+cwdVfUtmSyp+8DcR8uYLH2OMtRJ+4np9u4Z+++Zbq9a0TgMw1K/n1V1LMnOb9XvO8oYrMXC\n", - "zovpOXBLkvuSvG7uI2OdFnVefPN0++UkH0/yn5O8KcmNSe6oql+vqqfMc6Cs1ELOi57cpf21mSyr\n", - "/J2qekdVvamqfimTJRK3J/kHCzhexmPpc85jR/3AJdv530mz7oS68/x+78Rd1DgMw7K/n29O8qwk\n", - "v9rd7z/iGKzeIs+LH0/yjZm8WejL8x4Ya7Wo8+KS6fY1Sf53kr+eyeT9eJJ/neR5Sd6dxysbw7aw\n", - "vy+6+99U1SeT/PskLztj1yeS/Hx3f/bIR8kYLX3OOdTSDitVVT+U5EeS/J8k37fmw2ENpmtUfyzJ\n", - "v+ru/7bu42Ewdn5O/r8kL+juO7r74e7+7SQvSvLpJN9qqcz2qap/kskvbD+XyS9xT0jyTUnuTfKL\n", - "06vLwMIMddK+89vIrDdw7Dz/4IrGYRiW8v2sqn+c5C2ZVLST3e18GJe5z4vpsphfyOSSXK+f9bIj\n", - "HR3rsqi/L3b2f6y7P3Xmju5+JJOlEMnjy2gYtoWcF9M3K745kzei/mh339fdj3b3xzL5Ze4zSV5d\n", - "VVcs4JgZh6XPOYc6ab9zuj0xY//OeqBZ64YWPQ7DsPDvZ1W9KslbM7ke98nu/sOjHx5rsojz4oLp\n", - "656Z5NEzbqj0WCZLZpLk302fu3HuI2YVFv1zZNYP2p3n/9wBj4v1WtR58Z3T7Yd275j+Mvc/Mplj\n", - "feNhD5DRWvqcc6hr2nf+EFxXVdVnXJeyqi5Mck0ml9/66IrGYRgW+v2sqtdm8oayjyW5rt1ka6wW\n", - "cV48msm61L2ugftNSf5Kkg9nUuLvWMRBs3SL+vvi1zI5L565e5ypvzzdnl7AMbN8izovvma6vWTG\n", - "/oun268c9UAZnaXPOQdZ2rv73kzeeX1Fklfs2n1DJuvGbpn+NpuqOlZVz6iq4/OMw7At6ryY7vsX\n", - "mUzYfyvJc03Yx2sR58X0f2v/QHe/fPcjk6uFJJM3lr28u9+9/K+KeS3w58inMjkH/lKSs+7dUFXP\n", - "S/I3k3w+rjg1Cgv8OfJfp9uXV9VfOHNHVX17JhO0R+KX/I2zzjnnIG+ulCTT/xh3ZPJb7Hvz+K1g\n", - "r82kdj1nesmlVNXlmbzx45PdfcVRx2H4FnFeVNXfyeSNQ3+a5KYkX9jjU53u7p9f1tfBYi3q74sZ\n", - "Y5+KmyuN0gJ/jvzF6ThPy6S8fzyTH8wvzOTvke/p7luX/gWxEAv6OVKZvJ/h25J8McmtSf4gyddn\n", - "snSmk7yqu29axdfEfKrqhZn8eU4md7t9Xibf9517dfxRd79m+trLs64552Fun7rqR5LLMrlt9P2Z\n", - "XCP3dCZ3Kbxo1+suz+T2sPfOM47HOB7znheZvNHwsUx+2D424/HBdX+dHqs9L84z7uun58r3r/tr\n", - "9FjfeZHJDZbemsk1/L+c5A+T/HKSv7bur9FjPedFJkuMr8/kzqgPZXKFoQeS/Kck37bur9HjUOfD\n", - "mfOCMx+P7f7+r3POOdjSDgAATAxyTTsAAPA4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4\n", - "k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YA\n", - "ABg4k3YAABi4/w/Y3UZ5IHmVbAAAAABJRU5ErkJggg==\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": { - "image/png": { - "height": 255, - "width": 374 - } - }, - "output_type": "display_data" - } - ], - "source": [ - "%matplotlib inline\n", - "%config InlineBackend.figure_formats = set(['retina'])\n", - "import matplotlib.pyplot as plt\n", - "plt.plot([0,1],[1,0])" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "IPython mydev (Python 3)", - "name": "python3_mydev" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.4.2" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/exporters/tests/files/prompt_numbers.ipynb b/jupyter_nbconvert/exporters/tests/files/prompt_numbers.ipynb deleted file mode 100644 index 2e26355..0000000 --- a/jupyter_nbconvert/exporters/tests/files/prompt_numbers.ipynb +++ /dev/null @@ -1,81 +0,0 @@ -{ - "metadata": { - "name": "notebook2" - }, - "nbformat": 3, - "nbformat_minor": 0, - "worksheets": [ - { - "cells": [ - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import numpy as np" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 2 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "evs = np.zeros(100)", - "evs.shape" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 10, - "text": [ - "(100,)" - ] - } - ], - "prompt_number": 10 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": null - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": "*" - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 0 - } - ], - "metadata": {} - } - ] -} \ No newline at end of file diff --git a/jupyter_nbconvert/exporters/tests/files/rawtest.ipynb b/jupyter_nbconvert/exporters/tests/files/rawtest.ipynb deleted file mode 100644 index 9b0fabe..0000000 --- a/jupyter_nbconvert/exporters/tests/files/rawtest.ipynb +++ /dev/null @@ -1,77 +0,0 @@ -{ - "cells": [ - { - "cell_type": "raw", - "metadata": { - "raw_mimetype": "text/html" - }, - "source": [ - "raw html" - ] - }, - { - "cell_type": "raw", - "metadata": { - "raw_mimetype": "text/markdown" - }, - "source": [ - "* raw markdown\n", - "* bullet\n", - "* list" - ] - }, - { - "cell_type": "raw", - "metadata": { - "raw_mimetype": "text/restructuredtext" - }, - "source": [ - "``raw rst``\n", - "\n", - ".. sourcecode:: python\n", - "\n", - " def foo(): pass\n" - ] - }, - { - "cell_type": "raw", - "metadata": { - "raw_mimetype": "text/x-python" - }, - "source": [ - "def bar():\n", - " \"\"\"raw python\"\"\"\n", - " pass" - ] - }, - { - "cell_type": "raw", - "metadata": { - "raw_mimetype": "text/latex" - }, - "source": [ - "\\LaTeX\n", - "% raw latex" - ] - }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "# no raw_mimetype metadata, should be included by default" - ] - }, - { - "cell_type": "raw", - "metadata": { - "raw_mimetype": "doesnotexist" - }, - "source": [ - "garbage format defined, should never be included" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/exporters/tests/test_export.py b/jupyter_nbconvert/exporters/tests/test_export.py deleted file mode 100644 index 1b7292a..0000000 --- a/jupyter_nbconvert/exporters/tests/test_export.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -Module with tests for export.py -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import os - -from IPython import nbformat - -from .base import ExportersTestsBase -from ..export import * -from ..python import PythonExporter - - -class TestExport(ExportersTestsBase): - """Contains test functions for export.py""" - - - def test_export_wrong_name(self): - """ - Is the right error thrown when a bad template name is used? - """ - try: - export_by_name('not_a_name', self._get_notebook()) - except ExporterNameError as e: - pass - - - def test_export_filename(self): - """ - Can a notebook be exported by filename? - """ - (output, resources) = export_by_name('python', self._get_notebook()) - assert len(output) > 0 - - - def test_export_nbnode(self): - """ - Can a notebook be exported by a notebook node handle? - """ - with open(self._get_notebook(), 'r') as f: - notebook = nbformat.read(f, 4) - (output, resources) = export_by_name('python', notebook) - assert len(output) > 0 - - - def test_export_filestream(self): - """ - Can a notebook be exported by a filesteam? - """ - with open(self._get_notebook(), 'r') as f: - (output, resources) = export_by_name('python', f) - assert len(output) > 0 - - - def test_export_using_exporter(self): - """ - Can a notebook be exported using an instanciated exporter? - """ - (output, resources) = export(PythonExporter(), self._get_notebook()) - assert len(output) > 0 - - - def test_export_using_exporter_class(self): - """ - Can a notebook be exported using an exporter class type? - """ - (output, resources) = export(PythonExporter, self._get_notebook()) - assert len(output) > 0 - - - def test_export_resources(self): - """ - Can a notebook be exported along with a custom resources dict? - """ - (output, resources) = export(PythonExporter, self._get_notebook(), resources={}) - assert len(output) > 0 - - - def test_no_exporter(self): - """ - Is the right error thrown if no exporter is provided? - """ - try: - (output, resources) = export(None, self._get_notebook()) - except TypeError: - pass - diff --git a/jupyter_nbconvert/exporters/tests/test_exporter.py b/jupyter_nbconvert/exporters/tests/test_exporter.py deleted file mode 100644 index ed3cd52..0000000 --- a/jupyter_nbconvert/exporters/tests/test_exporter.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Module with tests for exporter.py -""" - -#----------------------------------------------------------------------------- -# 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 IPython.config import Config - -from .base import ExportersTestsBase -from ...preprocessors.base import Preprocessor -from ..exporter import Exporter - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class PizzaPreprocessor(Preprocessor): - """Simple preprocessor that adds a 'pizza' entry to the NotebookNode. Used - to test Exporter. - """ - - def preprocess(self, nb, resources): - nb['pizza'] = 'cheese' - return nb, resources - - -class TestExporter(ExportersTestsBase): - """Contains test functions for exporter.py""" - - - def test_constructor(self): - """Can an Exporter be constructed?""" - Exporter() - - - def test_export(self): - """Can an Exporter export something?""" - exporter = Exporter() - (notebook, resources) = exporter.from_filename(self._get_notebook()) - assert isinstance(notebook, dict) - - - def test_preprocessor(self): - """Do preprocessors work?""" - config = Config({'Exporter': {'preprocessors': [PizzaPreprocessor()]}}) - exporter = Exporter(config=config) - (notebook, resources) = exporter.from_filename(self._get_notebook()) - self.assertEqual(notebook['pizza'], 'cheese') diff --git a/jupyter_nbconvert/exporters/tests/test_html.py b/jupyter_nbconvert/exporters/tests/test_html.py deleted file mode 100644 index 07ecc84..0000000 --- a/jupyter_nbconvert/exporters/tests/test_html.py +++ /dev/null @@ -1,85 +0,0 @@ -"""Tests for HTMLExporter""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .base import ExportersTestsBase -from ..html import HTMLExporter -from IPython.nbformat import v4 -import re - - -class TestHTMLExporter(ExportersTestsBase): - """Tests for HTMLExporter""" - - exporter_class = HTMLExporter - should_include_raw = ['html'] - - def test_constructor(self): - """ - Can a HTMLExporter be constructed? - """ - HTMLExporter() - - - def test_export(self): - """ - Can a HTMLExporter export something? - """ - (output, resources) = HTMLExporter().from_filename(self._get_notebook()) - assert len(output) > 0 - - - def test_export_basic(self): - """ - Can a HTMLExporter export using the 'basic' template? - """ - (output, resources) = HTMLExporter(template_file='basic').from_filename(self._get_notebook()) - assert len(output) > 0 - - - def test_export_full(self): - """ - Can a HTMLExporter export using the 'full' template? - """ - (output, resources) = HTMLExporter(template_file='full').from_filename(self._get_notebook()) - assert len(output) > 0 - - def test_prompt_number(self): - """ - Does HTMLExporter properly format input and output prompts? - """ - (output, resources) = HTMLExporter(template_file='full').from_filename( - self._get_notebook(nb_name="prompt_numbers.ipynb")) - in_regex = r"In \[(.*)\]:" - out_regex = r"Out\[(.*)\]:" - - ins = ["2", "10", " ", " ", "*", "0"] - outs = ["10"] - - assert re.findall(in_regex, output) == ins - assert re.findall(out_regex, output) == outs - - def test_png_metadata(self): - """ - Does HTMLExporter with the 'basic' template treat pngs with width/height metadata correctly? - """ - (output, resources) = HTMLExporter(template_file='basic').from_filename( - self._get_notebook(nb_name="pngmetadata.ipynb")) - assert len(output) > 0 - - def test_javascript_output(self): - nb = v4.new_notebook( - cells=[ - v4.new_code_cell( - outputs=[v4.new_output( - output_type='display_data', - data={ - 'application/javascript': "javascript_output();" - } - )] - ) - ] - ) - (output, resources) = HTMLExporter(template_file='basic').from_notebook_node(nb) - self.assertIn('javascript_output', output) diff --git a/jupyter_nbconvert/exporters/tests/test_latex.py b/jupyter_nbconvert/exporters/tests/test_latex.py deleted file mode 100644 index 28807af..0000000 --- a/jupyter_nbconvert/exporters/tests/test_latex.py +++ /dev/null @@ -1,117 +0,0 @@ -"""Tests for Latex exporter""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import os.path -import textwrap -import re - -from .base import ExportersTestsBase -from ..latex import LatexExporter -from IPython.nbformat import write -from IPython.nbformat import v4 -from IPython.testing.decorators import onlyif_cmds_exist -from IPython.utils.tempdir import TemporaryDirectory - - -class TestLatexExporter(ExportersTestsBase): - """Contains test functions for latex.py""" - - exporter_class = LatexExporter - should_include_raw = ['latex'] - - def test_constructor(self): - """ - Can a LatexExporter be constructed? - """ - LatexExporter() - - - @onlyif_cmds_exist('pandoc') - def test_export(self): - """ - Can a LatexExporter export something? - """ - (output, resources) = LatexExporter().from_filename(self._get_notebook()) - assert len(output) > 0 - - - @onlyif_cmds_exist('pandoc') - def test_export_book(self): - """ - Can a LatexExporter export using 'report' template? - """ - (output, resources) = LatexExporter(template_file='report').from_filename(self._get_notebook()) - assert len(output) > 0 - - - @onlyif_cmds_exist('pandoc') - def test_export_basic(self): - """ - Can a LatexExporter export using 'article' template? - """ - (output, resources) = LatexExporter(template_file='article').from_filename(self._get_notebook()) - assert len(output) > 0 - - - @onlyif_cmds_exist('pandoc') - def test_export_article(self): - """ - Can a LatexExporter export using 'article' template? - """ - (output, resources) = LatexExporter(template_file='article').from_filename(self._get_notebook()) - assert len(output) > 0 - - @onlyif_cmds_exist('pandoc') - def test_very_long_cells(self): - """ - Torture test that long cells do not cause issues - """ - lorem_ipsum_text = textwrap.dedent("""\ - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec - dignissim, ipsum non facilisis tempus, dui felis tincidunt metus, - nec pulvinar neque odio eget risus. Nulla nisi lectus, cursus - suscipit interdum at, ultrices sit amet orci. Mauris facilisis - imperdiet elit, vitae scelerisque ipsum dignissim non. Integer - consequat malesuada neque sit amet pulvinar. Curabitur pretium - ut turpis eget aliquet. Maecenas sagittis lacus sed lectus - volutpat, eu adipiscing purus pulvinar. Maecenas consequat - luctus urna, eget cursus quam mollis a. Aliquam vitae ornare - erat, non hendrerit urna. Sed eu diam nec massa egestas pharetra - at nec tellus. Fusce feugiat lacus quis urna sollicitudin volutpat. - Quisque at sapien non nibh feugiat tempus ac ultricies purus. - """) - lorem_ipsum_text = lorem_ipsum_text.replace("\n"," ") + "\n\n" - large_lorem_ipsum_text = "".join([lorem_ipsum_text]*3000) - - notebook_name = "lorem_ipsum_long.ipynb" - nb = v4.new_notebook( - cells=[ - v4.new_markdown_cell(source=large_lorem_ipsum_text) - ] - ) - - with TemporaryDirectory() as td: - nbfile = os.path.join(td, notebook_name) - with open(nbfile, 'w') as f: - write(nb, f, 4) - - (output, resources) = LatexExporter(template_file='article').from_filename(nbfile) - assert len(output) > 0 - - @onlyif_cmds_exist('pandoc') - def test_prompt_number_color(self): - """ - Does LatexExporter properly format input and output prompts in color? - """ - (output, resources) = LatexExporter().from_filename( - self._get_notebook(nb_name="prompt_numbers.ipynb")) - in_regex = r"In \[\{\\color\{incolor\}(.*)\}\]:" - out_regex = r"Out\[\{\\color\{outcolor\}(.*)\}\]:" - - ins = ["2", "10", " ", " ", "*", "0"] - outs = ["10"] - - assert re.findall(in_regex, output) == ins - assert re.findall(out_regex, output) == outs diff --git a/jupyter_nbconvert/exporters/tests/test_markdown.py b/jupyter_nbconvert/exporters/tests/test_markdown.py deleted file mode 100644 index 1da8ed5..0000000 --- a/jupyter_nbconvert/exporters/tests/test_markdown.py +++ /dev/null @@ -1,40 +0,0 @@ -"""Tests for MarkdownExporter""" - -#----------------------------------------------------------------------------- -# 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 .base import ExportersTestsBase -from ..markdown import MarkdownExporter - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestMarkdownExporter(ExportersTestsBase): - """Tests for MarkdownExporter""" - - exporter_class = MarkdownExporter - should_include_raw = ['markdown', 'html'] - - def test_constructor(self): - """ - Can a MarkdownExporter be constructed? - """ - MarkdownExporter() - - - def test_export(self): - """ - Can a MarkdownExporter export something? - """ - (output, resources) = MarkdownExporter().from_filename(self._get_notebook()) - assert len(output) > 0 \ No newline at end of file diff --git a/jupyter_nbconvert/exporters/tests/test_notebook.py b/jupyter_nbconvert/exporters/tests/test_notebook.py deleted file mode 100644 index 68a966b..0000000 --- a/jupyter_nbconvert/exporters/tests/test_notebook.py +++ /dev/null @@ -1,39 +0,0 @@ -"""Tests for notebook.py""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import json - -from .base import ExportersTestsBase -from ..notebook import NotebookExporter - -from IPython.nbformat import validate -from jupyter_nbconvert.tests.base import assert_big_text_equal - -class TestNotebookExporter(ExportersTestsBase): - """Contains test functions for notebook.py""" - - exporter_class = NotebookExporter - - def test_export(self): - """ - Does the NotebookExporter return the file unchanged? - """ - with open(self._get_notebook()) as f: - file_contents = f.read() - (output, resources) = self.exporter_class().from_filename(self._get_notebook()) - assert len(output) > 0 - assert_big_text_equal(output.strip(), file_contents.strip()) - - def test_downgrade_3(self): - exporter = self.exporter_class(nbformat_version=3) - (output, resources) = exporter.from_filename(self._get_notebook()) - nb = json.loads(output) - validate(nb) - - def test_downgrade_2(self): - exporter = self.exporter_class(nbformat_version=2) - (output, resources) = exporter.from_filename(self._get_notebook()) - nb = json.loads(output) - self.assertEqual(nb['nbformat'], 2) diff --git a/jupyter_nbconvert/exporters/tests/test_pdf.py b/jupyter_nbconvert/exporters/tests/test_pdf.py deleted file mode 100644 index 6272605..0000000 --- a/jupyter_nbconvert/exporters/tests/test_pdf.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Tests for PDF export""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import logging -import os - -from IPython.testing import decorators as dec - -from .base import ExportersTestsBase -from ..pdf import PDFExporter - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestPDF(ExportersTestsBase): - """Test PDF export""" - - exporter_class = PDFExporter - - def test_constructor(self): - """Can a PDFExporter be constructed?""" - self.exporter_class() - - - @dec.onlyif_cmds_exist('pdflatex') - @dec.onlyif_cmds_exist('pandoc') - def test_export(self): - """Smoke test PDFExporter""" - (output, resources) = self.exporter_class(latex_count=1).from_filename(self._get_notebook()) - self.assertIsInstance(output, bytes) - assert len(output) > 0 - diff --git a/jupyter_nbconvert/exporters/tests/test_python.py b/jupyter_nbconvert/exporters/tests/test_python.py deleted file mode 100644 index 36ee0e9..0000000 --- a/jupyter_nbconvert/exporters/tests/test_python.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Tests for PythonExporter""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .base import ExportersTestsBase -from ..python import PythonExporter - - -class TestPythonExporter(ExportersTestsBase): - """Tests for PythonExporter""" - - exporter_class = PythonExporter - should_include_raw = ['python'] - - def test_constructor(self): - """Can a PythonExporter be constructed?""" - self.exporter_class() - - def test_export(self): - """Can a PythonExporter export something?""" - (output, resources) = self.exporter_class().from_filename(self._get_notebook()) - self.assertIn("coding: utf-8", output) diff --git a/jupyter_nbconvert/exporters/tests/test_rst.py b/jupyter_nbconvert/exporters/tests/test_rst.py deleted file mode 100644 index 1ccdb80..0000000 --- a/jupyter_nbconvert/exporters/tests/test_rst.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Tests for RSTExporter""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import io - -from IPython import nbformat -from IPython.nbformat import v4 - -from .base import ExportersTestsBase -from ..rst import RSTExporter -from IPython.testing.decorators import onlyif_cmds_exist - - -class TestRSTExporter(ExportersTestsBase): - """Tests for RSTExporter""" - - exporter_class = RSTExporter - should_include_raw = ['rst'] - - def test_constructor(self): - """ - Can a RSTExporter be constructed? - """ - RSTExporter() - - - @onlyif_cmds_exist('pandoc') - def test_export(self): - """ - Can a RSTExporter export something? - """ - (output, resources) = RSTExporter().from_filename(self._get_notebook()) - assert len(output) > 0 - - @onlyif_cmds_exist('pandoc') - def test_empty_code_cell(self): - """No empty code cells in rst""" - nbname = self._get_notebook() - with io.open(nbname, encoding='utf8') as f: - nb = nbformat.read(f, 4) - - exporter = self.exporter_class() - - (output, resources) = exporter.from_notebook_node(nb) - # add an empty code cell - nb.cells.append( - v4.new_code_cell(source="") - ) - (output2, resources) = exporter.from_notebook_node(nb) - # adding an empty code cell shouldn't change output - self.assertEqual(output.strip(), output2.strip()) - diff --git a/jupyter_nbconvert/exporters/tests/test_script.py b/jupyter_nbconvert/exporters/tests/test_script.py deleted file mode 100644 index 7e0bc43..0000000 --- a/jupyter_nbconvert/exporters/tests/test_script.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Tests for ScriptExporter""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import sys - -from IPython.nbformat import v4 -from IPython.utils.py3compat import PY3 - -from .base import ExportersTestsBase -from ..script import ScriptExporter - - -class TestScriptExporter(ExportersTestsBase): - """Tests for ScriptExporter""" - - exporter_class = ScriptExporter - - def test_constructor(self): - """Construct ScriptExporter""" - e = self.exporter_class() - - def test_export(self): - """ScriptExporter can export something""" - (output, resources) = self.exporter_class().from_filename(self._get_notebook()) - assert len(output) > 0 - - def test_export_python(self): - """delegate to custom exporter from language_info""" - exporter = self.exporter_class() - - pynb = v4.new_notebook() - (output, resources) = self.exporter_class().from_notebook_node(pynb) - self.assertNotIn('# coding: utf-8', output) - - pynb.metadata.language_info = { - 'name': 'python', - 'mimetype': 'text/x-python', - 'nbconvert_exporter': 'python', - } - (output, resources) = self.exporter_class().from_notebook_node(pynb) - self.assertIn('# coding: utf-8', output) - - \ No newline at end of file diff --git a/jupyter_nbconvert/exporters/tests/test_slides.py b/jupyter_nbconvert/exporters/tests/test_slides.py deleted file mode 100644 index ecb6889..0000000 --- a/jupyter_nbconvert/exporters/tests/test_slides.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Tests for SlidesExporter""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .base import ExportersTestsBase -from ..slides import SlidesExporter - - -class TestSlidesExporter(ExportersTestsBase): - """Tests for SlidesExporter""" - - exporter_class = SlidesExporter - should_include_raw = ['html'] - - def test_constructor(self): - """ - Can a SlidesExporter be constructed? - """ - SlidesExporter() - - - def test_export(self): - """ - Can a SlidesExporter export something? - """ - (output, resources) = SlidesExporter().from_filename(self._get_notebook()) - assert len(output) > 0 - - - def test_export_reveal(self): - """ - Can a SlidesExporter export using the 'reveal' template? - """ - (output, resources) = SlidesExporter(template_file='slides_reveal').from_filename(self._get_notebook()) - assert len(output) > 0 diff --git a/jupyter_nbconvert/exporters/tests/test_templateexporter.py b/jupyter_nbconvert/exporters/tests/test_templateexporter.py deleted file mode 100644 index 7a2b6d4..0000000 --- a/jupyter_nbconvert/exporters/tests/test_templateexporter.py +++ /dev/null @@ -1,108 +0,0 @@ -""" -Module with tests for templateexporter.py -""" - -#----------------------------------------------------------------------------- -# 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 IPython.config import Config - -from .base import ExportersTestsBase -from .cheese import CheesePreprocessor -from ..templateexporter import TemplateExporter - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestExporter(ExportersTestsBase): - """Contains test functions for exporter.py""" - - - def test_constructor(self): - """ - Can a TemplateExporter be constructed? - """ - TemplateExporter() - - - def test_export(self): - """ - Can a TemplateExporter export something? - """ - exporter = self._make_exporter() - (output, resources) = exporter.from_filename(self._get_notebook()) - assert len(output) > 0 - - - def test_extract_outputs(self): - """ - If the ExtractOutputPreprocessor is enabled, are outputs extracted? - """ - config = Config({'ExtractOutputPreprocessor': {'enabled': True}}) - exporter = self._make_exporter(config=config) - (output, resources) = exporter.from_filename(self._get_notebook()) - assert resources is not None - assert isinstance(resources['outputs'], dict) - assert len(resources['outputs']) > 0 - - - def test_preprocessor_class(self): - """ - Can a preprocessor be added to the preprocessors list by class type? - """ - config = Config({'Exporter': {'preprocessors': [CheesePreprocessor]}}) - exporter = self._make_exporter(config=config) - (output, resources) = exporter.from_filename(self._get_notebook()) - assert resources is not None - assert resources['cheese'] == 'real' - - - def test_preprocessor_instance(self): - """ - Can a preprocessor be added to the preprocessors list by instance? - """ - config = Config({'Exporter': {'preprocessors': [CheesePreprocessor()]}}) - exporter = self._make_exporter(config=config) - (output, resources) = exporter.from_filename(self._get_notebook()) - assert resources is not None - assert resources['cheese'] == 'real' - - - def test_preprocessor_dottedobjectname(self): - """ - Can a preprocessor be added to the preprocessors list by dotted object name? - """ - config = Config({'Exporter': {'preprocessors': ['jupyter_nbconvert.exporters.tests.cheese.CheesePreprocessor']}}) - exporter = self._make_exporter(config=config) - (output, resources) = exporter.from_filename(self._get_notebook()) - assert resources is not None - assert resources['cheese'] == 'real' - - - def test_preprocessor_via_method(self): - """ - Can a preprocessor be added via the Exporter convenience method? - """ - exporter = self._make_exporter() - exporter.register_preprocessor(CheesePreprocessor, enabled=True) - (output, resources) = exporter.from_filename(self._get_notebook()) - assert resources is not None - assert resources['cheese'] == 'real' - - - def _make_exporter(self, config=None): - # Create the exporter instance, make sure to set a template name since - # the base TemplateExporter doesn't have a template associated with it. - exporter = TemplateExporter(config=config, template_file='python') - return exporter diff --git a/jupyter_nbconvert/filters/__init__.py b/jupyter_nbconvert/filters/__init__.py deleted file mode 100755 index 1acf916..0000000 --- a/jupyter_nbconvert/filters/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .ansi import * -from .citation import * -from .datatypefilter import * -from .highlight import * -from .latex import * -from .markdown import * -from .strings import * diff --git a/jupyter_nbconvert/filters/ansi.py b/jupyter_nbconvert/filters/ansi.py deleted file mode 100644 index 0d6913d..0000000 --- a/jupyter_nbconvert/filters/ansi.py +++ /dev/null @@ -1,166 +0,0 @@ -"""Filters for processing ANSI colors within Jinja templates. -""" -#----------------------------------------------------------------------------- -# 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 -#----------------------------------------------------------------------------- - -import re -from IPython.utils import coloransi -from IPython.utils.text import strip_ansi - -#----------------------------------------------------------------------------- -# Classes and functions -#----------------------------------------------------------------------------- - -__all__ = [ - 'strip_ansi', - 'ansi2html', - 'single_ansi2latex', - 'ansi2latex' -] - -ansi_colormap = { - '30': 'ansiblack', - '31': 'ansired', - '32': 'ansigreen', - '33': 'ansiyellow', - '34': 'ansiblue', - '35': 'ansipurple', - '36': 'ansicyan', - '37': 'ansigrey', - '01': 'ansibold', -} - -html_escapes = { - '<': '<', - '>': '>', - "'": ''', - '"': '"', - '`': '`', -} -ansi_re = re.compile('\x1b' + r'\[([\dA-Fa-f;]*?)m') - -def ansi2html(text): - """ - Convert ansi colors to html colors. - - Parameters - ---------- - text : str - Text containing ansi colors to convert to html - """ - - # do ampersand first - text = text.replace('&', '&') - - for c, escape in html_escapes.items(): - text = text.replace(c, escape) - - m = ansi_re.search(text) - opened = False - cmds = [] - opener = '' - closer = '' - while m: - cmds = m.groups()[0].split(';') - closer = '' if opened else '' - - # True if there is there more than one element in cmds, *or* - # if there is only one but it is not equal to a string of zeroes. - opened = len(cmds) > 1 or cmds[0] != '0' * len(cmds[0]) - classes = [] - for cmd in cmds: - if cmd in ansi_colormap: - classes.append(ansi_colormap[cmd]) - - if classes: - opener = '' % (' '.join(classes)) - else: - opener = '' - text = re.sub(ansi_re, closer + opener, text, 1) - - m = ansi_re.search(text) - - if opened: - text += '' - return text - - -def single_ansi2latex(code): - """Converts single ansi markup to latex format. - - Return latex code and number of open brackets. - - Accepts codes like '\x1b[1;32m' (bold, red) and the short form '\x1b[32m' (red) - - Colors are matched to those defined in coloransi, which defines colors - using the 0, 1 (bold) and 5 (blinking) styles. Styles 1 and 5 are - interpreted as bold. All other styles are mapped to 0. Note that in - coloransi, a style of 1 does not just mean bold; for example, Brown is - "0;33", but Yellow is "1;33". An empty string is returned for unrecognised - codes and the "reset" code '\x1b[m'. - """ - components = code.split(';') - if len(components) > 1: - # Style is digits after '[' - style = int(components[0].split('[')[-1]) - color = components[1][:-1] - else: - style = 0 - color = components[0][-3:-1] - - # If the style is not normal (0), bold (1) or blinking (5) then treat it as normal - if style not in [0, 1, 5]: - style = 0 - - for name, tcode in coloransi.color_templates: - tstyle, tcolor = tcode.split(';') - tstyle = int(tstyle) - if tstyle == style and tcolor == color: - break - else: - return '', 0 - - if style == 5: - name = name[5:] # BlinkRed -> Red, etc - name = name.lower() - - if style in [1, 5]: - return r'\textbf{\color{'+name+'}', 1 - else: - return r'{\color{'+name+'}', 1 - -def ansi2latex(text): - """Converts ansi formated text to latex version - - based on https://bitbucket.org/birkenfeld/sphinx-contrib/ansi.py - """ - color_pattern = re.compile('\x1b\\[([^m]*)m') - last_end = 0 - openbrack = 0 - outstring = '' - for match in color_pattern.finditer(text): - head = text[last_end:match.start()] - outstring += head - if openbrack: - outstring += '}'*openbrack - openbrack = 0 - code = match.group() - if not (code == coloransi.TermColors.Normal or openbrack): - texform, openbrack = single_ansi2latex(code) - outstring += texform - last_end = match.end() - - # Add the remainer of the string and THEN close any remaining color brackets. - outstring += text[last_end:] - if openbrack: - outstring += '}'*openbrack - return outstring.strip() diff --git a/jupyter_nbconvert/filters/citation.py b/jupyter_nbconvert/filters/citation.py deleted file mode 100644 index 2ecd717..0000000 --- a/jupyter_nbconvert/filters/citation.py +++ /dev/null @@ -1,111 +0,0 @@ -"""Citation handling for LaTeX output.""" - -#----------------------------------------------------------------------------- -# 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 IPython.utils.py3compat import PY3 -if PY3: - from html.parser import HTMLParser -else: - from HTMLParser import HTMLParser - -#----------------------------------------------------------------------------- -# Functions -#----------------------------------------------------------------------------- - -__all__ = ['citation2latex'] - - -def citation2latex(s): - """Parse citations in Markdown cells. - - This looks for HTML tags having a data attribute names `data-cite` - and replaces it by the call to LaTeX cite command. The tranformation - looks like this: - - `(Granger, 2013)` - - Becomes - - `\\cite{granger}` - - Any HTML tag can be used, which allows the citations to be formatted - in HTML in any manner. - """ - parser = CitationParser() - parser.feed(s) - parser.close() - outtext = u'' - startpos = 0 - for citation in parser.citelist: - outtext += s[startpos:citation[1]] - outtext += '\\cite{%s}'%citation[0] - startpos = citation[2] if len(citation)==3 else -1 - outtext += s[startpos:] if startpos != -1 else '' - return outtext - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- -class CitationParser(HTMLParser): - """Citation Parser - - Replaces html tags with data-cite attribute with respective latex \\cite. - - Inherites from HTMLParser, overrides: - - handle_starttag - - handle_endtag - """ - # number of open tags - opentags = None - # list of found citations - citelist = None - # active citation tag - citetag = None - - def __init__(self): - self.citelist = [] - self.opentags = 0 - HTMLParser.__init__(self) - - def get_offset(self): - # Compute startposition in source - lin, offset = self.getpos() - pos = 0 - for i in range(lin-1): - pos = self.data.find('\n',pos) + 1 - return pos + offset - - def handle_starttag(self, tag, attrs): - # for each tag check if attributes are present and if no citation is active - if self.opentags == 0 and len(attrs)>0: - for atr, data in attrs: - if atr.lower() == 'data-cite': - self.citetag = tag - self.opentags = 1 - self.citelist.append([data, self.get_offset()]) - return - - if tag == self.citetag: - # found an open citation tag but not the starting one - self.opentags += 1 - - def handle_endtag(self, tag): - if tag == self.citetag: - # found citation tag check if starting one - if self.opentags == 1: - pos = self.get_offset() - self.citelist[-1].append(pos+len(tag)+3) - self.opentags -= 1 - - def feed(self, data): - self.data = data - HTMLParser.feed(self, data) diff --git a/jupyter_nbconvert/filters/datatypefilter.py b/jupyter_nbconvert/filters/datatypefilter.py deleted file mode 100755 index 5fc5923..0000000 --- a/jupyter_nbconvert/filters/datatypefilter.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Filter used to select the first preferred output format available. - -The filter contained in the file allows the converter templates to select -the output format that is most valuable to the active export format. The -value of the different formats is set via -NbConvertBase.display_data_priority -""" -#----------------------------------------------------------------------------- -# 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. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Classes and functions -#----------------------------------------------------------------------------- - -from ..utils.base import NbConvertBase - -__all__ = ['DataTypeFilter'] - -class DataTypeFilter(NbConvertBase): - """ Returns the preferred display format """ - - def __call__(self, output): - """ Return the first available format in the priority """ - - for fmt in self.display_data_priority: - if fmt in output: - return [fmt] - return [] diff --git a/jupyter_nbconvert/filters/highlight.py b/jupyter_nbconvert/filters/highlight.py deleted file mode 100644 index ea10e00..0000000 --- a/jupyter_nbconvert/filters/highlight.py +++ /dev/null @@ -1,135 +0,0 @@ -""" -Module containing filter functions that allow code to be highlighted -from within Jinja templates. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -# pygments must not be imported at the module level -# because errors should be raised at runtime if it's actually needed, -# not import time, when it may not be needed. - -from jupyter_nbconvert.utils.base import NbConvertBase -from warnings import warn - -MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json'] - -__all__ = [ - 'Highlight2HTML', - 'Highlight2Latex' -] - -class Highlight2HTML(NbConvertBase): - def __init__(self, pygments_lexer=None, **kwargs): - self.pygments_lexer = pygments_lexer or 'ipython3' - super(Highlight2HTML, self).__init__(**kwargs) - - def _default_language_changed(self, name, old, new): - warn('Setting default_language in config is deprecated, ' - 'please use language_info metadata instead.') - self.pygments_lexer = new - - def __call__(self, source, language=None, metadata=None): - """ - Return a syntax-highlighted version of the input source as html output. - - Parameters - ---------- - source : str - source of the cell to highlight - language : str - language to highlight the syntax of - metadata : NotebookNode cell metadata - metadata of the cell to highlight - """ - from pygments.formatters import HtmlFormatter - - if not language: - language=self.pygments_lexer - - return _pygments_highlight(source if len(source) > 0 else ' ', - # needed to help post processors: - HtmlFormatter(cssclass=" highlight hl-"+language), - language, metadata) - - -class Highlight2Latex(NbConvertBase): - def __init__(self, pygments_lexer=None, **kwargs): - self.pygments_lexer = pygments_lexer or 'ipython3' - super(Highlight2Latex, self).__init__(**kwargs) - - def _default_language_changed(self, name, old, new): - warn('Setting default_language in config is deprecated, ' - 'please use language_info metadata instead.') - self.pygments_lexer = new - - def __call__(self, source, language=None, metadata=None, strip_verbatim=False): - """ - Return a syntax-highlighted version of the input source as latex output. - - Parameters - ---------- - source : str - source of the cell to highlight - language : str - language to highlight the syntax of - metadata : NotebookNode cell metadata - metadata of the cell to highlight - strip_verbatim : bool - remove the Verbatim environment that pygments provides by default - """ - from pygments.formatters import LatexFormatter - if not language: - language=self.pygments_lexer - - latex = _pygments_highlight(source, LatexFormatter(), language, metadata) - if strip_verbatim: - latex = latex.replace(r'\begin{Verbatim}[commandchars=\\\{\}]' + '\n', '') - return latex.replace('\n\\end{Verbatim}\n', '') - else: - return latex - - - -def _pygments_highlight(source, output_formatter, language='ipython', metadata=None): - """ - Return a syntax-highlighted version of the input source - - Parameters - ---------- - source : str - source of the cell to highlight - output_formatter : Pygments formatter - language : str - language to highlight the syntax of - metadata : NotebookNode cell metadata - metadata of the cell to highlight - """ - from pygments import highlight - from pygments.lexers import get_lexer_by_name - from pygments.util import ClassNotFound - from IPython.lib.lexers import IPythonLexer, IPython3Lexer - - # If the cell uses a magic extension language, - # use the magic language instead. - if language.startswith('ipython') \ - and metadata \ - and 'magics_language' in metadata: - - language = metadata['magics_language'] - - if language == 'ipython2': - lexer = IPythonLexer() - elif language == 'ipython3': - lexer = IPython3Lexer() - else: - try: - lexer = get_lexer_by_name(language, stripall=True) - except ClassNotFound: - warn("No lexer found for language %r. Treating as plain text." % language) - from pygments.lexers.special import TextLexer - lexer = TextLexer() - - - return highlight(source, lexer, output_formatter) diff --git a/jupyter_nbconvert/filters/latex.py b/jupyter_nbconvert/filters/latex.py deleted file mode 100755 index e24dbb6..0000000 --- a/jupyter_nbconvert/filters/latex.py +++ /dev/null @@ -1,63 +0,0 @@ -"""Latex filters. - -Module of useful filters for processing Latex within Jinja latex templates. -""" -#----------------------------------------------------------------------------- -# 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 -#----------------------------------------------------------------------------- -import re - -#----------------------------------------------------------------------------- -# Globals and constants -#----------------------------------------------------------------------------- - -LATEX_RE_SUBS = ( - (re.compile(r'\.\.\.+'), r'{\\ldots}'), -) - -# Latex substitutions for escaping latex. -# see: http://stackoverflow.com/questions/16259923/how-can-i-escape-latex-special-characters-inside-django-templates - -LATEX_SUBS = { - '&': r'\&', - '%': r'\%', - '$': r'\$', - '#': r'\#', - '_': r'\_', - '{': r'\{', - '}': r'\}', - '~': r'\textasciitilde{}', - '^': r'\^{}', - '\\': r'\textbackslash{}', -} - - -#----------------------------------------------------------------------------- -# Functions -#----------------------------------------------------------------------------- - -__all__ = ['escape_latex'] - -def escape_latex(text): - """ - Escape characters that may conflict with latex. - - Parameters - ---------- - text : str - Text containing characters that may conflict with Latex - """ - text = ''.join(LATEX_SUBS.get(c, c) for c in text) - for pattern, replacement in LATEX_RE_SUBS: - text = pattern.sub(replacement, text) - - return text - diff --git a/jupyter_nbconvert/filters/markdown.py b/jupyter_nbconvert/filters/markdown.py deleted file mode 100755 index 5fce75a..0000000 --- a/jupyter_nbconvert/filters/markdown.py +++ /dev/null @@ -1,142 +0,0 @@ -"""Markdown filters - -This file contains a collection of utility filters for dealing with -markdown within Jinja templates. -""" -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from __future__ import print_function - -import os -import subprocess -from io import TextIOWrapper, BytesIO - -try: - from .markdown_mistune import markdown2html_mistune -except ImportError as e: - # store in variable for Python 3 - _mistune_import_error = e - def markdown2html_mistune(source): - """mistune is unavailable, raise ImportError""" - raise ImportError("markdown2html requires mistune: %s" % _mistune_import_error) - -from jupyter_nbconvert.utils.pandoc import pandoc -from jupyter_nbconvert.utils.exceptions import ConversionException -from jupyter_nbconvert.utils.version import check_version -from IPython.utils.py3compat import cast_bytes - - -marked = os.path.join(os.path.dirname(__file__), "marked.js") -_node = None - -__all__ = [ - 'markdown2html', - 'markdown2html_pandoc', - 'markdown2html_marked', - 'markdown2html_mistune', - 'markdown2latex', - 'markdown2rst', -] - -class NodeJSMissing(ConversionException): - """Exception raised when node.js is missing.""" - pass - - -def markdown2latex(source, markup='markdown', extra_args=None): - """Convert a markdown string to LaTeX via pandoc. - - This function will raise an error if pandoc is not installed. - Any error messages generated by pandoc are printed to stderr. - - Parameters - ---------- - source : string - Input string, assumed to be valid markdown. - markup : string - Markup used by pandoc's reader - default : pandoc extended markdown - (see http://johnmacfarlane.net/pandoc/README.html#pandocs-markdown) - - Returns - ------- - out : string - Output as returned by pandoc. - """ - return pandoc(source, markup, 'latex', extra_args=extra_args) - - -def markdown2html_pandoc(source, extra_args=None): - """Convert a markdown string to HTML via pandoc""" - extra_args = extra_args or ['--mathjax'] - return pandoc(source, 'markdown', 'html', extra_args=extra_args) - - -def _find_nodejs(): - global _node - if _node is None: - # prefer md2html via marked if node.js >= 0.9.12 is available - # node is called nodejs on debian, so try that first - _node = 'nodejs' - if not _verify_node(_node): - _node = 'node' - return _node - -def markdown2html_marked(source, encoding='utf-8'): - """Convert a markdown string to HTML via marked""" - command = [_find_nodejs(), marked] - try: - p = subprocess.Popen(command, - stdin=subprocess.PIPE, stdout=subprocess.PIPE - ) - except OSError as e: - raise NodeJSMissing( - "The command '%s' returned an error: %s.\n" % (" ".join(command), e) + - "Please check that Node.js is installed." - ) - out, _ = p.communicate(cast_bytes(source, encoding)) - out = TextIOWrapper(BytesIO(out), encoding, 'replace').read() - return out.rstrip('\n') - -# The mistune renderer is the default, because it's simple to depend on it -markdown2html = markdown2html_mistune - -def markdown2rst(source, extra_args=None): - """Convert a markdown string to ReST via pandoc. - - This function will raise an error if pandoc is not installed. - Any error messages generated by pandoc are printed to stderr. - - Parameters - ---------- - source : string - Input string, assumed to be valid markdown. - - Returns - ------- - out : string - Output as returned by pandoc. - """ - return pandoc(source, 'markdown', 'rst', extra_args=extra_args) - -def _verify_node(cmd): - """Verify that the node command exists and is at least the minimum supported - version of node. - - Parameters - ---------- - cmd : string - Node command to verify (i.e 'node').""" - try: - p = subprocess.Popen([cmd, '--version'], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - out, _ = p.communicate() - out = out.decode('utf8', 'replace') - except OSError: - # Command not found - return False - if p.returncode: - # Command error - return False - return check_version(out.lstrip('v'), '0.9.12') diff --git a/jupyter_nbconvert/filters/markdown_mistune.py b/jupyter_nbconvert/filters/markdown_mistune.py deleted file mode 100644 index c7cc305..0000000 --- a/jupyter_nbconvert/filters/markdown_mistune.py +++ /dev/null @@ -1,122 +0,0 @@ -"""Markdown filters with mistune - -Used from markdown.py -""" -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from __future__ import print_function - -import re - -import mistune - -from pygments import highlight -from pygments.lexers import get_lexer_by_name -from pygments.formatters import HtmlFormatter -from pygments.util import ClassNotFound - -from jupyter_nbconvert.filters.strings import add_anchor -from jupyter_nbconvert.utils.exceptions import ConversionException -from IPython.utils.decorators import undoc - - -@undoc -class MathBlockGrammar(mistune.BlockGrammar): - block_math = re.compile(r"^\$\$(.*?)\$\$", re.DOTALL) - latex_environment = re.compile(r"^\\begin\{([a-z]*\*?)\}(.*?)\\end\{\1\}", - re.DOTALL) - -@undoc -class MathBlockLexer(mistune.BlockLexer): - default_rules = ['block_math', 'latex_environment'] + mistune.BlockLexer.default_rules - - def __init__(self, rules=None, **kwargs): - if rules is None: - rules = MathBlockGrammar() - super(MathBlockLexer, self).__init__(rules, **kwargs) - - def parse_block_math(self, m): - """Parse a $$math$$ block""" - self.tokens.append({ - 'type': 'block_math', - 'text': m.group(1) - }) - - def parse_latex_environment(self, m): - self.tokens.append({ - 'type': 'latex_environment', - 'name': m.group(1), - 'text': m.group(2) - }) - -@undoc -class MathInlineGrammar(mistune.InlineGrammar): - math = re.compile(r"^\$(.+?)\$") - block_math = re.compile(r"^\$\$(.+?)\$\$", re.DOTALL) - text = re.compile(r'^[\s\S]+?(?=[\\%s\n' % \ - mistune.escape(code) - - formatter = HtmlFormatter() - return highlight(code, lexer, formatter) - - def header(self, text, level, raw=None): - html = super(IPythonRenderer, self).header(text, level, raw=raw) - return add_anchor(html) - - # Pass math through unaltered - mathjax does the rendering in the browser - def block_math(self, text): - return '$$%s$$' % text - - def latex_environment(self, name, text): - return r'\begin{%s}%s\end{%s}' % (name, text, name) - - def inline_math(self, text): - return '$%s$' % text - -def markdown2html_mistune(source): - """Convert a markdown string to HTML using mistune""" - return MarkdownWithMath(renderer=IPythonRenderer()).render(source) diff --git a/jupyter_nbconvert/filters/marked.js b/jupyter_nbconvert/filters/marked.js deleted file mode 100644 index aa98ac7..0000000 --- a/jupyter_nbconvert/filters/marked.js +++ /dev/null @@ -1,63 +0,0 @@ -// Node.js script for markdown to html conversion -// This applies the same math extraction and marked settings -// that we use in the live notebook. - -// IPython static_path dir relative to here: -var static_path = __dirname + "/../../html/static/"; - -// Excerpt from the example in require.js docs -// http://requirejs.org/docs/node.html -var requirejs = require('requirejs'); -requirejs.config({ - //Pass the top-level main.js/index.js require - //function to requirejs so that node modules - //are loaded relative to the top-level JS file. - nodeRequire: require, - baseUrl: static_path, -}); - -requirejs([ - 'fs', - 'components/marked/lib/marked', - 'components/highlight.js/build/highlight.pack', - 'base/js/utils', - 'notebook/js/mathjaxutils', - ], function(fs, marked, hljs, utils, mathjaxutils) { - - // this is copied from notebook.main. Should it be moved somewhere we can reuse it? - marked.setOptions({ - gfm : true, - tables: true, - langPrefix: "language-", - highlight: function(code, lang) { - if (!lang) { - // no language, no highlight - return code; - } - var highlighted; - try { - highlighted = hljs.highlight(lang, code, false); - } catch(err) { - highlighted = hljs.highlightAuto(code); - } - return highlighted.value; - } - }); - - // read the markdown from stdin - var md=''; - process.stdin.on("data", function (data) { - md += data; - }); - - // perform the md2html transform once stdin is complete - process.stdin.on("end", function () { - var text_and_math = mathjaxutils.remove_math(md); - var text = text_and_math[0]; - var math = text_and_math[1]; - var html = marked.parser(marked.lexer(text)); - html = mathjaxutils.replace_math(html, math); - process.stdout.write(html); - }); - -}); diff --git a/jupyter_nbconvert/filters/strings.py b/jupyter_nbconvert/filters/strings.py deleted file mode 100755 index 03c053a..0000000 --- a/jupyter_nbconvert/filters/strings.py +++ /dev/null @@ -1,221 +0,0 @@ -# coding: utf-8 -"""String filters. - -Contains a collection of useful string manipulation filters for use in Jinja -templates. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import os -import re -import textwrap -try: - from urllib.parse import quote # Py 3 -except ImportError: - from urllib2 import quote # Py 2 -from xml.etree import ElementTree - -from IPython.core.interactiveshell import InteractiveShell -from IPython.utils import py3compat - - -__all__ = [ - 'wrap_text', - 'html2text', - 'add_anchor', - 'strip_dollars', - 'strip_files_prefix', - 'comment_lines', - 'get_lines', - 'ipython2python', - 'posix_path', - 'path2url', - 'add_prompts', - 'ascii_only', - 'prevent_list_blocks', -] - - -def wrap_text(text, width=100): - """ - Intelligently wrap text. - Wrap text without breaking words if possible. - - Parameters - ---------- - text : str - Text to wrap. - width : int, optional - Number of characters to wrap to, default 100. - """ - - split_text = text.split('\n') - wrp = map(lambda x:textwrap.wrap(x,width), split_text) - wrpd = map('\n'.join, wrp) - return '\n'.join(wrpd) - - -def html2text(element): - """extract inner text from html - - Analog of jQuery's $(element).text() - """ - if isinstance(element, py3compat.string_types): - try: - element = ElementTree.fromstring(element) - except Exception: - # failed to parse, just return it unmodified - return element - - text = element.text or "" - for child in element: - text += html2text(child) - text += (element.tail or "") - return text - - -def add_anchor(html): - """Add an anchor-link to an html header - - For use on markdown headings - """ - try: - h = ElementTree.fromstring(py3compat.cast_bytes_py2(html, encoding='utf-8')) - except Exception: - # failed to parse, just return it unmodified - return html - link = html2text(h).replace(' ', '-') - h.set('id', link) - a = ElementTree.Element("a", {"class" : "anchor-link", "href" : "#" + link}) - a.text = u'¶' - h.append(a) - - # Known issue of Python3.x, ElementTree.tostring() returns a byte string - # instead of a text string. See issue http://bugs.python.org/issue10942 - # Workaround is to make sure the bytes are casted to a string. - return py3compat.decode(ElementTree.tostring(h), 'utf-8') - - -def add_prompts(code, first='>>> ', cont='... '): - """Add prompts to code snippets""" - new_code = [] - code_list = code.split('\n') - new_code.append(first + code_list[0]) - for line in code_list[1:]: - new_code.append(cont + line) - return '\n'.join(new_code) - - -def strip_dollars(text): - """ - Remove all dollar symbols from text - - Parameters - ---------- - text : str - Text to remove dollars from - """ - - return text.strip('$') - - -files_url_pattern = re.compile(r'(src|href)\=([\'"]?)/?files/') -markdown_url_pattern = re.compile(r'(!?)\[(?P.*?)\]\(/?files/(?P.*?)\)') - -def strip_files_prefix(text): - """ - Fix all fake URLs that start with `files/`, stripping out the `files/` prefix. - Applies to both urls (for html) and relative paths (for markdown paths). - - Parameters - ---------- - text : str - Text in which to replace 'src="files/real...' with 'src="real...' - """ - cleaned_text = files_url_pattern.sub(r"\1=\2", text) - cleaned_text = markdown_url_pattern.sub(r'\1[\2](\3)', cleaned_text) - return cleaned_text - - -def comment_lines(text, prefix='# '): - """ - Build a Python comment line from input text. - - Parameters - ---------- - text : str - Text to comment out. - prefix : str - Character to append to the start of each line. - """ - - #Replace line breaks with line breaks and comment symbols. - #Also add a comment symbol at the beginning to comment out - #the first line. - return prefix + ('\n'+prefix).join(text.split('\n')) - - -def get_lines(text, start=None,end=None): - """ - Split the input text into separate lines and then return the - lines that the caller is interested in. - - Parameters - ---------- - text : str - Text to parse lines from. - start : int, optional - First line to grab from. - end : int, optional - Last line to grab from. - """ - - # Split the input into lines. - lines = text.split("\n") - - # Return the right lines. - return "\n".join(lines[start:end]) #re-join - -def ipython2python(code): - """Transform IPython syntax to pure Python syntax - - Parameters - ---------- - - code : str - IPython code, to be transformed to pure Python - """ - shell = InteractiveShell.instance() - return shell.input_transformer_manager.transform_cell(code) - -def posix_path(path): - """Turn a path into posix-style path/to/etc - - Mainly for use in latex on Windows, - where native Windows paths are not allowed. - """ - if os.path.sep != '/': - return path.replace(os.path.sep, '/') - return path - -def path2url(path): - """Turn a file path into a URL""" - parts = path.split(os.path.sep) - return '/'.join(quote(part) for part in parts) - -def ascii_only(s): - """ensure a string is ascii""" - s = py3compat.cast_unicode(s) - return s.encode('ascii', 'replace').decode('ascii') - -def prevent_list_blocks(s): - """ - Prevent presence of enumerate or itemize blocks in latex headings cells - """ - out = re.sub('(^\s*\d*)\.', '\\1\.', s) - out = re.sub('(^\s*)\-', '\\1\-', out) - out = re.sub('(^\s*)\+', '\\1\+', out) - out = re.sub('(^\s*)\*', '\\1\*', out) - return out diff --git a/jupyter_nbconvert/filters/tests/__init__.py b/jupyter_nbconvert/filters/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_nbconvert/filters/tests/__init__.py +++ /dev/null diff --git a/jupyter_nbconvert/filters/tests/test_ansi.py b/jupyter_nbconvert/filters/tests/test_ansi.py deleted file mode 100644 index 5c448e6..0000000 --- a/jupyter_nbconvert/filters/tests/test_ansi.py +++ /dev/null @@ -1,89 +0,0 @@ -""" -Module with tests for ansi filters -""" - -#----------------------------------------------------------------------------- -# 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 IPython.utils.coloransi import TermColors - -from ...tests.base import TestsBase -from ..ansi import strip_ansi, ansi2html, ansi2latex - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestAnsi(TestsBase): - """Contains test functions for ansi.py""" - - def test_strip_ansi(self): - """strip_ansi test""" - correct_outputs = { - '%s%s%s' % (TermColors.Green, TermColors.White, TermColors.Red) : '', - 'hello%s' % TermColors.Blue: 'hello', - 'he%s%sllo' % (TermColors.Yellow, TermColors.Cyan) : 'hello', - '%shello' % TermColors.Blue : 'hello', - '{0}h{0}e{0}l{0}l{0}o{0}'.format(TermColors.Red) : 'hello', - 'hel%slo' % TermColors.Green : 'hello', - 'hello' : 'hello'} - - for inval, outval in correct_outputs.items(): - self._try_strip_ansi(inval, outval) - - - def _try_strip_ansi(self, inval, outval): - self.assertEqual(outval, strip_ansi(inval)) - - - def test_ansi2html(self): - """ansi2html test""" - correct_outputs = { - '%s' % (TermColors.Red) : '', - 'hello%s' % TermColors.Blue: 'hello', - 'he%s%sllo' % (TermColors.Green, TermColors.Cyan) : 'hello', - '%shello' % TermColors.Yellow : 'hello', - '{0}h{0}e{0}l{0}l{0}o{0}'.format(TermColors.White) : 'hello', - 'hel%slo' % TermColors.Green : 'hello', - 'hello' : 'hello'} - - for inval, outval in correct_outputs.items(): - self._try_ansi2html(inval, outval) - - - def _try_ansi2html(self, inval, outval): - self.fuzzy_compare(outval, ansi2html(inval)) - - - def test_ansi2latex(self): - """ansi2latex test""" - correct_outputs = { - '%s' % (TermColors.Red) : r'{\color{red}}', - 'hello%s' % TermColors.Blue: r'hello{\color{blue}}', - 'he%s%sllo' % (TermColors.Green, TermColors.Cyan) : r'he{\color{green}}{\color{cyan}llo}', - '%shello' % TermColors.Yellow : r'\textbf{\color{yellow}hello}', - '{0}h{0}e{0}l{0}l{0}o{0}'.format(TermColors.White) : r'\textbf{\color{white}h}\textbf{\color{white}e}\textbf{\color{white}l}\textbf{\color{white}l}\textbf{\color{white}o}\textbf{\color{white}}', - 'hel%slo' % TermColors.Green : r'hel{\color{green}lo}', - 'hello' : 'hello', - u'hello\x1b[34mthere\x1b[mworld' : u'hello{\\color{blue}there}world', - u'hello\x1b[mthere': u'hellothere', - u'hello\x1b[01;34mthere' : u"hello\\textbf{\\color{lightblue}there}", - u'hello\x1b[001;34mthere' : u"hello\\textbf{\\color{lightblue}there}" - } - - for inval, outval in correct_outputs.items(): - self._try_ansi2latex(inval, outval) - - - def _try_ansi2latex(self, inval, outval): - self.fuzzy_compare(outval, ansi2latex(inval), case_sensitive=True) diff --git a/jupyter_nbconvert/filters/tests/test_citation.py b/jupyter_nbconvert/filters/tests/test_citation.py deleted file mode 100644 index 3fc898c..0000000 --- a/jupyter_nbconvert/filters/tests/test_citation.py +++ /dev/null @@ -1,150 +0,0 @@ -#----------------------------------------------------------------------------- -# 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 ..citation import citation2latex -from nose.tools import assert_equal - -#----------------------------------------------------------------------------- -# Tests -#----------------------------------------------------------------------------- -test_md = {""" -# My Heading - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ac magna non augue -porttitor scelerisque ac id diam Granger. Mauris elit -velit, lobortis sed interdum at, vestibulum vitae libero Perez. -Lorem ipsum dolor sit amet, consectetur adipiscing elit -Thomas. Quisque iaculis ligula ut ipsum mattis viverra. - -

Here is a plain paragraph that should be unaffected. It contains simple -relations like 1<2 & 4>5.

- -* One Jonathan. -* Two Matthias. -* Three Paul. -""": """ -# My Heading - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ac magna non augue -porttitor scelerisque ac id diam \cite{granger}. Mauris elit -velit, lobortis sed interdum at, vestibulum vitae libero \cite{fperez}. -Lorem ipsum dolor sit amet, consectetur adipiscing elit -\cite{takluyver}. Quisque iaculis ligula ut ipsum mattis viverra. - -

Here is a plain paragraph that should be unaffected. It contains simple -relations like 1<2 & 4>5.

- -* One \cite{jdfreder}. -* Two \cite{carreau}. -* Three \cite{ivanov}. -""", - -# No citations -r"""The quick brown fox jumps over the lazy dog.""": -r"""The quick brown fox jumps over the lazy dog.""", - -# Simple inline -r"""Foo Text bar""": -r"""Foo \cite{asdf} bar""", - -# Multiline -r"""Text -Foo""": -r"""\cite{ewqr}Foo""", - -# Nested tags -r"""
Text
Bar""": -r"""
\cite{Foo}
Bar""", - -# Including Maths -r"""Foo $3*2*1$
Text
Bar""": -r"""Foo $3*2*1$ \cite{Foo} Bar""", - -# Missing end tag -r"""Test Foo""": -r"""\cite{asdf}""", - -r"""Test Foo""": -r"""\cite{asdf}""", - -r"""Test Foo""": -r"""\cite{asdf}""", - -# Multiple arguments -r"""Test Foo""": -r"""\cite{asdf} Foo""", - -# Wrong capitalization -r"""Test Foo""": -r"""\cite{asdf} Foo""", - -r"""Test Foo""": -r"""\cite{asdf} Foo""", - -# Wrong end tag -r""" ksjfs sdf ds """: -r"""\cite{wer}""", - -r"""""": -r"""\cite{wer}""", - -# Invalid tag names -r""" """: -r""" \cite{wer}""", - -# Non-nested tags -r"""

Test Foo

""": -r"""

\cite{asdf}Test Foo

""", - -# LXML errors -r"""Foo -\begin{eqnarray} -1 & bar1 \\ -3 & 4 \\ -\end{eqnarray}""": -r"""Foo -\begin{eqnarray} -1 & \cite{bar} \\ -3 & 4 \\ -\end{eqnarray}""", - -r""" -1<2 is true, but 3>4 is false. - -$1<2$ is true, but $3>4$ is false. - -1<2 it is even worse if it is alone in a line.""": -r""" -1<2 is true, but 3>4 is false. - -$1<2$ is true, but $3>4$ is false. - -1<2 it is even worse if it is alone in a line.""", - -r""" -1 < 2 is true, but 3 > 4 is false - -$1 < 2$ is true, but $3 > 4$ is false - -1 < 2 it is even worse if it is alone in a line. -""": -r""" -1 < 2 is true, but 3 > 4 is false - -$1 < 2$ is true, but $3 > 4$ is false - -1 < 2 it is even worse if it is alone in a line. -"""} - -def test_citation2latex(): - """Are citations parsed properly?""" - for input, output in test_md.items(): - yield (assert_equal, citation2latex(input), output) diff --git a/jupyter_nbconvert/filters/tests/test_datatypefilter.py b/jupyter_nbconvert/filters/tests/test_datatypefilter.py deleted file mode 100644 index 1deaf78..0000000 --- a/jupyter_nbconvert/filters/tests/test_datatypefilter.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Module with tests for DataTypeFilter""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from ...tests.base import TestsBase -from ..datatypefilter import DataTypeFilter - - -class TestDataTypeFilter(TestsBase): - """Contains test functions for datatypefilter.py""" - - def test_constructor(self): - """Can an instance of a DataTypeFilter be created?""" - DataTypeFilter() - - def test_junk_types(self): - """Can the DataTypeFilter pickout a useful type from a list of junk types?""" - filter = DataTypeFilter() - assert "image/png" in filter(["hair", "water", "image/png", "rock"]) - assert "application/pdf" in filter(["application/pdf", "hair", "water", "png", "rock"]) - self.assertEqual(filter(["hair", "water", "rock"]), []) - - def test_null(self): - """Will the DataTypeFilter fail if no types are passed in?""" - filter = DataTypeFilter() - self.assertEqual(filter([]), []) diff --git a/jupyter_nbconvert/filters/tests/test_highlight.py b/jupyter_nbconvert/filters/tests/test_highlight.py deleted file mode 100644 index 3eb7c75..0000000 --- a/jupyter_nbconvert/filters/tests/test_highlight.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -Module with tests for Highlight -""" - -#----------------------------------------------------------------------------- -# 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 ...tests.base import TestsBase -from ..highlight import Highlight2HTML, Highlight2Latex -from IPython.config import Config -import xml - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -highlight2html = Highlight2HTML() -highlight2latex = Highlight2Latex() -highlight2html_ruby = Highlight2HTML(pygments_lexer='ruby') - -class TestHighlight(TestsBase): - """Contains test functions for highlight.py""" - - #Hello world test, magics test, blank string test - tests = [ - """ - #Hello World Example - - import foo - - def say(text): - foo.bar(text) - - end - - say('Hello World!') - """, - """ - %%pylab - plot(x,y, 'r') - """ - ] - - tokens = [ - ['Hello World Example', 'say', 'text', 'import', 'def'], - ['pylab', 'plot']] - - - def test_highlight2html(self): - """highlight2html test""" - for index, test in enumerate(self.tests): - self._try_highlight(highlight2html, test, self.tokens[index]) - - - def test_highlight2latex(self): - """highlight2latex test""" - for index, test in enumerate(self.tests): - self._try_highlight(highlight2latex, test, self.tokens[index]) - - def test_parse_html_many_lang(self): - - ht = highlight2html(self.tests[0]) - rb = highlight2html_ruby(self.tests[0]) - - for lang,tkns in [ - ( ht, ('def', )), - ( rb, ('def','end' ) ) - ]: - print(tkns) - print(lang) - root = xml.etree.ElementTree.fromstring(lang) - self.assertEqual(self._extract_tokens(root,'k'), set(tkns)) - - def _extract_tokens(self, root, cls): - return set(map(lambda x:x.text,root.findall(".//*[@class='"+cls+"']"))) - - def _try_highlight(self, method, test, tokens): - """Try highlighting source, look for key tokens""" - results = method(test) - for token in tokens: - assert token in results diff --git a/jupyter_nbconvert/filters/tests/test_latex.py b/jupyter_nbconvert/filters/tests/test_latex.py deleted file mode 100644 index 3438f07..0000000 --- a/jupyter_nbconvert/filters/tests/test_latex.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Module with tests for Latex -""" - -#----------------------------------------------------------------------------- -# 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 ...tests.base import TestsBase -from ..latex import escape_latex - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestLatex(TestsBase): - - - def test_escape_latex(self): - """escape_latex test""" - tests = [ - (r'How are \you doing today?', r'How are \textbackslash{}you doing today?'), - (r'\escapechar=`\A\catcode`\|=0 |string|foo', r'\textbackslash{}escapechar=`\textbackslash{}A\textbackslash{}catcode`\textbackslash{}|=0 |string|foo'), - (r'# $ % & ~ _ ^ \ { }', r'\# \$ \% \& \textasciitilde{} \_ \^{} \textbackslash{} \{ \}'), - ('...', r'{\ldots}'), - ('','')] - - for test in tests: - self._try_escape_latex(test[0], test[1]) - - - def _try_escape_latex(self, test, result): - """Try to remove latex from string""" - self.assertEqual(escape_latex(test), result) diff --git a/jupyter_nbconvert/filters/tests/test_markdown.py b/jupyter_nbconvert/filters/tests/test_markdown.py deleted file mode 100644 index f627421..0000000 --- a/jupyter_nbconvert/filters/tests/test_markdown.py +++ /dev/null @@ -1,186 +0,0 @@ -# coding: utf-8 -"""Tests for conversions from markdown to other formats""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import re -from copy import copy - -from IPython.utils.py3compat import string_types -from IPython.testing import decorators as dec - -from ...tests.base import TestsBase -from ..markdown import markdown2latex, markdown2html, markdown2rst - -from jinja2 import Environment - -class TestMarkdown(TestsBase): - - tests = [ - '*test', - '**test', - '*test*', - '_test_', - '__test__', - '__*test*__', - '**test**', - '#test', - '##test', - 'test\n----', - 'test [link](https://google.com/)', - ] - - tokens = [ - '*test', - '**test', - 'test', - 'test', - 'test', - 'test', - 'test', - 'test', - 'test', - 'test', - ('test', 'https://google.com/'), - ] - - - @dec.onlyif_cmds_exist('pandoc') - def test_markdown2latex(self): - """markdown2latex test""" - for index, test in enumerate(self.tests): - self._try_markdown(markdown2latex, test, self.tokens[index]) - - @dec.onlyif_cmds_exist('pandoc') - def test_markdown2latex_markup(self): - """markdown2latex with markup kwarg test""" - # This string should be passed through unaltered with pandoc's - # markdown_strict reader - s = '1) arabic number with parenthesis' - self.assertEqual(markdown2latex(s, markup='markdown_strict'), s) - # This string should be passed through unaltered with pandoc's - # markdown_strict+tex_math_dollars reader - s = r'$\alpha$ latex math' - # sometimes pandoc uses $math$, sometimes it uses \(math\) - expected = re.compile(r'(\$|\\\()\\alpha(\$|\\\)) latex math') - try: - # py3 - assertRegex = self.assertRegex - except AttributeError: - # py2 - assertRegex = self.assertRegexpMatches - assertRegex( - markdown2latex(s, markup='markdown_strict+tex_math_dollars'), - expected) - - @dec.onlyif_cmds_exist('pandoc') - def test_pandoc_extra_args(self): - # pass --no-wrap - s = '\n'.join([ - "#latex {{long_line | md2l('markdown', ['--no-wrap'])}}", - "#rst {{long_line | md2r(['--columns', '5'])}}", - ]) - long_line = ' '.join(['long'] * 30) - env = Environment() - env.filters.update({ - 'md2l': markdown2latex, - 'md2r': markdown2rst, - }) - tpl = env.from_string(s) - rendered = tpl.render(long_line=long_line) - _, latex, rst = rendered.split('#') - - self.assertEqual(latex.strip(), 'latex %s' % long_line) - self.assertEqual(rst.strip(), 'rst %s' % long_line.replace(' ', '\n')) - - def test_markdown2html(self): - """markdown2html test""" - for index, test in enumerate(self.tests): - self._try_markdown(markdown2html, test, self.tokens[index]) - - def test_markdown2html_heading_anchors(self): - for md, tokens in [ - ('# test', - ('test', 'id="test"', u'¶
', "anchor-link") - ), - ('###test head space', - ('test head space', 'id="test-head-space"', u'¶', "anchor-link") - ) - ]: - self._try_markdown(markdown2html, md, tokens) - - def test_markdown2html_math(self): - # Mathematical expressions should be passed through unaltered - cases = [("\\begin{equation*}\n" - "\\left( \\sum_{k=1}^n a_k b_k \\right)^2 \\leq \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)\n" - "\\end{equation*}"), - ("$$\n" - "a = 1 *3* 5\n" - "$$"), - "$ a = 1 *3* 5 $", - ] - for case in cases: - self.assertIn(case, markdown2html(case)) - - def test_markdown2html_math_mixed(self): - """ensure markdown between inline and inline-block math""" - case = """The entries of $C$ are given by the exact formula: -$$ -C_{ik} = \sum_{j=1}^n A_{ij} B_{jk} -$$ -but there are many ways to _implement_ this computation. $\approx 2mnp$ flops""" - self._try_markdown(markdown2html, case, - case.replace("_implement_", "implement")) - - def test_markdown2html_math_paragraph(self): - """these should all parse without modification""" - cases = [ - # https://github.com/ipython/ipython/issues/6724 - """Water that is stored in $t$, $s_t$, must equal the storage content of the previous stage, -$s_{t-1}$, plus a stochastic inflow, $I_t$, minus what is being released in $t$, $r_t$. -With $s_0$ defined as the initial storage content in $t=1$, we have""", - # https://github.com/jupyter/nbviewer/issues/420 - """$C_{ik}$ -$$ -C_{ik} = \sum_{j=1} -$$ -$C_{ik}$""", - """$m$ -$$ -C = \begin{pmatrix} - 0 & 0 & 0 & \cdots & 0 & 0 & -c_0 \\ - 0 & 0 & 0 & \cdots & 0 & 1 & -c_{m-1} - \end{pmatrix} -$$ -$x^m$""", - """$r=\overline{1,n}$ -$$ {\bf -b}_{i}^{r}(t)=(1-t)\,{\bf b}_{i}^{r-1}(t)+t\,{\bf b}_{i+1}^{r-1}(t),\: - i=\overline{0,n-r}, $$ -i.e. the $i^{th}$""" - ] - - for case in cases: - self.assertIn(case, markdown2html(case)) - - @dec.onlyif_cmds_exist('pandoc') - def test_markdown2rst(self): - """markdown2rst test""" - - #Modify token array for rst, escape asterik - tokens = copy(self.tokens) - tokens[0] = r'\*test' - tokens[1] = r'\*\*test' - - for index, test in enumerate(self.tests): - self._try_markdown(markdown2rst, test, tokens[index]) - - - def _try_markdown(self, method, test, tokens): - results = method(test) - if isinstance(tokens, string_types): - assert tokens in results - else: - for token in tokens: - assert token in results diff --git a/jupyter_nbconvert/filters/tests/test_strings.py b/jupyter_nbconvert/filters/tests/test_strings.py deleted file mode 100644 index 0340cbb..0000000 --- a/jupyter_nbconvert/filters/tests/test_strings.py +++ /dev/null @@ -1,165 +0,0 @@ -""" -Module with tests for Strings -""" - -#----------------------------------------------------------------------------- -# 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 -#----------------------------------------------------------------------------- -import os - -from ...tests.base import TestsBase -from ..strings import (wrap_text, html2text, add_anchor, strip_dollars, - strip_files_prefix, get_lines, comment_lines, ipython2python, posix_path, - add_prompts, prevent_list_blocks -) - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestStrings(TestsBase): - - def test_wrap_text(self): - """wrap_text test""" - test_text = """ - Tush! never tell me; I take it much unkindly - That thou, Iago, who hast had my purse - As if the strings were thine, shouldst know of this. - """ - for length in [30,5,1]: - self._confirm_wrap_text(test_text, length) - - - def _confirm_wrap_text(self, text, length): - for line in wrap_text(text, length).split('\n'): - assert len(line) <= length - - - def test_html2text(self): - """html2text test""" - #TODO: More tests - self.assertEqual(html2text('joe'), 'joe') - - - def test_add_anchor(self): - """add_anchor test""" - #TODO: More tests - results = add_anchor('Hello World!') - assert 'Hello World!' in results - assert 'id="' in results - assert 'class="anchor-link"' in results - assert '' in results - - def test_add_anchor_fail(self): - """add_anchor does nothing when it fails""" - html = '

Hello
World!

' - results = add_anchor(html) - self.assertEqual(html, results) - - def test_strip_dollars(self): - """strip_dollars test""" - tests = [ - ('', ''), - ('$$', ''), - ('$H$', 'H'), - ('$He', 'He'), - ('H$el', 'H$el'), - ('Hell$', 'Hell'), - ('Hello', 'Hello'), - ('W$o$rld', 'W$o$rld')] - for test in tests: - self._try_strip_dollars(test[0], test[1]) - - - def _try_strip_dollars(self, test, result): - self.assertEqual(strip_dollars(test), result) - - - def test_strip_files_prefix(self): - """strip_files_prefix test""" - tests = [ - ('', ''), - ('/files', '/files'), - ('test="/files"', 'test="/files"'), - ('My files are in `files/`', 'My files are in `files/`'), - ('files/test.html', 'files/test.html'), - ('files/test.html', 'files/test.html'), - ("files/test.html", "files/test.html"), - ('', ''), - ('', ''), - ('hello![caption]', 'hello![caption]'), - ('hello![caption](/url/location.gif)', 'hello![caption](/url/location.gif)'), - ('hello![caption](url/location.gif)', 'hello![caption](url/location.gif)'), - ('hello![caption](url/location.gif)', 'hello![caption](url/location.gif)'), - ('hello![caption](files/url/location.gif)', 'hello![caption](url/location.gif)'), - ('hello![caption](/files/url/location.gif)', 'hello![caption](url/location.gif)'), - ('hello [text](/files/url/location.gif)', 'hello [text](url/location.gif)'), - ('hello [text space](files/url/location.gif)', 'hello [text space](url/location.gif)'), - ] - for test in tests: - self._try_files_prefix(test[0], test[1]) - - - def _try_files_prefix(self, test, result): - self.assertEqual(strip_files_prefix(test), result) - - - def test_comment_lines(self): - """comment_lines test""" - for line in comment_lines('hello\nworld\n!').split('\n'): - assert line.startswith('# ') - for line in comment_lines('hello\nworld\n!', 'beep').split('\n'): - assert line.startswith('beep') - - - def test_get_lines(self): - """get_lines test""" - text = "hello\nworld\n!" - self.assertEqual(get_lines(text, start=1), "world\n!") - self.assertEqual(get_lines(text, end=2), "hello\nworld") - self.assertEqual(get_lines(text, start=2, end=5), "!") - self.assertEqual(get_lines(text, start=-2), "world\n!") - - - def test_ipython2python(self): - """ipython2python test""" - #TODO: More tests - results = ipython2python(u'%%pylab\nprint("Hello-World")').replace("u'", "'") - self.fuzzy_compare(results, u"get_ipython().run_cell_magic('pylab', '', 'print(\"Hello-World\")')", - ignore_spaces=True, ignore_newlines=True) - - def test_posix_path(self): - """posix_path test""" - path_list = ['foo', 'bar'] - expected = '/'.join(path_list) - native = os.path.join(*path_list) - filtered = posix_path(native) - self.assertEqual(filtered, expected) - - def test_add_prompts(self): - """add_prompts test""" - text1 = """for i in range(10):\n i += 1\n print i""" - text2 = """>>> for i in range(10):\n... i += 1\n... print i""" - self.assertEqual(text2, add_prompts(text1)) - - def test_prevent_list_blocks(self): - """prevent_list_blocks test""" - tests = [ - ('1. arabic point', '1\\. arabic point'), - ('* bullet asterisk', '\\* bullet asterisk'), - ('+ bullet Plus Sign', '\\+ bullet Plus Sign'), - ('- bullet Hyphen-Minus', '\\- bullet Hyphen-Minus'), - (' 1. spaces + arabic point', ' 1\\. spaces + arabic point'), - ] - for test in tests: - self.assertEqual(prevent_list_blocks(test[0]), test[1]) diff --git a/jupyter_nbconvert/nbconvertapp.py b/jupyter_nbconvert/nbconvertapp.py deleted file mode 100755 index 92f6a05..0000000 --- a/jupyter_nbconvert/nbconvertapp.py +++ /dev/null @@ -1,407 +0,0 @@ -#!/usr/bin/env python -"""NbConvert is a utility for conversion of .ipynb files. - -Command-line interface for the NbConvert conversion utility. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from __future__ import print_function - -import logging -import sys -import os -import glob - -from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags -from IPython.core.profiledir import ProfileDir -from IPython.config import catch_config_error, Configurable -from IPython.utils.traitlets import ( - Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum, Bool, -) -from IPython.utils.importstring import import_item - -from .exporters.export import get_export_names, exporter_map -from jupyter_nbconvert import exporters, preprocessors, writers, postprocessors -from .utils.base import NbConvertBase -from .utils.exceptions import ConversionException - -#----------------------------------------------------------------------------- -#Classes and functions -#----------------------------------------------------------------------------- - -class DottedOrNone(DottedObjectName): - """ - A string holding a valid dotted object name in Python, such as A.b3._c - Also allows for None type.""" - - default_value = u'' - - def validate(self, obj, value): - if value is not None and len(value) > 0: - return super(DottedOrNone, self).validate(obj, value) - else: - return value - -nbconvert_aliases = {} -nbconvert_aliases.update(base_aliases) -nbconvert_aliases.update({ - 'to' : 'NbConvertApp.export_format', - 'template' : 'TemplateExporter.template_file', - 'writer' : 'NbConvertApp.writer_class', - 'post': 'NbConvertApp.postprocessor_class', - 'output': 'NbConvertApp.output_base', - 'reveal-prefix': 'RevealHelpPreprocessor.url_prefix', - 'nbformat': 'NotebookExporter.nbformat_version', -}) - -nbconvert_flags = {} -nbconvert_flags.update(base_flags) -nbconvert_flags.update({ - 'execute' : ( - {'ExecutePreprocessor' : {'enabled' : True}}, - "Execute the notebook prior to export." - ), - 'stdout' : ( - {'NbConvertApp' : {'writer_class' : "StdoutWriter"}}, - "Write notebook output to stdout instead of files." - ), - 'inplace' : ( - { - 'NbConvertApp' : {'use_output_suffix' : False}, - 'FilesWriter': {'build_directory': ''} - }, - """Run nbconvert in place, overwriting the existing notebook (only - relevant when converting to notebook format)""" - ) -}) - - -class NbConvertApp(BaseIPythonApplication): - """Application used to convert from notebook file type (``*.ipynb``)""" - - name = 'ipython-nbconvert' - aliases = nbconvert_aliases - flags = nbconvert_flags - - def _log_level_default(self): - return logging.INFO - - def _classes_default(self): - classes = [NbConvertBase, ProfileDir] - for pkg in (exporters, preprocessors, writers, postprocessors): - for name in dir(pkg): - cls = getattr(pkg, name) - if isinstance(cls, type) and issubclass(cls, Configurable): - classes.append(cls) - - return classes - - description = Unicode( - u"""This application is used to convert notebook files (*.ipynb) - to various other formats. - - WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""") - - output_base = Unicode('', config=True, help='''overwrite base name use for output files. - can only be used when converting one notebook at a time. - ''') - - use_output_suffix = Bool( - True, - config=True, - help="""Whether to apply a suffix prior to the extension (only relevant - when converting to notebook format). The suffix is determined by - the exporter, and is usually '.nbconvert'.""") - - examples = Unicode(u""" - The simplest way to use nbconvert is - - > ipython nbconvert mynotebook.ipynb - - which will convert mynotebook.ipynb to the default format (probably HTML). - - You can specify the export format with `--to`. - Options include {0} - - > ipython nbconvert --to latex mynotebook.ipynb - - Both HTML and LaTeX support multiple output templates. LaTeX includes - 'base', 'article' and 'report'. HTML includes 'basic' and 'full'. You - can specify the flavor of the format used. - - > ipython nbconvert --to html --template basic mynotebook.ipynb - - You can also pipe the output to stdout, rather than a file - - > ipython nbconvert mynotebook.ipynb --stdout - - PDF is generated via latex - - > ipython nbconvert mynotebook.ipynb --to pdf - - You can get (and serve) a Reveal.js-powered slideshow - - > ipython nbconvert myslides.ipynb --to slides --post serve - - Multiple notebooks can be given at the command line in a couple of - different ways: - - > ipython nbconvert notebook*.ipynb - > ipython nbconvert notebook1.ipynb notebook2.ipynb - - or you can specify the notebooks list in a config file, containing:: - - c.NbConvertApp.notebooks = ["my_notebook.ipynb"] - - > ipython nbconvert --config mycfg.py - """.format(get_export_names())) - - # Writer specific variables - writer = Instance('jupyter_nbconvert.writers.base.WriterBase', - help="""Instance of the writer class used to write the - results of the conversion.""", allow_none=True) - writer_class = DottedObjectName('FilesWriter', config=True, - help="""Writer class used to write the - results of the conversion""") - writer_aliases = {'fileswriter': 'jupyter_nbconvert.writers.files.FilesWriter', - 'debugwriter': 'jupyter_nbconvert.writers.debug.DebugWriter', - 'stdoutwriter': 'jupyter_nbconvert.writers.stdout.StdoutWriter'} - writer_factory = Type(allow_none=True) - - def _writer_class_changed(self, name, old, new): - if new.lower() in self.writer_aliases: - new = self.writer_aliases[new.lower()] - self.writer_factory = import_item(new) - - # Post-processor specific variables - postprocessor = Instance('jupyter_nbconvert.postprocessors.base.PostProcessorBase', - help="""Instance of the PostProcessor class used to write the - results of the conversion.""", allow_none=True) - - postprocessor_class = DottedOrNone(config=True, - help="""PostProcessor class used to write the - results of the conversion""") - postprocessor_aliases = {'serve': 'jupyter_nbconvert.postprocessors.serve.ServePostProcessor'} - postprocessor_factory = Type(allow_none=True) - - def _postprocessor_class_changed(self, name, old, new): - if new.lower() in self.postprocessor_aliases: - new = self.postprocessor_aliases[new.lower()] - if new: - self.postprocessor_factory = import_item(new) - - - # Other configurable variables - export_format = CaselessStrEnum(get_export_names(), - default_value="html", - config=True, - help="""The export format to be used.""" - ) - - notebooks = List([], config=True, help="""List of notebooks to convert. - Wildcards are supported. - Filenames passed positionally will be added to the list. - """) - - @catch_config_error - def initialize(self, argv=None): - self.init_syspath() - super(NbConvertApp, self).initialize(argv) - self.init_notebooks() - self.init_writer() - self.init_postprocessor() - - - - def init_syspath(self): - """ - Add the cwd to the sys.path ($PYTHONPATH) - """ - sys.path.insert(0, os.getcwd()) - - - def init_notebooks(self): - """Construct the list of notebooks. - If notebooks are passed on the command-line, - they override notebooks specified in config files. - Glob each notebook to replace notebook patterns with filenames. - """ - - # Specifying notebooks on the command-line overrides (rather than adds) - # the notebook list - if self.extra_args: - patterns = self.extra_args - else: - patterns = self.notebooks - - # Use glob to replace all the notebook patterns with filenames. - filenames = [] - for pattern in patterns: - - # Use glob to find matching filenames. Allow the user to convert - # notebooks without having to type the extension. - globbed_files = glob.glob(pattern) - globbed_files.extend(glob.glob(pattern + '.ipynb')) - if not globbed_files: - self.log.warn("pattern %r matched no files", pattern) - - for filename in globbed_files: - if not filename in filenames: - filenames.append(filename) - self.notebooks = filenames - - def init_writer(self): - """ - Initialize the writer (which is stateless) - """ - self._writer_class_changed(None, self.writer_class, self.writer_class) - self.writer = self.writer_factory(parent=self) - if hasattr(self.writer, 'build_directory') and self.writer.build_directory != '': - self.use_output_suffix = False - - def init_postprocessor(self): - """ - Initialize the postprocessor (which is stateless) - """ - self._postprocessor_class_changed(None, self.postprocessor_class, - self.postprocessor_class) - if self.postprocessor_factory: - self.postprocessor = self.postprocessor_factory(parent=self) - - def start(self): - """ - Ran after initialization completed - """ - super(NbConvertApp, self).start() - self.convert_notebooks() - - def init_single_notebook_resources(self, notebook_filename): - """Step 1: Initialize resources - - This intializes the resources dictionary for a single notebook. This - method should return the resources dictionary, and MUST include the - following keys: - - - profile_dir: the location of the profile directory - - unique_key: the notebook name - - output_files_dir: a directory where output files (not including - the notebook itself) should be saved - - """ - - # Get a unique key for the notebook and set it in the resources object. - basename = os.path.basename(notebook_filename) - notebook_name = basename[:basename.rfind('.')] - if self.output_base: - # strip duplicate extension from output_base, to avoid Basname.ext.ext - if getattr(self.exporter, 'file_extension', False): - base, ext = os.path.splitext(self.output_base) - if ext == self.exporter.file_extension: - self.output_base = base - notebook_name = self.output_base - - self.log.debug("Notebook name is '%s'", notebook_name) - - # first initialize the resources we want to use - resources = {} - resources['profile_dir'] = self.profile_dir.location - resources['unique_key'] = notebook_name - resources['output_files_dir'] = '%s_files' % notebook_name - - return resources - - def export_single_notebook(self, notebook_filename, resources): - """Step 2: Export the notebook - - Exports the notebook to a particular format according to the specified - exporter. This function returns the output and (possibly modified) - resources from the exporter. - - """ - try: - output, resources = self.exporter.from_filename(notebook_filename, resources=resources) - except ConversionException: - self.log.error("Error while converting '%s'", notebook_filename, exc_info=True) - self.exit(1) - - return output, resources - - def write_single_notebook(self, output, resources): - """Step 3: Write the notebook to file - - This writes output from the exporter to file using the specified writer. - It returns the results from the writer. - - """ - if 'unique_key' not in resources: - raise KeyError("unique_key MUST be specified in the resources, but it is not") - - notebook_name = resources['unique_key'] - if self.use_output_suffix and not self.output_base: - notebook_name += resources.get('output_suffix', '') - - write_results = self.writer.write( - output, resources, notebook_name=notebook_name) - return write_results - - def postprocess_single_notebook(self, write_results): - """Step 4: Postprocess the notebook - - This postprocesses the notebook after it has been written, taking as an - argument the results of writing the notebook to file. This only actually - does anything if a postprocessor has actually been specified. - - """ - # Post-process if post processor has been defined. - if hasattr(self, 'postprocessor') and self.postprocessor: - self.postprocessor(write_results) - - def convert_single_notebook(self, notebook_filename): - """Convert a single notebook. Performs the following steps: - - 1. Initialize notebook resources - 2. Export the notebook to a particular format - 3. Write the exported notebook to file - 4. (Maybe) postprocess the written file - - """ - self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format) - resources = self.init_single_notebook_resources(notebook_filename) - output, resources = self.export_single_notebook(notebook_filename, resources) - write_results = self.write_single_notebook(output, resources) - self.postprocess_single_notebook(write_results) - - def convert_notebooks(self): - """ - Convert the notebooks in the self.notebook traitlet - """ - # check that the output base isn't specified if there is more than - # one notebook to convert - if self.output_base != '' and len(self.notebooks) > 1: - self.log.error( - """ - UsageError: --output flag or `NbConvertApp.output_base` config option - cannot be used when converting multiple notebooks. - """ - ) - self.exit(1) - - # initialize the exporter - self.exporter = exporter_map[self.export_format](config=self.config) - - # no notebooks to convert! - if len(self.notebooks) == 0: - self.print_help() - sys.exit(-1) - - # convert each notebook - for notebook_filename in self.notebooks: - self.convert_single_notebook(notebook_filename) - -#----------------------------------------------------------------------------- -# Main entry point -#----------------------------------------------------------------------------- - -launch_new_instance = NbConvertApp.launch_instance diff --git a/jupyter_nbconvert/postprocessors/__init__.py b/jupyter_nbconvert/postprocessors/__init__.py deleted file mode 100644 index 75ff947..0000000 --- a/jupyter_nbconvert/postprocessors/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .base import PostProcessorBase - -# protect against unavailable tornado -try: - from .serve import ServePostProcessor -except ImportError: - pass diff --git a/jupyter_nbconvert/postprocessors/base.py b/jupyter_nbconvert/postprocessors/base.py deleted file mode 100644 index 3c720b3..0000000 --- a/jupyter_nbconvert/postprocessors/base.py +++ /dev/null @@ -1,35 +0,0 @@ -""" -Basic post processor -""" -#----------------------------------------------------------------------------- -#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 ..utils.base import NbConvertBase - - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- -class PostProcessorBase(NbConvertBase): - - def __call__(self, input): - """ - See def postprocess() ... - """ - self.postprocess(input) - - - def postprocess(self, input): - """ - Post-process output from a writer. - """ - raise NotImplementedError('postprocess') diff --git a/jupyter_nbconvert/postprocessors/serve.py b/jupyter_nbconvert/postprocessors/serve.py deleted file mode 100644 index 09caedd..0000000 --- a/jupyter_nbconvert/postprocessors/serve.py +++ /dev/null @@ -1,105 +0,0 @@ -"""PostProcessor for serving reveal.js HTML slideshows.""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from __future__ import print_function - -import os -import webbrowser - -from tornado import web, ioloop, httpserver -from tornado.httpclient import AsyncHTTPClient - -from IPython.utils.traitlets import Bool, Unicode, Int - -from .base import PostProcessorBase - - -class ProxyHandler(web.RequestHandler): - """handler the proxies requests from a local prefix to a CDN""" - @web.asynchronous - def get(self, prefix, url): - """proxy a request to a CDN""" - proxy_url = "/".join([self.settings['cdn'], url]) - client = self.settings['client'] - client.fetch(proxy_url, callback=self.finish_get) - - def finish_get(self, response): - """finish the request""" - # rethrow errors - response.rethrow() - - for header in ["Content-Type", "Cache-Control", "Date", "Last-Modified", "Expires"]: - if header in response.headers: - self.set_header(header, response.headers[header]) - self.finish(response.body) - - -class ServePostProcessor(PostProcessorBase): - """Post processor designed to serve files - - Proxies reveal.js requests to a CDN if no local reveal.js is present - """ - - - open_in_browser = Bool(True, config=True, - help="""Should the browser be opened automatically?""" - ) - reveal_cdn = Unicode("https://cdn.jsdelivr.net/reveal.js/2.6.2", config=True, - help="""URL for reveal.js CDN.""" - ) - reveal_prefix = Unicode("reveal.js", config=True, help="URL prefix for reveal.js") - ip = Unicode("127.0.0.1", config=True, help="The IP address to listen on.") - port = Int(8000, config=True, help="port for the server to listen on.") - - def postprocess(self, input): - """Serve the build directory with a webserver.""" - dirname, filename = os.path.split(input) - handlers = [ - (r"/(.+)", web.StaticFileHandler, {'path' : dirname}), - (r"/", web.RedirectHandler, {"url": "/%s" % filename}) - ] - - if ('://' in self.reveal_prefix or self.reveal_prefix.startswith("//")): - # reveal specifically from CDN, nothing to do - pass - elif os.path.isdir(os.path.join(dirname, self.reveal_prefix)): - # reveal prefix exists - self.log.info("Serving local %s", self.reveal_prefix) - else: - self.log.info("Redirecting %s requests to %s", self.reveal_prefix, self.reveal_cdn) - handlers.insert(0, (r"/(%s)/(.*)" % self.reveal_prefix, ProxyHandler)) - - app = web.Application(handlers, - cdn=self.reveal_cdn, - client=AsyncHTTPClient(), - ) - # hook up tornado logging to our logger - try: - from tornado import log - log.app_log = self.log - except ImportError: - # old tornado (<= 3), ignore - pass - - http_server = httpserver.HTTPServer(app) - http_server.listen(self.port, address=self.ip) - url = "http://%s:%i/%s" % (self.ip, self.port, filename) - print("Serving your slides at %s" % url) - print("Use Control-C to stop this server") - if self.open_in_browser: - webbrowser.open(url, new=2) - try: - ioloop.IOLoop.instance().start() - except KeyboardInterrupt: - print("\nInterrupted") - -def main(path): - """allow running this module to serve the slides""" - server = ServePostProcessor() - server(path) - -if __name__ == '__main__': - import sys - main(sys.argv[1]) diff --git a/jupyter_nbconvert/postprocessors/tests/__init__.py b/jupyter_nbconvert/postprocessors/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_nbconvert/postprocessors/tests/__init__.py +++ /dev/null diff --git a/jupyter_nbconvert/postprocessors/tests/test_serve.py b/jupyter_nbconvert/postprocessors/tests/test_serve.py deleted file mode 100644 index 5ac5413..0000000 --- a/jupyter_nbconvert/postprocessors/tests/test_serve.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Module with tests for the serve post-processor -""" - -#----------------------------------------------------------------------------- -# 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 ...tests.base import TestsBase -from ..serve import ServePostProcessor - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestServe(TestsBase): - """Contains test functions for serve.py""" - - - def test_constructor(self): - """Can a ServePostProcessor be constructed?""" - ServePostProcessor() diff --git a/jupyter_nbconvert/preprocessors/__init__.py b/jupyter_nbconvert/preprocessors/__init__.py deleted file mode 100755 index 3f1a591..0000000 --- a/jupyter_nbconvert/preprocessors/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Class base Preprocessors -from .base import Preprocessor -from .convertfigures import ConvertFiguresPreprocessor -from .svg2pdf import SVG2PDFPreprocessor -from .extractoutput import ExtractOutputPreprocessor -from .revealhelp import RevealHelpPreprocessor -from .latex import LatexPreprocessor -from .csshtmlheader import CSSHTMLHeaderPreprocessor -from .highlightmagics import HighlightMagicsPreprocessor -from .clearoutput import ClearOutputPreprocessor -from .execute import ExecutePreprocessor - -# decorated function Preprocessors -from .coalescestreams import coalesce_streams diff --git a/jupyter_nbconvert/preprocessors/base.py b/jupyter_nbconvert/preprocessors/base.py deleted file mode 100755 index 30843a8..0000000 --- a/jupyter_nbconvert/preprocessors/base.py +++ /dev/null @@ -1,92 +0,0 @@ -"""Base class for preprocessors""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from ..utils.base import NbConvertBase -from IPython.utils.traitlets import Bool - - -class Preprocessor(NbConvertBase): - """ A configurable preprocessor - - Inherit from this class if you wish to have configurability for your - preprocessor. - - Any configurable traitlets this class exposed will be configurable in - profiles using c.SubClassName.attribute = value - - you can overwrite :meth:`preprocess_cell` to apply a transformation - independently on each cell or :meth:`preprocess` if you prefer your own - logic. See corresponding docstring for informations. - - Disabled by default and can be enabled via the config by - 'c.YourPreprocessorName.enabled = True' - """ - - enabled = Bool(False, config=True) - - def __init__(self, **kw): - """ - Public constructor - - Parameters - ---------- - config : Config - Configuration file structure - **kw : misc - Additional arguments - """ - - super(Preprocessor, self).__init__(**kw) - - - def __call__(self, nb, resources): - if self.enabled: - self.log.debug("Applying preprocessor: %s", self.__class__.__name__) - return self.preprocess(nb,resources) - else: - return nb, resources - - - def preprocess(self, nb, resources): - """ - Preprocessing to apply on each notebook. - - Must return modified nb, resources. - - If you wish to apply your preprocessing to each cell, you might want - to override preprocess_cell method instead. - - Parameters - ---------- - nb : NotebookNode - Notebook being converted - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - """ - for index, cell in enumerate(nb.cells): - nb.cells[index], resources = self.preprocess_cell(cell, resources, index) - return nb, resources - - - def preprocess_cell(self, cell, resources, index): - """ - Override if you want to apply some preprocessing to each cell. - Must return modified cell and resource dictionary. - - Parameters - ---------- - cell : NotebookNode cell - Notebook cell being processed - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - index : int - Index of the cell being processed - """ - - raise NotImplementedError('should be implemented by subclass') - return cell, resources - diff --git a/jupyter_nbconvert/preprocessors/clearoutput.py b/jupyter_nbconvert/preprocessors/clearoutput.py deleted file mode 100644 index f28f189..0000000 --- a/jupyter_nbconvert/preprocessors/clearoutput.py +++ /dev/null @@ -1,20 +0,0 @@ -"""Module containing a preprocessor that removes the outputs from code cells""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .base import Preprocessor - -class ClearOutputPreprocessor(Preprocessor): - """ - Removes the output from all code cells in a notebook. - """ - - def preprocess_cell(self, cell, resources, cell_index): - """ - Apply a transformation on each cell. See base.py for details. - """ - if cell.cell_type == 'code': - cell.outputs = [] - cell.execution_count = None - return cell, resources diff --git a/jupyter_nbconvert/preprocessors/coalescestreams.py b/jupyter_nbconvert/preprocessors/coalescestreams.py deleted file mode 100644 index f7d4aba..0000000 --- a/jupyter_nbconvert/preprocessors/coalescestreams.py +++ /dev/null @@ -1,75 +0,0 @@ -"""Preprocessor for merging consecutive stream outputs for easier handling.""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import re -from IPython.utils.log import get_logger - -def cell_preprocessor(function): - """ - Wrap a function to be executed on all cells of a notebook - - The wrapped function should have these parameters: - - cell : NotebookNode cell - Notebook cell being processed - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - index : int - Index of the cell being processed - """ - - def wrappedfunc(nb, resources): - get_logger().debug( - "Applying preprocessor: %s", function.__name__ - ) - for index, cell in enumerate(nb.cells): - nb.cells[index], resources = function(cell, resources, index) - return nb, resources - return wrappedfunc - -cr_pat = re.compile(r'.*\r(?=[^\n])') - -@cell_preprocessor -def coalesce_streams(cell, resources, index): - """ - Merge consecutive sequences of stream output into single stream - to prevent extra newlines inserted at flush calls - - Parameters - ---------- - cell : NotebookNode cell - Notebook cell being processed - resources : dictionary - Additional resources used in the conversion process. Allows - transformers to pass variables into the Jinja engine. - index : int - Index of the cell being processed - """ - - outputs = cell.get('outputs', []) - if not outputs: - return cell, resources - - last = outputs[0] - new_outputs = [last] - for output in outputs[1:]: - if (output.output_type == 'stream' and - last.output_type == 'stream' and - last.name == output.name - ): - last.text += output.text - - else: - new_outputs.append(output) - last = output - - # process \r characters - for output in new_outputs: - if output.output_type == 'stream' and '\r' in output.text: - output.text = cr_pat.sub('', output.text) - - cell.outputs = new_outputs - return cell, resources diff --git a/jupyter_nbconvert/preprocessors/convertfigures.py b/jupyter_nbconvert/preprocessors/convertfigures.py deleted file mode 100644 index 3fafe73..0000000 --- a/jupyter_nbconvert/preprocessors/convertfigures.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Module containing a preprocessor that converts outputs in the notebook from -one format to another. -""" -#----------------------------------------------------------------------------- -# 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 .base import Preprocessor -from IPython.utils.traitlets import Unicode - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class ConvertFiguresPreprocessor(Preprocessor): - """ - Converts all of the outputs in a notebook from one format to another. - """ - - from_format = Unicode(config=True, help='Format the converter accepts') - to_format = Unicode(config=True, help='Format the converter writes') - - def __init__(self, **kw): - """ - Public constructor - """ - super(ConvertFiguresPreprocessor, self).__init__(**kw) - - - def convert_figure(self, data_format, data): - raise NotImplementedError() - - - def preprocess_cell(self, cell, resources, cell_index): - """ - Apply a transformation on each cell, - - See base.py - """ - - # Loop through all of the datatypes of the outputs in the cell. - for output in cell.get('outputs', []): - if output.output_type in {'execute_result', 'display_data'} \ - and self.from_format in output.data \ - and self.to_format not in output.data: - - output.data[self.to_format] = self.convert_figure( - self.from_format, output.data[self.from_format]) - - return cell, resources diff --git a/jupyter_nbconvert/preprocessors/csshtmlheader.py b/jupyter_nbconvert/preprocessors/csshtmlheader.py deleted file mode 100755 index a321ed9..0000000 --- a/jupyter_nbconvert/preprocessors/csshtmlheader.py +++ /dev/null @@ -1,85 +0,0 @@ -"""Module that pre-processes the notebook for export to HTML. -""" -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. -import os -import io -import hashlib - -from IPython.utils import path -from IPython.utils.traitlets import Unicode -from IPython.utils.py3compat import str_to_bytes -from .base import Preprocessor - -class CSSHTMLHeaderPreprocessor(Preprocessor): - """ - Preprocessor used to pre-process notebook for HTML output. Adds IPython notebook - front-end CSS and Pygments CSS to HTML output. - """ - highlight_class = Unicode('.highlight', config=True, - help="CSS highlight class identifier") - - def __init__(self, *pargs, **kwargs): - Preprocessor.__init__(self, *pargs, **kwargs) - self._default_css_hash = None - - def preprocess(self, nb, resources): - """Fetch and add CSS to the resource dictionary - - Fetch CSS from IPython and Pygments to add at the beginning - of the html files. Add this css in resources in the - "inlining.css" key - - Parameters - ---------- - nb : NotebookNode - Notebook being converted - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - """ - resources['inlining'] = {} - resources['inlining']['css'] = self._generate_header(resources) - return nb, resources - - def _generate_header(self, resources): - """ - Fills self.header with lines of CSS extracted from IPython - and Pygments. - """ - from pygments.formatters import HtmlFormatter - header = [] - - # Construct path to IPy CSS - from IPython.html import DEFAULT_STATIC_FILES_PATH - sheet_filename = os.path.join(DEFAULT_STATIC_FILES_PATH, - 'style', 'style.min.css') - - # Load style CSS file. - with io.open(sheet_filename, encoding='utf-8') as f: - header.append(f.read()) - - # Add pygments CSS - formatter = HtmlFormatter() - pygments_css = formatter.get_style_defs(self.highlight_class) - header.append(pygments_css) - - # Load the user's custom CSS and IPython's default custom CSS. If they - # differ, assume the user has made modifications to his/her custom CSS - # and that we should inline it in the nbconvert output. - profile_dir = resources['profile_dir'] - custom_css_filename = os.path.join(profile_dir, 'static', 'custom', 'custom.css') - if os.path.isfile(custom_css_filename): - if self._default_css_hash is None: - self._default_css_hash = self._hash(os.path.join(DEFAULT_STATIC_FILES_PATH, 'custom', 'custom.css')) - if self._hash(custom_css_filename) != self._default_css_hash: - with io.open(custom_css_filename, encoding='utf-8') as f: - header.append(f.read()) - return header - - def _hash(self, filename): - """Compute the hash of a file.""" - md5 = hashlib.md5() - with open(filename) as f: - md5.update(str_to_bytes(f.read())) - return md5.digest() diff --git a/jupyter_nbconvert/preprocessors/execute.py b/jupyter_nbconvert/preprocessors/execute.py deleted file mode 100644 index 46da10c..0000000 --- a/jupyter_nbconvert/preprocessors/execute.py +++ /dev/null @@ -1,143 +0,0 @@ -"""Module containing a preprocessor that removes the outputs from code cells""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import os -from textwrap import dedent - -try: - from queue import Empty # Py 3 -except ImportError: - from Queue import Empty # Py 2 - -from IPython.utils.traitlets import List, Unicode, Bool - -from IPython.nbformat.v4 import output_from_msg -from .base import Preprocessor -from IPython.utils.traitlets import Integer - - -class ExecutePreprocessor(Preprocessor): - """ - Executes all the cells in a notebook - """ - - timeout = Integer(30, config=True, - help="The time to wait (in seconds) for output from executions." - ) - - interrupt_on_timeout = Bool( - False, config=True, - help=dedent( - """ - If execution of a cell times out, interrupt the kernel and - continue executing other cells rather than throwing an error and - stopping. - """ - ) - ) - - extra_arguments = List(Unicode) - - def preprocess(self, nb, resources): - path = resources.get('metadata', {}).get('path', '') - if path == '': - path = None - - from IPython.kernel.manager import start_new_kernel - kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python') - self.log.info("Executing notebook with kernel: %s" % kernel_name) - self.km, self.kc = start_new_kernel( - kernel_name=kernel_name, - extra_arguments=self.extra_arguments, - stderr=open(os.devnull, 'w'), - cwd=path) - self.kc.allow_stdin = False - - try: - nb, resources = super(ExecutePreprocessor, self).preprocess(nb, resources) - finally: - self.kc.stop_channels() - self.km.shutdown_kernel(now=True) - - return nb, resources - - def preprocess_cell(self, cell, resources, cell_index): - """ - Apply a transformation on each code cell. See base.py for details. - """ - if cell.cell_type != 'code': - return cell, resources - try: - outputs = self.run_cell(cell) - except Exception as e: - self.log.error("failed to run cell: " + repr(e)) - self.log.error(str(cell.source)) - raise - cell.outputs = outputs - return cell, resources - - def run_cell(self, cell): - msg_id = self.kc.execute(cell.source) - self.log.debug("Executing cell:\n%s", cell.source) - # wait for finish, with timeout - while True: - try: - msg = self.kc.shell_channel.get_msg(timeout=self.timeout) - except Empty: - self.log.error("Timeout waiting for execute reply") - if self.interrupt_on_timeout: - self.log.error("Interrupting kernel") - self.km.interrupt_kernel() - break - else: - raise - - if msg['parent_header'].get('msg_id') == msg_id: - break - else: - # not our reply - continue - - outs = [] - - while True: - try: - msg = self.kc.iopub_channel.get_msg(timeout=self.timeout) - except Empty: - self.log.warn("Timeout waiting for IOPub output") - break - if msg['parent_header'].get('msg_id') != msg_id: - # not an output from our execution - continue - - msg_type = msg['msg_type'] - self.log.debug("output: %s", msg_type) - content = msg['content'] - - # set the prompt number for the input and the output - if 'execution_count' in content: - cell['execution_count'] = content['execution_count'] - - if msg_type == 'status': - if content['execution_state'] == 'idle': - break - else: - continue - elif msg_type == 'execute_input': - continue - elif msg_type == 'clear_output': - outs = [] - continue - elif msg_type.startswith('comm'): - continue - - try: - out = output_from_msg(msg) - except ValueError: - self.log.error("unhandled iopub msg: " + msg_type) - else: - outs.append(out) - - return outs diff --git a/jupyter_nbconvert/preprocessors/extractoutput.py b/jupyter_nbconvert/preprocessors/extractoutput.py deleted file mode 100755 index ee1e0af..0000000 --- a/jupyter_nbconvert/preprocessors/extractoutput.py +++ /dev/null @@ -1,98 +0,0 @@ -"""A preprocessor that extracts all of the outputs from the -notebook file. The extracted outputs are returned in the 'resources' dictionary. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import base64 -import sys -import os -from mimetypes import guess_extension - -from IPython.utils.traitlets import Unicode, Set -from .base import Preprocessor -from IPython.utils import py3compat - - -class ExtractOutputPreprocessor(Preprocessor): - """ - Extracts all of the outputs from the notebook file. The extracted - outputs are returned in the 'resources' dictionary. - """ - - output_filename_template = Unicode( - "{unique_key}_{cell_index}_{index}{extension}", config=True) - - extract_output_types = Set({'image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf'}, config=True) - - def preprocess_cell(self, cell, resources, cell_index): - """ - Apply a transformation on each cell, - - Parameters - ---------- - cell : NotebookNode cell - Notebook cell being processed - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - cell_index : int - Index of the cell being processed (see base.py) - """ - - #Get the unique key from the resource dict if it exists. If it does not - #exist, use 'output' as the default. Also, get files directory if it - #has been specified - unique_key = resources.get('unique_key', 'output') - output_files_dir = resources.get('output_files_dir', None) - - #Make sure outputs key exists - if not isinstance(resources['outputs'], dict): - resources['outputs'] = {} - - #Loop through all of the outputs in the cell - for index, out in enumerate(cell.get('outputs', [])): - if out.output_type not in {'display_data', 'execute_result'}: - continue - #Get the output in data formats that the template needs extracted - for mime_type in self.extract_output_types: - if mime_type in out.data: - data = out.data[mime_type] - - #Binary files are base64-encoded, SVG is already XML - if mime_type in {'image/png', 'image/jpeg', 'application/pdf'}: - - # data is b64-encoded as text (str, unicode) - # decodestring only accepts bytes - data = py3compat.cast_bytes(data) - data = base64.decodestring(data) - elif sys.platform == 'win32': - data = data.replace('\n', '\r\n').encode("UTF-8") - else: - data = data.encode("UTF-8") - - ext = guess_extension(mime_type) - if ext is None: - ext = '.' + mime_type.rsplit('/')[-1] - - filename = self.output_filename_template.format( - unique_key=unique_key, - cell_index=cell_index, - index=index, - extension=ext) - - # On the cell, make the figure available via - # cell.outputs[i].metadata.filenames['mime/type'] - # where - # cell.outputs[i].data['mime/type'] contains the data - if output_files_dir is not None: - filename = os.path.join(output_files_dir, filename) - out.metadata.setdefault('filenames', {}) - out.metadata['filenames'][mime_type] = filename - - #In the resources, make the figure available via - # resources['outputs']['filename'] = data - resources['outputs'][filename] = data - - return cell, resources diff --git a/jupyter_nbconvert/preprocessors/highlightmagics.py b/jupyter_nbconvert/preprocessors/highlightmagics.py deleted file mode 100644 index 83356d6..0000000 --- a/jupyter_nbconvert/preprocessors/highlightmagics.py +++ /dev/null @@ -1,100 +0,0 @@ -"""This preprocessor detect cells using a different language through -magic extensions such as `%%R` or `%%octave`. Cell's metadata is marked -so that the appropriate highlighter can be used in the `highlight` -filter. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from __future__ import print_function, absolute_import - -import re - -# Our own imports -from .base import Preprocessor -from IPython.utils.traitlets import Dict - - -class HighlightMagicsPreprocessor(Preprocessor): - """ - Detects and tags code cells that use a different languages than Python. - """ - - # list of magic language extensions and their associated pygment lexers - default_languages = Dict( - default_value={ - '%%R': 'r', - '%%bash': 'bash', - '%%cython': 'cython', - '%%javascript': 'javascript', - '%%julia': 'julia', - '%%latex': 'latex', - '%%octave': 'octave', - '%%perl': 'perl', - '%%ruby': 'ruby', - '%%sh': 'sh'}) - - # user defined language extensions - languages = Dict( - config=True, - help=("Syntax highlighting for magic's extension languages. " - "Each item associates a language magic extension such as %%R, " - "with a pygments lexer such as r.")) - - def __init__(self, config=None, **kw): - """Public constructor""" - - super(HighlightMagicsPreprocessor, self).__init__(config=config, **kw) - - # Update the default languages dict with the user configured ones - self.default_languages.update(self.languages) - - # build a regular expression to catch language extensions and choose - # an adequate pygments lexer - any_language = "|".join(self.default_languages.keys()) - self.re_magic_language = re.compile( - r'^\s*({0})\s+'.format(any_language)) - - def which_magic_language(self, source): - """ - When a cell uses another language through a magic extension, - the other language is returned. - If no language magic is detected, this function returns None. - - Parameters - ---------- - source: str - Source code of the cell to highlight - """ - - m = self.re_magic_language.match(source) - - if m: - # By construction of the re, the matched language must be in the - # languages dictionary - return self.default_languages[m.group(1)] - else: - return None - - def preprocess_cell(self, cell, resources, cell_index): - """ - Tags cells using a magic extension language - - Parameters - ---------- - cell : NotebookNode cell - Notebook cell being processed - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - cell_index : int - Index of the cell being processed (see base.py) - """ - - # Only tag code cells - if cell.cell_type == "code": - magic_language = self.which_magic_language(cell.source) - if magic_language: - cell['metadata']['magics_language'] = magic_language - return cell, resources diff --git a/jupyter_nbconvert/preprocessors/latex.py b/jupyter_nbconvert/preprocessors/latex.py deleted file mode 100755 index 4834831..0000000 --- a/jupyter_nbconvert/preprocessors/latex.py +++ /dev/null @@ -1,47 +0,0 @@ -"""Module that allows latex output notebooks to be conditioned before -they are converted. -""" -#----------------------------------------------------------------------------- -# 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 - -from .base import Preprocessor - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class LatexPreprocessor(Preprocessor): - """Preprocessor for latex destined documents. - - Mainly populates the `latex` key in the resources dict, - adding definitions for pygments highlight styles. - """ - - def preprocess(self, nb, resources): - """Preprocessing to apply on each notebook. - - Parameters - ---------- - nb : NotebookNode - Notebook being converted - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - """ - # Generate Pygments definitions for Latex - from pygments.formatters import LatexFormatter - - resources.setdefault("latex", {}) - resources["latex"].setdefault("pygments_definitions", LatexFormatter().get_style_defs()) - return nb, resources diff --git a/jupyter_nbconvert/preprocessors/revealhelp.py b/jupyter_nbconvert/preprocessors/revealhelp.py deleted file mode 100755 index 7b09c7f..0000000 --- a/jupyter_nbconvert/preprocessors/revealhelp.py +++ /dev/null @@ -1,62 +0,0 @@ -"""Module that pre-processes the notebook for export via Reveal.""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .base import Preprocessor -from IPython.utils.traitlets import Unicode - - -class RevealHelpPreprocessor(Preprocessor): - - url_prefix = Unicode('reveal.js', config=True, - help="""The URL prefix for reveal.js. - This can be a a relative URL for a local copy of reveal.js, - or point to a CDN. - - For speaker notes to work, a local reveal.js prefix must be used. - """ - ) - - def preprocess(self, nb, resources): - """ - Called once to 'preprocess' contents of the notebook. - - Parameters - ---------- - nb : NotebookNode - Notebook being converted - resources : dictionary - Additional resources used in the conversion process. Allows - preprocessors to pass variables into the Jinja engine. - """ - - for index, cell in enumerate(nb.cells): - - #Make sure the cell has slideshow metadata. - cell.metadata.slide_type = cell.get('metadata', {}).get('slideshow', {}).get('slide_type', '-') - - # Get the slide type. If type is start, subslide, or slide, - # end the last subslide/slide. - if cell.metadata.slide_type in ['slide']: - nb.cells[index - 1].metadata.slide_helper = 'slide_end' - if cell.metadata.slide_type in ['subslide']: - nb.cells[index - 1].metadata.slide_helper = 'subslide_end' - # Prevent the rendering of "do nothing" cells before fragments - # Group fragments passing frag_number to the data-fragment-index - if cell.metadata.slide_type in ['fragment']: - nb.cells[index].metadata.frag_number = index - i = 1 - while i < len(nb.cells) - index: - nb.cells[index + i].metadata.frag_helper = 'fragment_end' - nb.cells[index + i].metadata.frag_number = index - i += 1 - # Restart the slide_helper when the cell status is changed - # to other types. - if cell.metadata.slide_type in ['-', 'skip', 'notes', 'fragment']: - nb.cells[index - 1].metadata.slide_helper = '-' - - if not isinstance(resources['reveal'], dict): - resources['reveal'] = {} - resources['reveal']['url_prefix'] = self.url_prefix - return nb, resources diff --git a/jupyter_nbconvert/preprocessors/svg2pdf.py b/jupyter_nbconvert/preprocessors/svg2pdf.py deleted file mode 100644 index 02aee30..0000000 --- a/jupyter_nbconvert/preprocessors/svg2pdf.py +++ /dev/null @@ -1,83 +0,0 @@ -"""Module containing a preprocessor that converts outputs in the notebook from -one format to another. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import base64 -import io -import os -import sys -import subprocess - -from IPython.utils.py3compat import cast_unicode_py2 -from IPython.utils.tempdir import TemporaryDirectory -from IPython.utils.traitlets import Unicode - -from .convertfigures import ConvertFiguresPreprocessor - - -INKSCAPE_APP = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape' - - -class SVG2PDFPreprocessor(ConvertFiguresPreprocessor): - """ - Converts all of the outputs in a notebook from SVG to PDF. - """ - - def _from_format_default(self): - return 'image/svg+xml' - def _to_format_default(self): - return 'application/pdf' - - command = Unicode(config=True, - help="""The command to use for converting SVG to PDF - - This string is a template, which will be formatted with the keys - to_filename and from_filename. - - The conversion call must read the SVG from {from_flename}, - and write a PDF to {to_filename}. - """) - - def _command_default(self): - return self.inkscape + \ - ' --without-gui --export-pdf="{to_filename}" "{from_filename}"' - - inkscape = Unicode(config=True, help="The path to Inkscape, if necessary") - def _inkscape_default(self): - if sys.platform == "darwin": - if os.path.isfile(INKSCAPE_APP): - return INKSCAPE_APP - return "inkscape" - - - def convert_figure(self, data_format, data): - """ - Convert a single SVG figure to PDF. Returns converted data. - """ - - #Work in a temporary directory - with TemporaryDirectory() as tmpdir: - - #Write fig to temp file - input_filename = os.path.join(tmpdir, 'figure.svg') - # SVG data is unicode text - with io.open(input_filename, 'w', encoding='utf8') as f: - f.write(cast_unicode_py2(data)) - - #Call conversion application - output_filename = os.path.join(tmpdir, 'figure.pdf') - shell = self.command.format(from_filename=input_filename, - to_filename=output_filename) - subprocess.call(shell, shell=True) #Shell=True okay since input is trusted. - - #Read output from drive - # return value expects a filename - if os.path.isfile(output_filename): - with open(output_filename, 'rb') as f: - # PDF is a nb supported binary, data type, so base64 encode. - return base64.encodestring(f.read()) - else: - raise TypeError("Inkscape svg to pdf conversion failed") diff --git a/jupyter_nbconvert/preprocessors/tests/__init__.py b/jupyter_nbconvert/preprocessors/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_nbconvert/preprocessors/tests/__init__.py +++ /dev/null diff --git a/jupyter_nbconvert/preprocessors/tests/base.py b/jupyter_nbconvert/preprocessors/tests/base.py deleted file mode 100644 index e27cd57..0000000 --- a/jupyter_nbconvert/preprocessors/tests/base.py +++ /dev/null @@ -1,41 +0,0 @@ -"""utility functions for preprocessor tests""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from IPython.nbformat import v4 as nbformat - -from ...tests.base import TestsBase -from ...exporters.exporter import ResourcesDict - - -class PreprocessorTestsBase(TestsBase): - """Contains test functions preprocessor tests""" - - - def build_notebook(self): - """Build a notebook in memory for use with preprocessor tests""" - - outputs = [ - nbformat.new_output("stream", name="stdout", text="a"), - nbformat.new_output("display_data", data={'text/plain': 'b'}), - nbformat.new_output("stream", name="stdout", text="c"), - nbformat.new_output("stream", name="stdout", text="d"), - nbformat.new_output("stream", name="stderr", text="e"), - nbformat.new_output("stream", name="stderr", text="f"), - nbformat.new_output("display_data", data={'image/png': 'Zw=='}), # g - nbformat.new_output("display_data", data={'application/pdf': 'aA=='}), # h - ] - - cells=[nbformat.new_code_cell(source="$ e $", execution_count=1, outputs=outputs), - nbformat.new_markdown_cell(source="$ e $")] - - return nbformat.new_notebook(cells=cells) - - - def build_resources(self): - """Build an empty resources dictionary.""" - - res = ResourcesDict() - res['metadata'] = ResourcesDict() - return res diff --git a/jupyter_nbconvert/preprocessors/tests/files/Clear Output.ipynb b/jupyter_nbconvert/preprocessors/tests/files/Clear Output.ipynb deleted file mode 100644 index dfada39..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/Clear Output.ipynb +++ /dev/null @@ -1,39 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from IPython.display import clear_output" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9\n" - ] - } - ], - "source": [ - "for i in range(10):\n", - " clear_output()\n", - " print(i)" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/preprocessors/tests/files/Disable Stdin.ipynb b/jupyter_nbconvert/preprocessors/tests/files/Disable Stdin.ipynb deleted file mode 100644 index 6e5d786..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/Disable Stdin.ipynb +++ /dev/null @@ -1,23 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "try:\n", - " input = raw_input\n", - "except:\n", - " pass\n", - "\n", - "name = input(\"name: \")" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/jupyter_nbconvert/preprocessors/tests/files/Factorials.ipynb b/jupyter_nbconvert/preprocessors/tests/files/Factorials.ipynb deleted file mode 100644 index 939c49f..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/Factorials.ipynb +++ /dev/null @@ -1,48 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "i, j = 1, 1" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n", - "3\n", - "5\n", - "8\n", - "13\n", - "21\n", - "34\n", - "55\n", - "89\n", - "144\n" - ] - } - ], - "source": [ - "for m in range(10):\n", - " i, j = j, i + j\n", - " print(j)" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/preprocessors/tests/files/HelloWorld.ipynb b/jupyter_nbconvert/preprocessors/tests/files/HelloWorld.ipynb deleted file mode 100644 index 9b8f550..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/HelloWorld.ipynb +++ /dev/null @@ -1,26 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello World\n" - ] - } - ], - "source": [ - "print(\"Hello World\")" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/preprocessors/tests/files/Inline Image.ipynb b/jupyter_nbconvert/preprocessors/tests/files/Inline Image.ipynb deleted file mode 100644 index 18ab6ce..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/Inline Image.ipynb +++ /dev/null @@ -1,196 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from IPython.display import Image" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": [ - "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\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Image('python.png')" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/jupyter_nbconvert/preprocessors/tests/files/Interrupt.ipynb b/jupyter_nbconvert/preprocessors/tests/files/Interrupt.ipynb deleted file mode 100644 index ffcde4a..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/Interrupt.ipynb +++ /dev/null @@ -1,49 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mcontinue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "while True: continue" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "done\n" - ] - } - ], - "source": [ - "print(\"done\")" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/jupyter_nbconvert/preprocessors/tests/files/SVG.ipynb b/jupyter_nbconvert/preprocessors/tests/files/SVG.ipynb deleted file mode 100644 index 2769ab2..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/SVG.ipynb +++ /dev/null @@ -1,48 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from IPython.display import SVG" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - " \n", - "" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "SVG(data='''\n", - "\n", - " \n", - "''')" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/preprocessors/tests/files/Skip Exceptions.ipynb b/jupyter_nbconvert/preprocessors/tests/files/Skip Exceptions.ipynb deleted file mode 100644 index 452a454..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/Skip Exceptions.ipynb +++ /dev/null @@ -1,51 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "ename": "Exception", - "evalue": "message", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mException\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"message\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;31mException\u001b[0m: message" - ] - } - ], - "source": [ - "raise Exception(\"message\")" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ok\n" - ] - } - ], - "source": [ - "print('ok')" - ] - } - ], - "metadata": { - "signature": "sha256:9d47889f0678e9685429071216d0f3354db59bb66489f3225bcadfb6a1a9bbba" - }, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/preprocessors/tests/files/Unicode.ipynb b/jupyter_nbconvert/preprocessors/tests/files/Unicode.ipynb deleted file mode 100644 index cdbcb10..0000000 --- a/jupyter_nbconvert/preprocessors/tests/files/Unicode.ipynb +++ /dev/null @@ -1,26 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u2603\n" - ] - } - ], - "source": [ - "print('\u2603')" - ] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/preprocessors/tests/files/python.png b/jupyter_nbconvert/preprocessors/tests/files/python.png deleted file mode 100644 index c56d4c022a7130beed2ee67d7fff7274aff5de1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 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 diff --git a/jupyter_nbconvert/preprocessors/tests/test_clearoutput.py b/jupyter_nbconvert/preprocessors/tests/test_clearoutput.py deleted file mode 100644 index 78db651..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_clearoutput.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -Module with tests for the clearoutput preprocessor. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .base import PreprocessorTestsBase -from ..clearoutput import ClearOutputPreprocessor - - -class TestClearOutput(PreprocessorTestsBase): - """Contains test functions for clearoutput.py""" - - - def build_preprocessor(self): - """Make an instance of a preprocessor""" - preprocessor = ClearOutputPreprocessor() - preprocessor.enabled = True - return preprocessor - - def test_constructor(self): - """Can a ClearOutputPreprocessor be constructed?""" - self.build_preprocessor() - - def test_output(self): - """Test the output of the ClearOutputPreprocessor""" - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb, res = preprocessor(nb, res) - assert nb.cells[0].outputs == [] - assert nb.cells[0].execution_count is None diff --git a/jupyter_nbconvert/preprocessors/tests/test_coalescestreams.py b/jupyter_nbconvert/preprocessors/tests/test_coalescestreams.py deleted file mode 100644 index bded340..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_coalescestreams.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Tests for the coalescestreams preprocessor""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from IPython.nbformat import v4 as nbformat - -from .base import PreprocessorTestsBase -from ..coalescestreams import coalesce_streams - - -class TestCoalesceStreams(PreprocessorTestsBase): - """Contains test functions for coalescestreams.py""" - - def test_coalesce_streams(self): - """coalesce_streams preprocessor output test""" - nb = self.build_notebook() - res = self.build_resources() - nb, res = coalesce_streams(nb, res) - outputs = nb.cells[0].outputs - self.assertEqual(outputs[0].text, "a") - self.assertEqual(outputs[1].output_type, "display_data") - self.assertEqual(outputs[2].text, "cd") - self.assertEqual(outputs[3].text, "ef") - - def test_coalesce_sequenced_streams(self): - """Can the coalesce streams preprocessor merge a sequence of streams?""" - outputs = [nbformat.new_output(output_type="stream", name="stdout", text="0"), - nbformat.new_output(output_type="stream", name="stdout", text="1"), - nbformat.new_output(output_type="stream", name="stdout", text="2"), - nbformat.new_output(output_type="stream", name="stdout", text="3"), - nbformat.new_output(output_type="stream", name="stdout", text="4"), - nbformat.new_output(output_type="stream", name="stdout", text="5"), - nbformat.new_output(output_type="stream", name="stdout", text="6"), - nbformat.new_output(output_type="stream", name="stdout", text="7")] - cells=[nbformat.new_code_cell(source="# None", execution_count=1,outputs=outputs)] - - nb = nbformat.new_notebook(cells=cells) - res = self.build_resources() - nb, res = coalesce_streams(nb, res) - outputs = nb.cells[0].outputs - self.assertEqual(outputs[0].text, u'01234567') - - def test_coalesce_replace_streams(self): - """Are \\r characters handled?""" - outputs = [nbformat.new_output(output_type="stream", name="stdout", text="z"), - nbformat.new_output(output_type="stream", name="stdout", text="\ra"), - nbformat.new_output(output_type="stream", name="stdout", text="\nz\rb"), - nbformat.new_output(output_type="stream", name="stdout", text="\nz"), - nbformat.new_output(output_type="stream", name="stdout", text="\rc\n"), - nbformat.new_output(output_type="stream", name="stdout", text="z\rz\rd")] - cells=[nbformat.new_code_cell(source="# None", execution_count=1,outputs=outputs)] - - nb = nbformat.new_notebook(cells=cells) - res = self.build_resources() - nb, res = coalesce_streams(nb, res) - outputs = nb.cells[0].outputs - self.assertEqual(outputs[0].text, u'a\nb\nc\nd') diff --git a/jupyter_nbconvert/preprocessors/tests/test_csshtmlheader.py b/jupyter_nbconvert/preprocessors/tests/test_csshtmlheader.py deleted file mode 100644 index c259bad..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_csshtmlheader.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -Module with tests for the csshtmlheader preprocessor -""" - -#----------------------------------------------------------------------------- -# 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 .base import PreprocessorTestsBase -from ..csshtmlheader import CSSHTMLHeaderPreprocessor - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestCSSHTMLHeader(PreprocessorTestsBase): - """Contains test functions for csshtmlheader.py""" - - - def build_preprocessor(self): - """Make an instance of a preprocessor""" - preprocessor = CSSHTMLHeaderPreprocessor() - preprocessor.enabled = True - return preprocessor - - - def test_constructor(self): - """Can a CSSHTMLHeaderPreprocessor be constructed?""" - self.build_preprocessor() - - - def test_output(self): - """Test the output of the CSSHTMLHeaderPreprocessor""" - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb, res = preprocessor(nb, res) - assert 'css' in res['inlining'] diff --git a/jupyter_nbconvert/preprocessors/tests/test_execute.py b/jupyter_nbconvert/preprocessors/tests/test_execute.py deleted file mode 100644 index 2464650..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_execute.py +++ /dev/null @@ -1,151 +0,0 @@ -""" -Module with tests for the execute preprocessor. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import copy -import glob -import io -import os -import re - -try: - from queue import Empty # Py 3 -except ImportError: - from Queue import Empty # Py 2 - -from IPython import nbformat - -from .base import PreprocessorTestsBase -from ..execute import ExecutePreprocessor - -from jupyter_nbconvert.filters import strip_ansi -from nose.tools import assert_raises - -addr_pat = re.compile(r'0x[0-9a-f]{7,9}') - -class TestExecute(PreprocessorTestsBase): - """Contains test functions for execute.py""" - - @staticmethod - def normalize_output(output): - """ - Normalizes outputs for comparison. - """ - output = dict(output) - if 'metadata' in output: - del output['metadata'] - if 'text' in output: - output['text'] = re.sub(addr_pat, '', output['text']) - if 'text/plain' in output.get('data', {}): - output['data']['text/plain'] = \ - re.sub(addr_pat, '', output['data']['text/plain']) - if 'traceback' in output: - tb = [] - for line in output['traceback']: - tb.append(strip_ansi(line)) - output['traceback'] = tb - - return output - - - def assert_notebooks_equal(self, expected, actual): - expected_cells = expected['cells'] - actual_cells = actual['cells'] - self.assertEqual(len(expected_cells), len(actual_cells)) - - for expected_cell, actual_cell in zip(expected_cells, actual_cells): - expected_outputs = expected_cell.get('outputs', []) - actual_outputs = actual_cell.get('outputs', []) - normalized_expected_outputs = list(map(self.normalize_output, expected_outputs)) - normalized_actual_outputs = list(map(self.normalize_output, actual_outputs)) - self.assertEqual(normalized_expected_outputs, normalized_actual_outputs) - - expected_execution_count = expected_cell.get('execution_count', None) - actual_execution_count = actual_cell.get('execution_count', None) - self.assertEqual(expected_execution_count, actual_execution_count) - - - def build_preprocessor(self, opts): - """Make an instance of a preprocessor""" - preprocessor = ExecutePreprocessor() - preprocessor.enabled = True - for opt in opts: - setattr(preprocessor, opt, opts[opt]) - return preprocessor - - - def test_constructor(self): - """Can a ExecutePreprocessor be constructed?""" - self.build_preprocessor({}) - - - def run_notebook(self, filename, opts, resources): - """Loads and runs a notebook, returning both the version prior to - running it and the version after running it. - - """ - with io.open(filename) as f: - input_nb = nbformat.read(f, 4) - preprocessor = self.build_preprocessor(opts) - cleaned_input_nb = copy.deepcopy(input_nb) - for cell in cleaned_input_nb.cells: - if 'execution_count' in cell: - del cell['execution_count'] - cell['outputs'] = [] - output_nb, _ = preprocessor(cleaned_input_nb, resources) - return input_nb, output_nb - - def test_run_notebooks(self): - """Runs a series of test notebooks and compares them to their actual output""" - current_dir = os.path.dirname(__file__) - input_files = glob.glob(os.path.join(current_dir, 'files', '*.ipynb')) - for filename in input_files: - if os.path.basename(filename) == "Disable Stdin.ipynb": - continue - elif os.path.basename(filename) == "Interrupt.ipynb": - opts = dict(timeout=1, interrupt_on_timeout=True) - else: - opts = {} - res = self.build_resources() - res['metadata']['path'] = os.path.dirname(filename) - input_nb, output_nb = self.run_notebook(filename, opts, res) - self.assert_notebooks_equal(input_nb, output_nb) - - def test_empty_path(self): - """Can the kernel be started when the path is empty?""" - current_dir = os.path.dirname(__file__) - filename = os.path.join(current_dir, 'files', 'HelloWorld.ipynb') - res = self.build_resources() - res['metadata']['path'] = '' - input_nb, output_nb = self.run_notebook(filename, {}, res) - self.assert_notebooks_equal(input_nb, output_nb) - - def test_disable_stdin(self): - """Test disabling standard input""" - current_dir = os.path.dirname(__file__) - filename = os.path.join(current_dir, 'files', 'Disable Stdin.ipynb') - res = self.build_resources() - res['metadata']['path'] = os.path.dirname(filename) - input_nb, output_nb = self.run_notebook(filename, {}, res) - - # We need to special-case this particular notebook, because the - # traceback contains machine-specific stuff like where IPython - # is installed. It is sufficient here to just check that an error - # was thrown, and that it was a StdinNotImplementedError - self.assertEqual(len(output_nb['cells']), 1) - self.assertEqual(len(output_nb['cells'][0]['outputs']), 1) - output = output_nb['cells'][0]['outputs'][0] - self.assertEqual(output['output_type'], 'error') - self.assertEqual(output['ename'], 'StdinNotImplementedError') - self.assertEqual(output['evalue'], 'raw_input was called, but this frontend does not support input requests.') - - def test_timeout(self): - """Check that an error is raised when a computation times out""" - current_dir = os.path.dirname(__file__) - filename = os.path.join(current_dir, 'files', 'Interrupt.ipynb') - res = self.build_resources() - res['metadata']['path'] = os.path.dirname(filename) - assert_raises(Empty, self.run_notebook, filename, dict(timeout=1), res) diff --git a/jupyter_nbconvert/preprocessors/tests/test_extractoutput.py b/jupyter_nbconvert/preprocessors/tests/test_extractoutput.py deleted file mode 100644 index e7c19ea..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_extractoutput.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Tests for the extractoutput preprocessor""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .base import PreprocessorTestsBase -from ..extractoutput import ExtractOutputPreprocessor - - -class TestExtractOutput(PreprocessorTestsBase): - """Contains test functions for extractoutput.py""" - - def build_preprocessor(self): - """Make an instance of a preprocessor""" - preprocessor = ExtractOutputPreprocessor() - preprocessor.extract_output_types = {'text/plain', 'image/png', 'application/pdf'} - preprocessor.enabled = True - return preprocessor - - def test_constructor(self): - """Can a ExtractOutputPreprocessor be constructed?""" - self.build_preprocessor() - - def test_output(self): - """Test the output of the ExtractOutputPreprocessor""" - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb, res = preprocessor(nb, res) - # Check if text was extracted. - output = nb.cells[0].outputs[1] - self.assertIn('filenames', output.metadata) - self.assertIn('text/plain', output.metadata.filenames) - text_filename = output.metadata.filenames['text/plain'] - - # Check if png was extracted. - output = nb.cells[0].outputs[6] - self.assertIn('filenames', output.metadata) - self.assertIn('image/png', output.metadata.filenames) - png_filename = output.metadata.filenames['image/png'] - - # Check that pdf was extracted - output = nb.cells[0].outputs[7] - self.assertIn('filenames', output.metadata) - self.assertIn('application/pdf', output.metadata.filenames) - pdf_filename = output.metadata.filenames['application/pdf'] - - # Verify text output - self.assertIn(text_filename, res['outputs']) - self.assertEqual(res['outputs'][text_filename], b'b') - - # Verify png output - self.assertIn(png_filename, res['outputs']) - self.assertEqual(res['outputs'][png_filename], b'g') - - # Verify pdf output - self.assertIn(pdf_filename, res['outputs']) - self.assertEqual(res['outputs'][pdf_filename], b'h') diff --git a/jupyter_nbconvert/preprocessors/tests/test_highlightmagics.py b/jupyter_nbconvert/preprocessors/tests/test_highlightmagics.py deleted file mode 100644 index 81364f2..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_highlightmagics.py +++ /dev/null @@ -1,50 +0,0 @@ -"""Tests for the HighlightMagics preprocessor""" - -from .base import PreprocessorTestsBase -from ..highlightmagics import HighlightMagicsPreprocessor - - -class TestHighlightMagics(PreprocessorTestsBase): - """Contains test functions for highlightmagics.py""" - - - def build_preprocessor(self): - """Make an instance of a preprocessor""" - preprocessor = HighlightMagicsPreprocessor() - preprocessor.enabled = True - return preprocessor - - def test_constructor(self): - """Can a HighlightMagicsPreprocessor be constructed?""" - self.build_preprocessor() - - def test_tagging(self): - """Test the HighlightMagicsPreprocessor tagging""" - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb.cells[0].source = """%%R -i x,y -o XYcoef - lm.fit <- lm(y~x) - par(mfrow=c(2,2)) - print(summary(lm.fit)) - plot(lm.fit) - XYcoef <- coef(lm.fit)""" - - nb, res = preprocessor(nb, res) - - assert('magics_language' in nb.cells[0]['metadata']) - - self.assertEqual(nb.cells[0]['metadata']['magics_language'], 'r') - - def test_no_false_positive(self): - """Test that HighlightMagicsPreprocessor does not tag false positives""" - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb.cells[0].source = """# this should not be detected - print(\""" - %%R -i x, y - \""")""" - nb, res = preprocessor(nb, res) - - assert('magics_language' not in nb.cells[0]['metadata']) \ No newline at end of file diff --git a/jupyter_nbconvert/preprocessors/tests/test_latex.py b/jupyter_nbconvert/preprocessors/tests/test_latex.py deleted file mode 100644 index b9a76e7..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_latex.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Tests for the latex preprocessor""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from .base import PreprocessorTestsBase -from ..latex import LatexPreprocessor - - -class TestLatex(PreprocessorTestsBase): - """Contains test functions for latex.py""" - - - def build_preprocessor(self): - """Make an instance of a preprocessor""" - preprocessor = LatexPreprocessor() - preprocessor.enabled = True - return preprocessor - - def test_constructor(self): - """Can a LatexPreprocessor be constructed?""" - self.build_preprocessor() - - - def test_output(self): - """Test the output of the LatexPreprocessor""" - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb, res = preprocessor(nb, res) - - # Make sure the code cell wasn't modified. - self.assertEqual(nb.cells[0].source, '$ e $') - - # Verify that the markdown cell wasn't processed. - self.assertEqual(nb.cells[1].source, '$ e $') diff --git a/jupyter_nbconvert/preprocessors/tests/test_revealhelp.py b/jupyter_nbconvert/preprocessors/tests/test_revealhelp.py deleted file mode 100644 index 07fb23a..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_revealhelp.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Tests for the revealhelp preprocessor""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from IPython.nbformat import v4 as nbformat - -from .base import PreprocessorTestsBase -from ..revealhelp import RevealHelpPreprocessor - - -class Testrevealhelp(PreprocessorTestsBase): - """Contains test functions for revealhelp.py""" - - def build_notebook(self): - """Build a reveal slides notebook in memory for use with tests. - Overrides base in PreprocessorTestsBase""" - - outputs = [nbformat.new_output(output_type="stream", name="stdout", text="a")] - - slide_metadata = {'slideshow' : {'slide_type': 'slide'}} - subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}} - - cells=[nbformat.new_code_cell(source="", execution_count=1, outputs=outputs), - nbformat.new_markdown_cell(source="", metadata=slide_metadata), - nbformat.new_code_cell(source="", execution_count=2, outputs=outputs), - nbformat.new_markdown_cell(source="", metadata=slide_metadata), - nbformat.new_markdown_cell(source="", metadata=subslide_metadata)] - - return nbformat.new_notebook(cells=cells) - - - def build_preprocessor(self): - """Make an instance of a preprocessor""" - preprocessor = RevealHelpPreprocessor() - preprocessor.enabled = True - return preprocessor - - - def test_constructor(self): - """Can a RevealHelpPreprocessor be constructed?""" - self.build_preprocessor() - - - def test_reveal_attribute(self): - """Make sure the reveal url_prefix resources is set""" - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb, res = preprocessor(nb, res) - assert 'reveal' in res - assert 'url_prefix' in res['reveal'] - - - def test_reveal_output(self): - """Make sure that the reveal preprocessor """ - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb, res = preprocessor(nb, res) - cells = nb.cells - - # Make sure correct metadata tags are available on every cell. - for cell in cells: - assert 'slide_type' in cell.metadata - - # Make sure slide end is only applied to the cells preceeding slide - # cells. - assert 'slide_helper' in cells[1].metadata - self.assertEqual(cells[1].metadata['slide_helper'], '-') - - # Verify 'slide-end' - assert 'slide_helper' in cells[0].metadata - self.assertEqual(cells[0].metadata['slide_helper'], 'slide_end') - assert 'slide_helper' in cells[2].metadata - self.assertEqual(cells[2].metadata['slide_helper'], 'slide_end') - assert 'slide_helper' in cells[3].metadata - self.assertEqual(cells[3].metadata['slide_helper'], 'subslide_end') diff --git a/jupyter_nbconvert/preprocessors/tests/test_svg2pdf.py b/jupyter_nbconvert/preprocessors/tests/test_svg2pdf.py deleted file mode 100644 index 6b672f6..0000000 --- a/jupyter_nbconvert/preprocessors/tests/test_svg2pdf.py +++ /dev/null @@ -1,73 +0,0 @@ -"""Tests for the svg2pdf preprocessor""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from IPython.testing import decorators as dec -from IPython.nbformat import v4 as nbformat - -from .base import PreprocessorTestsBase -from ..svg2pdf import SVG2PDFPreprocessor - - -class Testsvg2pdf(PreprocessorTestsBase): - """Contains test functions for svg2pdf.py""" - - simple_svg = """ - - - - - - -""" - - def build_notebook(self): - """Build a reveal slides notebook in memory for use with tests. - Overrides base in PreprocessorTestsBase""" - - outputs = [nbformat.new_output(output_type='display_data', - data={'image/svg+xml':self.simple_svg}) - ] - - cells=[nbformat.new_code_cell(source="", execution_count=1, outputs=outputs)] - - return nbformat.new_notebook(cells=cells) - - - def build_preprocessor(self): - """Make an instance of a preprocessor""" - preprocessor = SVG2PDFPreprocessor() - preprocessor.enabled = True - return preprocessor - - - def test_constructor(self): - """Can a SVG2PDFPreprocessor be constructed?""" - self.build_preprocessor() - - - @dec.onlyif_cmds_exist('inkscape') - def test_output(self): - """Test the output of the SVG2PDFPreprocessor""" - nb = self.build_notebook() - res = self.build_resources() - preprocessor = self.build_preprocessor() - nb, res = preprocessor(nb, res) - self.assertIn('application/pdf', nb.cells[0].outputs[0].data) diff --git a/jupyter_nbconvert/templates/README.md b/jupyter_nbconvert/templates/README.md deleted file mode 100644 index 3b3ecb8..0000000 --- a/jupyter_nbconvert/templates/README.md +++ /dev/null @@ -1,9 +0,0 @@ -README FIRST -============ - -Please do not add new templates for nbconvert here. - -In order to speed up the distribution of nbconvert templates and make it -simpler to share such contributions, we encourage [sharing those links on our -wiki -page](https://github.com/ipython/ipython/wiki/Cookbook:%20nbconvert%20templates). diff --git a/jupyter_nbconvert/templates/html/basic.tpl b/jupyter_nbconvert/templates/html/basic.tpl deleted file mode 100644 index edafdca..0000000 --- a/jupyter_nbconvert/templates/html/basic.tpl +++ /dev/null @@ -1,201 +0,0 @@ -{%- extends 'display_priority.tpl' -%} - - -{% block codecell %} -
-{{ super() }} -
-{%- endblock codecell %} - -{% block input_group -%} -
-{{ super() }} -
-{% endblock input_group %} - -{% block output_group %} -
-
-{{ super() }} -
-
-{% endblock output_group %} - -{% block in_prompt -%} -
-{%- if cell.execution_count is defined -%} -In [{{ cell.execution_count|replace(None, " ") }}]: -{%- else -%} -In [ ]: -{%- endif -%} -
-{%- endblock in_prompt %} - -{% block empty_in_prompt -%} -
-
-{%- endblock empty_in_prompt %} - -{# - output_prompt doesn't do anything in HTML, - because there is a prompt div in each output area (see output block) -#} -{% block output_prompt %} -{% endblock output_prompt %} - -{% block input %} -
-
-{{ cell.source | highlight_code(metadata=cell.metadata) }} -
-
-{%- endblock input %} - -{% block output %} -
-{%- if output.output_type == 'execute_result' -%} -
-{%- if cell.execution_count is defined -%} - Out[{{ cell.execution_count|replace(None, " ") }}]: -{%- else -%} - Out[ ]: -{%- endif -%} -{%- else -%} -
-{%- endif -%} -
-{{ super() }} -
-{% endblock output %} - -{% block markdowncell scoped %} -
-{{ self.empty_in_prompt() }} -
-
-{{ cell.source | markdown2html | strip_files_prefix }} -
-
-
-{%- endblock markdowncell %} - -{% block unknowncell scoped %} -unknown type {{ cell.type }} -{% endblock unknowncell %} - -{% block execute_result -%} -{%- set extra_class="output_execute_result" -%} -{% block data_priority scoped %} -{{ super() }} -{% endblock %} -{%- set extra_class="" -%} -{%- endblock execute_result %} - -{% block stream_stdout -%} -
-
-{{- output.text | ansi2html -}}
-
-
-{%- endblock stream_stdout %} - -{% block stream_stderr -%} -
-
-{{- output.text | ansi2html -}}
-
-
-{%- endblock stream_stderr %} - -{% block data_svg scoped -%} -
-{%- if output.svg_filename %} - -{%- endblock data_svg %} - -{% block data_html scoped -%} -
-{{ output.data['text/html'] }} -
-{%- endblock data_html %} - -{% block data_markdown scoped -%} -
-{{ output.data['text/markdown'] | markdown2html }} -
-{%- endblock data_markdown %} - -{% block data_png scoped %} -
-{%- if 'image/png' in output.metadata.get('filenames', {}) %} - -
-{%- endblock data_png %} - -{% block data_jpg scoped %} -
-{%- if 'image/jpeg' in output.metadata.get('filenames', {}) %} - -
-{%- endblock data_jpg %} - -{% block data_latex scoped %} -
-{{ output.data['text/latex'] }} -
-{%- endblock data_latex %} - -{% block error -%} -
-
-{{- super() -}}
-
-
-{%- endblock error %} - -{%- block traceback_line %} -{{ line | ansi2html }} -{%- endblock traceback_line %} - -{%- block data_text scoped %} -
-
-{{- output.data['text/plain'] | ansi2html -}}
-
-
-{%- endblock -%} - -{%- block data_javascript scoped %} -
- -
-{%- endblock -%} diff --git a/jupyter_nbconvert/templates/html/full.tpl b/jupyter_nbconvert/templates/html/full.tpl deleted file mode 100644 index c89258d..0000000 --- a/jupyter_nbconvert/templates/html/full.tpl +++ /dev/null @@ -1,71 +0,0 @@ -{%- extends 'basic.tpl' -%} -{% from 'mathjax.tpl' import mathjax %} - - -{%- block header -%} - - - - - -{{resources['metadata']['name']}} - - - - -{% for css in resources.inlining.css -%} - -{% endfor %} - - - - - - - -{{ mathjax() }} - - -{%- endblock header -%} - -{% block body %} - -
-
-{{ super() }} -
-
- -{%- endblock body %} - -{% block footer %} - -{% endblock footer %} diff --git a/jupyter_nbconvert/templates/html/mathjax.tpl b/jupyter_nbconvert/templates/html/mathjax.tpl deleted file mode 100644 index fd177d4..0000000 --- a/jupyter_nbconvert/templates/html/mathjax.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{%- macro mathjax() -%} - - - - - -{%- endmacro %} \ No newline at end of file diff --git a/jupyter_nbconvert/templates/html/slides_reveal.tpl b/jupyter_nbconvert/templates/html/slides_reveal.tpl deleted file mode 100644 index 2276a25..0000000 --- a/jupyter_nbconvert/templates/html/slides_reveal.tpl +++ /dev/null @@ -1,203 +0,0 @@ -{%- extends 'basic.tpl' -%} -{% from 'mathjax.tpl' import mathjax %} - -{%- block any_cell scoped -%} -{%- if cell.metadata.slide_type in ['slide'] -%} -
-
- {{ super() }} -{%- elif cell.metadata.slide_type in ['subslide'] -%} -
- {{ super() }} -{%- elif cell.metadata.slide_type in ['-'] -%} - {%- if cell.metadata.frag_helper in ['fragment_end'] -%} -
- {{ super() }} -
- {%- else -%} - {{ super() }} - {%- endif -%} -{%- elif cell.metadata.slide_type in ['skip'] -%} -
- {{ super() }} -
-{%- elif cell.metadata.slide_type in ['notes'] -%} - -{%- elif cell.metadata.slide_type in ['fragment'] -%} -
- {{ super() }} -
-{%- endif -%} -{%- if cell.metadata.slide_helper in ['subslide_end'] -%} -
-{%- elif cell.metadata.slide_helper in ['slide_end'] -%} -
-
-{%- endif -%} -{%- endblock any_cell -%} - -{% block header %} - - - - - - - - - - -{{resources['metadata']['name']}} slides - - - - - - - - - - - - - - - - -{% for css in resources.inlining.css -%} - -{% endfor %} - - - - - - - -{% endblock header%} - - -{% block body %} - -
-
-{{ super() }} -
-
- - - - - - - - -{{ mathjax() }} - - - - -{% endblock body %} - -{% block footer %} - -{% endblock footer %} diff --git a/jupyter_nbconvert/templates/latex/article.tplx b/jupyter_nbconvert/templates/latex/article.tplx deleted file mode 100644 index be59552..0000000 --- a/jupyter_nbconvert/templates/latex/article.tplx +++ /dev/null @@ -1,17 +0,0 @@ - -% Default to the notebook output style -((* if not cell_style is defined *)) - ((* set cell_style = 'style_ipython.tplx' *)) -((* endif *)) - -% Inherit from the specified cell style. -((* extends cell_style *)) - - -%=============================================================================== -% Latex Article -%=============================================================================== - -((* block docclass *)) -\documentclass{article} -((* endblock docclass *)) \ No newline at end of file diff --git a/jupyter_nbconvert/templates/latex/base.tplx b/jupyter_nbconvert/templates/latex/base.tplx deleted file mode 100644 index 8dd29bb..0000000 --- a/jupyter_nbconvert/templates/latex/base.tplx +++ /dev/null @@ -1,203 +0,0 @@ -((= Latex base template (must inherit) -This template builds upon the abstract template, adding common latex output -functions. Figures, data_text, -This template does not define a docclass, the inheriting class must define this.=)) - -((*- extends 'display_priority.tplx' -*)) - -%=============================================================================== -% Abstract overrides -%=============================================================================== - -((* block header *)) - ((* block docclass *))((* endblock docclass *)) - - ((* block packages *)) - \usepackage{graphicx} % Used to insert images - \usepackage{adjustbox} % Used to constrain images to a maximum size - \usepackage{color} % Allow colors to be defined - \usepackage{enumerate} % Needed for markdown enumerations to work - \usepackage{geometry} % Used to adjust the document margins - \usepackage{amsmath} % Equations - \usepackage{amssymb} % Equations - \usepackage{eurosym} % defines \euro - \usepackage[mathletters]{ucs} % Extended unicode (utf-8) support - \usepackage[utf8x]{inputenc} % Allow utf-8 characters in the tex document - \usepackage{fancyvrb} % verbatim replacement that allows latex - \usepackage{grffile} % extends the file name processing of package graphics - % to support a larger range - % The hyperref package gives us a pdf with properly built - % internal navigation ('pdf bookmarks' for the table of contents, - % internal cross-reference links, web links for URLs, etc.) - \usepackage{hyperref} - \usepackage{longtable} % longtable support required by pandoc >1.10 - \usepackage{booktabs} % table support for pandoc > 1.12.2 - ((* endblock packages *)) - - ((* block definitions *)) - \definecolor{orange}{cmyk}{0,0.4,0.8,0.2} - \definecolor{darkorange}{rgb}{.71,0.21,0.01} - \definecolor{darkgreen}{rgb}{.12,.54,.11} - \definecolor{myteal}{rgb}{.26, .44, .56} - \definecolor{gray}{gray}{0.45} - \definecolor{lightgray}{gray}{.95} - \definecolor{mediumgray}{gray}{.8} - \definecolor{inputbackground}{rgb}{.95, .95, .85} - \definecolor{outputbackground}{rgb}{.95, .95, .95} - \definecolor{traceback}{rgb}{1, .95, .95} - % ansi colors - \definecolor{red}{rgb}{.6,0,0} - \definecolor{green}{rgb}{0,.65,0} - \definecolor{brown}{rgb}{0.6,0.6,0} - \definecolor{blue}{rgb}{0,.145,.698} - \definecolor{purple}{rgb}{.698,.145,.698} - \definecolor{cyan}{rgb}{0,.698,.698} - \definecolor{lightgray}{gray}{0.5} - - % bright ansi colors - \definecolor{darkgray}{gray}{0.25} - \definecolor{lightred}{rgb}{1.0,0.39,0.28} - \definecolor{lightgreen}{rgb}{0.48,0.99,0.0} - \definecolor{lightblue}{rgb}{0.53,0.81,0.92} - \definecolor{lightpurple}{rgb}{0.87,0.63,0.87} - \definecolor{lightcyan}{rgb}{0.5,1.0,0.83} - - % commands and environments needed by pandoc snippets - % extracted from the output of `pandoc -s` - \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} - % Add ',fontsize=\small' for more characters per line - \newenvironment{Shaded}{}{} - \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} - \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}} - \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} - \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} - \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} - \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} - \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} - \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}} - \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} - \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} - \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}} - \newcommand{\RegionMarkerTok}[1]{{#1}} - \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} - \newcommand{\NormalTok}[1]{{#1}} - - % Define a nice break command that doesn't care if a line doesn't already - % exist. - \def\br{\hspace*{\fill} \\* } - % Math Jax compatability definitions - \def\gt{>} - \def\lt{<} - % Document parameters - ((* block title *))\title{((( resources.metadata.name | ascii_only | escape_latex )))}((* endblock title *)) - ((* block date *))((* endblock date *)) - ((* block author *))((* endblock author *)) - ((* endblock definitions *)) - - ((* block commands *)) - % Prevent overflowing lines due to hard-to-break entities - \sloppy - % Setup hyperref package - \hypersetup{ - breaklinks=true, % so long urls are correctly broken across lines - colorlinks=true, - urlcolor=blue, - linkcolor=darkorange, - citecolor=darkgreen, - } - % Slightly bigger margins than the latex defaults - ((* block margins *)) - \geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in} - ((* endblock margins *)) - ((* endblock commands *)) -((* endblock header *)) - -((* block body *)) - \begin{document} - - ((* block predoc *)) - ((* block maketitle *))\maketitle((* endblock maketitle *)) - ((* block abstract *))((* endblock abstract *)) - ((* endblock predoc *)) - - ((( super() ))) - - % Add a bibliography block to the postdoc - ((* block postdoc *)) - ((* block bibliography *))((* endblock bibliography *)) - ((* endblock postdoc *)) - \end{document} -((* endblock body *)) - -%=============================================================================== -% Support blocks -%=============================================================================== - -% Displaying simple data text -((* block data_text *)) - \begin{verbatim} -((( output.data['text/plain'] ))) - \end{verbatim} -((* endblock data_text *)) - -% Display python error text as-is -((* block error *)) - \begin{Verbatim}[commandchars=\\\{\}] -((( super() ))) - \end{Verbatim} -((* endblock error *)) -((* block traceback_line *)) - ((( line | indent | strip_ansi | escape_latex ))) -((* endblock traceback_line *)) - -% Display stream ouput with coloring -((* block stream *)) - \begin{Verbatim}[commandchars=\\\{\}] -((( output.text | escape_latex | ansi2latex ))) - \end{Verbatim} -((* endblock stream *)) - -% Display latex -((* block data_latex -*)) - ((*- if output.data['text/latex'].startswith('$'): -*)) - ((= Replace $ symbols with more explicit, equation block. =)) - \begin{equation*}\adjustbox{max width=\hsize}{$ - ((( output.data['text/latex'] | strip_dollars ))) - $}\end{equation*} - ((*- else -*)) - ((( output.data['text/latex'] ))) - ((*- endif *)) -((* endblock data_latex *)) - -% Default mechanism for rendering figures -((*- block data_png -*))((( draw_figure(output.metadata.filenames['image/png']) )))((*- endblock -*)) -((*- block data_jpg -*))((( draw_figure(output.metadata.filenames['image/jpeg']) )))((*- endblock -*)) -((*- block data_svg -*))((( draw_figure(output.metadata.filenames['image/svg+xml']) )))((*- endblock -*)) -((*- block data_pdf -*))((( draw_figure(output.metadata.filenames['application/pdf']) )))((*- endblock -*)) - -% Draw a figure using the graphicx package. -((* macro draw_figure(filename) -*)) -((* set filename = filename | posix_path *)) -((*- block figure scoped -*)) - \begin{center} - \adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{((( filename )))} - \end{center} - { \hspace*{\fill} \\} -((*- endblock figure -*)) -((*- endmacro *)) - -% Redirect execute_result to display data priority. -((* block execute_result scoped *)) - ((* block data_priority scoped *)) - ((( super() ))) - ((* endblock *)) -((* endblock execute_result *)) - -% Render markdown -((* block markdowncell scoped *)) - ((( cell.source | citation2latex | strip_files_prefix | markdown2latex ))) -((* endblock markdowncell *)) - -% Don't display unknown types -((* block unknowncell scoped *)) -((* endblock unknowncell *)) diff --git a/jupyter_nbconvert/templates/latex/report.tplx b/jupyter_nbconvert/templates/latex/report.tplx deleted file mode 100644 index 3a32310..0000000 --- a/jupyter_nbconvert/templates/latex/report.tplx +++ /dev/null @@ -1,26 +0,0 @@ - -% Default to the notebook output style -((* if not cell_style is defined *)) - ((* set cell_style = 'style_ipython.tplx' *)) -((* endif *)) - -% Inherit from the specified cell style. -((* extends cell_style *)) - - -%=============================================================================== -% Latex Book -%=============================================================================== - -((* block predoc *)) - ((( super() ))) - ((* block tableofcontents *))\tableofcontents((* endblock tableofcontents *)) -((* endblock predoc *)) - -((* block docclass *)) -\documentclass{report} -((* endblock docclass *)) - -((* block markdowncell scoped *)) -((( cell.source | citation2latex | strip_files_prefix | markdown2latex(extra_args=["--chapters"]) ))) -((* endblock markdowncell *)) diff --git a/jupyter_nbconvert/templates/latex/skeleton/display_priority.tplx b/jupyter_nbconvert/templates/latex/skeleton/display_priority.tplx deleted file mode 100644 index 6e5366c..0000000 --- a/jupyter_nbconvert/templates/latex/skeleton/display_priority.tplx +++ /dev/null @@ -1,44 +0,0 @@ -((= Auto-generated template file, DO NOT edit directly! - To edit this file, please refer to ../../skeleton/README.md =)) - - -((*- extends 'null.tplx' -*)) - -((=display data priority=)) - - -((*- block data_priority scoped -*)) - ((*- for type in output.data | filter_data_type -*)) - ((*- if type == 'application/pdf' -*)) - ((*- block data_pdf -*)) - ((*- endblock -*)) - ((*- elif type == 'image/svg+xml' -*)) - ((*- block data_svg -*)) - ((*- endblock -*)) - ((*- elif type == 'image/png' -*)) - ((*- block data_png -*)) - ((*- endblock -*)) - ((*- elif type == 'text/html' -*)) - ((*- block data_html -*)) - ((*- endblock -*)) - ((*- elif type == 'text/markdown' -*)) - ((*- block data_markdown -*)) - ((*- endblock -*)) - ((*- elif type == 'image/jpeg' -*)) - ((*- block data_jpg -*)) - ((*- endblock -*)) - ((*- elif type == 'text/plain' -*)) - ((*- block data_text -*)) - ((*- endblock -*)) - ((*- elif type == 'text/latex' -*)) - ((*- block data_latex -*)) - ((*- endblock -*)) - ((*- elif type == 'application/javascript' -*)) - ((*- block data_javascript -*)) - ((*- endblock -*)) - ((*- else -*)) - ((*- block data_other -*)) - ((*- endblock -*)) - ((*- endif -*)) - ((*- endfor -*)) -((*- endblock data_priority -*)) diff --git a/jupyter_nbconvert/templates/latex/skeleton/null.tplx b/jupyter_nbconvert/templates/latex/skeleton/null.tplx deleted file mode 100644 index 47dd461..0000000 --- a/jupyter_nbconvert/templates/latex/skeleton/null.tplx +++ /dev/null @@ -1,93 +0,0 @@ -((= Auto-generated template file, DO NOT edit directly! - To edit this file, please refer to ../../skeleton/README.md =)) - - -((= - -DO NOT USE THIS AS A BASE, -IF YOU ARE COPY AND PASTING THIS FILE -YOU ARE PROBABLY DOING THINGS INCORRECTLY. - -Null template, does nothing except defining a basic structure -To layout the different blocks of a notebook. - -Subtemplates can override blocks to define their custom representation. - -If one of the block you do overwrite is not a leave block, consider -calling super. - -((*- block nonLeaveBlock -*)) - #add stuff at beginning - ((( super() ))) - #add stuff at end -((*- endblock nonLeaveBlock -*)) - -consider calling super even if it is a leave block, we might insert more blocks later. - -=)) -((*- block header -*)) -((*- endblock header -*)) -((*- block body -*)) -((*- for cell in nb.cells -*)) - ((*- block any_cell scoped -*)) - ((*- if cell.cell_type == 'code' -*)) - ((*- block codecell scoped -*)) - ((*- block input_group -*)) - ((*- block in_prompt -*))((*- endblock in_prompt -*)) - ((*- block input -*))((*- endblock input -*)) - ((*- endblock input_group -*)) - ((*- if cell.outputs -*)) - ((*- block output_group -*)) - ((*- block output_prompt -*))((*- endblock output_prompt -*)) - ((*- block outputs scoped -*)) - ((*- for output in cell.outputs -*)) - ((*- block output scoped -*)) - ((*- if output.output_type == 'execute_result' -*)) - ((*- block execute_result scoped -*))((*- endblock execute_result -*)) - ((*- elif output.output_type == 'stream' -*)) - ((*- block stream scoped -*)) - ((*- if output.name == 'stdout' -*)) - ((*- block stream_stdout scoped -*)) - ((*- endblock stream_stdout -*)) - ((*- elif output.name == 'stderr' -*)) - ((*- block stream_stderr scoped -*)) - ((*- endblock stream_stderr -*)) - ((*- endif -*)) - ((*- endblock stream -*)) - ((*- elif output.output_type == 'display_data' -*)) - ((*- block display_data scoped -*)) - ((*- block data_priority scoped -*)) - ((*- endblock data_priority -*)) - ((*- endblock display_data -*)) - ((*- elif output.output_type == 'error' -*)) - ((*- block error scoped -*)) - ((*- for line in output.traceback -*)) - ((*- block traceback_line scoped -*))((*- endblock traceback_line -*)) - ((*- endfor -*)) - ((*- endblock error -*)) - ((*- endif -*)) - ((*- endblock output -*)) - ((*- endfor -*)) - ((*- endblock outputs -*)) - ((*- endblock output_group -*)) - ((*- endif -*)) - ((*- endblock codecell -*)) - ((*- elif cell.cell_type in ['markdown'] -*)) - ((*- block markdowncell scoped-*)) - ((*- endblock markdowncell -*)) - ((*- elif cell.cell_type in ['raw'] -*)) - ((*- block rawcell scoped -*)) - ((*- if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) -*)) - ((( cell.source ))) - ((*- endif -*)) - ((*- endblock rawcell -*)) - ((*- else -*)) - ((*- block unknowncell scoped-*)) - ((*- endblock unknowncell -*)) - ((*- endif -*)) - ((*- endblock any_cell -*)) -((*- endfor -*)) -((*- endblock body -*)) - -((*- block footer -*)) -((*- endblock footer -*)) diff --git a/jupyter_nbconvert/templates/latex/style_bw_ipython.tplx b/jupyter_nbconvert/templates/latex/style_bw_ipython.tplx deleted file mode 100644 index 7edf508..0000000 --- a/jupyter_nbconvert/templates/latex/style_bw_ipython.tplx +++ /dev/null @@ -1,45 +0,0 @@ -((= Black&white ipython input/output style =)) - -((*- extends 'base.tplx' -*)) - -%=============================================================================== -% Input -%=============================================================================== - -((* block input scoped *)) -((( add_prompt(cell.source, cell, 'In ') ))) -((* endblock input *)) - - -%=============================================================================== -% Output -%=============================================================================== - -((* block execute_result scoped *)) - ((*- for type in output.data | filter_data_type -*)) - ((*- if type in ['text/plain']*)) -((( add_prompt(output.data['text/plain'], cell, 'Out') ))) - ((*- else -*)) -\verb+Out[((( cell.execution_count )))]:+((( super() ))) - ((*- endif -*)) - ((*- endfor -*)) -((* endblock execute_result *)) - - -%============================================================================== -% Support Macros -%============================================================================== - -% Name: draw_prompt -% Purpose: Renders an output/input prompt -((* macro add_prompt(text, cell, prompt) -*)) - ((*- if cell.execution_count is defined -*)) - ((*- set execution_count = "" ~ (cell.execution_count | replace(None, " ")) -*)) - ((*- else -*)) - ((*- set execution_count = " " -*)) - ((*- endif -*)) - ((*- set indentation = " " * (execution_count | length + 7) -*)) -\begin{verbatim} -(((- text | add_prompts(first=prompt ~ '[' ~ execution_count ~ ']: ', cont=indentation) -))) -\end{verbatim} -((*- endmacro *)) diff --git a/jupyter_nbconvert/templates/latex/style_bw_python.tplx b/jupyter_nbconvert/templates/latex/style_bw_python.tplx deleted file mode 100644 index 5371900..0000000 --- a/jupyter_nbconvert/templates/latex/style_bw_python.tplx +++ /dev/null @@ -1,13 +0,0 @@ -((= Black&white Python input/output style =)) - -((*- extends 'base.tplx' -*)) - -%=============================================================================== -% Input -%=============================================================================== - -((* block input scoped *)) -\begin{verbatim} -((( cell.source | add_prompts ))) -\end{verbatim} -((* endblock input *)) diff --git a/jupyter_nbconvert/templates/latex/style_ipython.tplx b/jupyter_nbconvert/templates/latex/style_ipython.tplx deleted file mode 100644 index 86c7a03..0000000 --- a/jupyter_nbconvert/templates/latex/style_ipython.tplx +++ /dev/null @@ -1,58 +0,0 @@ -((= IPython input/output style =)) - -((*- extends 'base.tplx' -*)) - -% Custom definitions -((* block definitions *)) - ((( super() ))) - - % Pygments definitions - ((( resources.latex.pygments_definitions ))) - - % Exact colors from NB - \definecolor{incolor}{rgb}{0.0, 0.0, 0.5} - \definecolor{outcolor}{rgb}{0.545, 0.0, 0.0} - -((* endblock definitions *)) - -%=============================================================================== -% Input -%=============================================================================== - -((* block input scoped *)) - ((( add_prompt(cell.source | highlight_code(strip_verbatim=True), cell, 'In ', 'incolor') ))) -((* endblock input *)) - - -%=============================================================================== -% Output -%=============================================================================== - -((* block execute_result scoped *)) - ((*- for type in output.data | filter_data_type -*)) - ((*- if type in ['text/plain']*)) - ((( add_prompt(output.data['text/plain'] | escape_latex, cell, 'Out', 'outcolor') ))) - ((* else -*)) -\texttt{\color{outcolor}Out[{\color{outcolor}((( cell.execution_count )))}]:}((( super() ))) - ((*- endif -*)) - ((*- endfor -*)) -((* endblock execute_result *)) - - -%============================================================================== -% Support Macros -%============================================================================== - -% Name: draw_prompt -% Purpose: Renders an output/input prompt -((* macro add_prompt(text, cell, prompt, prompt_color) -*)) - ((*- if cell.execution_count is defined -*)) - ((*- set execution_count = "" ~ (cell.execution_count | replace(None, " ")) -*)) - ((*- else -*)) - ((*- set execution_count = " " -*)) - ((*- endif -*)) - ((*- set indention = " " * (execution_count | length + 7) -*)) -\begin{Verbatim}[commandchars=\\\{\}] -((( text | add_prompts(first='{\color{' ~ prompt_color ~ '}' ~ prompt ~ '[{\\color{' ~ prompt_color ~ '}' ~ execution_count ~ '}]:} ', cont=indention) ))) -\end{Verbatim} -((*- endmacro *)) diff --git a/jupyter_nbconvert/templates/latex/style_python.tplx b/jupyter_nbconvert/templates/latex/style_python.tplx deleted file mode 100644 index 6673744..0000000 --- a/jupyter_nbconvert/templates/latex/style_python.tplx +++ /dev/null @@ -1,21 +0,0 @@ -((= Python input/output style =)) - -((*- extends 'base.tplx' -*)) - -% Custom definitions -((* block definitions *)) - ((( super() ))) - - % Pygments definitions - ((( resources.latex.pygments_definitions ))) -((* endblock definitions *)) - -%=============================================================================== -% Input -%=============================================================================== - -((* block input scoped *)) - \begin{Verbatim}[commandchars=\\\{\}] -((( cell.source | highlight_code(strip_verbatim=True) | add_prompts ))) - \end{Verbatim} -((* endblock input *)) diff --git a/jupyter_nbconvert/templates/markdown.tpl b/jupyter_nbconvert/templates/markdown.tpl deleted file mode 100644 index b0de4e9..0000000 --- a/jupyter_nbconvert/templates/markdown.tpl +++ /dev/null @@ -1,67 +0,0 @@ -{% extends 'display_priority.tpl' %} - - -{% block in_prompt %} -{% endblock in_prompt %} - -{% block output_prompt %} -{%- endblock output_prompt %} - -{% block input %} -{{ cell.source | indent(4)}} -{% endblock input %} - -{% block error %} -{{ super() }} -{% endblock error %} - -{% block traceback_line %} -{{ line | indent | strip_ansi }} -{% endblock traceback_line %} - -{% block execute_result %} - -{% block data_priority scoped %} -{{ super() }} -{% endblock %} -{% endblock execute_result %} - -{% block stream %} -{{ output.text | indent }} -{% endblock stream %} - -{% block data_svg %} -![svg]({{ output.svg_filename | path2url }}) -{% endblock data_svg %} - -{% block data_png %} -![png]({{ output.metadata.filenames['image/png'] | path2url }}) -{% endblock data_png %} - -{% block data_jpg %} -![jpeg]({{ output.metadata.filenames['image/jpeg'] | path2url }}) -{% endblock data_jpg %} - -{% block data_latex %} -{{ output.data['text/latex'] }} -{% endblock data_latex %} - -{% block data_html scoped %} -{{ output.data['text/html'] }} -{% endblock data_html %} - -{% block data_markdown scoped %} -{{ output.data['text/markdown'] }} -{% endblock data_markdown %} - -{% block data_text scoped %} -{{ output.data['text/plain'] | indent }} -{% endblock data_text %} - -{% block markdowncell scoped %} -{{ cell.source }} -{% endblock markdowncell %} - -{% block unknowncell scoped %} -unknown type {{ cell.type }} -{% endblock unknowncell %} \ No newline at end of file diff --git a/jupyter_nbconvert/templates/python.tpl b/jupyter_nbconvert/templates/python.tpl deleted file mode 100644 index 3918e25..0000000 --- a/jupyter_nbconvert/templates/python.tpl +++ /dev/null @@ -1,17 +0,0 @@ -{%- extends 'null.tpl' -%} - -{% block header %} -# coding: utf-8 -{% endblock header %} - -{% block in_prompt %} -# In[{{ cell.execution_count if cell.execution_count else ' ' }}]: -{% endblock in_prompt %} - -{% block input %} -{{ cell.source | ipython2python }} -{% endblock input %} - -{% block markdowncell scoped %} -{{ cell.source | comment_lines }} -{% endblock markdowncell %} diff --git a/jupyter_nbconvert/templates/rst.tpl b/jupyter_nbconvert/templates/rst.tpl deleted file mode 100644 index aaca417..0000000 --- a/jupyter_nbconvert/templates/rst.tpl +++ /dev/null @@ -1,86 +0,0 @@ -{%- extends 'display_priority.tpl' -%} - - -{% block in_prompt %} -{% endblock in_prompt %} - -{% block output_prompt %} -{% endblock output_prompt %} - -{% block input %} -{%- if cell.source.strip() -%} -.. code:: python - -{{ cell.source | indent}} -{% endif -%} -{% endblock input %} - -{% block error %} -:: - -{{ super() }} -{% endblock error %} - -{% block traceback_line %} -{{ line | indent | strip_ansi }} -{% endblock traceback_line %} - -{% block execute_result %} -{% block data_priority scoped %} -{{ super() }} -{% endblock %} -{% endblock execute_result %} - -{% block stream %} -.. parsed-literal:: - -{{ output.text | indent }} -{% endblock stream %} - -{% block data_svg %} -.. image:: {{ output.metadata.filenames['image/svg+xml'] | urlencode }} -{% endblock data_svg %} - -{% block data_png %} -.. image:: {{ output.metadata.filenames['image/png'] | urlencode }} -{% endblock data_png %} - -{% block data_jpg %} -.. image:: {{ output.metadata.filenames['image/jpeg'] | urlencode }} -{% endblock data_jpg %} - -{% block data_latex %} -.. math:: - -{{ output.data['text/latex'] | strip_dollars | indent }} -{% endblock data_latex %} - -{% block data_text scoped %} -.. parsed-literal:: - -{{ output.data['text/plain'] | indent }} -{% endblock data_text %} - -{% block data_html scoped %} -.. raw:: html - -{{ output.data['text/html'] | indent }} -{% endblock data_html %} - -{% block markdowncell scoped %} -{{ cell.source | markdown2rst }} -{% endblock markdowncell %} - -{%- block rawcell scoped -%} -{%- if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) %} -{{cell.source}} -{% endif -%} -{%- endblock rawcell -%} - -{% block headingcell scoped %} -{{ ("#" * cell.level + cell.source) | replace('\n', ' ') | markdown2rst }} -{% endblock headingcell %} - -{% block unknowncell scoped %} -unknown type {{cell.type}} -{% endblock unknowncell %} diff --git a/jupyter_nbconvert/templates/script.tpl b/jupyter_nbconvert/templates/script.tpl deleted file mode 100644 index cbd971d..0000000 --- a/jupyter_nbconvert/templates/script.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{%- extends 'null.tpl' -%} - -{% block input %} -{{ cell.source }} -{% endblock input %} diff --git a/jupyter_nbconvert/templates/skeleton/Makefile b/jupyter_nbconvert/templates/skeleton/Makefile deleted file mode 100644 index c02ac0f..0000000 --- a/jupyter_nbconvert/templates/skeleton/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -TPLS := $(patsubst %.tpl,../latex/skeleton/%.tplx,$(wildcard *.tpl)) - -all: clean $(TPLS) - -# Convert standard Jinja2 syntax to LaTeX safe Jinja2 -# see http://flask.pocoo.org/snippets/55/ for more info -../latex/skeleton/%.tplx: %.tpl - @echo 'generating tex equivalent of $^: $@' - @echo '((= Auto-generated template file, DO NOT edit directly!\n' \ - ' To edit this file, please refer to ../../skeleton/README.md' \ - '=))\n\n' > $@ - @sed \ - -e 's/{%/((*/g' \ - -e 's/%}/*))/g' \ - -e 's/{{/(((/g' \ - -e 's/}}/)))/g' \ - -e 's/{#/((=/g' \ - -e 's/#}/=))/g' \ - -e "s/tpl'/tplx'/g" \ - $^ >> $@ - -clean: - @echo "cleaning generated tplx files..." - @-rm ../latex/skeleton/*.tplx diff --git a/jupyter_nbconvert/templates/skeleton/README.md b/jupyter_nbconvert/templates/skeleton/README.md deleted file mode 100644 index 2faa239..0000000 --- a/jupyter_nbconvert/templates/skeleton/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## Template skeleton - -This directory contains the template skeleton files. - -Do not modify the contents of the `../latex/skeleton` folder. Instead, -if you need to, make modifications to the files in this folder and then run -`make` to generate the corresponding latex skeleton files in the -`../latex/skeleton` folder. - -If you would like to share your resulting templates with others, we encourage -[sharing those links on our wiki -page](https://github.com/ipython/ipython/wiki/Cookbook:%20nbconvert%20templates). diff --git a/jupyter_nbconvert/templates/skeleton/display_priority.tpl b/jupyter_nbconvert/templates/skeleton/display_priority.tpl deleted file mode 100644 index e73d6ef..0000000 --- a/jupyter_nbconvert/templates/skeleton/display_priority.tpl +++ /dev/null @@ -1,40 +0,0 @@ -{%- extends 'null.tpl' -%} - -{#display data priority#} - - -{%- block data_priority scoped -%} - {%- for type in output.data | filter_data_type -%} - {%- if type == 'application/pdf' -%} - {%- block data_pdf -%} - {%- endblock -%} - {%- elif type == 'image/svg+xml' -%} - {%- block data_svg -%} - {%- endblock -%} - {%- elif type == 'image/png' -%} - {%- block data_png -%} - {%- endblock -%} - {%- elif type == 'text/html' -%} - {%- block data_html -%} - {%- endblock -%} - {%- elif type == 'text/markdown' -%} - {%- block data_markdown -%} - {%- endblock -%} - {%- elif type == 'image/jpeg' -%} - {%- block data_jpg -%} - {%- endblock -%} - {%- elif type == 'text/plain' -%} - {%- block data_text -%} - {%- endblock -%} - {%- elif type == 'text/latex' -%} - {%- block data_latex -%} - {%- endblock -%} - {%- elif type == 'application/javascript' -%} - {%- block data_javascript -%} - {%- endblock -%} - {%- else -%} - {%- block data_other -%} - {%- endblock -%} - {%- endif -%} - {%- endfor -%} -{%- endblock data_priority -%} diff --git a/jupyter_nbconvert/templates/skeleton/null.tpl b/jupyter_nbconvert/templates/skeleton/null.tpl deleted file mode 100644 index a1d4210..0000000 --- a/jupyter_nbconvert/templates/skeleton/null.tpl +++ /dev/null @@ -1,89 +0,0 @@ -{# - -DO NOT USE THIS AS A BASE, -IF YOU ARE COPY AND PASTING THIS FILE -YOU ARE PROBABLY DOING THINGS INCORRECTLY. - -Null template, does nothing except defining a basic structure -To layout the different blocks of a notebook. - -Subtemplates can override blocks to define their custom representation. - -If one of the block you do overwrite is not a leave block, consider -calling super. - -{%- block nonLeaveBlock -%} - #add stuff at beginning - {{ super() }} - #add stuff at end -{%- endblock nonLeaveBlock -%} - -consider calling super even if it is a leave block, we might insert more blocks later. - -#} -{%- block header -%} -{%- endblock header -%} -{%- block body -%} -{%- for cell in nb.cells -%} - {%- block any_cell scoped -%} - {%- if cell.cell_type == 'code' -%} - {%- block codecell scoped -%} - {%- block input_group -%} - {%- block in_prompt -%}{%- endblock in_prompt -%} - {%- block input -%}{%- endblock input -%} - {%- endblock input_group -%} - {%- if cell.outputs -%} - {%- block output_group -%} - {%- block output_prompt -%}{%- endblock output_prompt -%} - {%- block outputs scoped -%} - {%- for output in cell.outputs -%} - {%- block output scoped -%} - {%- if output.output_type == 'execute_result' -%} - {%- block execute_result scoped -%}{%- endblock execute_result -%} - {%- elif output.output_type == 'stream' -%} - {%- block stream scoped -%} - {%- if output.name == 'stdout' -%} - {%- block stream_stdout scoped -%} - {%- endblock stream_stdout -%} - {%- elif output.name == 'stderr' -%} - {%- block stream_stderr scoped -%} - {%- endblock stream_stderr -%} - {%- endif -%} - {%- endblock stream -%} - {%- elif output.output_type == 'display_data' -%} - {%- block display_data scoped -%} - {%- block data_priority scoped -%} - {%- endblock data_priority -%} - {%- endblock display_data -%} - {%- elif output.output_type == 'error' -%} - {%- block error scoped -%} - {%- for line in output.traceback -%} - {%- block traceback_line scoped -%}{%- endblock traceback_line -%} - {%- endfor -%} - {%- endblock error -%} - {%- endif -%} - {%- endblock output -%} - {%- endfor -%} - {%- endblock outputs -%} - {%- endblock output_group -%} - {%- endif -%} - {%- endblock codecell -%} - {%- elif cell.cell_type in ['markdown'] -%} - {%- block markdowncell scoped-%} - {%- endblock markdowncell -%} - {%- elif cell.cell_type in ['raw'] -%} - {%- block rawcell scoped -%} - {%- if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) -%} - {{ cell.source }} - {%- endif -%} - {%- endblock rawcell -%} - {%- else -%} - {%- block unknowncell scoped-%} - {%- endblock unknowncell -%} - {%- endif -%} - {%- endblock any_cell -%} -{%- endfor -%} -{%- endblock body -%} - -{%- block footer -%} -{%- endblock footer -%} diff --git a/jupyter_nbconvert/tests/README.md b/jupyter_nbconvert/tests/README.md deleted file mode 100644 index c628582..0000000 --- a/jupyter_nbconvert/tests/README.md +++ /dev/null @@ -1 +0,0 @@ -To compare nbconvert html output to the notebook's native html see https://gist.github.com/9241376.git. diff --git a/jupyter_nbconvert/tests/__init__.py b/jupyter_nbconvert/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_nbconvert/tests/__init__.py +++ /dev/null diff --git a/jupyter_nbconvert/tests/base.py b/jupyter_nbconvert/tests/base.py deleted file mode 100644 index 5903a40..0000000 --- a/jupyter_nbconvert/tests/base.py +++ /dev/null @@ -1,171 +0,0 @@ -"""Base test class for nbconvert""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import io -import os -import glob -import shlex -import shutil -import sys -import unittest -from subprocess import Popen, PIPE - -import nose.tools as nt - -from IPython.nbformat import v4, write -from IPython.utils.tempdir import TemporaryWorkingDirectory - -from IPython.utils.py3compat import string_types, bytes_to_str - -class TestsBase(unittest.TestCase): - """Base tests class. Contains useful fuzzy comparison and nbconvert - functions.""" - - - def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True, - fuzzy_spacing=True, ignore_spaces=False, - ignore_newlines=False, case_sensitive=False, leave_padding=False): - """ - Performs a fuzzy comparison of two strings. A fuzzy comparison is a - comparison that ignores insignificant differences in the two comparands. - The significance of certain differences can be specified via the keyword - parameters of this method. - """ - - if not leave_padding: - a = a.strip() - b = b.strip() - - if ignore_newlines: - a = a.replace('\n', '') - b = b.replace('\n', '') - - if newlines_are_spaces: - a = a.replace('\n', ' ') - b = b.replace('\n', ' ') - - if tabs_are_spaces: - a = a.replace('\t', ' ') - b = b.replace('\t', ' ') - - if ignore_spaces: - a = a.replace(' ', '') - b = b.replace(' ', '') - - if fuzzy_spacing: - a = self.recursive_replace(a, ' ', ' ') - b = self.recursive_replace(b, ' ', ' ') - - if not case_sensitive: - a = a.lower() - b = b.lower() - - self.assertEqual(a, b) - - - def recursive_replace(self, text, search, replacement): - """ - Performs a recursive replacement operation. Replaces all instances - of a search string in a text string with a replacement string until - the search string no longer exists. Recursion is needed because the - replacement string may generate additional search strings. - - For example: - Replace "ii" with "i" in the string "Hiiii" yields "Hii" - Another replacement cds "Hi" (the desired output) - - Parameters - ---------- - text : string - Text to replace in. - search : string - String to search for within "text" - replacement : string - String to replace "search" with - """ - while search in text: - text = text.replace(search, replacement) - return text - - def create_temp_cwd(self, copy_filenames=None): - temp_dir = TemporaryWorkingDirectory() - - #Copy the files if requested. - if copy_filenames is not None: - self.copy_files_to(copy_filenames, dest=temp_dir.name) - - #Return directory handler - return temp_dir - - def create_empty_notebook(self, path): - nb = v4.new_notebook() - with io.open(path, 'w', encoding='utf-8') as f: - write(nb, f, 4) - - def copy_files_to(self, copy_filenames, dest='.'): - "Copy test files into the destination directory" - if not os.path.isdir(dest): - os.makedirs(dest) - files_path = self._get_files_path() - for pattern in copy_filenames: - for match in glob.glob(os.path.join(files_path, pattern)): - shutil.copyfile(match, os.path.join(dest, os.path.basename(match))) - - - def _get_files_path(self): - - #Get the relative path to this module in the IPython directory. - names = self.__module__.split('.')[1:-1] - names.append('files') - - #Build a path using the nbconvert directory and the relative path we just - #found. - import jupyter_nbconvert - path = os.path.dirname(jupyter_nbconvert.__file__) - return os.path.join(path, *names) - - - def nbconvert(self, parameters, ignore_return_code=False): - """ - Run nbconvert a, IPython shell command, listening for both Errors and non-zero - return codes. - - Parameters - ---------- - parameters : str, list(str) - List of parameters to pass to IPython. - ignore_return_code : optional bool (default False) - Throw an OSError if the return code - """ - if isinstance(parameters, string_types): - parameters = shlex.split(parameters) - cmd = [sys.executable, '-m', 'jupyter_nbconvert'] + parameters - p = Popen(cmd, stdout=PIPE, stderr=PIPE) - stdout, stderr = p.communicate() - if not (p.returncode == 0 or ignore_return_code): - raise OSError(bytes_to_str(stderr)) - return stdout.decode('utf8', 'replace'), stderr.decode('utf8', 'replace') - - -def assert_big_text_equal(a, b, chunk_size=80): - """assert that large strings are equal - - Zooms in on first chunk that differs, - to give better info than vanilla assertEqual for large text blobs. - """ - for i in range(0, len(a), chunk_size): - chunk_a = a[i:i + chunk_size] - chunk_b = b[i:i + chunk_size] - nt.assert_equal(chunk_a, chunk_b, "[offset: %i]\n%r != \n%r" % ( - i, chunk_a, chunk_b)) - - if len(a) > len(b): - nt.fail("Length doesn't match (%i > %i). Extra text:\n%r" % ( - len(a), len(b), a[len(b):] - )) - elif len(a) < len(b): - nt.fail("Length doesn't match (%i < %i). Extra text:\n%r" % ( - len(a), len(b), b[len(a):] - )) diff --git a/jupyter_nbconvert/tests/files/hello.py b/jupyter_nbconvert/tests/files/hello.py deleted file mode 100644 index 9984db6..0000000 --- a/jupyter_nbconvert/tests/files/hello.py +++ /dev/null @@ -1,7 +0,0 @@ -from jupyter_nbconvert.writers.base import WriterBase - -class HelloWriter(WriterBase): - - def write(self, output, resources, notebook_name=None, **kw): - with open('hello.txt', 'w') as outfile: - outfile.write('hello world') diff --git a/jupyter_nbconvert/tests/files/ipython_nbconvert_config.py b/jupyter_nbconvert/tests/files/ipython_nbconvert_config.py deleted file mode 100644 index d0516b8..0000000 --- a/jupyter_nbconvert/tests/files/ipython_nbconvert_config.py +++ /dev/null @@ -1,6 +0,0 @@ -c = get_config() - -#Export all the notebooks in the current directory to the sphinx_howto format. -c.NbConvertApp.notebooks = ['notebook1.ipynb'] -c.NbConvertApp.export_format = 'python' - diff --git a/jupyter_nbconvert/tests/files/notebook1.ipynb b/jupyter_nbconvert/tests/files/notebook1.ipynb deleted file mode 100644 index 9ffa91d..0000000 --- a/jupyter_nbconvert/tests/files/notebook1.ipynb +++ /dev/null @@ -1,189 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# A simple SymPy example" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First we import SymPy and initialize printing:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from sympy import init_printing\n", - "from sympy import *\n", - " init_printing()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create a few symbols:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "x,y,z = symbols('x y z')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is a basic expression:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": [ - "iVBORw0KGgoAAAANSUhEUgAAAKMAAAAZBAMAAACvE4OgAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\n", - "me8Q6PJIAAACz0lEQVRIDa1UTWjUQBT+ZpvdzW7TGlrxItjYSg/C6vbiDwjmoCgUpHioPYhdqig9\n", - "FJYiPYmW4klB14NgFGnw4EHpj7UgUtTFXhSEBgVBxIOFggWVrrUqiMY3mZkkLNIK7oN575vvvfky\n", - "8yYJIGzgkSlRrULKrivVSkvq6LbxtcaSjV3aSo0lgWyl5pK69V+SRlEsPxNTGYhhDrV3M2Ue2etc\n", - "EDmuMmM+IjolrCuHXNoLoQDNSAXdzbjsfFVKTY1vCgFXFIxenG4cFSSzRewAPnN0FugXjPDr45MQ\n", - "JwoKtitgXL9zT+CsJeIHYG+Z4H1gwhRU4G/FcAQbbYU3KdDo+0sCK8lRU0guA72uKqMYk9RehHxP\n", - "iDIu0NS2v90KGShJYi7T7tgvkrQ2vIT2XtRISWNra6lzGc8/PW3ji4PL7Vmge095YIX0iB71NCaZ\n", - "5N3XyM0VCuNIyFNIyY3AMG/KDUvjn90DGmwq9wpIl5AyU5WsTYy0aJf6JFGB5An3Der5jExKHjNR\n", - "4JKPge/EXqDBoOXpkxkmkJHFfAFRVhDIveWA0S57N2Me6yw+DSX1n1uCq3sIfCF2IcjNkjeWyKli\n", - "ginHubboOB4vSNAjyaiXE26ygrkyTfod55Lj3CTE+n2P73ImJpnk6wJJKjYJSwt3OQbNJu4icM5s\n", - "KGGbzMuD70N6JSbJD44x7pLDyJrbkfiLpOEhYVMJSVEj83x5YFLyNrAzJsmvJ+uhLrieXvcJDshy\n", - "HtQuD54c2IWWEnSXfUTDZJJfAjcpOW5imp9aHvw4ZZ4NDV4FGjw0tzadKgbFwinJUd//AT0P1tdW\n", - "BtuRU39oKdk9ONQ163fM+nvu/s4D/FX30otdQIZGlSnJKpq6KUxKVqV1WxGHFIhishjhEO1Gi3r4\n", - "kZCMg+hH1henV8EjmFoly1PTMs/Uadaox+FceY2STpmvt9co/Pe0Jvt1GvgDK/Osw/4jQ4wAAAAA\n", - "SUVORK5CYII=\n" - ], - "text/latex": [ - "$$x^{2} + 2.0 y + \\sin{\\left (z \\right )}$$" - ], - "text/plain": [ - " 2 \n", - "x + 2.0\u22c5y + sin(z)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "e = x**2 + 2.0*y + sin(z); e" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": [ - "iVBORw0KGgoAAAANSUhEUgAAABQAAAAOBAMAAADd6iHDAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpm7MhCriUTv3c12\n", - "VGZoascqAAAAgElEQVQIHWNgVDJ2YICAMAb2H1BmKgPDTChzFgNDvgOEvT8AzgQKrA9gPZPYUwNk\n", - "cXxnCGd4dWA1kMllwFDKUB9wEchUZmAIYNgMZDDwJIDIPyDiEgOjAAPLFwZWBhYFBh6BqzwfGI4y\n", - "SJUXZXH8Zf7A+IBh////v1hzjh5/xwAAW80hUDE8HYkAAAAASUVORK5CYII=\n" - ], - "text/latex": [ - "$$2 x$$" - ], - "text/plain": [ - "2\u22c5x" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "diff(e, x)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": [ - "iVBORw0KGgoAAAANSUhEUgAAALsAAAAZBAMAAACbakK8AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\n", - "me8Q6PJIAAADAklEQVRIDbVVS2gTURQ90/wmk0k6tCJCsR1SKShIsxE3CgNWBKUxq9qFmqFqShfF\n", - "UKQrkaDiF0pcCKYgBBcuBLV+wIWKARe6kQ4UhNKKWdiF4KIptmA/xPvmzZuMxdYUzIPcd+655568\n", - "vLlJAL6G32oOasQWNHz5Rvg6nrKh/mygfSzlX2ygPaBUGmov6//NXs1yq4sex2EPrsHemTd2snNg\n", - "tkb+Cx1zBL6SqwxZLvQAKYHzKZaPY4fh4TeHd0S5Nox9OClItm/jiU9DrEwwVEawpiVis9VkimqX\n", - "AOr4o2cCs/0BT2I5+FYJRhJbePQxgzcD7QLEqtV5gdnu2Icr3L45gcCyt74Z7neL4SLQ0nm4S+dM\n", - "YCz1gSPHnhKZDWyHhcCCNKwjqaF/TkwGl0L6nClie/wc1D1xdoNsSLhT0IJkhi7Lzr22xb8keE/N\n", - "Pm0Sc9yEuhRUyuiG9HzvFNeImCyq39SriOhtQI7IV/TiTqE8glqwohjE0NJwiANxOZTdZoxtfzSa\n", - "x2tI8DtHcKQoQFmV6f1XT2swibxFL+6k5EgenhBCqKLTPX3ULnaYdDlaTMcCSd8zuXTvBq2bJUJr\n", - "lE4WgSV5ZRdBzLFgO6nzhJp1ltvrlB2HCoWxQuG+jTvt2GxBWUZaU2mMApZNuSHA3vJpCliRhqqs\n", - "ZtvbTrb9ZIk+i70Ut1OcnpgeKskTCFUwjaYy8Jhr3eiefq0HIfa7yC6HOwVyULRuNDn21JngbcL+\n", - "E8A+MNnSxb+w59+Cj2tELJBbjEZr8SGwn0j2aLkTPdp08R2OcKV6fXB3ikPH3n8tM5WTfrETtZcw\n", - "g3QWH0dH7nKNiMkszqo/EDafaHhJ5Bm6ee4UtdAabxnMcmUUl0SnYx+uVqs5XAGN9QGgdeCrASv0\n", - "3TmCsJcOdhnozexD38goK9HXynEKr1OKDs9guhQD039kGySyIQpJAdbvJ9YTlPvyUl3/aLUf34G/\n", - "uGxIyXpE37DoLbAHwJaU53t9MRCfrU8o/k4iRn36Lar8Wd5wAfgN4R6xelyy/ssAAAAASUVORK5C\n", - "YII=\n" - ], - "text/latex": [ - "$$x^{2} z + 2.0 y z - \\cos{\\left (z \\right )}$$" - ], - "text/plain": [ - " 2 \n", - "x \u22c5z + 2.0\u22c5y\u22c5z - cos(z)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "integrate(e, z)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [] - } - ], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/tests/files/notebook2.ipynb b/jupyter_nbconvert/tests/files/notebook2.ipynb deleted file mode 100644 index dd5786e..0000000 --- a/jupyter_nbconvert/tests/files/notebook2.ipynb +++ /dev/null @@ -1,1584 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# NumPy and Matplotlib examples" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First import NumPy and Matplotlib:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "module://IPython.kernel.zmq.pylab.backend_inline\n" - ] - } - ], - "source": [ - "%matplotlib inline\n", - "import matplotlib\n", - "import matplotlib.pyplot as plt\n", - "print(matplotlib.backends.backend)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from IPython.display import set_matplotlib_formats\n", - "set_matplotlib_formats('png', 'pdf')\n", - "matplotlib.rcParams['figure.figsize'] = (2,1)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{matplotlib.figure.Figure: >}" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ip.display_formatter.formatters['application/pdf'].type_printers" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we show some very basic examples of how they can be used." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "a = np.random.uniform(size=(100,100))" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(100, 100)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "evs = np.linalg.eigvals(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(100,)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "evs.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Here is a very long heading that pandoc will wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is a cell that has both text and PNG output:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(array([97, 2, 0, 0, 0, 0, 0, 0, 0, 1]),\n", - " array([ -2.59479443, 2.67371141, 7.94221725, 13.21072308,\n", - " 18.47922892, 23.74773476, 29.0162406 , 34.28474644,\n", - " 39.55325228, 44.82175812, 50.09026395]),\n", - " )" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/pdf": [ - "JVBERi0xLjQKJazcIKu6CjEgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cgL1BhZ2VzIDIgMCBSID4+\n", - "CmVuZG9iago4IDAgb2JqCjw8IC9YT2JqZWN0IDcgMCBSIC9QYXR0ZXJuIDUgMCBSCi9Qcm9jU2V0\n", - "IFsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9FeHRHU3RhdGUgNCAwIFIK\n", - "L1NoYWRpbmcgNiAwIFIgL0ZvbnQgMyAwIFIgPj4KZW5kb2JqCjEwIDAgb2JqCjw8IC9Hcm91cCA8\n", - "PCAvQ1MgL0RldmljZVJHQiAvUyAvVHJhbnNwYXJlbmN5IC9UeXBlIC9Hcm91cCA+PiAvUGFyZW50\n", - "IDIgMCBSCi9NZWRpYUJveCBbIDAgMCAxNTIuMzk4NDM3NSA4Ny4xOTIxODc1IF0gL1Jlc291cmNl\n", - "cyA4IDAgUiAvVHlwZSAvUGFnZQovQ29udGVudHMgOSAwIFIgPj4KZW5kb2JqCjkgMCBvYmoKPDwg\n", - "L0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAxMSAwIFIgPj4Kc3RyZWFtCnicxZi/btwwDMYz\n", - "a+wTCJ3aRSEpiZLGHtAG6FbkgL5AmwTBXYCmQ16/dJycRcWq7SV3k81Pf76fzyZpo703l1/Q3v61\n", - "ZL9bsE8W7ZUBOTpajOR8ycGnKOcHdZ6Tw0KY5fAgojq9Mw+yKA2Lgiv+9WdvZeCVoewCR6ZoCVyk\n", - "jHIkewVw0IYPdTix8y/hao0qKvveiHOhcF5t6qJgqWDPRRXlkwmzm92vHp1g8rYzzf5on8xuby+/\n", - "oUWw+xsjO2L0w+gk06Ld/zKfPn64wAv4bPf39uu+XeGZwITgAuSQCQMVZbtRlHWt1fYbZRNCIAdA\n", - "5F/mnjAWEFiiEb0vlGNSCI2iELRWIzTKJoQYXSglJU7PcyeEpf9BDFAJWDhQZgXRKApCazVEo2yC\n", - "SOiQ0efhCnANQQsQhRz5BNHHhEFBNIqC0FoN0SibICR5QCjxde4E4RcgELLDVAqCTPQ6nzSSwmjE\n", - "mqOVNoEgkCuFwuvkiSQskVBwSDTejKhJGkmTaFGRNNI2Esyu5PLyp9QkcYlkLpHr/K4J5jK8Gr/R\n", - "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\n", - "c+tTOz5911Weq+KfyX7mK9f4ru2/9t5rv3Pdjs+e9Lmxz09d/+ANX/uTxTce/8W5N+Vv+sub/vam\n", - "vTcdutm+uf/m3bc8sXXktk/dduNtk7d/4kuXfelzX/7Uf3vov/3sT/N/etmffvtPX9n2uW3T2/Zv\n", - "e/eO+p32nVfe+fCdu+985c5Df9b1Zz/88xu+kv/K1r84/i+uu2vwbnH3GXdfdvef3f303b+455R7\n", - "7tpe3X7a9s9tv2P7S9v3bP/ZvcvuPePej997yb1X33vjV6/56k1fveOr9311x32R+/L3dd83et9J\n", - "951y30P3/eV9z973/P3x+8v3998/dv/i+z9y/7n3X3j/p+7/wv2333/X/Q/d/5f3P3v/8/f/8P7X\n", - "vrb7a9//2itfe+Nrv35g9IGTHjjlgdUPfOKByx+MPJh/sPvB0QdPevCUB1d/fcnXV339Y1/f9PUr\n", - "v37DQ2se2vjQ5oc+99DWb4x848RvTHzjrG9s+MZl3/jdw+Jh8+GtD08/vPfhAw//7hHxiPlI9pGu\n", - "R0YeOfGRiUfOemTDI5c9cs0jNz1yxyP3PbLj0Tseve/RHY9OPrr7sfHHTntszWMbH9v82Od29O6Y\n", - "u2N8x2k71uzYuGPzjjt23PH4xidGGLbLSFJ4/gGetwHbPiBGW4PDraHh1qDd6p5udQ/vSvvebQ3Z\n", - "rebeXUXfu+KvvFqXb+CvmloO1KdpvoGR2fPnzUn19MydPzY2/yTvvLndjXog2DM2Nmc0nUryLwIG\n", - "UplYLabheG3BPI8VTMfsZNg3VKkMBUaDp4yNLct1NwOB5w5t1P7hkLjq5JOvii3IWaVYNJOI6V2z\n", - "B+eEJhYtP7E6r1FLJOc+7bn4vbs99703iiELoaJ1z196P+3phucXWhBe6XXEDh9qX2Fo6yYXGisN\n", - "zxbajS2TO6PPRT3rpnZHp6P7ot51grZmHe3UOhqhdbQruETNkdlH2r240+5G2e6YbLe90NC2jFsP\n", - "GDuN54wfGK8bbxuBde0rSnxSkk9KO0vPlX5Qer30dimwbmT2B4zzetneQPsKC29xgKJ9mKdvcxgL\n", - "3bF0RoVGZs73nk47fyvbWdleFUPtK2KofQPIlIjZsWrMu2Vqd2w6ti/mxZ2aXavWvKhUY481Dc9q\n", - "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\n", - "8nhdaeWPtzq2X+MRXM7vGlfxRN0HC/abRZ3KRXzGa3d631Ht98JcicgNdcQqKUqZ6E3DnLF1FvY7\n", - "eZnDvTDnpW15FMecizPZO9u9Le+ZJTtX3t783qOrMa9dC84q3FMTcg5yLytRVqPgq8w9vknuOmc/\n", - "PR5lys63JNwR8+s1z9HZPwdhKHH7aW+r6GPj97OSu8K2X3Fa2ae3o0xbVLqupgrbKrRY99j4tDtj\n", - "szhbi6jkd5v8Ph2TI+ZOMtF/8p5ds0iViz6cPx2Sjntotbi/7rZPlYiNdpxxoLjDn8lFuYhrw2Je\n", - "Z2udK6mzrvmTIOGekF89w7S0DL/j19QeWqQrtV5cDS2uvtZppQ1yXP+pe0bnPS1/+i+gju98rx4v\n", - "7czeXuL+0ijin9cn7+Nv/9TQ2TKOUizWcO/Tc6sMS4nLn1z59Zt1PA/PFsu8VhWOKNP+t8+9rojO\n", - "ROTG823graNFjdtWyxJvS1WiP/EsnMM7Tctas9Bpve97vRP973J/lFrpOjj9uah+2dmO8beXQp/v\n", - "3Mln3Hx3lv/5++0zyXJ1ud+2CP+8necX3Ifch638K91VVt7vuOPud93fuI+4q901drWccL/nft/9\n", - "gb0hzbHa/BlvVXusbP0jwn9otflj9/3uF+2NaoG73t3g/sLeGv/enstfdS9bS1+xp/RCu3Pc5P7W\n", - "Pedudn9lb0S6Nz1k7f2ivV1Mtdr3WYxnug9YW5e5j7md7i63y93iFrk33Dfcg9bn/tTa9XV3v40V\n", - "3uvOdZ9zx6zHjLkvu0/buOtZqavdq9Z7honI3e497in3K+6Xjatv2ojhp6xHf8ld6n7T/Yy7xD3v\n", - "VrvPGIfvt3fcJ91vuBesl71p7/prLbojxkLb3Wq9Yb17n3vC/bnb4LvcP7gfcf/oNrrLrYd027vo\n", - "qLvH3et+yb1ld6eL3L+4f3X/5A67R91PuvvcZhsTTrdRRK873092L7pzbOy7xe5Uj9to5bfcr7pn\n", - "bGz4a+4rbprbaiOfP3G3ub90D7hZ7jL3bhsXvWTjytvdt9zF7t/cP7vX3efdu9y33R3uE+6T7lPu\n", - "gPF7p9vmPu62u79zR90Pux3ur92Fforv9j2+10/10/x0P8PP9Of4c/15/nx/gb/QX+Tf5S92j/lL\n", - "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\n", - "2UlrVKk0bv9hjY2seH4AHtCFLgplbmRzdHJlYW0KZW5kb2JqCjEzIDAgb2JqCjw8IC9DSURUb0dJ\n", - "RE1hcCAxNSAwIFIgL0ZvbnREZXNjcmlwdG9yIDEyIDAgUiAvQmFzZUZvbnQgL0F2ZW5pci1Cb29r\n", - "Ci9DSURTeXN0ZW1JbmZvIDw8IC9PcmRlcmluZyAoSWRlbnRpdHkpIC9TdXBwbGVtZW50IDAgL1Jl\n", - "Z2lzdHJ5IChBZG9iZSkgPj4KL1N1YnR5cGUgL0NJREZvbnRUeXBlMiAvVyAxNyAwIFIgL1R5cGUg\n", - "L0ZvbnQgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9FbmNvZGluZyAvSWRlbnRpdHktSCAvQmFzZUZv\n", - "bnQgL0F2ZW5pci1Cb29rCi9EZXNjZW5kYW50Rm9udHMgWyAxMyAwIFIgXSAvU3VidHlwZSAvVHlw\n", - "ZTAgL1RvVW5pY29kZSAxOCAwIFIgL1R5cGUgL0ZvbnQKPj4KZW5kb2JqCjEyIDAgb2JqCjw8IC9E\n", - "ZXNjZW50IC0zNjYgL0ZvbnRCQm94IFsgLTE2NyAtMjg4IDEwMDAgOTQwIF0gL1N0ZW1WIDAgL0Zs\n", - "YWdzIDMyCi9YSGVpZ2h0IDAgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Gb250RmlsZTIgMTYgMCBS\n", - "IC9Gb250TmFtZSAvQXZlbmlyLUJvb2sKL01heFdpZHRoIDY4MiAvQ2FwSGVpZ2h0IDAgL0l0YWxp\n", - "Y0FuZ2xlIDAgL0FzY2VudCAxMDAwID4+CmVuZG9iagoxNyAwIG9iagpbIDQ4ClsgNTY5LjMzMzMz\n", - "MzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMKNTY5LjMz\n", - "MzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgXQo1NiBbIDU2OS4zMzMzMzMz\n", - "MzMzIF0gODcyMiBbIDY4MiBdIF0KZW5kb2JqCjMgMCBvYmoKPDwgL0YxIDE0IDAgUiA+PgplbmRv\n", - "YmoKNCAwIG9iago8PCAvQTEgPDwgL0NBIDAgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMCA+PgovQTIg\n", - "PDwgL0NBIDEgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMSA+PiA+PgplbmRvYmoKNSAwIG9iago8PCA+\n", - "PgplbmRvYmoKNiAwIG9iago8PCA+PgplbmRvYmoKNyAwIG9iago8PCA+PgplbmRvYmoKMiAwIG9i\n", - "ago8PCAvQ291bnQgMSAvS2lkcyBbIDEwIDAgUiBdIC9UeXBlIC9QYWdlcyA+PgplbmRvYmoKMjEg\n", - "MCBvYmoKPDwgL0NyZWF0aW9uRGF0ZSAoRDoyMDE0MDIyMDE3NTMyNS0wNycwMCcpCi9Qcm9kdWNl\n", - "ciAobWF0cGxvdGxpYiBwZGYgYmFja2VuZCkKL0NyZWF0b3IgKG1hdHBsb3RsaWIgMS4xLjEsIGh0\n", - "dHA6Ly9tYXRwbG90bGliLnNmLm5ldCkgPj4KZW5kb2JqCnhyZWYKMCAyMgowMDAwMDAwMDAwIDY1\n", - "NTM1IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDA3MzYzOCAwMDAwMCBuIAowMDAwMDczNDQ0\n", - "IDAwMDAwIG4gCjAwMDAwNzM0NzYgMDAwMDAgbiAKMDAwMDA3MzU3NSAwMDAwMCBuIAowMDAwMDcz\n", - "NTk2IDAwMDAwIG4gCjAwMDAwNzM2MTcgMDAwMDAgbiAKMDAwMDAwMDA2NSAwMDAwMCBuIAowMDAw\n", - "MDAwMzg4IDAwMDAwIG4gCjAwMDAwMDAyMDggMDAwMDAgbiAKMDAwMDAwMTMzMyAwMDAwMCBuIAow\n", - "MDAwMDczMDYwIDAwMDAwIG4gCjAwMDAwNzI3MTIgMDAwMDAgbiAKMDAwMDA3MjkxOSAwMDAwMCBu\n", - "IAowMDAwMDcyMjM5IDAwMDAwIG4gCjAwMDAwMDEzNTMgMDAwMDAgbiAKMDAwMDA3MzI3NyAwMDAw\n", - "MCBuIAowMDAwMDcyMzc4IDAwMDAwIG4gCjAwMDAwNzIyMTYgMDAwMDAgbiAKMDAwMDA3MjE5NCAw\n", - "MDAwMCBuIAowMDAwMDczNjk4IDAwMDAwIG4gCnRyYWlsZXIKPDwgL0luZm8gMjEgMCBSIC9Sb290\n", - "IDEgMCBSIC9TaXplIDIyID4+CnN0YXJ0eHJlZgo3Mzg0OQolJUVPRgo=\n" - ], - "image/png": [ - "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\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.hist(evs.real)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```python\n", - "def foo(bar=1):\n", - " \"\"\"docstring\"\"\"\n", - " raise Exception(\"message\")\n", - "```" - ] - } - ], - "metadata": { - "signature": "sha256:9fffd84e69e3d9b8aee7b4cde2099ca5d4158a45391698b191f94fabaf394b41" - }, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/jupyter_nbconvert/tests/files/override.py b/jupyter_nbconvert/tests/files/override.py deleted file mode 100644 index f0bc77a..0000000 --- a/jupyter_nbconvert/tests/files/override.py +++ /dev/null @@ -1,6 +0,0 @@ -c = get_config() - -#Export all the notebooks in the current directory to the sphinx_howto format. -c.NbConvertApp.notebooks = ['notebook2.ipynb'] -c.NbConvertApp.export_format = 'python' - diff --git a/jupyter_nbconvert/tests/test_nbconvertapp.py b/jupyter_nbconvert/tests/test_nbconvertapp.py deleted file mode 100644 index e81aef5..0000000 --- a/jupyter_nbconvert/tests/test_nbconvertapp.py +++ /dev/null @@ -1,243 +0,0 @@ -# -*- coding: utf-8 -*- -"""Test NbConvertApp""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import os -import glob -import sys - -from .base import TestsBase -from ..postprocessors import PostProcessorBase - -from traitlets.tests.utils import check_help_all_output -from IPython.testing import decorators as dec - -#----------------------------------------------------------------------------- -# Classes and functions -#----------------------------------------------------------------------------- - -class DummyPost(PostProcessorBase): - def postprocess(self, filename): - print("Dummy:%s" % filename) - -class TestNbConvertApp(TestsBase): - """Collection of NbConvertApp tests""" - - - def test_notebook_help(self): - """Will help show if no notebooks are specified?""" - with self.create_temp_cwd(): - out, err = self.nbconvert('--log-level 0', ignore_return_code=True) - self.assertIn("see '--help-all'", out) - - def test_help_output(self): - """ipython nbconvert --help-all works""" - check_help_all_output('jupyter_nbconvert') - - def test_glob(self): - """ - Do search patterns work for notebook names? - """ - with self.create_temp_cwd(['notebook*.ipynb']): - self.nbconvert('--to python *.ipynb --log-level 0') - assert os.path.isfile('notebook1.py') - assert os.path.isfile('notebook2.py') - - - def test_glob_subdir(self): - """ - Do search patterns work for subdirectory notebook names? - """ - with self.create_temp_cwd(): - self.copy_files_to(['notebook*.ipynb'], 'subdir/') - self.nbconvert('--to python --log-level 0 ' + - os.path.join('subdir', '*.ipynb')) - assert os.path.isfile('notebook1.py') - assert os.path.isfile('notebook2.py') - - - def test_explicit(self): - """ - Do explicit notebook names work? - """ - with self.create_temp_cwd(['notebook*.ipynb']): - self.nbconvert('--log-level 0 --to python notebook2') - assert not os.path.isfile('notebook1.py') - assert os.path.isfile('notebook2.py') - - - @dec.onlyif_cmds_exist('pdflatex') - @dec.onlyif_cmds_exist('pandoc') - def test_filename_spaces(self): - """ - Generate PDFs with graphics if notebooks have spaces in the name? - """ - with self.create_temp_cwd(['notebook2.ipynb']): - os.rename('notebook2.ipynb', 'notebook with spaces.ipynb') - self.nbconvert('--log-level 0 --to pdf' - ' "notebook with spaces"' - ' --PDFExporter.latex_count=1' - ' --PDFExporter.verbose=True' - ) - assert os.path.isfile('notebook with spaces.pdf') - - def test_post_processor(self): - """Do post processors work?""" - with self.create_temp_cwd(['notebook1.ipynb']): - out, err = self.nbconvert('--log-level 0 --to python notebook1 ' - '--post jupyter_nbconvert.tests.test_nbconvertapp.DummyPost') - self.assertIn('Dummy:notebook1.py', out) - - @dec.onlyif_cmds_exist('pandoc') - def test_spurious_cr(self): - """Check for extra CR characters""" - with self.create_temp_cwd(['notebook2.ipynb']): - self.nbconvert('--log-level 0 --to latex notebook2') - assert os.path.isfile('notebook2.tex') - with open('notebook2.tex') as f: - tex = f.read() - self.nbconvert('--log-level 0 --to html notebook2') - assert os.path.isfile('notebook2.html') - with open('notebook2.html') as f: - html = f.read() - self.assertEqual(tex.count('\r'), tex.count('\r\n')) - self.assertEqual(html.count('\r'), html.count('\r\n')) - - @dec.onlyif_cmds_exist('pandoc') - def test_png_base64_html_ok(self): - """Is embedded png data well formed in HTML?""" - with self.create_temp_cwd(['notebook2.ipynb']): - self.nbconvert('--log-level 0 --to HTML ' - 'notebook2.ipynb --template full') - assert os.path.isfile('notebook2.html') - with open('notebook2.html') as f: - assert "data:image/png;base64,b'" not in f.read() - - @dec.onlyif_cmds_exist('pandoc') - def test_template(self): - """ - Do export templates work? - """ - with self.create_temp_cwd(['notebook2.ipynb']): - self.nbconvert('--log-level 0 --to slides ' - 'notebook2.ipynb') - assert os.path.isfile('notebook2.slides.html') - with open('notebook2.slides.html') as f: - assert '/reveal.css' in f.read() - - def test_output_ext(self): - """test --output=outputfile[.ext]""" - with self.create_temp_cwd(['notebook1.ipynb']): - self.nbconvert('--log-level 0 --to python ' - 'notebook1.ipynb --output nb.py') - assert os.path.exists('nb.py') - - self.nbconvert('--log-level 0 --to python ' - 'notebook1.ipynb --output nb2') - assert os.path.exists('nb2.py') - - def test_glob_explicit(self): - """ - Can a search pattern be used along with matching explicit notebook names? - """ - with self.create_temp_cwd(['notebook*.ipynb']): - self.nbconvert('--log-level 0 --to python ' - '*.ipynb notebook1.ipynb notebook2.ipynb') - assert os.path.isfile('notebook1.py') - assert os.path.isfile('notebook2.py') - - - def test_explicit_glob(self): - """ - Can explicit notebook names be used and then a matching search pattern? - """ - with self.create_temp_cwd(['notebook*.ipynb']): - self.nbconvert('--log-level 0 --to=python ' - 'notebook1.ipynb notebook2.ipynb *.ipynb') - assert os.path.isfile('notebook1.py') - assert os.path.isfile('notebook2.py') - - - def test_default_config(self): - """ - Does the default config work? - """ - with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']): - self.nbconvert('--log-level 0') - assert os.path.isfile('notebook1.py') - assert not os.path.isfile('notebook2.py') - - - def test_override_config(self): - """ - Can the default config be overriden? - """ - with self.create_temp_cwd(['notebook*.ipynb', - 'ipython_nbconvert_config.py', - 'override.py']): - self.nbconvert('--log-level 0 --config="override.py"') - assert not os.path.isfile('notebook1.py') - assert os.path.isfile('notebook2.py') - - def test_accents_in_filename(self): - """ - Can notebook names include accents? - """ - with self.create_temp_cwd(): - self.create_empty_notebook(u'nb1_análisis.ipynb') - self.nbconvert('--log-level 0 --to python nb1_*') - assert os.path.isfile(u'nb1_análisis.py') - - @dec.onlyif_cmds_exist('pdflatex', 'pandoc') - def test_filename_accent_pdf(self): - """ - Generate PDFs if notebooks have an accent in their name? - """ - with self.create_temp_cwd(): - self.create_empty_notebook(u'nb1_análisis.ipynb') - self.nbconvert('--log-level 0 --to pdf "nb1_*"' - ' --PDFExporter.latex_count=1' - ' --PDFExporter.verbose=True') - assert os.path.isfile(u'nb1_análisis.pdf') - - def test_cwd_plugin(self): - """ - Verify that an extension in the cwd can be imported. - """ - with self.create_temp_cwd(['hello.py']): - self.create_empty_notebook(u'empty.ipynb') - self.nbconvert('empty --to html --NbConvertApp.writer_class=\'hello.HelloWriter\'') - assert os.path.isfile(u'hello.txt') - - def test_output_suffix(self): - """ - Verify that the output suffix is applied - """ - with self.create_temp_cwd(): - self.create_empty_notebook('empty.ipynb') - self.nbconvert('empty.ipynb --to notebook') - assert os.path.isfile('empty.nbconvert.ipynb') - - def test_different_build_dir(self): - """ - Verify that the output suffix is not applied - """ - with self.create_temp_cwd(): - self.create_empty_notebook('empty.ipynb') - os.mkdir('output') - self.nbconvert( - 'empty.ipynb --to notebook ' - '--FilesWriter.build_directory=output') - assert os.path.isfile('output/empty.ipynb') - - def test_inplace(self): - """ - Verify that the notebook is converted in place - """ - with self.create_temp_cwd(): - self.create_empty_notebook('empty.ipynb') - self.nbconvert('empty.ipynb --to notebook --inplace') - assert os.path.isfile('empty.ipynb') - assert not os.path.isfile('empty.nbconvert.ipynb') diff --git a/jupyter_nbconvert/utils/__init__.py b/jupyter_nbconvert/utils/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_nbconvert/utils/__init__.py +++ /dev/null diff --git a/jupyter_nbconvert/utils/base.py b/jupyter_nbconvert/utils/base.py deleted file mode 100644 index c26b235..0000000 --- a/jupyter_nbconvert/utils/base.py +++ /dev/null @@ -1,29 +0,0 @@ -"""Global configuration class.""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from IPython.utils.traitlets import List -from IPython.config.configurable import LoggingConfigurable -from IPython.utils.traitlets import Unicode - -class NbConvertBase(LoggingConfigurable): - """Global configurable class for shared config - - Useful for display data priority that might be use by many transformers - """ - - display_data_priority = List(['text/html', 'application/pdf', 'text/latex', 'image/svg+xml', 'image/png', 'image/jpeg', 'text/plain'], - config=True, - help= """ - An ordered list of preferred output type, the first - encountered will usually be used when converting discarding - the others. - """ - ) - - default_language = Unicode('ipython', config=True, - help='DEPRECATED default highlight language, please use language_info metadata instead') - - def __init__(self, **kw): - super(NbConvertBase, self).__init__(**kw) diff --git a/jupyter_nbconvert/utils/exceptions.py b/jupyter_nbconvert/utils/exceptions.py deleted file mode 100644 index 6a4e0e6..0000000 --- a/jupyter_nbconvert/utils/exceptions.py +++ /dev/null @@ -1,17 +0,0 @@ -"""NbConvert specific exceptions""" -#----------------------------------------------------------------------------- -# 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. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Classes and functions -#----------------------------------------------------------------------------- - -class ConversionException(Exception): - """An exception raised by the conversion process.""" - - pass \ No newline at end of file diff --git a/jupyter_nbconvert/utils/io.py b/jupyter_nbconvert/utils/io.py deleted file mode 100644 index c03ec7b..0000000 --- a/jupyter_nbconvert/utils/io.py +++ /dev/null @@ -1,33 +0,0 @@ -# coding: utf-8 -"""io-related utilities""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import codecs -import sys -from IPython.utils.py3compat import PY3 - - -def unicode_std_stream(stream='stdout'): - u"""Get a wrapper to write unicode to stdout/stderr as UTF-8. - - This ignores environment variables and default encodings, to reliably write - unicode to stdout or stderr. - - :: - - unicode_std_stream().write(u'ł@e¶ŧ←') - """ - assert stream in ('stdout', 'stderr') - stream = getattr(sys, stream) - if PY3: - try: - stream_b = stream.buffer - except AttributeError: - # sys.stdout has been replaced - use it directly - return stream - else: - stream_b = stream - - return codecs.getwriter('utf-8')(stream_b) diff --git a/jupyter_nbconvert/utils/lexers.py b/jupyter_nbconvert/utils/lexers.py deleted file mode 100644 index 063e892..0000000 --- a/jupyter_nbconvert/utils/lexers.py +++ /dev/null @@ -1,3 +0,0 @@ -"""Deprecated; import from IPython.lib.lexers instead.""" - -from IPython.lib.lexers import * diff --git a/jupyter_nbconvert/utils/pandoc.py b/jupyter_nbconvert/utils/pandoc.py deleted file mode 100644 index 35506d9..0000000 --- a/jupyter_nbconvert/utils/pandoc.py +++ /dev/null @@ -1,127 +0,0 @@ -"""Utility for calling pandoc""" -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from __future__ import print_function, absolute_import - -import subprocess -import warnings -import re -from io import TextIOWrapper, BytesIO - -from jupyter_nbconvert.utils.version import check_version -from IPython.utils.py3compat import cast_bytes, which - -from .exceptions import ConversionException - -_minimal_version = "1.12.1" - -def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'): - """Convert an input string in format `from` to format `to` via pandoc. - - Parameters - ---------- - source : string - Input string, assumed to be valid format `from`. - fmt : string - The name of the input format (markdown, etc.) - to : string - The name of the output format (html, etc.) - - Returns - ------- - out : unicode - Output as returned by pandoc. - - Raises - ------ - PandocMissing - If pandoc is not installed. - - Any error messages generated by pandoc are printed to stderr. - - """ - cmd = ['pandoc', '-f', fmt, '-t', to] - if extra_args: - cmd.extend(extra_args) - - # this will raise an exception that will pop us out of here - check_pandoc_version() - - # we can safely continue - p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - out, _ = p.communicate(cast_bytes(source, encoding)) - out = TextIOWrapper(BytesIO(out), encoding, 'replace').read() - return out.rstrip('\n') - - -def get_pandoc_version(): - """Gets the Pandoc version if Pandoc is installed. - - If the minimal version is not met, it will probe Pandoc for its version, cache it and return that value. - If the minimal version is met, it will return the cached version and stop probing Pandoc - (unless :func:`clean_cache()` is called). - - Raises - ------ - PandocMissing - If pandoc is unavailable. - """ - global __version - - if __version is None: - if not which('pandoc'): - raise PandocMissing() - - out = subprocess.check_output(['pandoc', '-v'], - universal_newlines=True) - out_lines = out.splitlines() - version_pattern = re.compile(r"^\d+(\.\d+){1,}$") - for tok in out_lines[0].split(): - if version_pattern.match(tok): - __version = tok - break - return __version - - -def check_pandoc_version(): - """Returns True if minimal pandoc version is met. - - Raises - ------ - PandocMissing - If pandoc is unavailable. - """ - v = get_pandoc_version() - if v is None: - warnings.warn("Sorry, we cannot determine the version of pandoc.\n" - "Please consider reporting this issue and include the" - "output of pandoc --version.\nContinuing...", - RuntimeWarning, stacklevel=2) - return False - ok = check_version(v , _minimal_version ) - if not ok: - warnings.warn( "You are using an old version of pandoc (%s)\n" % v + - "Recommended version is %s.\nTry updating." % _minimal_version + - "http://johnmacfarlane.net/pandoc/installing.html.\nContinuing with doubts...", - RuntimeWarning, stacklevel=2) - return ok - -#----------------------------------------------------------------------------- -# Exception handling -#----------------------------------------------------------------------------- -class PandocMissing(ConversionException): - """Exception raised when Pandoc is missing. """ - def __init__(self, *args, **kwargs): - super(PandocMissing, self).__init__( "Pandoc wasn't found.\n" + - "Please check that pandoc is installed:\n" + - "http://johnmacfarlane.net/pandoc/installing.html" ) - -#----------------------------------------------------------------------------- -# Internal state management -#----------------------------------------------------------------------------- -def clean_cache(): - global __version - __version = None - -__version = None diff --git a/jupyter_nbconvert/utils/tests/__init__.py b/jupyter_nbconvert/utils/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_nbconvert/utils/tests/__init__.py +++ /dev/null diff --git a/jupyter_nbconvert/utils/tests/test_io.py b/jupyter_nbconvert/utils/tests/test_io.py deleted file mode 100644 index 6c4af00..0000000 --- a/jupyter_nbconvert/utils/tests/test_io.py +++ /dev/null @@ -1,50 +0,0 @@ -# encoding: utf-8 -"""Tests for utils.io""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import io as stdlib_io -import sys - -import nose.tools as nt - -from IPython.testing.decorators import skipif -from ..io import unicode_std_stream -from IPython.utils.py3compat import PY3 - -if PY3: - from io import StringIO -else: - from StringIO import StringIO - -def test_UnicodeStdStream(): - # Test wrapping a bytes-level stdout - if PY3: - stdoutb = stdlib_io.BytesIO() - stdout = stdlib_io.TextIOWrapper(stdoutb, encoding='ascii') - else: - stdout = stdoutb = stdlib_io.BytesIO() - - orig_stdout = sys.stdout - sys.stdout = stdout - try: - sample = u"@łe¶ŧ←" - unicode_std_stream().write(sample) - - output = stdoutb.getvalue().decode('utf-8') - nt.assert_equal(output, sample) - assert not stdout.closed - finally: - sys.stdout = orig_stdout - -@skipif(not PY3, "Not applicable on Python 2") -def test_UnicodeStdStream_nowrap(): - # If we replace stdout with a StringIO, it shouldn't get wrapped. - orig_stdout = sys.stdout - sys.stdout = StringIO() - try: - nt.assert_is(unicode_std_stream(), sys.stdout) - assert not sys.stdout.closed - finally: - sys.stdout = orig_stdout diff --git a/jupyter_nbconvert/utils/tests/test_lexers.py b/jupyter_nbconvert/utils/tests/test_lexers.py deleted file mode 100644 index 97e7ada..0000000 --- a/jupyter_nbconvert/utils/tests/test_lexers.py +++ /dev/null @@ -1,131 +0,0 @@ -"""Test lexers module""" -#----------------------------------------------------------------------------- -# Copyright (C) 2014 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- -from pygments.token import Token - -from jupyter_nbconvert.tests.base import TestsBase -from .. import lexers - - -#----------------------------------------------------------------------------- -# Classes and functions -#----------------------------------------------------------------------------- -class TestLexers(TestsBase): - """Collection of lexers tests""" - def setUp(self): - self.lexer = lexers.IPythonLexer() - - def testIPythonLexer(self): - fragment = '!echo $HOME\n' - tokens = [ - (Token.Operator, '!'), - (Token.Name.Builtin, 'echo'), - (Token.Text, ' '), - (Token.Name.Variable, '$HOME'), - (Token.Text, '\n'), - ] - self.assertEqual(tokens, list(self.lexer.get_tokens(fragment))) - - fragment_2 = '!' + fragment - tokens_2 = [ - (Token.Operator, '!!'), - ] + tokens[1:] - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = '\t %%!\n' + fragment[1:] - tokens_2 = [ - (Token.Text, '\t '), - (Token.Operator, '%%!'), - (Token.Text, '\n'), - ] + tokens[1:] - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = 'x = ' + fragment - tokens_2 = [ - (Token.Name, 'x'), - (Token.Text, ' '), - (Token.Operator, '='), - (Token.Text, ' '), - ] + tokens - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = 'x, = ' + fragment - tokens_2 = [ - (Token.Name, 'x'), - (Token.Punctuation, ','), - (Token.Text, ' '), - (Token.Operator, '='), - (Token.Text, ' '), - ] + tokens - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = 'x, = %sx ' + fragment[1:] - tokens_2 = [ - (Token.Name, 'x'), - (Token.Punctuation, ','), - (Token.Text, ' '), - (Token.Operator, '='), - (Token.Text, ' '), - (Token.Operator, '%'), - (Token.Keyword, 'sx'), - (Token.Text, ' '), - ] + tokens[1:] - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = 'f = %R function () {}\n' - tokens_2 = [ - (Token.Name, 'f'), - (Token.Text, ' '), - (Token.Operator, '='), - (Token.Text, ' '), - (Token.Operator, '%'), - (Token.Keyword, 'R'), - (Token.Text, ' function () {}\n'), - ] - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = '\t%%xyz\n$foo\n' - tokens_2 = [ - (Token.Text, '\t'), - (Token.Operator, '%%'), - (Token.Keyword, 'xyz'), - (Token.Text, '\n$foo\n'), - ] - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = '%system?\n' - tokens_2 = [ - (Token.Operator, '%'), - (Token.Keyword, 'system'), - (Token.Operator, '?'), - (Token.Text, '\n'), - ] - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = 'x != y\n' - tokens_2 = [ - (Token.Name, 'x'), - (Token.Text, ' '), - (Token.Operator, '!='), - (Token.Text, ' '), - (Token.Name, 'y'), - (Token.Text, '\n'), - ] - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) - - fragment_2 = ' ?math.sin\n' - tokens_2 = [ - (Token.Text, ' '), - (Token.Operator, '?'), - (Token.Text, 'math.sin'), - (Token.Text, '\n'), - ] - self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) diff --git a/jupyter_nbconvert/utils/tests/test_pandoc.py b/jupyter_nbconvert/utils/tests/test_pandoc.py deleted file mode 100644 index cb220ba..0000000 --- a/jupyter_nbconvert/utils/tests/test_pandoc.py +++ /dev/null @@ -1,70 +0,0 @@ -"""Test Pandoc module""" -#----------------------------------------------------------------------------- -# Copyright (C) 2014 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- -import os -import warnings - -from IPython.testing import decorators as dec - -from jupyter_nbconvert.tests.base import TestsBase -from .. import pandoc - -#----------------------------------------------------------------------------- -# Classes and functions -#----------------------------------------------------------------------------- -class TestPandoc(TestsBase): - """Collection of Pandoc tests""" - - def __init__(self, *args, **kwargs): - super(TestPandoc, self).__init__(*args, **kwargs) - self.original_env = os.environ.copy() - - @dec.onlyif_cmds_exist('pandoc') - def test_pandoc_available(self): - """ Test behaviour that pandoc functions raise PandocMissing as documented """ - pandoc.clean_cache() - - os.environ["PATH"] = "" - with self.assertRaises(pandoc.PandocMissing): - pandoc.get_pandoc_version() - with self.assertRaises(pandoc.PandocMissing): - pandoc.check_pandoc_version() - with self.assertRaises(pandoc.PandocMissing): - pandoc.pandoc("", "markdown", "html") - - # original_env["PATH"] should contain pandoc - os.environ["PATH"] = self.original_env["PATH"] - with warnings.catch_warnings(record=True) as w: - pandoc.get_pandoc_version() - pandoc.check_pandoc_version() - pandoc.pandoc("", "markdown", "html") - self.assertEqual(w, []) - - @dec.onlyif_cmds_exist('pandoc') - def test_minimal_version(self): - original_minversion = pandoc._minimal_version - - pandoc._minimal_version = "120.0" - with warnings.catch_warnings(record=True) as w: - assert not pandoc.check_pandoc_version() - self.assertEqual(len(w), 1) - - pandoc._minimal_version = pandoc.get_pandoc_version() - assert pandoc.check_pandoc_version() - - -def pandoc_function_raised_missing(f, *args, **kwargs): - try: - f(*args, **kwargs) - except pandoc.PandocMissing: - return True - else: - return False diff --git a/jupyter_nbconvert/utils/version.py b/jupyter_nbconvert/utils/version.py deleted file mode 100644 index 7d71479..0000000 --- a/jupyter_nbconvert/utils/version.py +++ /dev/null @@ -1,25 +0,0 @@ -# encoding: utf-8 -""" -Utilities for version comparison - -It is a bit ridiculous that we need these. -""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -from distutils.version import LooseVersion - - -def check_version(v, check): - """check version string v >= check - - If dev/prerelease tags result in TypeError for string-number comparison, - it is assumed that the dependency is satisfied. - Users on dev branches are responsible for keeping their own packages up to date. - """ - try: - return LooseVersion(v) >= LooseVersion(check) - except TypeError: - return True - diff --git a/jupyter_nbconvert/writers/__init__.py b/jupyter_nbconvert/writers/__init__.py deleted file mode 100644 index 2b678f2..0000000 --- a/jupyter_nbconvert/writers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .files import FilesWriter -from .stdout import StdoutWriter -from .base import WriterBase diff --git a/jupyter_nbconvert/writers/base.py b/jupyter_nbconvert/writers/base.py deleted file mode 100644 index 75fd3de..0000000 --- a/jupyter_nbconvert/writers/base.py +++ /dev/null @@ -1,56 +0,0 @@ -""" -Contains writer base class. -""" -#----------------------------------------------------------------------------- -#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 IPython.utils.traitlets import List - -from ..utils.base import NbConvertBase - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class WriterBase(NbConvertBase): - """Consumes output from nbconvert export...() methods and writes to a - useful location. """ - - - files = List([], config=True, help=""" - List of the files that the notebook references. Files will be - included with written output.""") - - - def __init__(self, config=None, **kw): - """ - Constructor - """ - super(WriterBase, self).__init__(config=config, **kw) - - - def write(self, output, resources, **kw): - """ - Consume and write Jinja output. - - Parameters - ---------- - output : string - Conversion results. This string contains the file contents of the - converted file. - resources : dict - Resources created and filled by the nbconvert conversion process. - Includes output from preprocessors, such as the extract figure - preprocessor. - """ - - raise NotImplementedError() diff --git a/jupyter_nbconvert/writers/debug.py b/jupyter_nbconvert/writers/debug.py deleted file mode 100644 index 85cc24b..0000000 --- a/jupyter_nbconvert/writers/debug.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Contains debug writer. -""" -from __future__ import print_function -#----------------------------------------------------------------------------- -#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 .base import WriterBase -from pprint import pprint - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class DebugWriter(WriterBase): - """Consumes output from nbconvert export...() methods and writes usefull - debugging information to the stdout. The information includes a list of - resources that were extracted from the notebook(s) during export.""" - - - def write(self, output, resources, notebook_name='notebook', **kw): - """ - Consume and write Jinja output. - - See base for more... - """ - - if isinstance(resources['outputs'], dict): - print("outputs extracted from %s" % notebook_name) - print('-' * 80) - pprint(resources['outputs'], indent=2, width=70) - else: - print("no outputs extracted from %s" % notebook_name) - print('=' * 80) diff --git a/jupyter_nbconvert/writers/files.py b/jupyter_nbconvert/writers/files.py deleted file mode 100644 index f94a790..0000000 --- a/jupyter_nbconvert/writers/files.py +++ /dev/null @@ -1,135 +0,0 @@ -"""Contains writer for writing nbconvert output to filesystem.""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import io -import os -import glob - -from IPython.utils.traitlets import Unicode -from IPython.utils.path import link_or_copy, ensure_dir_exists -from IPython.utils.py3compat import unicode_type - -from .base import WriterBase - -#----------------------------------------------------------------------------- -# Classes -#----------------------------------------------------------------------------- - -class FilesWriter(WriterBase): - """Consumes nbconvert output and produces files.""" - - - build_directory = Unicode("", config=True, - help="""Directory to write output to. Leave blank - to output to the current directory""") - - relpath = Unicode( - "", config=True, - help="""When copying files that the notebook depends on, copy them in - relation to this path, such that the destination filename will be - os.path.relpath(filename, relpath). If FilesWriter is operating on a - notebook that already exists elsewhere on disk, then the default will be - the directory containing that notebook.""") - - - # Make sure that the output directory exists. - def _build_directory_changed(self, name, old, new): - if new: - ensure_dir_exists(new) - - - def __init__(self, **kw): - super(FilesWriter, self).__init__(**kw) - self._build_directory_changed('build_directory', self.build_directory, - self.build_directory) - - def _makedir(self, path): - """Make a directory if it doesn't already exist""" - if path: - self.log.info("Making directory %s", path) - ensure_dir_exists(path) - - def write(self, output, resources, notebook_name=None, **kw): - """ - Consume and write Jinja output to the file system. Output directory - is set via the 'build_directory' variable of this instance (a - configurable). - - See base for more... - """ - - # Verify that a notebook name is provided. - if notebook_name is None: - raise TypeError('notebook_name') - - # Pull the extension and subdir from the resources dict. - output_extension = resources.get('output_extension', None) - - # Get the relative path for copying files - if self.relpath == '': - relpath = resources.get('metadata', {}).get('path', '') - else: - relpath = self.relpath - - # Write all of the extracted resources to the destination directory. - # NOTE: WE WRITE EVERYTHING AS-IF IT'S BINARY. THE EXTRACT FIG - # PREPROCESSOR SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS... - - items = resources.get('outputs', {}).items() - if items: - self.log.info("Support files will be in %s", os.path.join(resources.get('output_files_dir',''), '')) - for filename, data in items: - - # Determine where to write the file to - dest = os.path.join(self.build_directory, filename) - path = os.path.dirname(dest) - self._makedir(path) - - # Write file - self.log.debug("Writing %i bytes to support file %s", len(data), dest) - with io.open(dest, 'wb') as f: - f.write(data) - - # Copy referenced files to output directory - if self.build_directory: - for filename in self.files: - - # Copy files that match search pattern - for matching_filename in glob.glob(filename): - - # compute the relative path for the filename - if relpath != '': - dest_filename = os.path.relpath(matching_filename, relpath) - else: - dest_filename = matching_filename - - # Make sure folder exists. - dest = os.path.join(self.build_directory, dest_filename) - path = os.path.dirname(dest) - self._makedir(path) - - # Copy if destination is different. - if not os.path.normpath(dest) == os.path.normpath(matching_filename): - self.log.info("Linking %s -> %s", matching_filename, dest) - link_or_copy(matching_filename, dest) - - # Determine where to write conversion results. - if output_extension is not None: - dest = notebook_name + output_extension - else: - dest = notebook_name - if self.build_directory: - dest = os.path.join(self.build_directory, dest) - - # Write conversion results. - self.log.info("Writing %i bytes to %s", len(output), dest) - if isinstance(output, unicode_type): - with io.open(dest, 'w', encoding='utf-8') as f: - f.write(output) - else: - with io.open(dest, 'wb') as f: - f.write(output) - - return dest diff --git a/jupyter_nbconvert/writers/stdout.py b/jupyter_nbconvert/writers/stdout.py deleted file mode 100644 index 6970219..0000000 --- a/jupyter_nbconvert/writers/stdout.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -Contains Stdout writer -""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -from jupyter_nbconvert.utils import io -from .base import WriterBase - - -class StdoutWriter(WriterBase): - """Consumes output from nbconvert export...() methods and writes to the - stdout stream.""" - - - def write(self, output, resources, **kw): - """ - Consume and write Jinja output. - - See base for more... - """ - io.unicode_std_stream().write(output) diff --git a/jupyter_nbconvert/writers/tests/__init__.py b/jupyter_nbconvert/writers/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_nbconvert/writers/tests/__init__.py +++ /dev/null diff --git a/jupyter_nbconvert/writers/tests/test_debug.py b/jupyter_nbconvert/writers/tests/test_debug.py deleted file mode 100644 index 81bf4f5..0000000 --- a/jupyter_nbconvert/writers/tests/test_debug.py +++ /dev/null @@ -1,56 +0,0 @@ -""" -Module with tests for debug -""" - -#----------------------------------------------------------------------------- -# 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 -#----------------------------------------------------------------------------- - -import sys - -from ...tests.base import TestsBase -from ..debug import DebugWriter -from IPython.utils.py3compat import PY3 - -if PY3: - from io import StringIO -else: - from StringIO import StringIO - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestDebug(TestsBase): - """Contains test functions for debug.py""" - - def test_output(self): - """Test debug writer output.""" - - # Capture the stdout. Remember original. - stdout = sys.stdout - stream = StringIO() - sys.stdout = stream - - # Create stdout writer, get output - writer = DebugWriter() - writer.write('aaa', {'outputs': {'bbb': 'ccc'}}) - output = stream.getvalue() - - # Check output. Make sure resources dictionary is dumped, but nothing - # else. - assert 'aaa' not in output - assert 'bbb' in output - assert 'ccc' in output - - # Revert stdout - sys.stdout = stdout \ No newline at end of file diff --git a/jupyter_nbconvert/writers/tests/test_files.py b/jupyter_nbconvert/writers/tests/test_files.py deleted file mode 100644 index 0f4c2f6..0000000 --- a/jupyter_nbconvert/writers/tests/test_files.py +++ /dev/null @@ -1,307 +0,0 @@ -""" -Module with tests for files -""" - -#----------------------------------------------------------------------------- -# 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 -#----------------------------------------------------------------------------- - -import sys -import os - -from ...tests.base import TestsBase -from ..files import FilesWriter -from IPython.utils.py3compat import PY3 - -if PY3: - from io import StringIO -else: - from StringIO import StringIO - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class Testfiles(TestsBase): - """Contains test functions for files.py""" - - def test_basic_output(self): - """Is FilesWriter basic output correct?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create the resoruces dictionary - res = {} - - # Create files writer, test output - writer = FilesWriter() - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - with open('z', 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - def test_ext(self): - """Does the FilesWriter add the correct extension to the output?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create the resoruces dictionary - res = {'output_extension': '.txt'} - - # Create files writer, test output - writer = FilesWriter() - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - assert os.path.isfile('z.txt') - with open('z.txt', 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - - def test_extract(self): - """Can FilesWriter write extracted figures correctly?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create the resoruces dictionary - res = {'outputs': {os.path.join('z_files', 'a'): b'b'}} - - # Create files writer, test output - writer = FilesWriter() - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - with open('z', 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - # Check the output of the extracted file - extracted_file_dest = os.path.join('z_files', 'a') - assert os.path.isfile(extracted_file_dest) - with open(extracted_file_dest, 'r') as f: - output = f.read() - self.assertEqual(output, 'b') - - - def test_builddir(self): - """Can FilesWriter write to a build dir correctly?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create the resoruces dictionary - res = {'outputs': {os.path.join('z_files', 'a'): b'b'}} - - # Create files writer, test output - writer = FilesWriter() - writer.build_directory = u'build' - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - assert os.path.isdir(writer.build_directory) - dest = os.path.join(writer.build_directory, 'z') - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - # Check the output of the extracted file - extracted_file_dest = os.path.join(writer.build_directory, 'z_files', 'a') - assert os.path.isfile(extracted_file_dest) - with open(extracted_file_dest, 'r') as f: - output = f.read() - self.assertEqual(output, 'b') - - - def test_links(self): - """Can the FilesWriter handle linked files correctly?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create test file - os.mkdir('sub') - with open(os.path.join('sub', 'c'), 'w') as f: - f.write('d') - - # Create the resoruces dictionary - res = {} - - # Create files writer, test output - writer = FilesWriter() - writer.files = [os.path.join('sub', 'c')] - writer.build_directory = u'build' - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - assert os.path.isdir(writer.build_directory) - dest = os.path.join(writer.build_directory, 'z') - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - # Check to make sure the linked file was copied - path = os.path.join(writer.build_directory, 'sub') - assert os.path.isdir(path) - dest = os.path.join(path, 'c') - assert os.path.isfile(dest) - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, 'd') - - def test_glob(self): - """Can the FilesWriter handle globbed files correctly?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create test files - os.mkdir('sub') - with open(os.path.join('sub', 'c'), 'w') as f: - f.write('e') - with open(os.path.join('sub', 'd'), 'w') as f: - f.write('e') - - # Create the resoruces dictionary - res = {} - - # Create files writer, test output - writer = FilesWriter() - writer.files = ['sub/*'] - writer.build_directory = u'build' - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - assert os.path.isdir(writer.build_directory) - dest = os.path.join(writer.build_directory, 'z') - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - # Check to make sure the globbed files were copied - path = os.path.join(writer.build_directory, 'sub') - assert os.path.isdir(path) - for filename in ['c', 'd']: - dest = os.path.join(path, filename) - assert os.path.isfile(dest) - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, 'e') - - def test_relpath(self): - """Can the FilesWriter handle relative paths for linked files correctly?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create test file - os.mkdir('sub') - with open(os.path.join('sub', 'c'), 'w') as f: - f.write('d') - - # Create the resoruces dictionary - res = {} - - # Create files writer, test output - writer = FilesWriter() - writer.files = [os.path.join('sub', 'c')] - writer.build_directory = u'build' - writer.relpath = 'sub' - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - assert os.path.isdir(writer.build_directory) - dest = os.path.join(writer.build_directory, 'z') - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - # Check to make sure the linked file was copied - dest = os.path.join(writer.build_directory, 'c') - assert os.path.isfile(dest) - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, 'd') - - def test_relpath_default(self): - """Is the FilesWriter default relative path correct?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create test file - os.mkdir('sub') - with open(os.path.join('sub', 'c'), 'w') as f: - f.write('d') - - # Create the resoruces dictionary - res = dict(metadata=dict(path="sub")) - - # Create files writer, test output - writer = FilesWriter() - writer.files = [os.path.join('sub', 'c')] - writer.build_directory = u'build' - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - assert os.path.isdir(writer.build_directory) - dest = os.path.join(writer.build_directory, 'z') - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - # Check to make sure the linked file was copied - dest = os.path.join(writer.build_directory, 'c') - assert os.path.isfile(dest) - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, 'd') - - def test_relpath_default(self): - """Does the FilesWriter relpath option take precedence over the path?""" - - # Work in a temporary directory. - with self.create_temp_cwd(): - - # Create test file - os.mkdir('sub') - with open(os.path.join('sub', 'c'), 'w') as f: - f.write('d') - - # Create the resoruces dictionary - res = dict(metadata=dict(path="other_sub")) - - # Create files writer, test output - writer = FilesWriter() - writer.files = [os.path.join('sub', 'c')] - writer.build_directory = u'build' - writer.relpath = 'sub' - writer.write(u'y', res, notebook_name="z") - - # Check the output of the file - assert os.path.isdir(writer.build_directory) - dest = os.path.join(writer.build_directory, 'z') - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, u'y') - - # Check to make sure the linked file was copied - dest = os.path.join(writer.build_directory, 'c') - assert os.path.isfile(dest) - with open(dest, 'r') as f: - output = f.read() - self.assertEqual(output, 'd') diff --git a/jupyter_nbconvert/writers/tests/test_stdout.py b/jupyter_nbconvert/writers/tests/test_stdout.py deleted file mode 100644 index 58c4cea..0000000 --- a/jupyter_nbconvert/writers/tests/test_stdout.py +++ /dev/null @@ -1,54 +0,0 @@ -# coding: utf-8 -""" -Module with tests for stdout -""" - -#----------------------------------------------------------------------------- -# 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 -#----------------------------------------------------------------------------- - -import sys - -from ...tests.base import TestsBase -from ..stdout import StdoutWriter -from IPython.utils.py3compat import PY3 - -if PY3: - from io import StringIO -else: - from StringIO import StringIO - - -#----------------------------------------------------------------------------- -# Class -#----------------------------------------------------------------------------- - -class TestStdout(TestsBase): - """Contains test functions for stdout.py""" - - def test_output(self): - """Test stdout writer output.""" - - # Capture the stdout. Remember original. - stdout = sys.stdout - stream = StringIO() - sys.stdout = stream - - # Create stdout writer, test output - writer = StdoutWriter() - writer.write(u'a×', {'b': 'c'}) - output = stream.getvalue() - if not PY3: - output = output.decode('utf-8') - self.fuzzy_compare(output, u'a×') - - # Revert stdout - sys.stdout = stdout \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 1967c41..d4f31bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ -e git+https://github.com/jupyter/jupyter_nbformat.git#egg=jupyter_nbformat -e git+https://github.com/jupyter/jupyter_client.git#egg=jupyter_client -e git+https://github.com/ipython/ipython_kernel.git#egg=ipython_kernel +-e git+https://github.com/jupyter/jupyter_nbconvert.git#egg=jupyter_nbconvert diff --git a/setupbase.py b/setupbase.py index 9517dfa..bdfed1f 100644 --- a/setupbase.py +++ b/setupbase.py @@ -176,20 +176,6 @@ def find_package_data(): # os.chdir(os.path.join('tests',)) # js_tests = glob('*.js') + glob('*/*.js') - # nbconvert package_data: - # os.chdir(os.path.join(cwd, 'IPython', 'nbconvert')) - # nbconvert_templates = [os.path.join(dirpath, '*.*') - # for dirpath, _, _ in os.walk('templates')] - # package_data = { - # 'IPython.nbconvert.filters' : ['marked.js'], - # 'IPython.nbconvert' : nbconvert_templates + - # [ - # 'tests/files/*.*', - # 'exporters/tests/files/*.*', - # 'preprocessors/tests/files/*.*', - # ], - # } - # os.chdir(cwd) package_data = {