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