##// END OF EJS Templates
Adding --to slides --post serve example in help.
damianavila -
Show More
@@ -1,301 +1,305 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) 2013, the IPython Development Team.
7 #Copyright (c) 2013, the IPython Development Team.
8 #
8 #
9 #Distributed under the terms of the Modified BSD License.
9 #Distributed under the terms of the Modified BSD License.
10 #
10 #
11 #The full license is in the file COPYING.txt, distributed with this software.
11 #The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 #Imports
15 #Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Stdlib imports
18 # Stdlib imports
19 from __future__ import print_function
19 from __future__ import print_function
20 import sys
20 import sys
21 import os
21 import os
22 import glob
22 import glob
23
23
24 # From IPython
24 # From IPython
25 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
25 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
26 from IPython.config import catch_config_error, Configurable
26 from IPython.config import catch_config_error, Configurable
27 from IPython.utils.traitlets import (
27 from IPython.utils.traitlets import (
28 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
28 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
29 )
29 )
30 from IPython.utils.importstring import import_item
30 from IPython.utils.importstring import import_item
31
31
32 from .exporters.export import export_by_name, get_export_names, ExporterNameError
32 from .exporters.export import export_by_name, get_export_names, ExporterNameError
33 from IPython.nbconvert import exporters, transformers, writers, post_processors
33 from IPython.nbconvert import exporters, transformers, writers, post_processors
34 from .utils.base import NbConvertBase
34 from .utils.base import NbConvertBase
35 from .utils.exceptions import ConversionException
35 from .utils.exceptions import ConversionException
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 #Classes and functions
38 #Classes and functions
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40
40
41 class DottedOrNone(DottedObjectName):
41 class DottedOrNone(DottedObjectName):
42 """
42 """
43 A string holding a valid dotted object name in Python, such as A.b3._c
43 A string holding a valid dotted object name in Python, such as A.b3._c
44 Also allows for None type."""
44 Also allows for None type."""
45
45
46 default_value = u''
46 default_value = u''
47
47
48 def validate(self, obj, value):
48 def validate(self, obj, value):
49 if value is not None and len(value) > 0:
49 if value is not None and len(value) > 0:
50 return super(DottedOrNone, self).validate(obj, value)
50 return super(DottedOrNone, self).validate(obj, value)
51 else:
51 else:
52 return value
52 return value
53
53
54 nbconvert_aliases = {}
54 nbconvert_aliases = {}
55 nbconvert_aliases.update(base_aliases)
55 nbconvert_aliases.update(base_aliases)
56 nbconvert_aliases.update({
56 nbconvert_aliases.update({
57 'to' : 'NbConvertApp.export_format',
57 'to' : 'NbConvertApp.export_format',
58 'template' : 'Exporter.template_file',
58 'template' : 'Exporter.template_file',
59 'notebooks' : 'NbConvertApp.notebooks',
59 'notebooks' : 'NbConvertApp.notebooks',
60 'writer' : 'NbConvertApp.writer_class',
60 'writer' : 'NbConvertApp.writer_class',
61 'post': 'NbConvertApp.post_processor_class'
61 'post': 'NbConvertApp.post_processor_class'
62 })
62 })
63
63
64 nbconvert_flags = {}
64 nbconvert_flags = {}
65 nbconvert_flags.update(base_flags)
65 nbconvert_flags.update(base_flags)
66 nbconvert_flags.update({
66 nbconvert_flags.update({
67 'stdout' : (
67 'stdout' : (
68 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
68 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
69 "Write notebook output to stdout instead of files."
69 "Write notebook output to stdout instead of files."
70 )
70 )
71 })
71 })
72
72
73
73
74 class NbConvertApp(BaseIPythonApplication):
74 class NbConvertApp(BaseIPythonApplication):
75 """Application used to convert to and from notebook file type (*.ipynb)"""
75 """Application used to convert to and from notebook file type (*.ipynb)"""
76
76
77 name = 'ipython-nbconvert'
77 name = 'ipython-nbconvert'
78 aliases = nbconvert_aliases
78 aliases = nbconvert_aliases
79 flags = nbconvert_flags
79 flags = nbconvert_flags
80
80
81 def _classes_default(self):
81 def _classes_default(self):
82 classes = [NbConvertBase]
82 classes = [NbConvertBase]
83 for pkg in (exporters, transformers, writers):
83 for pkg in (exporters, transformers, writers):
84 for name in dir(pkg):
84 for name in dir(pkg):
85 cls = getattr(pkg, name)
85 cls = getattr(pkg, name)
86 if isinstance(cls, type) and issubclass(cls, Configurable):
86 if isinstance(cls, type) and issubclass(cls, Configurable):
87 classes.append(cls)
87 classes.append(cls)
88 return classes
88 return classes
89
89
90 description = Unicode(
90 description = Unicode(
91 u"""This application is used to convert notebook files (*.ipynb)
91 u"""This application is used to convert notebook files (*.ipynb)
92 to various other formats.
92 to various other formats.
93
93
94 WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""")
94 WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""")
95
95
96 examples = Unicode(u"""
96 examples = Unicode(u"""
97 The simplest way to use nbconvert is
97 The simplest way to use nbconvert is
98
98
99 > ipython nbconvert mynotebook.ipynb
99 > ipython nbconvert mynotebook.ipynb
100
100
101 which will convert mynotebook.ipynb to the default format (probably HTML).
101 which will convert mynotebook.ipynb to the default format (probably HTML).
102
102
103 You can specify the export format with `--to`.
103 You can specify the export format with `--to`.
104 Options include {0}
104 Options include {0}
105
105
106 > ipython nbconvert --to latex mynotebook.ipnynb
106 > ipython nbconvert --to latex mynotebook.ipnynb
107
107
108 Both HTML and LaTeX support multiple output templates. LaTeX includes
108 Both HTML and LaTeX support multiple output templates. LaTeX includes
109 'basic', 'book', and 'article'. HTML includes 'basic' and 'full'. You
109 'basic', 'book', and 'article'. HTML includes 'basic' and 'full'. You
110 can specify the flavor of the format used.
110 can specify the flavor of the format used.
111
111
112 > ipython nbconvert --to html --template basic mynotebook.ipynb
112 > ipython nbconvert --to html --template basic mynotebook.ipynb
113
113
114 You can also pipe the output to stdout, rather than a file
114 You can also pipe the output to stdout, rather than a file
115
115
116 > ipython nbconvert mynotebook.ipynb --stdout
116 > ipython nbconvert mynotebook.ipynb --stdout
117
117
118 A post-processor can be used to compile a PDF
118 A post-processor can be used to compile a PDF
119
119
120 > ipython nbconvert mynotebook.ipynb --to latex --post PDF
120 > ipython nbconvert mynotebook.ipynb --to latex --post PDF
121
121
122 You can get (and serve) a Reveal.js-powered slideshow
123
124 > ipython nbconvert myslides.ipynb --to slides --post serve
125
122 Multiple notebooks can be given at the command line in a couple of
126 Multiple notebooks can be given at the command line in a couple of
123 different ways:
127 different ways:
124
128
125 > ipython nbconvert notebook*.ipynb
129 > ipython nbconvert notebook*.ipynb
126 > ipython nbconvert notebook1.ipynb notebook2.ipynb
130 > ipython nbconvert notebook1.ipynb notebook2.ipynb
127
131
128 or you can specify the notebooks list in a config file, containing::
132 or you can specify the notebooks list in a config file, containing::
129
133
130 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
134 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
131
135
132 > ipython nbconvert --config mycfg.py
136 > ipython nbconvert --config mycfg.py
133 """.format(get_export_names()))
137 """.format(get_export_names()))
134
138
135 # Writer specific variables
139 # Writer specific variables
136 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
140 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
137 help="""Instance of the writer class used to write the
141 help="""Instance of the writer class used to write the
138 results of the conversion.""")
142 results of the conversion.""")
139 writer_class = DottedObjectName('FilesWriter', config=True,
143 writer_class = DottedObjectName('FilesWriter', config=True,
140 help="""Writer class used to write the
144 help="""Writer class used to write the
141 results of the conversion""")
145 results of the conversion""")
142 writer_aliases = {'FilesWriter': 'IPython.nbconvert.writers.files.FilesWriter',
146 writer_aliases = {'FilesWriter': 'IPython.nbconvert.writers.files.FilesWriter',
143 'DebugWriter': 'IPython.nbconvert.writers.debug.DebugWriter',
147 'DebugWriter': 'IPython.nbconvert.writers.debug.DebugWriter',
144 'StdoutWriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
148 'StdoutWriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
145 writer_factory = Type()
149 writer_factory = Type()
146
150
147 def _writer_class_changed(self, name, old, new):
151 def _writer_class_changed(self, name, old, new):
148 if new in self.writer_aliases:
152 if new in self.writer_aliases:
149 new = self.writer_aliases[new]
153 new = self.writer_aliases[new]
150 self.writer_factory = import_item(new)
154 self.writer_factory = import_item(new)
151
155
152 # Post-processor specific variables
156 # Post-processor specific variables
153 post_processor = Instance('IPython.nbconvert.post_processors.base.PostProcessorBase',
157 post_processor = Instance('IPython.nbconvert.post_processors.base.PostProcessorBase',
154 help="""Instance of the PostProcessor class used to write the
158 help="""Instance of the PostProcessor class used to write the
155 results of the conversion.""")
159 results of the conversion.""")
156
160
157 post_processor_class = DottedOrNone(config=True,
161 post_processor_class = DottedOrNone(config=True,
158 help="""PostProcessor class used to write the
162 help="""PostProcessor class used to write the
159 results of the conversion""")
163 results of the conversion""")
160 post_processor_aliases = {'PDF': 'IPython.nbconvert.post_processors.pdf.PDFPostProcessor',
164 post_processor_aliases = {'PDF': 'IPython.nbconvert.post_processors.pdf.PDFPostProcessor',
161 'serve': 'IPython.nbconvert.post_processors.serve.ServePostProcessor'}
165 'serve': 'IPython.nbconvert.post_processors.serve.ServePostProcessor'}
162 post_processor_factory = Type()
166 post_processor_factory = Type()
163
167
164 def _post_processor_class_changed(self, name, old, new):
168 def _post_processor_class_changed(self, name, old, new):
165 if new in self.post_processor_aliases:
169 if new in self.post_processor_aliases:
166 new = self.post_processor_aliases[new]
170 new = self.post_processor_aliases[new]
167 if new:
171 if new:
168 self.post_processor_factory = import_item(new)
172 self.post_processor_factory = import_item(new)
169
173
170
174
171 # Other configurable variables
175 # Other configurable variables
172 export_format = CaselessStrEnum(get_export_names(),
176 export_format = CaselessStrEnum(get_export_names(),
173 default_value="html",
177 default_value="html",
174 config=True,
178 config=True,
175 help="""The export format to be used."""
179 help="""The export format to be used."""
176 )
180 )
177
181
178 notebooks = List([], config=True, help="""List of notebooks to convert.
182 notebooks = List([], config=True, help="""List of notebooks to convert.
179 Wildcards are supported.
183 Wildcards are supported.
180 Filenames passed positionally will be added to the list.
184 Filenames passed positionally will be added to the list.
181 """)
185 """)
182
186
183 @catch_config_error
187 @catch_config_error
184 def initialize(self, argv=None):
188 def initialize(self, argv=None):
185 super(NbConvertApp, self).initialize(argv)
189 super(NbConvertApp, self).initialize(argv)
186 self.init_syspath()
190 self.init_syspath()
187 self.init_notebooks()
191 self.init_notebooks()
188 self.init_writer()
192 self.init_writer()
189 self.init_post_processor()
193 self.init_post_processor()
190
194
191
195
192
196
193 def init_syspath(self):
197 def init_syspath(self):
194 """
198 """
195 Add the cwd to the sys.path ($PYTHONPATH)
199 Add the cwd to the sys.path ($PYTHONPATH)
196 """
200 """
197 sys.path.insert(0, os.getcwd())
201 sys.path.insert(0, os.getcwd())
198
202
199
203
200 def init_notebooks(self):
204 def init_notebooks(self):
201 """Construct the list of notebooks.
205 """Construct the list of notebooks.
202 If notebooks are passed on the command-line,
206 If notebooks are passed on the command-line,
203 they override notebooks specified in config files.
207 they override notebooks specified in config files.
204 Glob each notebook to replace notebook patterns with filenames.
208 Glob each notebook to replace notebook patterns with filenames.
205 """
209 """
206
210
207 # Specifying notebooks on the command-line overrides (rather than adds)
211 # Specifying notebooks on the command-line overrides (rather than adds)
208 # the notebook list
212 # the notebook list
209 if self.extra_args:
213 if self.extra_args:
210 patterns = self.extra_args
214 patterns = self.extra_args
211 else:
215 else:
212 patterns = self.notebooks
216 patterns = self.notebooks
213
217
214 # Use glob to replace all the notebook patterns with filenames.
218 # Use glob to replace all the notebook patterns with filenames.
215 filenames = []
219 filenames = []
216 for pattern in patterns:
220 for pattern in patterns:
217
221
218 # Use glob to find matching filenames. Allow the user to convert
222 # Use glob to find matching filenames. Allow the user to convert
219 # notebooks without having to type the extension.
223 # notebooks without having to type the extension.
220 globbed_files = glob.glob(pattern)
224 globbed_files = glob.glob(pattern)
221 globbed_files.extend(glob.glob(pattern + '.ipynb'))
225 globbed_files.extend(glob.glob(pattern + '.ipynb'))
222
226
223 for filename in globbed_files:
227 for filename in globbed_files:
224 if not filename in filenames:
228 if not filename in filenames:
225 filenames.append(filename)
229 filenames.append(filename)
226 self.notebooks = filenames
230 self.notebooks = filenames
227
231
228 def init_writer(self):
232 def init_writer(self):
229 """
233 """
230 Initialize the writer (which is stateless)
234 Initialize the writer (which is stateless)
231 """
235 """
232 self._writer_class_changed(None, self.writer_class, self.writer_class)
236 self._writer_class_changed(None, self.writer_class, self.writer_class)
233 self.writer = self.writer_factory(parent=self)
237 self.writer = self.writer_factory(parent=self)
234
238
235 def init_post_processor(self):
239 def init_post_processor(self):
236 """
240 """
237 Initialize the post_processor (which is stateless)
241 Initialize the post_processor (which is stateless)
238 """
242 """
239 self._post_processor_class_changed(None, self.post_processor_class,
243 self._post_processor_class_changed(None, self.post_processor_class,
240 self.post_processor_class)
244 self.post_processor_class)
241 if self.post_processor_factory:
245 if self.post_processor_factory:
242 self.post_processor = self.post_processor_factory(parent=self)
246 self.post_processor = self.post_processor_factory(parent=self)
243
247
244 def start(self):
248 def start(self):
245 """
249 """
246 Ran after initialization completed
250 Ran after initialization completed
247 """
251 """
248 super(NbConvertApp, self).start()
252 super(NbConvertApp, self).start()
249 self.convert_notebooks()
253 self.convert_notebooks()
250
254
251 def convert_notebooks(self):
255 def convert_notebooks(self):
252 """
256 """
253 Convert the notebooks in the self.notebook traitlet
257 Convert the notebooks in the self.notebook traitlet
254 """
258 """
255 # Export each notebook
259 # Export each notebook
256 conversion_success = 0
260 conversion_success = 0
257 for notebook_filename in self.notebooks:
261 for notebook_filename in self.notebooks:
258
262
259 # Get a unique key for the notebook and set it in the resources object.
263 # Get a unique key for the notebook and set it in the resources object.
260 basename = os.path.basename(notebook_filename)
264 basename = os.path.basename(notebook_filename)
261 notebook_name = basename[:basename.rfind('.')]
265 notebook_name = basename[:basename.rfind('.')]
262 resources = {}
266 resources = {}
263 resources['unique_key'] = notebook_name
267 resources['unique_key'] = notebook_name
264 resources['output_files_dir'] = '%s_files' % notebook_name
268 resources['output_files_dir'] = '%s_files' % notebook_name
265
269
266 # Try to export
270 # Try to export
267 try:
271 try:
268 output, resources = export_by_name(self.export_format,
272 output, resources = export_by_name(self.export_format,
269 notebook_filename,
273 notebook_filename,
270 resources=resources,
274 resources=resources,
271 config=self.config)
275 config=self.config)
272 except ExporterNameError as e:
276 except ExporterNameError as e:
273 print("Error while converting '%s': '%s' exporter not found."
277 print("Error while converting '%s': '%s' exporter not found."
274 %(notebook_filename, self.export_format),
278 %(notebook_filename, self.export_format),
275 file=sys.stderr)
279 file=sys.stderr)
276 print("Known exporters are:",
280 print("Known exporters are:",
277 "\n\t" + "\n\t".join(get_export_names()),
281 "\n\t" + "\n\t".join(get_export_names()),
278 file=sys.stderr)
282 file=sys.stderr)
279 self.exit(1)
283 self.exit(1)
280 except ConversionException as e:
284 except ConversionException as e:
281 print("Error while converting '%s': %s" %(notebook_filename, e),
285 print("Error while converting '%s': %s" %(notebook_filename, e),
282 file=sys.stderr)
286 file=sys.stderr)
283 self.exit(1)
287 self.exit(1)
284 else:
288 else:
285 write_resultes = self.writer.write(output, resources, notebook_name=notebook_name)
289 write_resultes = self.writer.write(output, resources, notebook_name=notebook_name)
286
290
287 #Post-process if post processor has been defined.
291 #Post-process if post processor has been defined.
288 if hasattr(self, 'post_processor') and self.post_processor:
292 if hasattr(self, 'post_processor') and self.post_processor:
289 self.post_processor(write_resultes)
293 self.post_processor(write_resultes)
290 conversion_success += 1
294 conversion_success += 1
291
295
292 # If nothing was converted successfully, help the user.
296 # If nothing was converted successfully, help the user.
293 if conversion_success == 0:
297 if conversion_success == 0:
294 self.print_help()
298 self.print_help()
295 sys.exit(-1)
299 sys.exit(-1)
296
300
297 #-----------------------------------------------------------------------------
301 #-----------------------------------------------------------------------------
298 # Main entry point
302 # Main entry point
299 #-----------------------------------------------------------------------------
303 #-----------------------------------------------------------------------------
300
304
301 launch_new_instance = NbConvertApp.launch_instance
305 launch_new_instance = NbConvertApp.launch_instance
General Comments 0
You need to be logged in to leave comments. Login now