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