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