From d7aa64bd9bb60bb2f02e3cc6886d93b2c261968b 2014-10-08 19:33:32 From: MinRK Date: 2014-10-08 19:33:32 Subject: [PATCH] support downgrading notebooks with nbconvert Use: ipython nbconvert --to notebook --nbformat 3 notebook.ipynb to write `notebook.v3.ipynb` Adds `output_suffix` resource, inserted before file ext. Suffix is used if `--output` is not specified. Default is `.nbconvert`, to prevent `--to notebook` from clobbering existing notebooks by default. --- diff --git a/IPython/nbconvert/exporters/__init__.py b/IPython/nbconvert/exporters/__init__.py index 6397472..5518850 100644 --- a/IPython/nbconvert/exporters/__init__.py +++ b/IPython/nbconvert/exporters/__init__.py @@ -4,6 +4,7 @@ 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 diff --git a/IPython/nbconvert/exporters/notebook.py b/IPython/nbconvert/exporters/notebook.py index a2e434b..65250a3 100644 --- a/IPython/nbconvert/exporters/notebook.py +++ b/IPython/nbconvert/exporters/notebook.py @@ -5,11 +5,18 @@ from .exporter import Exporter from IPython.nbformat import current as nbformat +from IPython.utils.traitlets import Enum class NotebookExporter(Exporter): - """ - Exports an IPython notebook. - """ + """Exports to an IPython notebook.""" + + nbformat_version = Enum(list(range(2, nbformat.current_nbformat + 1)), + 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' @@ -17,5 +24,9 @@ class NotebookExporter(Exporter): def from_notebook_node(self, nb, resources=None, **kw): nb_copy, resources = super(NotebookExporter, self).from_notebook_node(nb, resources, **kw) - output = nbformat.writes_json(nb_copy) + if self.nbformat_version != nbformat.current_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/IPython/nbconvert/exporters/tests/test_notebook.py b/IPython/nbconvert/exporters/tests/test_notebook.py index a5d3a04..ac51218 100644 --- a/IPython/nbconvert/exporters/tests/test_notebook.py +++ b/IPython/nbconvert/exporters/tests/test_notebook.py @@ -3,6 +3,8 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +import json + from .base import ExportersTestsBase from ..notebook import NotebookExporter @@ -17,6 +19,18 @@ class TestNotebookExporter(ExportersTestsBase): """ with open(self._get_notebook()) as f: file_contents = f.read() - (output, resources) = NotebookExporter().from_filename(self._get_notebook()) + (output, resources) = self.exporter_class().from_filename(self._get_notebook()) assert len(output) > 0 - assert output == file_contents + self.assertEqual(output, file_contents) + + def test_downgrade_3(self): + exporter = self.exporter_class(nbformat_version=3) + (output, resources) = exporter.from_filename(self._get_notebook()) + nb = json.loads(output) + self.assertEqual(nb['nbformat'], 3) + + 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/IPython/nbconvert/nbconvertapp.py b/IPython/nbconvert/nbconvertapp.py index c105728..96d6350 100755 --- a/IPython/nbconvert/nbconvertapp.py +++ b/IPython/nbconvert/nbconvertapp.py @@ -53,6 +53,7 @@ nbconvert_aliases.update({ 'post': 'NbConvertApp.postprocessor_class', 'output': 'NbConvertApp.output_base', 'reveal-prefix': 'RevealHelpPreprocessor.url_prefix', + 'nbformat': 'NotebookExporter.nbformat_version', }) nbconvert_flags = {} @@ -92,7 +93,7 @@ class NbConvertApp(BaseIPythonApplication): 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 use when converting one notebook at a time. + can only be used when converting one notebook at a time. ''') examples = Unicode(u""" @@ -298,6 +299,8 @@ class NbConvertApp(BaseIPythonApplication): exc_info=True) self.exit(1) else: + if 'output_suffix' in resources and not self.output_base: + notebook_name += resources['output_suffix'] write_results = self.writer.write(output, resources, notebook_name=notebook_name) #Post-process if post processor has been defined.