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