##// END OF EJS Templates
support downgrading notebooks with nbconvert...
MinRK -
Show More
@@ -1,10 +1,11 b''
1 from .export import *
1 from .export import *
2 from .html import HTMLExporter
2 from .html import HTMLExporter
3 from .slides import SlidesExporter
3 from .slides import SlidesExporter
4 from .templateexporter import TemplateExporter
4 from .templateexporter import TemplateExporter
5 from .latex import LatexExporter
5 from .latex import LatexExporter
6 from .markdown import MarkdownExporter
6 from .markdown import MarkdownExporter
7 from .notebook import NotebookExporter
7 from .pdf import PDFExporter
8 from .pdf import PDFExporter
8 from .python import PythonExporter
9 from .python import PythonExporter
9 from .rst import RSTExporter
10 from .rst import RSTExporter
10 from .exporter import Exporter
11 from .exporter import Exporter
@@ -1,21 +1,32 b''
1 """NotebookExporter class"""
1 """NotebookExporter class"""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 from .exporter import Exporter
6 from .exporter import Exporter
7 from IPython.nbformat import current as nbformat
7 from IPython.nbformat import current as nbformat
8 from IPython.utils.traitlets import Enum
8
9
9 class NotebookExporter(Exporter):
10 class NotebookExporter(Exporter):
10 """
11 """Exports to an IPython notebook."""
11 Exports an IPython notebook.
12
12 """
13 nbformat_version = Enum(list(range(2, nbformat.current_nbformat + 1)),
14 default_value=nbformat.current_nbformat,
15 config=True,
16 help="""The nbformat version to write.
17 Use this to downgrade notebooks.
18 """
19 )
13 def _file_extension_default(self):
20 def _file_extension_default(self):
14 return 'ipynb'
21 return 'ipynb'
15
22
16 output_mimetype = 'application/json'
23 output_mimetype = 'application/json'
17
24
18 def from_notebook_node(self, nb, resources=None, **kw):
25 def from_notebook_node(self, nb, resources=None, **kw):
19 nb_copy, resources = super(NotebookExporter, self).from_notebook_node(nb, resources, **kw)
26 nb_copy, resources = super(NotebookExporter, self).from_notebook_node(nb, resources, **kw)
20 output = nbformat.writes_json(nb_copy)
27 if self.nbformat_version != nbformat.current_nbformat:
28 resources['output_suffix'] = '.v%i' % self.nbformat_version
29 else:
30 resources['output_suffix'] = '.nbconvert'
31 output = nbformat.writes(nb_copy, version=self.nbformat_version)
21 return output, resources
32 return output, resources
@@ -1,22 +1,36 b''
1 """Tests for notebook.py"""
1 """Tests for notebook.py"""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import json
7
6 from .base import ExportersTestsBase
8 from .base import ExportersTestsBase
7 from ..notebook import NotebookExporter
9 from ..notebook import NotebookExporter
8
10
9 class TestNotebookExporter(ExportersTestsBase):
11 class TestNotebookExporter(ExportersTestsBase):
10 """Contains test functions for notebook.py"""
12 """Contains test functions for notebook.py"""
11
13
12 exporter_class = NotebookExporter
14 exporter_class = NotebookExporter
13
15
14 def test_export(self):
16 def test_export(self):
15 """
17 """
16 Does the NotebookExporter return the file unchanged?
18 Does the NotebookExporter return the file unchanged?
17 """
19 """
18 with open(self._get_notebook()) as f:
20 with open(self._get_notebook()) as f:
19 file_contents = f.read()
21 file_contents = f.read()
20 (output, resources) = NotebookExporter().from_filename(self._get_notebook())
22 (output, resources) = self.exporter_class().from_filename(self._get_notebook())
21 assert len(output) > 0
23 assert len(output) > 0
22 assert output == file_contents
24 self.assertEqual(output, file_contents)
25
26 def test_downgrade_3(self):
27 exporter = self.exporter_class(nbformat_version=3)
28 (output, resources) = exporter.from_filename(self._get_notebook())
29 nb = json.loads(output)
30 self.assertEqual(nb['nbformat'], 3)
31
32 def test_downgrade_2(self):
33 exporter = self.exporter_class(nbformat_version=2)
34 (output, resources) = exporter.from_filename(self._get_notebook())
35 nb = json.loads(output)
36 self.assertEqual(nb['nbformat'], 2)
@@ -1,317 +1,320 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """NbConvert is a utility for conversion of .ipynb files.
2 """NbConvert is a utility for conversion of .ipynb files.
3
3
4 Command-line interface for the NbConvert conversion utility.
4 Command-line interface for the NbConvert conversion utility.
5 """
5 """
6
6
7 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9
9
10 from __future__ import print_function
10 from __future__ import print_function
11
11
12 import logging
12 import logging
13 import sys
13 import sys
14 import os
14 import os
15 import glob
15 import glob
16
16
17 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
17 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
18 from IPython.core.profiledir import ProfileDir
18 from IPython.core.profiledir import ProfileDir
19 from IPython.config import catch_config_error, Configurable
19 from IPython.config import catch_config_error, Configurable
20 from IPython.utils.traitlets import (
20 from IPython.utils.traitlets import (
21 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
21 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
22 )
22 )
23 from IPython.utils.importstring import import_item
23 from IPython.utils.importstring import import_item
24
24
25 from .exporters.export import get_export_names, exporter_map
25 from .exporters.export import get_export_names, exporter_map
26 from IPython.nbconvert import exporters, preprocessors, writers, postprocessors
26 from IPython.nbconvert import exporters, preprocessors, writers, postprocessors
27 from .utils.base import NbConvertBase
27 from .utils.base import NbConvertBase
28 from .utils.exceptions import ConversionException
28 from .utils.exceptions import ConversionException
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 #Classes and functions
31 #Classes and functions
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34 class DottedOrNone(DottedObjectName):
34 class DottedOrNone(DottedObjectName):
35 """
35 """
36 A string holding a valid dotted object name in Python, such as A.b3._c
36 A string holding a valid dotted object name in Python, such as A.b3._c
37 Also allows for None type."""
37 Also allows for None type."""
38
38
39 default_value = u''
39 default_value = u''
40
40
41 def validate(self, obj, value):
41 def validate(self, obj, value):
42 if value is not None and len(value) > 0:
42 if value is not None and len(value) > 0:
43 return super(DottedOrNone, self).validate(obj, value)
43 return super(DottedOrNone, self).validate(obj, value)
44 else:
44 else:
45 return value
45 return value
46
46
47 nbconvert_aliases = {}
47 nbconvert_aliases = {}
48 nbconvert_aliases.update(base_aliases)
48 nbconvert_aliases.update(base_aliases)
49 nbconvert_aliases.update({
49 nbconvert_aliases.update({
50 'to' : 'NbConvertApp.export_format',
50 'to' : 'NbConvertApp.export_format',
51 'template' : 'TemplateExporter.template_file',
51 'template' : 'TemplateExporter.template_file',
52 'writer' : 'NbConvertApp.writer_class',
52 'writer' : 'NbConvertApp.writer_class',
53 'post': 'NbConvertApp.postprocessor_class',
53 'post': 'NbConvertApp.postprocessor_class',
54 'output': 'NbConvertApp.output_base',
54 'output': 'NbConvertApp.output_base',
55 'reveal-prefix': 'RevealHelpPreprocessor.url_prefix',
55 'reveal-prefix': 'RevealHelpPreprocessor.url_prefix',
56 'nbformat': 'NotebookExporter.nbformat_version',
56 })
57 })
57
58
58 nbconvert_flags = {}
59 nbconvert_flags = {}
59 nbconvert_flags.update(base_flags)
60 nbconvert_flags.update(base_flags)
60 nbconvert_flags.update({
61 nbconvert_flags.update({
61 'stdout' : (
62 'stdout' : (
62 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
63 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
63 "Write notebook output to stdout instead of files."
64 "Write notebook output to stdout instead of files."
64 )
65 )
65 })
66 })
66
67
67
68
68 class NbConvertApp(BaseIPythonApplication):
69 class NbConvertApp(BaseIPythonApplication):
69 """Application used to convert from notebook file type (``*.ipynb``)"""
70 """Application used to convert from notebook file type (``*.ipynb``)"""
70
71
71 name = 'ipython-nbconvert'
72 name = 'ipython-nbconvert'
72 aliases = nbconvert_aliases
73 aliases = nbconvert_aliases
73 flags = nbconvert_flags
74 flags = nbconvert_flags
74
75
75 def _log_level_default(self):
76 def _log_level_default(self):
76 return logging.INFO
77 return logging.INFO
77
78
78 def _classes_default(self):
79 def _classes_default(self):
79 classes = [NbConvertBase, ProfileDir]
80 classes = [NbConvertBase, ProfileDir]
80 for pkg in (exporters, preprocessors, writers, postprocessors):
81 for pkg in (exporters, preprocessors, writers, postprocessors):
81 for name in dir(pkg):
82 for name in dir(pkg):
82 cls = getattr(pkg, name)
83 cls = getattr(pkg, name)
83 if isinstance(cls, type) and issubclass(cls, Configurable):
84 if isinstance(cls, type) and issubclass(cls, Configurable):
84 classes.append(cls)
85 classes.append(cls)
85
86
86 return classes
87 return classes
87
88
88 description = Unicode(
89 description = Unicode(
89 u"""This application is used to convert notebook files (*.ipynb)
90 u"""This application is used to convert notebook files (*.ipynb)
90 to various other formats.
91 to various other formats.
91
92
92 WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""")
93 WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""")
93
94
94 output_base = Unicode('', config=True, help='''overwrite base name use for output files.
95 output_base = Unicode('', config=True, help='''overwrite base name use for output files.
95 can only be use when converting one notebook at a time.
96 can only be used when converting one notebook at a time.
96 ''')
97 ''')
97
98
98 examples = Unicode(u"""
99 examples = Unicode(u"""
99 The simplest way to use nbconvert is
100 The simplest way to use nbconvert is
100
101
101 > ipython nbconvert mynotebook.ipynb
102 > ipython nbconvert mynotebook.ipynb
102
103
103 which will convert mynotebook.ipynb to the default format (probably HTML).
104 which will convert mynotebook.ipynb to the default format (probably HTML).
104
105
105 You can specify the export format with `--to`.
106 You can specify the export format with `--to`.
106 Options include {0}
107 Options include {0}
107
108
108 > ipython nbconvert --to latex mynotebook.ipynb
109 > ipython nbconvert --to latex mynotebook.ipynb
109
110
110 Both HTML and LaTeX support multiple output templates. LaTeX includes
111 Both HTML and LaTeX support multiple output templates. LaTeX includes
111 'base', 'article' and 'report'. HTML includes 'basic' and 'full'. You
112 'base', 'article' and 'report'. HTML includes 'basic' and 'full'. You
112 can specify the flavor of the format used.
113 can specify the flavor of the format used.
113
114
114 > ipython nbconvert --to html --template basic mynotebook.ipynb
115 > ipython nbconvert --to html --template basic mynotebook.ipynb
115
116
116 You can also pipe the output to stdout, rather than a file
117 You can also pipe the output to stdout, rather than a file
117
118
118 > ipython nbconvert mynotebook.ipynb --stdout
119 > ipython nbconvert mynotebook.ipynb --stdout
119
120
120 PDF is generated via latex
121 PDF is generated via latex
121
122
122 > ipython nbconvert mynotebook.ipynb --to pdf
123 > ipython nbconvert mynotebook.ipynb --to pdf
123
124
124 You can get (and serve) a Reveal.js-powered slideshow
125 You can get (and serve) a Reveal.js-powered slideshow
125
126
126 > ipython nbconvert myslides.ipynb --to slides --post serve
127 > ipython nbconvert myslides.ipynb --to slides --post serve
127
128
128 Multiple notebooks can be given at the command line in a couple of
129 Multiple notebooks can be given at the command line in a couple of
129 different ways:
130 different ways:
130
131
131 > ipython nbconvert notebook*.ipynb
132 > ipython nbconvert notebook*.ipynb
132 > ipython nbconvert notebook1.ipynb notebook2.ipynb
133 > ipython nbconvert notebook1.ipynb notebook2.ipynb
133
134
134 or you can specify the notebooks list in a config file, containing::
135 or you can specify the notebooks list in a config file, containing::
135
136
136 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
137 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
137
138
138 > ipython nbconvert --config mycfg.py
139 > ipython nbconvert --config mycfg.py
139 """.format(get_export_names()))
140 """.format(get_export_names()))
140
141
141 # Writer specific variables
142 # Writer specific variables
142 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
143 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
143 help="""Instance of the writer class used to write the
144 help="""Instance of the writer class used to write the
144 results of the conversion.""")
145 results of the conversion.""")
145 writer_class = DottedObjectName('FilesWriter', config=True,
146 writer_class = DottedObjectName('FilesWriter', config=True,
146 help="""Writer class used to write the
147 help="""Writer class used to write the
147 results of the conversion""")
148 results of the conversion""")
148 writer_aliases = {'fileswriter': 'IPython.nbconvert.writers.files.FilesWriter',
149 writer_aliases = {'fileswriter': 'IPython.nbconvert.writers.files.FilesWriter',
149 'debugwriter': 'IPython.nbconvert.writers.debug.DebugWriter',
150 'debugwriter': 'IPython.nbconvert.writers.debug.DebugWriter',
150 'stdoutwriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
151 'stdoutwriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
151 writer_factory = Type()
152 writer_factory = Type()
152
153
153 def _writer_class_changed(self, name, old, new):
154 def _writer_class_changed(self, name, old, new):
154 if new.lower() in self.writer_aliases:
155 if new.lower() in self.writer_aliases:
155 new = self.writer_aliases[new.lower()]
156 new = self.writer_aliases[new.lower()]
156 self.writer_factory = import_item(new)
157 self.writer_factory = import_item(new)
157
158
158 # Post-processor specific variables
159 # Post-processor specific variables
159 postprocessor = Instance('IPython.nbconvert.postprocessors.base.PostProcessorBase',
160 postprocessor = Instance('IPython.nbconvert.postprocessors.base.PostProcessorBase',
160 help="""Instance of the PostProcessor class used to write the
161 help="""Instance of the PostProcessor class used to write the
161 results of the conversion.""")
162 results of the conversion.""")
162
163
163 postprocessor_class = DottedOrNone(config=True,
164 postprocessor_class = DottedOrNone(config=True,
164 help="""PostProcessor class used to write the
165 help="""PostProcessor class used to write the
165 results of the conversion""")
166 results of the conversion""")
166 postprocessor_aliases = {'serve': 'IPython.nbconvert.postprocessors.serve.ServePostProcessor'}
167 postprocessor_aliases = {'serve': 'IPython.nbconvert.postprocessors.serve.ServePostProcessor'}
167 postprocessor_factory = Type()
168 postprocessor_factory = Type()
168
169
169 def _postprocessor_class_changed(self, name, old, new):
170 def _postprocessor_class_changed(self, name, old, new):
170 if new.lower() in self.postprocessor_aliases:
171 if new.lower() in self.postprocessor_aliases:
171 new = self.postprocessor_aliases[new.lower()]
172 new = self.postprocessor_aliases[new.lower()]
172 if new:
173 if new:
173 self.postprocessor_factory = import_item(new)
174 self.postprocessor_factory = import_item(new)
174
175
175
176
176 # Other configurable variables
177 # Other configurable variables
177 export_format = CaselessStrEnum(get_export_names(),
178 export_format = CaselessStrEnum(get_export_names(),
178 default_value="html",
179 default_value="html",
179 config=True,
180 config=True,
180 help="""The export format to be used."""
181 help="""The export format to be used."""
181 )
182 )
182
183
183 notebooks = List([], config=True, help="""List of notebooks to convert.
184 notebooks = List([], config=True, help="""List of notebooks to convert.
184 Wildcards are supported.
185 Wildcards are supported.
185 Filenames passed positionally will be added to the list.
186 Filenames passed positionally will be added to the list.
186 """)
187 """)
187
188
188 @catch_config_error
189 @catch_config_error
189 def initialize(self, argv=None):
190 def initialize(self, argv=None):
190 self.init_syspath()
191 self.init_syspath()
191 super(NbConvertApp, self).initialize(argv)
192 super(NbConvertApp, self).initialize(argv)
192 self.init_notebooks()
193 self.init_notebooks()
193 self.init_writer()
194 self.init_writer()
194 self.init_postprocessor()
195 self.init_postprocessor()
195
196
196
197
197
198
198 def init_syspath(self):
199 def init_syspath(self):
199 """
200 """
200 Add the cwd to the sys.path ($PYTHONPATH)
201 Add the cwd to the sys.path ($PYTHONPATH)
201 """
202 """
202 sys.path.insert(0, os.getcwd())
203 sys.path.insert(0, os.getcwd())
203
204
204
205
205 def init_notebooks(self):
206 def init_notebooks(self):
206 """Construct the list of notebooks.
207 """Construct the list of notebooks.
207 If notebooks are passed on the command-line,
208 If notebooks are passed on the command-line,
208 they override notebooks specified in config files.
209 they override notebooks specified in config files.
209 Glob each notebook to replace notebook patterns with filenames.
210 Glob each notebook to replace notebook patterns with filenames.
210 """
211 """
211
212
212 # Specifying notebooks on the command-line overrides (rather than adds)
213 # Specifying notebooks on the command-line overrides (rather than adds)
213 # the notebook list
214 # the notebook list
214 if self.extra_args:
215 if self.extra_args:
215 patterns = self.extra_args
216 patterns = self.extra_args
216 else:
217 else:
217 patterns = self.notebooks
218 patterns = self.notebooks
218
219
219 # Use glob to replace all the notebook patterns with filenames.
220 # Use glob to replace all the notebook patterns with filenames.
220 filenames = []
221 filenames = []
221 for pattern in patterns:
222 for pattern in patterns:
222
223
223 # Use glob to find matching filenames. Allow the user to convert
224 # Use glob to find matching filenames. Allow the user to convert
224 # notebooks without having to type the extension.
225 # notebooks without having to type the extension.
225 globbed_files = glob.glob(pattern)
226 globbed_files = glob.glob(pattern)
226 globbed_files.extend(glob.glob(pattern + '.ipynb'))
227 globbed_files.extend(glob.glob(pattern + '.ipynb'))
227 if not globbed_files:
228 if not globbed_files:
228 self.log.warn("pattern %r matched no files", pattern)
229 self.log.warn("pattern %r matched no files", pattern)
229
230
230 for filename in globbed_files:
231 for filename in globbed_files:
231 if not filename in filenames:
232 if not filename in filenames:
232 filenames.append(filename)
233 filenames.append(filename)
233 self.notebooks = filenames
234 self.notebooks = filenames
234
235
235 def init_writer(self):
236 def init_writer(self):
236 """
237 """
237 Initialize the writer (which is stateless)
238 Initialize the writer (which is stateless)
238 """
239 """
239 self._writer_class_changed(None, self.writer_class, self.writer_class)
240 self._writer_class_changed(None, self.writer_class, self.writer_class)
240 self.writer = self.writer_factory(parent=self)
241 self.writer = self.writer_factory(parent=self)
241
242
242 def init_postprocessor(self):
243 def init_postprocessor(self):
243 """
244 """
244 Initialize the postprocessor (which is stateless)
245 Initialize the postprocessor (which is stateless)
245 """
246 """
246 self._postprocessor_class_changed(None, self.postprocessor_class,
247 self._postprocessor_class_changed(None, self.postprocessor_class,
247 self.postprocessor_class)
248 self.postprocessor_class)
248 if self.postprocessor_factory:
249 if self.postprocessor_factory:
249 self.postprocessor = self.postprocessor_factory(parent=self)
250 self.postprocessor = self.postprocessor_factory(parent=self)
250
251
251 def start(self):
252 def start(self):
252 """
253 """
253 Ran after initialization completed
254 Ran after initialization completed
254 """
255 """
255 super(NbConvertApp, self).start()
256 super(NbConvertApp, self).start()
256 self.convert_notebooks()
257 self.convert_notebooks()
257
258
258 def convert_notebooks(self):
259 def convert_notebooks(self):
259 """
260 """
260 Convert the notebooks in the self.notebook traitlet
261 Convert the notebooks in the self.notebook traitlet
261 """
262 """
262 # Export each notebook
263 # Export each notebook
263 conversion_success = 0
264 conversion_success = 0
264
265
265 if self.output_base != '' and len(self.notebooks) > 1:
266 if self.output_base != '' and len(self.notebooks) > 1:
266 self.log.error(
267 self.log.error(
267 """UsageError: --output flag or `NbConvertApp.output_base` config option
268 """UsageError: --output flag or `NbConvertApp.output_base` config option
268 cannot be used when converting multiple notebooks.
269 cannot be used when converting multiple notebooks.
269 """)
270 """)
270 self.exit(1)
271 self.exit(1)
271
272
272 exporter = exporter_map[self.export_format](config=self.config)
273 exporter = exporter_map[self.export_format](config=self.config)
273
274
274 for notebook_filename in self.notebooks:
275 for notebook_filename in self.notebooks:
275 self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format)
276 self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format)
276
277
277 # Get a unique key for the notebook and set it in the resources object.
278 # Get a unique key for the notebook and set it in the resources object.
278 basename = os.path.basename(notebook_filename)
279 basename = os.path.basename(notebook_filename)
279 notebook_name = basename[:basename.rfind('.')]
280 notebook_name = basename[:basename.rfind('.')]
280 if self.output_base:
281 if self.output_base:
281 # strip duplicate extension from output_base, to avoid Basname.ext.ext
282 # strip duplicate extension from output_base, to avoid Basname.ext.ext
282 if getattr(exporter, 'file_extension', False):
283 if getattr(exporter, 'file_extension', False):
283 base, ext = os.path.splitext(self.output_base)
284 base, ext = os.path.splitext(self.output_base)
284 if ext == '.' + exporter.file_extension:
285 if ext == '.' + exporter.file_extension:
285 self.output_base = base
286 self.output_base = base
286 notebook_name = self.output_base
287 notebook_name = self.output_base
287 resources = {}
288 resources = {}
288 resources['profile_dir'] = self.profile_dir.location
289 resources['profile_dir'] = self.profile_dir.location
289 resources['unique_key'] = notebook_name
290 resources['unique_key'] = notebook_name
290 resources['output_files_dir'] = '%s_files' % notebook_name
291 resources['output_files_dir'] = '%s_files' % notebook_name
291 self.log.info("Support files will be in %s", os.path.join(resources['output_files_dir'], ''))
292 self.log.info("Support files will be in %s", os.path.join(resources['output_files_dir'], ''))
292
293
293 # Try to export
294 # Try to export
294 try:
295 try:
295 output, resources = exporter.from_filename(notebook_filename, resources=resources)
296 output, resources = exporter.from_filename(notebook_filename, resources=resources)
296 except ConversionException as e:
297 except ConversionException as e:
297 self.log.error("Error while converting '%s'", notebook_filename,
298 self.log.error("Error while converting '%s'", notebook_filename,
298 exc_info=True)
299 exc_info=True)
299 self.exit(1)
300 self.exit(1)
300 else:
301 else:
302 if 'output_suffix' in resources and not self.output_base:
303 notebook_name += resources['output_suffix']
301 write_results = self.writer.write(output, resources, notebook_name=notebook_name)
304 write_results = self.writer.write(output, resources, notebook_name=notebook_name)
302
305
303 #Post-process if post processor has been defined.
306 #Post-process if post processor has been defined.
304 if hasattr(self, 'postprocessor') and self.postprocessor:
307 if hasattr(self, 'postprocessor') and self.postprocessor:
305 self.postprocessor(write_results)
308 self.postprocessor(write_results)
306 conversion_success += 1
309 conversion_success += 1
307
310
308 # If nothing was converted successfully, help the user.
311 # If nothing was converted successfully, help the user.
309 if conversion_success == 0:
312 if conversion_success == 0:
310 self.print_help()
313 self.print_help()
311 sys.exit(-1)
314 sys.exit(-1)
312
315
313 #-----------------------------------------------------------------------------
316 #-----------------------------------------------------------------------------
314 # Main entry point
317 # Main entry point
315 #-----------------------------------------------------------------------------
318 #-----------------------------------------------------------------------------
316
319
317 launch_new_instance = NbConvertApp.launch_instance
320 launch_new_instance = NbConvertApp.launch_instance
General Comments 0
You need to be logged in to leave comments. Login now