##// END OF EJS Templates
Exporter -> TemplateExporter / BaseExporter
Matthias BUSSONNIER -
Show More
@@ -1,9 +1,9 b''
1 from .export import *
1 from .export import *
2 from .html import HTMLExporter
2 from .html import HTMLExporter
3 from .slides import SlidesExporter
3 from .slides import SlidesExporter
4 from .exporter import Exporter
4 from .exporter import TemplateExporter
5 from .latex import LatexExporter
5 from .latex import LatexExporter
6 from .markdown import MarkdownExporter
6 from .markdown import MarkdownExporter
7 from .python import PythonExporter
7 from .python import PythonExporter
8 from .rst import RSTExporter
8 from .rst import RSTExporter
9 from .baseexporter import BaseExporter
9 from .baseexporter import BaseExporter
@@ -1,282 +1,282 b''
1 """This module defines Exporter, a highly configurable converter
1 """This module defines BaseExporter, a highly configurable converter
2 that uses Jinja2 to export notebook files into different formats.
2 that uses Jinja2 to export notebook files into different formats.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import print_function, absolute_import
17 from __future__ import print_function, absolute_import
18
18
19 # Stdlib imports
19 # Stdlib imports
20 import io
20 import io
21 import os
21 import os
22 import copy
22 import copy
23 import collections
23 import collections
24 import datetime
24 import datetime
25
25
26
26
27 # IPython imports
27 # IPython imports
28 from IPython.config.configurable import LoggingConfigurable
28 from IPython.config.configurable import LoggingConfigurable
29 from IPython.config import Config
29 from IPython.config import Config
30 from IPython.nbformat import current as nbformat
30 from IPython.nbformat import current as nbformat
31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
32 from IPython.utils.importstring import import_item
32 from IPython.utils.importstring import import_item
33 from IPython.utils import py3compat
33 from IPython.utils import py3compat
34
34
35 from IPython.nbconvert import transformers as nbtransformers
35 from IPython.nbconvert import transformers as nbtransformers
36
36
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Class
39 # Class
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 class ResourcesDict(collections.defaultdict):
42 class ResourcesDict(collections.defaultdict):
43 def __missing__(self, key):
43 def __missing__(self, key):
44 return ''
44 return ''
45
45
46
46
47 class BaseExporter(LoggingConfigurable):
47 class BaseExporter(LoggingConfigurable):
48 """
48 """
49 Base Exporter Class that only conver notebook to notebook
49 Base Exporter Class that only conver notebook to notebook
50 and apply the transformers and provide basic methods for
50 and apply the transformers and provide basic methods for
51 reading a notebook from different sources.
51 reading a notebook from different sources.
52
52
53 """
53 """
54
54
55 # finish the docstring
55 # finish the docstring
56
56
57 file_extension = Unicode(
57 file_extension = Unicode(
58 'txt', config=True,
58 'txt', config=True,
59 help="Extension of the file that should be written to disk"
59 help="Extension of the file that should be written to disk"
60 )
60 )
61
61
62 #Configurability, allows the user to easily add transformers.
62 #Configurability, allows the user to easily add transformers.
63 transformers = List(config=True,
63 transformers = List(config=True,
64 help="""List of transformers, by name or namespace, to enable.""")
64 help="""List of transformers, by name or namespace, to enable.""")
65
65
66 _transformers = None
66 _transformers = None
67
67
68 default_transformers = List([nbtransformers.coalesce_streams,
68 default_transformers = List([nbtransformers.coalesce_streams,
69 nbtransformers.SVG2PDFTransformer,
69 nbtransformers.SVG2PDFTransformer,
70 nbtransformers.ExtractOutputTransformer,
70 nbtransformers.ExtractOutputTransformer,
71 nbtransformers.CSSHTMLHeaderTransformer,
71 nbtransformers.CSSHTMLHeaderTransformer,
72 nbtransformers.RevealHelpTransformer,
72 nbtransformers.RevealHelpTransformer,
73 nbtransformers.LatexTransformer,
73 nbtransformers.LatexTransformer,
74 nbtransformers.SphinxTransformer],
74 nbtransformers.SphinxTransformer],
75 config=True,
75 config=True,
76 help="""List of transformers available by default, by name, namespace,
76 help="""List of transformers available by default, by name, namespace,
77 instance, or type.""")
77 instance, or type.""")
78
78
79
79
80 def __init__(self, config=None, **kw):
80 def __init__(self, config=None, **kw):
81 """
81 """
82 Public constructor
82 Public constructor
83
83
84 Parameters
84 Parameters
85 ----------
85 ----------
86 config : config
86 config : config
87 User configuration instance.
87 User configuration instance.
88 """
88 """
89 if not config:
89 if not config:
90 config = self.default_config
90 config = self.default_config
91
91
92 super(BaseExporter, self).__init__(config=config, **kw)
92 super(BaseExporter, self).__init__(config=config, **kw)
93
93
94 #Init
94 #Init
95 self._init_transformers()
95 self._init_transformers()
96
96
97
97
98 @property
98 @property
99 def default_config(self):
99 def default_config(self):
100 return Config()
100 return Config()
101
101
102 def _config_changed(self, name, old, new):
102 def _config_changed(self, name, old, new):
103 """When setting config, make sure to start with our default_config"""
103 """When setting config, make sure to start with our default_config"""
104 c = self.default_config
104 c = self.default_config
105 if new:
105 if new:
106 c.merge(new)
106 c.merge(new)
107 if c != old:
107 if c != old:
108 self.config = c
108 self.config = c
109 super(BaseExporter, self)._config_changed(name, old, c)
109 super(BaseExporter, self)._config_changed(name, old, c)
110
110
111
111
112 def from_notebook_node(self, nb, resources=None):
112 def from_notebook_node(self, nb, resources=None):
113 """
113 """
114 Convert a notebook from a notebook node instance.
114 Convert a notebook from a notebook node instance.
115
115
116 Parameters
116 Parameters
117 ----------
117 ----------
118 nb : Notebook node
118 nb : Notebook node
119 resources : dict (**kw)
119 resources : dict (**kw)
120 of additional resources that can be accessed read/write by
120 of additional resources that can be accessed read/write by
121 transformers.
121 transformers.
122 """
122 """
123 nb_copy = copy.deepcopy(nb)
123 nb_copy = copy.deepcopy(nb)
124 resources = self._init_resources(resources)
124 resources = self._init_resources(resources)
125
125
126 # Preprocess
126 # Preprocess
127 nb_copy, resources = self._transform(nb_copy, resources)
127 nb_copy, resources = self._transform(nb_copy, resources)
128
128
129 return nb_copy, resources
129 return nb_copy, resources
130
130
131
131
132 def from_filename(self, filename, resources=None, **kw):
132 def from_filename(self, filename, resources=None, **kw):
133 """
133 """
134 Convert a notebook from a notebook file.
134 Convert a notebook from a notebook file.
135
135
136 Parameters
136 Parameters
137 ----------
137 ----------
138 filename : str
138 filename : str
139 Full filename of the notebook file to open and convert.
139 Full filename of the notebook file to open and convert.
140 """
140 """
141
141
142 #Pull the metadata from the filesystem.
142 #Pull the metadata from the filesystem.
143 if resources is None:
143 if resources is None:
144 resources = ResourcesDict()
144 resources = ResourcesDict()
145 if not 'metadata' in resources or resources['metadata'] == '':
145 if not 'metadata' in resources or resources['metadata'] == '':
146 resources['metadata'] = ResourcesDict()
146 resources['metadata'] = ResourcesDict()
147 basename = os.path.basename(filename)
147 basename = os.path.basename(filename)
148 notebook_name = basename[:basename.rfind('.')]
148 notebook_name = basename[:basename.rfind('.')]
149 resources['metadata']['name'] = notebook_name
149 resources['metadata']['name'] = notebook_name
150
150
151 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
151 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
152 resources['metadata']['modified_date'] = modified_date.strftime("%B %d, %Y")
152 resources['metadata']['modified_date'] = modified_date.strftime("%B %d, %Y")
153
153
154 with io.open(filename) as f:
154 with io.open(filename) as f:
155 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
155 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
156
156
157
157
158 def from_file(self, file_stream, resources=None, **kw):
158 def from_file(self, file_stream, resources=None, **kw):
159 """
159 """
160 Convert a notebook from a notebook file.
160 Convert a notebook from a notebook file.
161
161
162 Parameters
162 Parameters
163 ----------
163 ----------
164 file_stream : file-like object
164 file_stream : file-like object
165 Notebook file-like object to convert.
165 Notebook file-like object to convert.
166 """
166 """
167 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
167 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
168
168
169
169
170 def register_transformer(self, transformer, enabled=False):
170 def register_transformer(self, transformer, enabled=False):
171 """
171 """
172 Register a transformer.
172 Register a transformer.
173 Transformers are classes that act upon the notebook before it is
173 Transformers are classes that act upon the notebook before it is
174 passed into the Jinja templating engine. Transformers are also
174 passed into the Jinja templating engine. Transformers are also
175 capable of passing additional information to the Jinja
175 capable of passing additional information to the Jinja
176 templating engine.
176 templating engine.
177
177
178 Parameters
178 Parameters
179 ----------
179 ----------
180 transformer : transformer
180 transformer : transformer
181 """
181 """
182 if transformer is None:
182 if transformer is None:
183 raise TypeError('transformer')
183 raise TypeError('transformer')
184 isclass = isinstance(transformer, type)
184 isclass = isinstance(transformer, type)
185 constructed = not isclass
185 constructed = not isclass
186
186
187 #Handle transformer's registration based on it's type
187 #Handle transformer's registration based on it's type
188 if constructed and isinstance(transformer, py3compat.string_types):
188 if constructed and isinstance(transformer, py3compat.string_types):
189 #Transformer is a string, import the namespace and recursively call
189 #Transformer is a string, import the namespace and recursively call
190 #this register_transformer method
190 #this register_transformer method
191 transformer_cls = import_item(transformer)
191 transformer_cls = import_item(transformer)
192 return self.register_transformer(transformer_cls, enabled)
192 return self.register_transformer(transformer_cls, enabled)
193
193
194 if constructed and hasattr(transformer, '__call__'):
194 if constructed and hasattr(transformer, '__call__'):
195 #Transformer is a function, no need to construct it.
195 #Transformer is a function, no need to construct it.
196 #Register and return the transformer.
196 #Register and return the transformer.
197 if enabled:
197 if enabled:
198 transformer.enabled = True
198 transformer.enabled = True
199 self._transformers.append(transformer)
199 self._transformers.append(transformer)
200 return transformer
200 return transformer
201
201
202 elif isclass and isinstance(transformer, MetaHasTraits):
202 elif isclass and isinstance(transformer, MetaHasTraits):
203 #Transformer is configurable. Make sure to pass in new default for
203 #Transformer is configurable. Make sure to pass in new default for
204 #the enabled flag if one was specified.
204 #the enabled flag if one was specified.
205 self.register_transformer(transformer(parent=self), enabled)
205 self.register_transformer(transformer(parent=self), enabled)
206
206
207 elif isclass:
207 elif isclass:
208 #Transformer is not configurable, construct it
208 #Transformer is not configurable, construct it
209 self.register_transformer(transformer(), enabled)
209 self.register_transformer(transformer(), enabled)
210
210
211 else:
211 else:
212 #Transformer is an instance of something without a __call__
212 #Transformer is an instance of something without a __call__
213 #attribute.
213 #attribute.
214 raise TypeError('transformer')
214 raise TypeError('transformer')
215
215
216
216
217 def _init_transformers(self):
217 def _init_transformers(self):
218 """
218 """
219 Register all of the transformers needed for this exporter, disabled
219 Register all of the transformers needed for this exporter, disabled
220 unless specified explicitly.
220 unless specified explicitly.
221 """
221 """
222 if self._transformers is None:
222 if self._transformers is None:
223 self._transformers = []
223 self._transformers = []
224
224
225 #Load default transformers (not necessarly enabled by default).
225 #Load default transformers (not necessarly enabled by default).
226 if self.default_transformers:
226 if self.default_transformers:
227 for transformer in self.default_transformers:
227 for transformer in self.default_transformers:
228 self.register_transformer(transformer)
228 self.register_transformer(transformer)
229
229
230 #Load user transformers. Enable by default.
230 #Load user transformers. Enable by default.
231 if self.transformers:
231 if self.transformers:
232 for transformer in self.transformers:
232 for transformer in self.transformers:
233 self.register_transformer(transformer, enabled=True)
233 self.register_transformer(transformer, enabled=True)
234
234
235
235
236 def _init_resources(self, resources):
236 def _init_resources(self, resources):
237
237
238 #Make sure the resources dict is of ResourcesDict type.
238 #Make sure the resources dict is of ResourcesDict type.
239 if resources is None:
239 if resources is None:
240 resources = ResourcesDict()
240 resources = ResourcesDict()
241 if not isinstance(resources, ResourcesDict):
241 if not isinstance(resources, ResourcesDict):
242 new_resources = ResourcesDict()
242 new_resources = ResourcesDict()
243 new_resources.update(resources)
243 new_resources.update(resources)
244 resources = new_resources
244 resources = new_resources
245
245
246 #Make sure the metadata extension exists in resources
246 #Make sure the metadata extension exists in resources
247 if 'metadata' in resources:
247 if 'metadata' in resources:
248 if not isinstance(resources['metadata'], ResourcesDict):
248 if not isinstance(resources['metadata'], ResourcesDict):
249 resources['metadata'] = ResourcesDict(resources['metadata'])
249 resources['metadata'] = ResourcesDict(resources['metadata'])
250 else:
250 else:
251 resources['metadata'] = ResourcesDict()
251 resources['metadata'] = ResourcesDict()
252 if not resources['metadata']['name']:
252 if not resources['metadata']['name']:
253 resources['metadata']['name'] = 'Notebook'
253 resources['metadata']['name'] = 'Notebook'
254
254
255 #Set the output extension
255 #Set the output extension
256 resources['output_extension'] = self.file_extension
256 resources['output_extension'] = self.file_extension
257 return resources
257 return resources
258
258
259
259
260 def _transform(self, nb, resources):
260 def _transform(self, nb, resources):
261 """
261 """
262 Preprocess the notebook before passing it into the Jinja engine.
262 Preprocess the notebook before passing it into the Jinja engine.
263 To preprocess the notebook is to apply all of the
263 To preprocess the notebook is to apply all of the
264
264
265 Parameters
265 Parameters
266 ----------
266 ----------
267 nb : notebook node
267 nb : notebook node
268 notebook that is being exported.
268 notebook that is being exported.
269 resources : a dict of additional resources that
269 resources : a dict of additional resources that
270 can be accessed read/write by transformers
270 can be accessed read/write by transformers
271 """
271 """
272
272
273 # Do a copy.deepcopy first,
273 # Do a copy.deepcopy first,
274 # we are never safe enough with what the transformers could do.
274 # we are never safe enough with what the transformers could do.
275 nbc = copy.deepcopy(nb)
275 nbc = copy.deepcopy(nb)
276 resc = copy.deepcopy(resources)
276 resc = copy.deepcopy(resources)
277
277
278 #Run each transformer on the notebook. Carry the output along
278 #Run each transformer on the notebook. Carry the output along
279 #to each transformer
279 #to each transformer
280 for transformer in self._transformers:
280 for transformer in self._transformers:
281 nbc, resc = transformer(nbc, resc)
281 nbc, resc = transformer(nbc, resc)
282 return nbc, resc
282 return nbc, resc
@@ -1,169 +1,169 b''
1 """
1 """
2 Module containing single call export functions.
2 Module containing single call export functions.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
5 # Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from functools import wraps
16 from functools import wraps
17
17
18 from IPython.nbformat.v3.nbbase import NotebookNode
18 from IPython.nbformat.v3.nbbase import NotebookNode
19 from IPython.config import Config
19 from IPython.config import Config
20
20
21 from .exporter import Exporter
21 from .exporter import TemplateExporter
22 from .html import HTMLExporter
22 from .html import HTMLExporter
23 from .slides import SlidesExporter
23 from .slides import SlidesExporter
24 from .latex import LatexExporter
24 from .latex import LatexExporter
25 from .markdown import MarkdownExporter
25 from .markdown import MarkdownExporter
26 from .python import PythonExporter
26 from .python import PythonExporter
27 from .rst import RSTExporter
27 from .rst import RSTExporter
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Classes
30 # Classes
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 def DocDecorator(f):
33 def DocDecorator(f):
34
34
35 #Set docstring of function
35 #Set docstring of function
36 f.__doc__ = f.__doc__ + """
36 f.__doc__ = f.__doc__ + """
37 nb : Notebook node
37 nb : Notebook node
38 config : config (optional, keyword arg)
38 config : config (optional, keyword arg)
39 User configuration instance.
39 User configuration instance.
40 resources : dict (optional, keyword arg)
40 resources : dict (optional, keyword arg)
41 Resources used in the conversion process.
41 Resources used in the conversion process.
42
42
43 Returns
43 Returns
44 ----------
44 ----------
45 tuple- output, resources, exporter_instance
45 tuple- output, resources, exporter_instance
46 output : str
46 output : str
47 Jinja 2 output. This is the resulting converted notebook.
47 Jinja 2 output. This is the resulting converted notebook.
48 resources : dictionary
48 resources : dictionary
49 Dictionary of resources used prior to and during the conversion
49 Dictionary of resources used prior to and during the conversion
50 process.
50 process.
51 exporter_instance : Exporter
51 exporter_instance : Exporter
52 Instance of the Exporter class used to export the document. Useful
52 Instance of the Exporter class used to export the document. Useful
53 to caller because it provides a 'file_extension' property which
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
55
56 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT
56 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT
57 """
57 """
58
58
59 @wraps(f)
59 @wraps(f)
60 def decorator(*args, **kwargs):
60 def decorator(*args, **kwargs):
61 return f(*args, **kwargs)
61 return f(*args, **kwargs)
62
62
63 return decorator
63 return decorator
64
64
65
65
66 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
67 # Functions
67 # Functions
68 #-----------------------------------------------------------------------------
68 #-----------------------------------------------------------------------------
69
69
70 __all__ = [
70 __all__ = [
71 'export',
71 'export',
72 'export_html',
72 'export_html',
73 'export_custom',
73 'export_custom',
74 'export_slides',
74 'export_slides',
75 'export_latex',
75 'export_latex',
76 'export_markdown',
76 'export_markdown',
77 'export_python',
77 'export_python',
78 'export_rst',
78 'export_rst',
79 'export_by_name',
79 'export_by_name',
80 'get_export_names',
80 'get_export_names',
81 'ExporterNameError'
81 'ExporterNameError'
82 ]
82 ]
83
83
84
84
85 class ExporterNameError(NameError):
85 class ExporterNameError(NameError):
86 pass
86 pass
87
87
88 @DocDecorator
88 @DocDecorator
89 def export(exporter, nb, **kw):
89 def export(exporter, nb, **kw):
90 """
90 """
91 Export a notebook object using specific exporter class.
91 Export a notebook object using specific exporter class.
92
92
93 exporter : Exporter class type or instance
93 exporter : Exporter class type or instance
94 Class type or instance of the exporter that should be used. If the
94 Class type or instance of the exporter that should be used. If the
95 method initializes it's own instance of the class, it is ASSUMED that
95 method initializes it's own instance of the class, it is ASSUMED that
96 the class type provided exposes a constructor (__init__) with the same
96 the class type provided exposes a constructor (__init__) with the same
97 signature as the base Exporter class.
97 signature as the base Exporter class.
98 """
98 """
99
99
100 #Check arguments
100 #Check arguments
101 if exporter is None:
101 if exporter is None:
102 raise TypeError("Exporter is None")
102 raise TypeError("Exporter is None")
103 elif not isinstance(exporter, Exporter) and not issubclass(exporter, Exporter):
103 elif not isinstance(exporter, TemplateExporter) and not issubclass(exporter, TemplateExporter):
104 raise TypeError("exporter does not inherit from Exporter (base)")
104 raise TypeError("exporter does not inherit from Exporter (base)")
105 if nb is None:
105 if nb is None:
106 raise TypeError("nb is None")
106 raise TypeError("nb is None")
107
107
108 #Create the exporter
108 #Create the exporter
109 resources = kw.pop('resources', None)
109 resources = kw.pop('resources', None)
110 if isinstance(exporter, Exporter):
110 if isinstance(exporter, TemplateExporter):
111 exporter_instance = exporter
111 exporter_instance = exporter
112 else:
112 else:
113 exporter_instance = exporter(**kw)
113 exporter_instance = exporter(**kw)
114
114
115 #Try to convert the notebook using the appropriate conversion function.
115 #Try to convert the notebook using the appropriate conversion function.
116 if isinstance(nb, NotebookNode):
116 if isinstance(nb, NotebookNode):
117 output, resources = exporter_instance.from_notebook_node(nb, resources)
117 output, resources = exporter_instance.from_notebook_node(nb, resources)
118 elif isinstance(nb, basestring):
118 elif isinstance(nb, basestring):
119 output, resources = exporter_instance.from_filename(nb, resources)
119 output, resources = exporter_instance.from_filename(nb, resources)
120 else:
120 else:
121 output, resources = exporter_instance.from_file(nb, resources)
121 output, resources = exporter_instance.from_file(nb, resources)
122 return output, resources
122 return output, resources
123
123
124 exporter_map = dict(
124 exporter_map = dict(
125 custom=Exporter,
125 custom=TemplateExporter,
126 html=HTMLExporter,
126 html=HTMLExporter,
127 slides=SlidesExporter,
127 slides=SlidesExporter,
128 latex=LatexExporter,
128 latex=LatexExporter,
129 markdown=MarkdownExporter,
129 markdown=MarkdownExporter,
130 python=PythonExporter,
130 python=PythonExporter,
131 rst=RSTExporter,
131 rst=RSTExporter,
132 )
132 )
133
133
134 def _make_exporter(name, E):
134 def _make_exporter(name, E):
135 """make an export_foo function from a short key and Exporter class E"""
135 """make an export_foo function from a short key and Exporter class E"""
136 def _export(nb, **kw):
136 def _export(nb, **kw):
137 return export(E, nb, **kw)
137 return export(E, nb, **kw)
138 _export.__doc__ = """Export a notebook object to {0} format""".format(name)
138 _export.__doc__ = """Export a notebook object to {0} format""".format(name)
139 return _export
139 return _export
140
140
141 g = globals()
141 g = globals()
142
142
143 for name, E in exporter_map.items():
143 for name, E in exporter_map.items():
144 g['export_%s' % name] = DocDecorator(_make_exporter(name, E))
144 g['export_%s' % name] = DocDecorator(_make_exporter(name, E))
145
145
146 @DocDecorator
146 @DocDecorator
147 def export_by_name(format_name, nb, **kw):
147 def export_by_name(format_name, nb, **kw):
148 """
148 """
149 Export a notebook object to a template type by its name. Reflection
149 Export a notebook object to a template type by its name. Reflection
150 (Inspect) is used to find the template's corresponding explicit export
150 (Inspect) is used to find the template's corresponding explicit export
151 method defined in this module. That method is then called directly.
151 method defined in this module. That method is then called directly.
152
152
153 format_name : str
153 format_name : str
154 Name of the template style to export to.
154 Name of the template style to export to.
155 """
155 """
156
156
157 function_name = "export_" + format_name.lower()
157 function_name = "export_" + format_name.lower()
158
158
159 if function_name in globals():
159 if function_name in globals():
160 return globals()[function_name](nb, **kw)
160 return globals()[function_name](nb, **kw)
161 else:
161 else:
162 raise ExporterNameError("template for `%s` not found" % function_name)
162 raise ExporterNameError("template for `%s` not found" % function_name)
163
163
164
164
165 def get_export_names():
165 def get_export_names():
166 """Return a list of the currently supported export targets
166 """Return a list of the currently supported export targets
167
167
168 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT"""
168 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT"""
169 return sorted(exporter_map.keys())
169 return sorted(exporter_map.keys())
@@ -1,52 +1,52 b''
1 """
1 """
2 Exporter that exports Basic HTML.
2 Exporter that exports Basic HTML.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from IPython.utils.traitlets import Unicode, List
17 from IPython.utils.traitlets import Unicode, List
18
18
19 from IPython.nbconvert import preprocessors
19 from IPython.nbconvert import preprocessors
20 from IPython.config import Config
20 from IPython.config import Config
21
21
22 from .exporter import Exporter
22 from .exporter import TemplateExporter
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Classes
25 # Classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 class HTMLExporter(Exporter):
28 class HTMLExporter(TemplateExporter):
29 """
29 """
30 Exports a basic HTML document. This exporter assists with the export of
30 Exports a basic HTML document. This exporter assists with the export of
31 HTML. Inherit from it if you are writing your own HTML template and need
31 HTML. Inherit from it if you are writing your own HTML template and need
32 custom preprocessors/filters. If you don't need custom preprocessors/
32 custom preprocessors/filters. If you don't need custom preprocessors/
33 filters, just change the 'template_file' config option.
33 filters, just change the 'template_file' config option.
34 """
34 """
35
35
36 file_extension = Unicode(
36 file_extension = Unicode(
37 'html', config=True,
37 'html', config=True,
38 help="Extension of the file that should be written to disk"
38 help="Extension of the file that should be written to disk"
39 )
39 )
40
40
41 default_template = Unicode('full', config=True, help="""Flavor of the data
41 default_template = Unicode('full', config=True, help="""Flavor of the data
42 format to use. I.E. 'full' or 'basic'""")
42 format to use. I.E. 'full' or 'basic'""")
43
43
44 @property
44 @property
45 def default_config(self):
45 def default_config(self):
46 c = Config({
46 c = Config({
47 'CSSHTMLHeaderPreprocessor':{
47 'CSSHTMLHeaderPreprocessor':{
48 'enabled':True
48 'enabled':True
49 }
49 }
50 })
50 })
51 c.merge(super(HTMLExporter,self).default_config)
51 c.merge(super(HTMLExporter,self).default_config)
52 return c
52 return c
@@ -1,38 +1,38 b''
1 """
1 """
2 Exporter that will export your ipynb to Markdown.
2 Exporter that will export your ipynb to Markdown.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
5 # Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from IPython.config import Config
16 from IPython.config import Config
17 from IPython.utils.traitlets import Unicode
17 from IPython.utils.traitlets import Unicode
18
18
19 from .exporter import Exporter
19 from .exporter import TemplateExporter
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Classes
22 # Classes
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 class MarkdownExporter(Exporter):
25 class MarkdownExporter(TemplateExporter):
26 """
26 """
27 Exports to a markdown document (.md)
27 Exports to a markdown document (.md)
28 """
28 """
29
29
30 file_extension = Unicode(
30 file_extension = Unicode(
31 'md', config=True,
31 'md', config=True,
32 help="Extension of the file that should be written to disk")
32 help="Extension of the file that should be written to disk")
33
33
34 @property
34 @property
35 def default_config(self):
35 def default_config(self):
36 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
36 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
37 c.merge(super(MarkdownExporter,self).default_config)
37 c.merge(super(MarkdownExporter,self).default_config)
38 return c
38 return c
@@ -1,31 +1,31 b''
1 """
1 """
2 Python exporter which exports Notebook code into a PY file.
2 Python exporter which exports Notebook code into a PY file.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
5 # Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from IPython.utils.traitlets import Unicode
16 from IPython.utils.traitlets import Unicode
17
17
18 from .exporter import Exporter
18 from .exporter import TemplateExporter
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Classes
21 # Classes
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 class PythonExporter(Exporter):
24 class PythonExporter(TemplateExporter):
25 """
25 """
26 Exports a Python code file.
26 Exports a Python code file.
27 """
27 """
28
28
29 file_extension = Unicode(
29 file_extension = Unicode(
30 'py', config=True,
30 'py', config=True,
31 help="Extension of the file that should be written to disk")
31 help="Extension of the file that should be written to disk")
@@ -1,38 +1,38 b''
1 """
1 """
2 Exporter for exporting notebooks to restructured text.
2 Exporter for exporting notebooks to restructured text.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
5 # Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from IPython.utils.traitlets import Unicode
16 from IPython.utils.traitlets import Unicode
17 from IPython.config import Config
17 from IPython.config import Config
18
18
19 from .exporter import Exporter
19 from .exporter import TemplateExporter
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Classes
22 # Classes
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 class RSTExporter(Exporter):
25 class RSTExporter(TemplateExporter):
26 """
26 """
27 Exports restructured text documents.
27 Exports restructured text documents.
28 """
28 """
29
29
30 file_extension = Unicode(
30 file_extension = Unicode(
31 'rst', config=True,
31 'rst', config=True,
32 help="Extension of the file that should be written to disk")
32 help="Extension of the file that should be written to disk")
33
33
34 @property
34 @property
35 def default_config(self):
35 def default_config(self):
36 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
36 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
37 c.merge(super(RSTExporter,self).default_config)
37 c.merge(super(RSTExporter,self).default_config)
38 return c
38 return c
@@ -1,52 +1,52 b''
1 """
1 """
2 Contains slide show exporter
2 Contains slide show exporter
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from IPython.utils.traitlets import Unicode
17 from IPython.utils.traitlets import Unicode
18
18
19 from IPython.nbconvert import preprocessors
19 from IPython.nbconvert import preprocessors
20 from IPython.config import Config
20 from IPython.config import Config
21
21
22 from .exporter import Exporter
22 from .exporter import TemplateExporter
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Classes
25 # Classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 class SlidesExporter(Exporter):
28 class SlidesExporter(TemplateExporter):
29 """
29 """
30 Exports slides
30 Exports slides
31 """
31 """
32
32
33 file_extension = Unicode(
33 file_extension = Unicode(
34 'slides.html', config=True,
34 'slides.html', config=True,
35 help="Extension of the file that should be written to disk"
35 help="Extension of the file that should be written to disk"
36 )
36 )
37
37
38 default_template = Unicode('reveal', config=True, help="""Template of the
38 default_template = Unicode('reveal', config=True, help="""Template of the
39 data format to use. I.E. 'reveal'""")
39 data format to use. I.E. 'reveal'""")
40
40
41 @property
41 @property
42 def default_config(self):
42 def default_config(self):
43 c = Config({
43 c = Config({
44 'CSSHTMLHeaderPreprocessor':{
44 'CSSHTMLHeaderPreprocessor':{
45 'enabled':True
45 'enabled':True
46 },
46 },
47 'RevealHelpPreprocessor':{
47 'RevealHelpPreprocessor':{
48 'enabled':True,
48 'enabled':True,
49 },
49 },
50 })
50 })
51 c.merge(super(SlidesExporter,self).default_config)
51 c.merge(super(SlidesExporter,self).default_config)
52 return c
52 return c
@@ -1,30 +1,30 b''
1 """
1 """
2 Module with tests base for exporters
2 Module with tests base for exporters
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import os
17 import os
18
18
19 from ...tests.base import TestsBase
19 from ...tests.base import TestsBase
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Class
22 # Class
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 class ExportersTestsBase(TestsBase):
25 class ExportersTestsBase(TestsBase):
26 """Contains base test functions for exporters"""
26 """Contains base test functions for exporters"""
27
27
28 def _get_notebook(self):
28 def _get_notebook(self):
29 return os.path.join(self._get_files_path(), 'notebook2.ipynb')
29 return os.path.join(self._get_files_path(), 'notebook2.ipynb')
30 No newline at end of file
30
@@ -1,102 +1,102 b''
1 """
1 """
2 Module with tests for export.py
2 Module with tests for export.py
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import os
17 import os
18
18
19 from IPython.nbformat import current as nbformat
19 from IPython.nbformat import current as nbformat
20
20
21 from .base import ExportersTestsBase
21 from .base import ExportersTestsBase
22 from ..export import *
22 from ..export import *
23 from ..python import PythonExporter
23 from ..python import PythonExporter
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Class
26 # Class
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 class TestExport(ExportersTestsBase):
29 class TestExport(ExportersTestsBase):
30 """Contains test functions for export.py"""
30 """Contains test functions for export.py"""
31
31
32
32
33 def test_export_wrong_name(self):
33 def test_export_wrong_name(self):
34 """
34 """
35 Is the right error thrown when a bad template name is used?
35 Is the right error thrown when a bad template name is used?
36 """
36 """
37 try:
37 try:
38 export_by_name('not_a_name', self._get_notebook())
38 export_by_name('not_a_name', self._get_notebook())
39 except ExporterNameError as e:
39 except ExporterNameError as e:
40 pass
40 pass
41
41
42
42
43 def test_export_filename(self):
43 def test_export_filename(self):
44 """
44 """
45 Can a notebook be exported by filename?
45 Can a notebook be exported by filename?
46 """
46 """
47 (output, resources) = export_by_name('python', self._get_notebook())
47 (output, resources) = export_by_name('python', self._get_notebook())
48 assert len(output) > 0
48 assert len(output) > 0
49
49
50
50
51 def test_export_nbnode(self):
51 def test_export_nbnode(self):
52 """
52 """
53 Can a notebook be exported by a notebook node handle?
53 Can a notebook be exported by a notebook node handle?
54 """
54 """
55 with open(self._get_notebook(), 'r') as f:
55 with open(self._get_notebook(), 'r') as f:
56 notebook = nbformat.read(f, 'json')
56 notebook = nbformat.read(f, 'json')
57 (output, resources) = export_by_name('python', notebook)
57 (output, resources) = export_by_name('python', notebook)
58 assert len(output) > 0
58 assert len(output) > 0
59
59
60
60
61 def test_export_filestream(self):
61 def test_export_filestream(self):
62 """
62 """
63 Can a notebook be exported by a filesteam?
63 Can a notebook be exported by a filesteam?
64 """
64 """
65 with open(self._get_notebook(), 'r') as f:
65 with open(self._get_notebook(), 'r') as f:
66 (output, resources) = export_by_name('python', f)
66 (output, resources) = export_by_name('python', f)
67 assert len(output) > 0
67 assert len(output) > 0
68
68
69
69
70 def test_export_using_exporter(self):
70 def test_export_using_exporter(self):
71 """
71 """
72 Can a notebook be exported using an instanciated exporter?
72 Can a notebook be exported using an instanciated exporter?
73 """
73 """
74 (output, resources) = export(PythonExporter(), self._get_notebook())
74 (output, resources) = export(PythonExporter(), self._get_notebook())
75 assert len(output) > 0
75 assert len(output) > 0
76
76
77
77
78 def test_export_using_exporter_class(self):
78 def test_export_using_exporter_class(self):
79 """
79 """
80 Can a notebook be exported using an exporter class type?
80 Can a notebook be exported using an exporter class type?
81 """
81 """
82 (output, resources) = export(PythonExporter, self._get_notebook())
82 (output, resources) = export(PythonExporter, self._get_notebook())
83 assert len(output) > 0
83 assert len(output) > 0
84
84
85
85
86 def test_export_resources(self):
86 def test_export_resources(self):
87 """
87 """
88 Can a notebook be exported along with a custom resources dict?
88 Can a notebook be exported along with a custom resources dict?
89 """
89 """
90 (output, resources) = export(PythonExporter, self._get_notebook(), resources={})
90 (output, resources) = export(PythonExporter, self._get_notebook(), resources={})
91 assert len(output) > 0
91 assert len(output) > 0
92
92
93
93
94 def test_no_exporter(self):
94 def test_no_exporter(self):
95 """
95 """
96 Is the right error thrown if no exporter is provided?
96 Is the right error thrown if no exporter is provided?
97 """
97 """
98 try:
98 try:
99 (output, resources) = export(None, self._get_notebook())
99 (output, resources) = export(None, self._get_notebook())
100 except TypeError:
100 except TypeError:
101 pass
101 pass
102 No newline at end of file
102
@@ -1,324 +1,324 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """NBConvert is a utility for conversion of .ipynb files.
2 """NBConvert is a utility for conversion of .ipynb files.
3
3
4 Command-line interface for the NbConvert conversion utility.
4 Command-line interface for the NbConvert conversion utility.
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 #Copyright (c) 2013, the IPython Development Team.
7 #Copyright (c) 2013, the IPython Development Team.
8 #
8 #
9 #Distributed under the terms of the Modified BSD License.
9 #Distributed under the terms of the Modified BSD License.
10 #
10 #
11 #The full license is in the file COPYING.txt, distributed with this software.
11 #The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 #Imports
15 #Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Stdlib imports
18 # Stdlib imports
19 from __future__ import print_function
19 from __future__ import print_function
20
20
21 import logging
21 import logging
22 import sys
22 import sys
23 import os
23 import os
24 import glob
24 import glob
25
25
26 # From IPython
26 # From IPython
27 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
27 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
28 from IPython.core.profiledir import ProfileDir
28 from IPython.core.profiledir import ProfileDir
29 from IPython.config import catch_config_error, Configurable
29 from IPython.config import catch_config_error, Configurable
30 from IPython.utils.traitlets import (
30 from IPython.utils.traitlets import (
31 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
31 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
32 )
32 )
33 from IPython.utils.importstring import import_item
33 from IPython.utils.importstring import import_item
34 from IPython.utils.text import dedent
34 from IPython.utils.text import dedent
35
35
36 from .exporters.export import get_export_names, exporter_map
36 from .exporters.export import get_export_names, exporter_map
37 from IPython.nbconvert import exporters, preprocessors, writers, postprocessors
37 from IPython.nbconvert import exporters, preprocessors, writers, postprocessors
38 from .utils.base import NbConvertBase
38 from .utils.base import NbConvertBase
39 from .utils.exceptions import ConversionException
39 from .utils.exceptions import ConversionException
40
40
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42 #Classes and functions
42 #Classes and functions
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44
44
45 class DottedOrNone(DottedObjectName):
45 class DottedOrNone(DottedObjectName):
46 """
46 """
47 A string holding a valid dotted object name in Python, such as A.b3._c
47 A string holding a valid dotted object name in Python, such as A.b3._c
48 Also allows for None type."""
48 Also allows for None type."""
49
49
50 default_value = u''
50 default_value = u''
51
51
52 def validate(self, obj, value):
52 def validate(self, obj, value):
53 if value is not None and len(value) > 0:
53 if value is not None and len(value) > 0:
54 return super(DottedOrNone, self).validate(obj, value)
54 return super(DottedOrNone, self).validate(obj, value)
55 else:
55 else:
56 return value
56 return value
57
57
58 nbconvert_aliases = {}
58 nbconvert_aliases = {}
59 nbconvert_aliases.update(base_aliases)
59 nbconvert_aliases.update(base_aliases)
60 nbconvert_aliases.update({
60 nbconvert_aliases.update({
61 'to' : 'NbConvertApp.export_format',
61 'to' : 'NbConvertApp.export_format',
62 'template' : 'Exporter.template_file',
62 'template' : 'TemplateExporter.template_file',
63 'writer' : 'NbConvertApp.writer_class',
63 'writer' : 'NbConvertApp.writer_class',
64 'post': 'NbConvertApp.postprocessor_class',
64 'post': 'NbConvertApp.postprocessor_class',
65 'output': 'NbConvertApp.output_base',
65 'output': 'NbConvertApp.output_base',
66 'offline-slides': 'RevealHelpPreprocessor.url_prefix',
66 'offline-slides': 'RevealHelpPreprocessor.url_prefix',
67 'slide-notes': 'RevealHelpPreprocessor.speaker_notes'
67 'slide-notes': 'RevealHelpPreprocessor.speaker_notes'
68 })
68 })
69
69
70 nbconvert_flags = {}
70 nbconvert_flags = {}
71 nbconvert_flags.update(base_flags)
71 nbconvert_flags.update(base_flags)
72 nbconvert_flags.update({
72 nbconvert_flags.update({
73 'stdout' : (
73 'stdout' : (
74 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
74 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
75 "Write notebook output to stdout instead of files."
75 "Write notebook output to stdout instead of files."
76 )
76 )
77 })
77 })
78
78
79
79
80 class NbConvertApp(BaseIPythonApplication):
80 class NbConvertApp(BaseIPythonApplication):
81 """Application used to convert to and from notebook file type (*.ipynb)"""
81 """Application used to convert to and from notebook file type (*.ipynb)"""
82
82
83 name = 'ipython-nbconvert'
83 name = 'ipython-nbconvert'
84 aliases = nbconvert_aliases
84 aliases = nbconvert_aliases
85 flags = nbconvert_flags
85 flags = nbconvert_flags
86
86
87 def _log_level_default(self):
87 def _log_level_default(self):
88 return logging.INFO
88 return logging.INFO
89
89
90 def _classes_default(self):
90 def _classes_default(self):
91 classes = [NbConvertBase, ProfileDir]
91 classes = [NbConvertBase, ProfileDir]
92 for pkg in (exporters, preprocessors, writers):
92 for pkg in (exporters, preprocessors, writers):
93 for name in dir(pkg):
93 for name in dir(pkg):
94 cls = getattr(pkg, name)
94 cls = getattr(pkg, name)
95 if isinstance(cls, type) and issubclass(cls, Configurable):
95 if isinstance(cls, type) and issubclass(cls, Configurable):
96 classes.append(cls)
96 classes.append(cls)
97
97
98 return classes
98 return classes
99
99
100 description = Unicode(
100 description = Unicode(
101 u"""This application is used to convert notebook files (*.ipynb)
101 u"""This application is used to convert notebook files (*.ipynb)
102 to various other formats.
102 to various other formats.
103
103
104 WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""")
104 WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""")
105
105
106 output_base = Unicode('', config=True, help='''overwrite base name use for output files.
106 output_base = Unicode('', config=True, help='''overwrite base name use for output files.
107 can only be use when converting one notebook at a time.
107 can only be use when converting one notebook at a time.
108 ''')
108 ''')
109
109
110 examples = Unicode(u"""
110 examples = Unicode(u"""
111 The simplest way to use nbconvert is
111 The simplest way to use nbconvert is
112
112
113 > ipython nbconvert mynotebook.ipynb
113 > ipython nbconvert mynotebook.ipynb
114
114
115 which will convert mynotebook.ipynb to the default format (probably HTML).
115 which will convert mynotebook.ipynb to the default format (probably HTML).
116
116
117 You can specify the export format with `--to`.
117 You can specify the export format with `--to`.
118 Options include {0}
118 Options include {0}
119
119
120 > ipython nbconvert --to latex mynotebook.ipnynb
120 > ipython nbconvert --to latex mynotebook.ipnynb
121
121
122 Both HTML and LaTeX support multiple output templates. LaTeX includes
122 Both HTML and LaTeX support multiple output templates. LaTeX includes
123 'basic', 'book', and 'article'. HTML includes 'basic' and 'full'. You
123 'basic', 'book', and 'article'. HTML includes 'basic' and 'full'. You
124 can specify the flavor of the format used.
124 can specify the flavor of the format used.
125
125
126 > ipython nbconvert --to html --template basic mynotebook.ipynb
126 > ipython nbconvert --to html --template basic mynotebook.ipynb
127
127
128 You can also pipe the output to stdout, rather than a file
128 You can also pipe the output to stdout, rather than a file
129
129
130 > ipython nbconvert mynotebook.ipynb --stdout
130 > ipython nbconvert mynotebook.ipynb --stdout
131
131
132 A post-processor can be used to compile a PDF
132 A post-processor can be used to compile a PDF
133
133
134 > ipython nbconvert mynotebook.ipynb --to latex --post PDF
134 > ipython nbconvert mynotebook.ipynb --to latex --post PDF
135
135
136 You can get (and serve) a Reveal.js-powered slideshow
136 You can get (and serve) a Reveal.js-powered slideshow
137
137
138 > ipython nbconvert myslides.ipynb --to slides --post serve
138 > ipython nbconvert myslides.ipynb --to slides --post serve
139
139
140 Multiple notebooks can be given at the command line in a couple of
140 Multiple notebooks can be given at the command line in a couple of
141 different ways:
141 different ways:
142
142
143 > ipython nbconvert notebook*.ipynb
143 > ipython nbconvert notebook*.ipynb
144 > ipython nbconvert notebook1.ipynb notebook2.ipynb
144 > ipython nbconvert notebook1.ipynb notebook2.ipynb
145
145
146 or you can specify the notebooks list in a config file, containing::
146 or you can specify the notebooks list in a config file, containing::
147
147
148 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
148 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
149
149
150 > ipython nbconvert --config mycfg.py
150 > ipython nbconvert --config mycfg.py
151 """.format(get_export_names()))
151 """.format(get_export_names()))
152
152
153 # Writer specific variables
153 # Writer specific variables
154 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
154 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
155 help="""Instance of the writer class used to write the
155 help="""Instance of the writer class used to write the
156 results of the conversion.""")
156 results of the conversion.""")
157 writer_class = DottedObjectName('FilesWriter', config=True,
157 writer_class = DottedObjectName('FilesWriter', config=True,
158 help="""Writer class used to write the
158 help="""Writer class used to write the
159 results of the conversion""")
159 results of the conversion""")
160 writer_aliases = {'fileswriter': 'IPython.nbconvert.writers.files.FilesWriter',
160 writer_aliases = {'fileswriter': 'IPython.nbconvert.writers.files.FilesWriter',
161 'debugwriter': 'IPython.nbconvert.writers.debug.DebugWriter',
161 'debugwriter': 'IPython.nbconvert.writers.debug.DebugWriter',
162 'stdoutwriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
162 'stdoutwriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
163 writer_factory = Type()
163 writer_factory = Type()
164
164
165 def _writer_class_changed(self, name, old, new):
165 def _writer_class_changed(self, name, old, new):
166 if new.lower() in self.writer_aliases:
166 if new.lower() in self.writer_aliases:
167 new = self.writer_aliases[new.lower()]
167 new = self.writer_aliases[new.lower()]
168 self.writer_factory = import_item(new)
168 self.writer_factory = import_item(new)
169
169
170 # Post-processor specific variables
170 # Post-processor specific variables
171 postprocessor = Instance('IPython.nbconvert.postprocessors.base.PostProcessorBase',
171 postprocessor = Instance('IPython.nbconvert.postprocessors.base.PostProcessorBase',
172 help="""Instance of the PostProcessor class used to write the
172 help="""Instance of the PostProcessor class used to write the
173 results of the conversion.""")
173 results of the conversion.""")
174
174
175 postprocessor_class = DottedOrNone(config=True,
175 postprocessor_class = DottedOrNone(config=True,
176 help="""PostProcessor class used to write the
176 help="""PostProcessor class used to write the
177 results of the conversion""")
177 results of the conversion""")
178 postprocessor_aliases = {'pdf': 'IPython.nbconvert.postprocessors.pdf.PDFPostProcessor',
178 postprocessor_aliases = {'pdf': 'IPython.nbconvert.postprocessors.pdf.PDFPostProcessor',
179 'serve': 'IPython.nbconvert.postprocessors.serve.ServePostProcessor'}
179 'serve': 'IPython.nbconvert.postprocessors.serve.ServePostProcessor'}
180 postprocessor_factory = Type()
180 postprocessor_factory = Type()
181
181
182 def _postprocessor_class_changed(self, name, old, new):
182 def _postprocessor_class_changed(self, name, old, new):
183 if new.lower() in self.postprocessor_aliases:
183 if new.lower() in self.postprocessor_aliases:
184 new = self.postprocessor_aliases[new.lower()]
184 new = self.postprocessor_aliases[new.lower()]
185 if new:
185 if new:
186 self.postprocessor_factory = import_item(new)
186 self.postprocessor_factory = import_item(new)
187
187
188
188
189 # Other configurable variables
189 # Other configurable variables
190 export_format = CaselessStrEnum(get_export_names(),
190 export_format = CaselessStrEnum(get_export_names(),
191 default_value="html",
191 default_value="html",
192 config=True,
192 config=True,
193 help="""The export format to be used."""
193 help="""The export format to be used."""
194 )
194 )
195
195
196 notebooks = List([], config=True, help="""List of notebooks to convert.
196 notebooks = List([], config=True, help="""List of notebooks to convert.
197 Wildcards are supported.
197 Wildcards are supported.
198 Filenames passed positionally will be added to the list.
198 Filenames passed positionally will be added to the list.
199 """)
199 """)
200
200
201 @catch_config_error
201 @catch_config_error
202 def initialize(self, argv=None):
202 def initialize(self, argv=None):
203 super(NbConvertApp, self).initialize(argv)
203 super(NbConvertApp, self).initialize(argv)
204 self.init_syspath()
204 self.init_syspath()
205 self.init_notebooks()
205 self.init_notebooks()
206 self.init_writer()
206 self.init_writer()
207 self.init_postprocessor()
207 self.init_postprocessor()
208
208
209
209
210
210
211 def init_syspath(self):
211 def init_syspath(self):
212 """
212 """
213 Add the cwd to the sys.path ($PYTHONPATH)
213 Add the cwd to the sys.path ($PYTHONPATH)
214 """
214 """
215 sys.path.insert(0, os.getcwd())
215 sys.path.insert(0, os.getcwd())
216
216
217
217
218 def init_notebooks(self):
218 def init_notebooks(self):
219 """Construct the list of notebooks.
219 """Construct the list of notebooks.
220 If notebooks are passed on the command-line,
220 If notebooks are passed on the command-line,
221 they override notebooks specified in config files.
221 they override notebooks specified in config files.
222 Glob each notebook to replace notebook patterns with filenames.
222 Glob each notebook to replace notebook patterns with filenames.
223 """
223 """
224
224
225 # Specifying notebooks on the command-line overrides (rather than adds)
225 # Specifying notebooks on the command-line overrides (rather than adds)
226 # the notebook list
226 # the notebook list
227 if self.extra_args:
227 if self.extra_args:
228 patterns = self.extra_args
228 patterns = self.extra_args
229 else:
229 else:
230 patterns = self.notebooks
230 patterns = self.notebooks
231
231
232 # Use glob to replace all the notebook patterns with filenames.
232 # Use glob to replace all the notebook patterns with filenames.
233 filenames = []
233 filenames = []
234 for pattern in patterns:
234 for pattern in patterns:
235
235
236 # Use glob to find matching filenames. Allow the user to convert
236 # Use glob to find matching filenames. Allow the user to convert
237 # notebooks without having to type the extension.
237 # notebooks without having to type the extension.
238 globbed_files = glob.glob(pattern)
238 globbed_files = glob.glob(pattern)
239 globbed_files.extend(glob.glob(pattern + '.ipynb'))
239 globbed_files.extend(glob.glob(pattern + '.ipynb'))
240 if not globbed_files:
240 if not globbed_files:
241 self.log.warn("pattern %r matched no files", pattern)
241 self.log.warn("pattern %r matched no files", pattern)
242
242
243 for filename in globbed_files:
243 for filename in globbed_files:
244 if not filename in filenames:
244 if not filename in filenames:
245 filenames.append(filename)
245 filenames.append(filename)
246 self.notebooks = filenames
246 self.notebooks = filenames
247
247
248 def init_writer(self):
248 def init_writer(self):
249 """
249 """
250 Initialize the writer (which is stateless)
250 Initialize the writer (which is stateless)
251 """
251 """
252 self._writer_class_changed(None, self.writer_class, self.writer_class)
252 self._writer_class_changed(None, self.writer_class, self.writer_class)
253 self.writer = self.writer_factory(parent=self)
253 self.writer = self.writer_factory(parent=self)
254
254
255 def init_postprocessor(self):
255 def init_postprocessor(self):
256 """
256 """
257 Initialize the postprocessor (which is stateless)
257 Initialize the postprocessor (which is stateless)
258 """
258 """
259 self._postprocessor_class_changed(None, self.postprocessor_class,
259 self._postprocessor_class_changed(None, self.postprocessor_class,
260 self.postprocessor_class)
260 self.postprocessor_class)
261 if self.postprocessor_factory:
261 if self.postprocessor_factory:
262 self.postprocessor = self.postprocessor_factory(parent=self)
262 self.postprocessor = self.postprocessor_factory(parent=self)
263
263
264 def start(self):
264 def start(self):
265 """
265 """
266 Ran after initialization completed
266 Ran after initialization completed
267 """
267 """
268 super(NbConvertApp, self).start()
268 super(NbConvertApp, self).start()
269 self.convert_notebooks()
269 self.convert_notebooks()
270
270
271 def convert_notebooks(self):
271 def convert_notebooks(self):
272 """
272 """
273 Convert the notebooks in the self.notebook traitlet
273 Convert the notebooks in the self.notebook traitlet
274 """
274 """
275 # Export each notebook
275 # Export each notebook
276 conversion_success = 0
276 conversion_success = 0
277
277
278 if self.output_base != '' and len(self.notebooks) > 1:
278 if self.output_base != '' and len(self.notebooks) > 1:
279 self.log.error(
279 self.log.error(
280 """UsageError: --output flag or `NbConvertApp.output_base` config option
280 """UsageError: --output flag or `NbConvertApp.output_base` config option
281 cannot be used when converting multiple notebooks.
281 cannot be used when converting multiple notebooks.
282 """)
282 """)
283 self.exit(1)
283 self.exit(1)
284
284
285 exporter = exporter_map[self.export_format](config=self.config)
285 exporter = exporter_map[self.export_format](config=self.config)
286
286
287 for notebook_filename in self.notebooks:
287 for notebook_filename in self.notebooks:
288 self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format)
288 self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format)
289
289
290 # Get a unique key for the notebook and set it in the resources object.
290 # Get a unique key for the notebook and set it in the resources object.
291 basename = os.path.basename(notebook_filename)
291 basename = os.path.basename(notebook_filename)
292 notebook_name = basename[:basename.rfind('.')]
292 notebook_name = basename[:basename.rfind('.')]
293 if self.output_base:
293 if self.output_base:
294 notebook_name = self.output_base
294 notebook_name = self.output_base
295 resources = {}
295 resources = {}
296 resources['unique_key'] = notebook_name
296 resources['unique_key'] = notebook_name
297 resources['output_files_dir'] = '%s_files' % notebook_name
297 resources['output_files_dir'] = '%s_files' % notebook_name
298 self.log.info("Support files will be in %s", os.path.join(resources['output_files_dir'], ''))
298 self.log.info("Support files will be in %s", os.path.join(resources['output_files_dir'], ''))
299
299
300 # Try to export
300 # Try to export
301 try:
301 try:
302 output, resources = exporter.from_filename(notebook_filename, resources=resources)
302 output, resources = exporter.from_filename(notebook_filename, resources=resources)
303 except ConversionException as e:
303 except ConversionException as e:
304 self.log.error("Error while converting '%s'", notebook_filename,
304 self.log.error("Error while converting '%s'", notebook_filename,
305 exc_info=True)
305 exc_info=True)
306 self.exit(1)
306 self.exit(1)
307 else:
307 else:
308 write_resultes = self.writer.write(output, resources, notebook_name=notebook_name)
308 write_resultes = self.writer.write(output, resources, notebook_name=notebook_name)
309
309
310 #Post-process if post processor has been defined.
310 #Post-process if post processor has been defined.
311 if hasattr(self, 'postprocessor') and self.postprocessor:
311 if hasattr(self, 'postprocessor') and self.postprocessor:
312 self.postprocessor(write_resultes)
312 self.postprocessor(write_resultes)
313 conversion_success += 1
313 conversion_success += 1
314
314
315 # If nothing was converted successfully, help the user.
315 # If nothing was converted successfully, help the user.
316 if conversion_success == 0:
316 if conversion_success == 0:
317 self.print_help()
317 self.print_help()
318 sys.exit(-1)
318 sys.exit(-1)
319
319
320 #-----------------------------------------------------------------------------
320 #-----------------------------------------------------------------------------
321 # Main entry point
321 # Main entry point
322 #-----------------------------------------------------------------------------
322 #-----------------------------------------------------------------------------
323
323
324 launch_new_instance = NbConvertApp.launch_instance
324 launch_new_instance = NbConvertApp.launch_instance
General Comments 0
You need to be logged in to leave comments. Login now