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