Show More
@@ -85,7 +85,6 __all__ = [ | |||||
85 | class ExporterNameError(NameError): |
|
85 | class ExporterNameError(NameError): | |
86 | pass |
|
86 | pass | |
87 |
|
87 | |||
88 |
|
||||
89 | @DocDecorator |
|
88 | @DocDecorator | |
90 | def export(exporter, nb, **kw): |
|
89 | def export(exporter, nb, **kw): | |
91 | """ |
|
90 | """ | |
@@ -112,7 +111,7 def export(exporter, nb, **kw): | |||||
112 | exporter_instance = exporter |
|
111 | exporter_instance = exporter | |
113 | else: |
|
112 | else: | |
114 | exporter_instance = exporter(**kw) |
|
113 | exporter_instance = exporter(**kw) | |
115 |
|
114 | |||
116 | #Try to convert the notebook using the appropriate conversion function. |
|
115 | #Try to convert the notebook using the appropriate conversion function. | |
117 | if isinstance(nb, NotebookNode): |
|
116 | if isinstance(nb, NotebookNode): | |
118 | output, resources = exporter_instance.from_notebook_node(nb, resources) |
|
117 | output, resources = exporter_instance.from_notebook_node(nb, resources) | |
@@ -122,62 +121,27 def export(exporter, nb, **kw): | |||||
122 | output, resources = exporter_instance.from_file(nb, resources) |
|
121 | output, resources = exporter_instance.from_file(nb, resources) | |
123 | return output, resources |
|
122 | return output, resources | |
124 |
|
123 | |||
|
124 | exporter_map = dict( | |||
|
125 | custom=Exporter, | |||
|
126 | html=HTMLExporter, | |||
|
127 | slides=SlidesExporter, | |||
|
128 | latex=LatexExporter, | |||
|
129 | markdown=MarkdownExporter, | |||
|
130 | python=PythonExporter, | |||
|
131 | rst=RSTExporter, | |||
|
132 | ) | |||
|
133 | ||||
|
134 | def _make_exporter(name, E): | |||
|
135 | """make an export_foo function from a short key and Exporter class E""" | |||
|
136 | def _export(nb, **kw): | |||
|
137 | return export(E, nb, **kw) | |||
|
138 | _export.__doc__ = """Export a notebook object to {0} format""".format(name) | |||
|
139 | return _export | |||
|
140 | ||||
|
141 | g = globals() | |||
125 |
|
142 | |||
126 | @DocDecorator |
|
143 | for name, E in exporter_map.items(): | |
127 | def export_custom(nb, **kw): |
|
144 | g['export_%s' % name] = DocDecorator(_make_exporter(name, E)) | |
128 | """ |
|
|||
129 | Export a notebook object to a custom format |
|
|||
130 | """ |
|
|||
131 | return export(Exporter, nb, **kw) |
|
|||
132 |
|
||||
133 |
|
||||
134 | @DocDecorator |
|
|||
135 | def export_html(nb, **kw): |
|
|||
136 | """ |
|
|||
137 | Export a notebook object to HTML |
|
|||
138 | """ |
|
|||
139 | return export(HTMLExporter, nb, **kw) |
|
|||
140 |
|
||||
141 |
|
||||
142 | @DocDecorator |
|
|||
143 | def export_slides(nb, **kw): |
|
|||
144 | """ |
|
|||
145 | Export a notebook object to Slides |
|
|||
146 | """ |
|
|||
147 | return export(SlidesExporter, nb, **kw) |
|
|||
148 |
|
||||
149 |
|
||||
150 | @DocDecorator |
|
|||
151 | def export_latex(nb, **kw): |
|
|||
152 | """ |
|
|||
153 | Export a notebook object to LaTeX |
|
|||
154 | """ |
|
|||
155 | return export(LatexExporter, nb, **kw) |
|
|||
156 |
|
||||
157 |
|
||||
158 | @DocDecorator |
|
|||
159 | def export_markdown(nb, **kw): |
|
|||
160 | """ |
|
|||
161 | Export a notebook object to Markdown |
|
|||
162 | """ |
|
|||
163 | return export(MarkdownExporter, nb, **kw) |
|
|||
164 |
|
||||
165 |
|
||||
166 | @DocDecorator |
|
|||
167 | def export_python(nb, **kw): |
|
|||
168 | """ |
|
|||
169 | Export a notebook object to Python |
|
|||
170 | """ |
|
|||
171 | return export(PythonExporter, nb, **kw) |
|
|||
172 |
|
||||
173 |
|
||||
174 | @DocDecorator |
|
|||
175 | def export_rst(nb, **kw): |
|
|||
176 | """ |
|
|||
177 | Export a notebook object to reStructuredText |
|
|||
178 | """ |
|
|||
179 | return export(RSTExporter, nb, **kw) |
|
|||
180 |
|
||||
181 |
|
145 | |||
182 | @DocDecorator |
|
146 | @DocDecorator | |
183 | def export_by_name(format_name, nb, **kw): |
|
147 | def export_by_name(format_name, nb, **kw): | |
@@ -202,10 +166,4 def get_export_names(): | |||||
202 | """Return a list of the currently supported export targets |
|
166 | """Return a list of the currently supported export targets | |
203 |
|
167 | |||
204 | WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT""" |
|
168 | WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT""" | |
205 |
|
169 | return sorted(exporter_map.keys()) | ||
206 | # grab everything after 'export_' |
|
|||
207 | l = [x[len('export_'):] for x in __all__ if x.startswith('export_')] |
|
|||
208 |
|
||||
209 | # filter out the one method that is not a template |
|
|||
210 | l = [x for x in l if 'by_name' not in x] |
|
|||
211 | return sorted(l) |
|
@@ -28,10 +28,10 import datetime | |||||
28 | from jinja2 import Environment, FileSystemLoader, ChoiceLoader, TemplateNotFound |
|
28 | from jinja2 import Environment, FileSystemLoader, ChoiceLoader, TemplateNotFound | |
29 |
|
29 | |||
30 | # IPython imports |
|
30 | # IPython imports | |
31 | from IPython.config.configurable import Configurable |
|
31 | from IPython.config.configurable import LoggingConfigurable | |
32 | from IPython.config import Config |
|
32 | from IPython.config import Config | |
33 | from IPython.nbformat import current as nbformat |
|
33 | from IPython.nbformat import current as nbformat | |
34 | from IPython.utils.traitlets import MetaHasTraits, DottedObjectName, Unicode, List, Dict |
|
34 | from IPython.utils.traitlets import MetaHasTraits, DottedObjectName, Unicode, List, Dict, Any | |
35 | from IPython.utils.importstring import import_item |
|
35 | from IPython.utils.importstring import import_item | |
36 | from IPython.utils.text import indent |
|
36 | from IPython.utils.text import indent | |
37 | from IPython.utils import py3compat |
|
37 | from IPython.utils import py3compat | |
@@ -78,7 +78,7 class ResourcesDict(collections.defaultdict): | |||||
78 | return '' |
|
78 | return '' | |
79 |
|
79 | |||
80 |
|
80 | |||
81 | class Exporter(Configurable): |
|
81 | class Exporter(LoggingConfigurable): | |
82 | """ |
|
82 | """ | |
83 | Exports notebooks into other file formats. Uses Jinja 2 templating engine |
|
83 | Exports notebooks into other file formats. Uses Jinja 2 templating engine | |
84 | to output new formats. Inherit from this class if you are creating a new |
|
84 | to output new formats. Inherit from this class if you are creating a new | |
@@ -102,7 +102,12 class Exporter(Configurable): | |||||
102 | self.template_file = self.default_template |
|
102 | self.template_file = self.default_template | |
103 | else: |
|
103 | else: | |
104 | self.template_file = new |
|
104 | self.template_file = new | |
|
105 | self.template = None | |||
|
106 | self._load_template() | |||
|
107 | ||||
105 | default_template = Unicode(u'') |
|
108 | default_template = Unicode(u'') | |
|
109 | template = Any() | |||
|
110 | environment = Any() | |||
106 |
|
111 | |||
107 | file_extension = Unicode( |
|
112 | file_extension = Unicode( | |
108 | 'txt', config=True, |
|
113 | 'txt', config=True, | |
@@ -110,6 +115,8 class Exporter(Configurable): | |||||
110 | ) |
|
115 | ) | |
111 |
|
116 | |||
112 | template_path = List(['.'], config=True) |
|
117 | template_path = List(['.'], config=True) | |
|
118 | def _template_path_changed(self, name, old, new): | |||
|
119 | self._load_template() | |||
113 |
|
120 | |||
114 | default_template_path = Unicode( |
|
121 | default_template_path = Unicode( | |
115 | os.path.join("..", "templates"), |
|
122 | os.path.join("..", "templates"), | |
@@ -159,21 +166,18 class Exporter(Configurable): | |||||
159 | config : config |
|
166 | config : config | |
160 | User configuration instance. |
|
167 | User configuration instance. | |
161 | extra_loaders : list[of Jinja Loaders] |
|
168 | extra_loaders : list[of Jinja Loaders] | |
162 | ordered list of Jinja loder to find templates. Will be tried in order |
|
169 | ordered list of Jinja loader to find templates. Will be tried in order | |
163 |
before the default FileSystem |
|
170 | before the default FileSystem ones. | |
164 | template : str (optional, kw arg) |
|
171 | template : str (optional, kw arg) | |
165 | Template to use when exporting. |
|
172 | Template to use when exporting. | |
166 | """ |
|
173 | """ | |
|
174 | if not config: | |||
|
175 | config = self.default_config | |||
167 |
|
176 | |||
168 | #Call the base class constructor |
|
177 | super(Exporter, self).__init__(config=config, **kw) | |
169 | c = self.default_config |
|
|||
170 | if config: |
|
|||
171 | c.merge(config) |
|
|||
172 |
|
||||
173 | super(Exporter, self).__init__(config=c, **kw) |
|
|||
174 |
|
178 | |||
175 | #Init |
|
179 | #Init | |
176 |
self._init_template( |
|
180 | self._init_template() | |
177 | self._init_environment(extra_loaders=extra_loaders) |
|
181 | self._init_environment(extra_loaders=extra_loaders) | |
178 | self._init_transformers() |
|
182 | self._init_transformers() | |
179 | self._init_filters() |
|
183 | self._init_filters() | |
@@ -182,7 +186,48 class Exporter(Configurable): | |||||
182 | @property |
|
186 | @property | |
183 | def default_config(self): |
|
187 | def default_config(self): | |
184 | return Config() |
|
188 | return Config() | |
|
189 | ||||
|
190 | def _config_changed(self, name, old, new): | |||
|
191 | """When setting config, make sure to start with our default_config""" | |||
|
192 | c = self.default_config | |||
|
193 | if new: | |||
|
194 | c.merge(new) | |||
|
195 | if c != old: | |||
|
196 | self.config = c | |||
|
197 | super(Exporter, self)._config_changed(name, old, c) | |||
|
198 | ||||
185 |
|
199 | |||
|
200 | def _load_template(self): | |||
|
201 | """Load the Jinja template object from the template file | |||
|
202 | ||||
|
203 | This is a no-op if the template attribute is already defined, | |||
|
204 | or the Jinja environment is not setup yet. | |||
|
205 | ||||
|
206 | This is triggered by various trait changes that would change the template. | |||
|
207 | """ | |||
|
208 | if self.template is not None: | |||
|
209 | return | |||
|
210 | # called too early, do nothing | |||
|
211 | if self.environment is None: | |||
|
212 | return | |||
|
213 | # Try different template names during conversion. First try to load the | |||
|
214 | # template by name with extension added, then try loading the template | |||
|
215 | # as if the name is explicitly specified, then try the name as a | |||
|
216 | # 'flavor', and lastly just try to load the template by module name. | |||
|
217 | module_name = self.__module__.rsplit('.', 1)[-1] | |||
|
218 | try_names = [self.template_file + self.template_extension, | |||
|
219 | self.template_file, | |||
|
220 | module_name + '_' + self.template_file + self.template_extension, | |||
|
221 | module_name + self.template_extension] | |||
|
222 | for try_name in try_names: | |||
|
223 | self.log.debug("Attempting to load template %s", try_name) | |||
|
224 | try: | |||
|
225 | self.template = self.environment.get_template(try_name) | |||
|
226 | except TemplateNotFound: | |||
|
227 | pass | |||
|
228 | else: | |||
|
229 | self.log.info("Loaded template %s", try_name) | |||
|
230 | break | |||
186 |
|
231 | |||
187 | def from_notebook_node(self, nb, resources=None, **kw): |
|
232 | def from_notebook_node(self, nb, resources=None, **kw): | |
188 | """ |
|
233 | """ | |
@@ -201,23 +246,9 class Exporter(Configurable): | |||||
201 | # Preprocess |
|
246 | # Preprocess | |
202 | nb_copy, resources = self._transform(nb_copy, resources) |
|
247 | nb_copy, resources = self._transform(nb_copy, resources) | |
203 |
|
248 | |||
204 | # Try different template names during conversion. First try to load the |
|
249 | self._load_template() | |
205 | # template by name with extension added, then try loading the template |
|
|||
206 | # as if the name is explicitly specified, then try the name as a |
|
|||
207 | # 'flavor', and lastly just try to load the template by module name. |
|
|||
208 | module_name = self.__module__.split('.')[-1] |
|
|||
209 | try_names = [self.template_file + self.template_extension, |
|
|||
210 | self.template_file, |
|
|||
211 | module_name + '_' + self.template_file + self.template_extension, |
|
|||
212 | module_name + self.template_extension] |
|
|||
213 | for try_name in try_names: |
|
|||
214 | try: |
|
|||
215 | self.template = self.environment.get_template(try_name) |
|
|||
216 | break |
|
|||
217 | except TemplateNotFound: |
|
|||
218 | pass |
|
|||
219 |
|
250 | |||
220 |
if |
|
251 | if self.template is not None: | |
221 | output = self.template.render(nb=nb_copy, resources=resources) |
|
252 | output = self.template.render(nb=nb_copy, resources=resources) | |
222 | else: |
|
253 | else: | |
223 | raise IOError('template file "%s" could not be found' % self.template_file) |
|
254 | raise IOError('template file "%s" could not be found' % self.template_file) | |
@@ -355,14 +386,12 class Exporter(Configurable): | |||||
355 | raise TypeError('filter') |
|
386 | raise TypeError('filter') | |
356 |
|
387 | |||
357 |
|
388 | |||
358 |
def _init_template(self |
|
389 | def _init_template(self): | |
359 | """ |
|
390 | """ | |
360 | Make sure a template name is specified. If one isn't specified, try to |
|
391 | Make sure a template name is specified. If one isn't specified, try to | |
361 | build one from the information we know. |
|
392 | build one from the information we know. | |
362 | """ |
|
393 | """ | |
363 | self._template_file_changed('template_file', self.template_file, self.template_file) |
|
394 | self._template_file_changed('template_file', self.template_file, self.template_file) | |
364 | if 'template' in kw: |
|
|||
365 | self.template_file = kw['template'] |
|
|||
366 |
|
395 | |||
367 |
|
396 | |||
368 | def _init_environment(self, extra_loaders=None): |
|
397 | def _init_environment(self, extra_loaders=None): |
@@ -95,7 +95,7 class TestExporter(ExportersTestsBase): | |||||
95 |
|
95 | |||
96 | def test_transformer_via_method(self): |
|
96 | def test_transformer_via_method(self): | |
97 | """ |
|
97 | """ | |
98 |
Can a transformer be added via the Exporter conv |
|
98 | Can a transformer be added via the Exporter convenience method? | |
99 | """ |
|
99 | """ | |
100 | exporter = self._make_exporter() |
|
100 | exporter = self._make_exporter() | |
101 | exporter.register_transformer(CheeseTransformer, enabled=True) |
|
101 | exporter.register_transformer(CheeseTransformer, enabled=True) | |
@@ -108,6 +108,5 class TestExporter(ExportersTestsBase): | |||||
108 | def _make_exporter(self, config=None): |
|
108 | def _make_exporter(self, config=None): | |
109 | #Create the exporter instance, make sure to set a template name since |
|
109 | #Create the exporter instance, make sure to set a template name since | |
110 | #the base Exporter doesn't have a template associated with it. |
|
110 | #the base Exporter doesn't have a template associated with it. | |
111 | exporter = Exporter(config=config) |
|
111 | exporter = Exporter(config=config, template_file='python') | |
112 | exporter.template_file = 'python' |
|
|||
113 | return exporter No newline at end of file |
|
112 | return exporter |
@@ -46,7 +46,7 class TestHTMLExporter(ExportersTestsBase): | |||||
46 | """ |
|
46 | """ | |
47 | Can a HTMLExporter export using the 'basic' template? |
|
47 | Can a HTMLExporter export using the 'basic' template? | |
48 | """ |
|
48 | """ | |
49 | (output, resources) = HTMLExporter(template='basic').from_filename(self._get_notebook()) |
|
49 | (output, resources) = HTMLExporter(template_file='basic').from_filename(self._get_notebook()) | |
50 | assert len(output) > 0 |
|
50 | assert len(output) > 0 | |
51 |
|
51 | |||
52 |
|
52 | |||
@@ -55,5 +55,5 class TestHTMLExporter(ExportersTestsBase): | |||||
55 | """ |
|
55 | """ | |
56 | Can a HTMLExporter export using the 'full' template? |
|
56 | Can a HTMLExporter export using the 'full' template? | |
57 | """ |
|
57 | """ | |
58 | (output, resources) = HTMLExporter(template='full').from_filename(self._get_notebook()) |
|
58 | (output, resources) = HTMLExporter(template_file='full').from_filename(self._get_notebook()) | |
59 | assert len(output) > 0 |
|
59 | assert len(output) > 0 |
@@ -46,7 +46,7 class TestLatexExporter(ExportersTestsBase): | |||||
46 | """ |
|
46 | """ | |
47 | Can a LatexExporter export using 'book' template? |
|
47 | Can a LatexExporter export using 'book' template? | |
48 | """ |
|
48 | """ | |
49 | (output, resources) = LatexExporter(template='book').from_filename(self._get_notebook()) |
|
49 | (output, resources) = LatexExporter(template_file='book').from_filename(self._get_notebook()) | |
50 | assert len(output) > 0 |
|
50 | assert len(output) > 0 | |
51 |
|
51 | |||
52 |
|
52 | |||
@@ -55,7 +55,7 class TestLatexExporter(ExportersTestsBase): | |||||
55 | """ |
|
55 | """ | |
56 | Can a LatexExporter export using 'basic' template? |
|
56 | Can a LatexExporter export using 'basic' template? | |
57 | """ |
|
57 | """ | |
58 | (output, resources) = LatexExporter(template='basic').from_filename(self._get_notebook()) |
|
58 | (output, resources) = LatexExporter(template_file='basic').from_filename(self._get_notebook()) | |
59 | assert len(output) > 0 |
|
59 | assert len(output) > 0 | |
60 |
|
60 | |||
61 |
|
61 | |||
@@ -64,5 +64,5 class TestLatexExporter(ExportersTestsBase): | |||||
64 | """ |
|
64 | """ | |
65 | Can a LatexExporter export using 'article' template? |
|
65 | Can a LatexExporter export using 'article' template? | |
66 | """ |
|
66 | """ | |
67 | (output, resources) = LatexExporter(template='article').from_filename(self._get_notebook()) |
|
67 | (output, resources) = LatexExporter(template_file='article').from_filename(self._get_notebook()) | |
68 | assert len(output) > 0 No newline at end of file |
|
68 | assert len(output) > 0 |
@@ -46,5 +46,5 class TestSlidesExporter(ExportersTestsBase): | |||||
46 | """ |
|
46 | """ | |
47 | Can a SlidesExporter export using the 'reveal' template? |
|
47 | Can a SlidesExporter export using the 'reveal' template? | |
48 | """ |
|
48 | """ | |
49 | (output, resources) = SlidesExporter(template='reveal').from_filename(self._get_notebook()) |
|
49 | (output, resources) = SlidesExporter(template_file='reveal').from_filename(self._get_notebook()) | |
50 | assert len(output) > 0 |
|
50 | assert len(output) > 0 |
@@ -17,6 +17,8 Command-line interface for the NbConvert conversion utility. | |||||
17 |
|
17 | |||
18 | # Stdlib imports |
|
18 | # Stdlib imports | |
19 | from __future__ import print_function |
|
19 | from __future__ import print_function | |
|
20 | ||||
|
21 | import logging | |||
20 | import sys |
|
22 | import sys | |
21 | import os |
|
23 | import os | |
22 | import glob |
|
24 | import glob | |
@@ -30,7 +32,7 from IPython.utils.traitlets import ( | |||||
30 | from IPython.utils.importstring import import_item |
|
32 | from IPython.utils.importstring import import_item | |
31 | from IPython.utils.text import dedent |
|
33 | from IPython.utils.text import dedent | |
32 |
|
34 | |||
33 |
from .exporters.export import |
|
35 | from .exporters.export import get_export_names, exporter_map | |
34 | from IPython.nbconvert import exporters, transformers, writers, post_processors |
|
36 | from IPython.nbconvert import exporters, transformers, writers, post_processors | |
35 | from .utils.base import NbConvertBase |
|
37 | from .utils.base import NbConvertBase | |
36 | from .utils.exceptions import ConversionException |
|
38 | from .utils.exceptions import ConversionException | |
@@ -80,6 +82,9 class NbConvertApp(BaseIPythonApplication): | |||||
80 | aliases = nbconvert_aliases |
|
82 | aliases = nbconvert_aliases | |
81 | flags = nbconvert_flags |
|
83 | flags = nbconvert_flags | |
82 |
|
84 | |||
|
85 | def _log_level_default(self): | |||
|
86 | return logging.INFO | |||
|
87 | ||||
83 | def _classes_default(self): |
|
88 | def _classes_default(self): | |
84 | classes = [NbConvertBase] |
|
89 | classes = [NbConvertBase] | |
85 | for pkg in (exporters, transformers, writers): |
|
90 | for pkg in (exporters, transformers, writers): | |
@@ -229,6 +234,8 class NbConvertApp(BaseIPythonApplication): | |||||
229 | # notebooks without having to type the extension. |
|
234 | # notebooks without having to type the extension. | |
230 | globbed_files = glob.glob(pattern) |
|
235 | globbed_files = glob.glob(pattern) | |
231 | globbed_files.extend(glob.glob(pattern + '.ipynb')) |
|
236 | globbed_files.extend(glob.glob(pattern + '.ipynb')) | |
|
237 | if not globbed_files: | |||
|
238 | self.log.warn("pattern %r matched no files", pattern) | |||
232 |
|
239 | |||
233 | for filename in globbed_files: |
|
240 | for filename in globbed_files: | |
234 | if not filename in filenames: |
|
241 | if not filename in filenames: | |
@@ -266,13 +273,16 class NbConvertApp(BaseIPythonApplication): | |||||
266 | conversion_success = 0 |
|
273 | conversion_success = 0 | |
267 |
|
274 | |||
268 | if self.output_base != '' and len(self.notebooks) > 1: |
|
275 | if self.output_base != '' and len(self.notebooks) > 1: | |
269 | print(dedent( |
|
276 | self.log.error( | |
270 | """UsageError: --output flag or `NbConvertApp.output_base` config option |
|
277 | """UsageError: --output flag or `NbConvertApp.output_base` config option | |
271 | cannot be used when converting multiple notebooks. |
|
278 | cannot be used when converting multiple notebooks. | |
272 |
""") |
|
279 | """) | |
273 | self.exit(1) |
|
280 | self.exit(1) | |
|
281 | ||||
|
282 | exporter = exporter_map[self.export_format](config=self.config) | |||
274 |
|
283 | |||
275 | for notebook_filename in self.notebooks: |
|
284 | for notebook_filename in self.notebooks: | |
|
285 | self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format) | |||
276 |
|
286 | |||
277 | # Get a unique key for the notebook and set it in the resources object. |
|
287 | # Get a unique key for the notebook and set it in the resources object. | |
278 | basename = os.path.basename(notebook_filename) |
|
288 | basename = os.path.basename(notebook_filename) | |
@@ -282,24 +292,14 class NbConvertApp(BaseIPythonApplication): | |||||
282 | resources = {} |
|
292 | resources = {} | |
283 | resources['unique_key'] = notebook_name |
|
293 | resources['unique_key'] = notebook_name | |
284 | resources['output_files_dir'] = '%s_files' % notebook_name |
|
294 | resources['output_files_dir'] = '%s_files' % notebook_name | |
|
295 | self.log.info("Support files will be in %s", os.path.join(resources['output_files_dir'], '')) | |||
285 |
|
296 | |||
286 | # Try to export |
|
297 | # Try to export | |
287 | try: |
|
298 | try: | |
288 |
output, resources = export |
|
299 | output, resources = exporter.from_filename(notebook_filename, resources=resources) | |
289 | notebook_filename, |
|
|||
290 | resources=resources, |
|
|||
291 | config=self.config) |
|
|||
292 | except ExporterNameError as e: |
|
|||
293 | print("Error while converting '%s': '%s' exporter not found." |
|
|||
294 | %(notebook_filename, self.export_format), |
|
|||
295 | file=sys.stderr) |
|
|||
296 | print("Known exporters are:", |
|
|||
297 | "\n\t" + "\n\t".join(get_export_names()), |
|
|||
298 | file=sys.stderr) |
|
|||
299 | self.exit(1) |
|
|||
300 | except ConversionException as e: |
|
300 | except ConversionException as e: | |
301 |
|
|
301 | self.log.error("Error while converting '%s'", notebook_filename, | |
302 |
|
|
302 | exc_info=True) | |
303 | self.exit(1) |
|
303 | self.exit(1) | |
304 | else: |
|
304 | else: | |
305 | write_resultes = self.writer.write(output, resources, notebook_name=notebook_name) |
|
305 | write_resultes = self.writer.write(output, resources, notebook_name=notebook_name) |
@@ -43,6 +43,7 class PDFPostProcessor(PostProcessorBase): | |||||
43 | See files.py for more... |
|
43 | See files.py for more... | |
44 | """ |
|
44 | """ | |
45 | command = self.compiler.format(input) |
|
45 | command = self.compiler.format(input) | |
|
46 | self.log.info("Building PDF: `%s`", command) | |||
46 | for index in range(self.iteration_count): |
|
47 | for index in range(self.iteration_count): | |
47 | if self.verbose: |
|
48 | if self.verbose: | |
48 | subprocess.Popen(command, shell=True) |
|
49 | subprocess.Popen(command, shell=True) |
@@ -79,8 +79,9 class Transformer(NbConvertBase): | |||||
79 | Additional resources used in the conversion process. Allows |
|
79 | Additional resources used in the conversion process. Allows | |
80 | transformers to pass variables into the Jinja engine. |
|
80 | transformers to pass variables into the Jinja engine. | |
81 | """ |
|
81 | """ | |
|
82 | self.log.debug("Applying transform: %s", self.__class__.__name__) | |||
82 | try : |
|
83 | try : | |
83 |
for worksheet in nb.worksheets |
|
84 | for worksheet in nb.worksheets: | |
84 | for index, cell in enumerate(worksheet.cells): |
|
85 | for index, cell in enumerate(worksheet.cells): | |
85 | worksheet.cells[index], resources = self.transform_cell(cell, resources, index) |
|
86 | worksheet.cells[index], resources = self.transform_cell(cell, resources, index) | |
86 | return nb, resources |
|
87 | return nb, resources |
@@ -12,13 +12,13 | |||||
12 | #----------------------------------------------------------------------------- |
|
12 | #----------------------------------------------------------------------------- | |
13 |
|
13 | |||
14 | from IPython.utils.traitlets import List |
|
14 | from IPython.utils.traitlets import List | |
15 | from IPython.config.configurable import Configurable |
|
15 | from IPython.config.configurable import LoggingConfigurable | |
16 |
|
16 | |||
17 | #----------------------------------------------------------------------------- |
|
17 | #----------------------------------------------------------------------------- | |
18 | # Classes and functions |
|
18 | # Classes and functions | |
19 | #----------------------------------------------------------------------------- |
|
19 | #----------------------------------------------------------------------------- | |
20 |
|
20 | |||
21 | class NbConvertBase(Configurable): |
|
21 | class NbConvertBase(LoggingConfigurable): | |
22 | """Global configurable class for shared config |
|
22 | """Global configurable class for shared config | |
23 |
|
23 | |||
24 | Usefull for display data priority that might be use by many trasnformers |
|
24 | Usefull for display data priority that might be use by many trasnformers |
@@ -45,7 +45,12 class FilesWriter(WriterBase): | |||||
45 | super(FilesWriter, self).__init__(**kw) |
|
45 | super(FilesWriter, self).__init__(**kw) | |
46 | self._build_directory_changed('build_directory', self.build_directory, |
|
46 | self._build_directory_changed('build_directory', self.build_directory, | |
47 | self.build_directory) |
|
47 | self.build_directory) | |
48 |
|
48 | |||
|
49 | def _makedir(self, path): | |||
|
50 | """Make a directory if it doesn't already exist""" | |||
|
51 | if not os.path.isdir(path): | |||
|
52 | self.log.info("Making directory %s", path) | |||
|
53 | os.makedirs(path) | |||
49 |
|
54 | |||
50 | def write(self, output, resources, notebook_name=None, **kw): |
|
55 | def write(self, output, resources, notebook_name=None, **kw): | |
51 | """ |
|
56 | """ | |
@@ -67,10 +72,10 class FilesWriter(WriterBase): | |||||
67 | # Determine where to write the file to |
|
72 | # Determine where to write the file to | |
68 | dest = os.path.join(self.build_directory, filename) |
|
73 | dest = os.path.join(self.build_directory, filename) | |
69 | path = os.path.dirname(dest) |
|
74 | path = os.path.dirname(dest) | |
70 |
|
|
75 | self._makedir(path) | |
71 | os.makedirs(path) |
|
|||
72 |
|
76 | |||
73 | # Write file |
|
77 | # Write file | |
|
78 | self.log.debug("Writing %i bytes to support file %s", len(data), dest) | |||
74 | with io.open(dest, 'wb') as f: |
|
79 | with io.open(dest, 'wb') as f: | |
75 | f.write(data) |
|
80 | f.write(data) | |
76 |
|
81 | |||
@@ -84,11 +89,11 class FilesWriter(WriterBase): | |||||
84 | # Make sure folder exists. |
|
89 | # Make sure folder exists. | |
85 | dest = os.path.join(self.build_directory, filename) |
|
90 | dest = os.path.join(self.build_directory, filename) | |
86 | path = os.path.dirname(dest) |
|
91 | path = os.path.dirname(dest) | |
87 |
|
|
92 | self._makedir(path) | |
88 | os.makedirs(path) |
|
|||
89 |
|
93 | |||
90 | # Copy if destination is different. |
|
94 | # Copy if destination is different. | |
91 | if not os.path.normpath(dest) == os.path.normpath(matching_filename): |
|
95 | if not os.path.normpath(dest) == os.path.normpath(matching_filename): | |
|
96 | self.log.info("Linking %s -> %s", matching_filename, dest) | |||
92 | link_or_copy(matching_filename, dest) |
|
97 | link_or_copy(matching_filename, dest) | |
93 |
|
98 | |||
94 | # Determine where to write conversion results. |
|
99 | # Determine where to write conversion results. | |
@@ -97,6 +102,7 class FilesWriter(WriterBase): | |||||
97 | dest = os.path.join(self.build_directory, dest) |
|
102 | dest = os.path.join(self.build_directory, dest) | |
98 |
|
103 | |||
99 | # Write conversion results. |
|
104 | # Write conversion results. | |
|
105 | self.log.info("Writing %i bytes to %s", len(output), dest) | |||
100 | with io.open(dest, 'w') as f: |
|
106 | with io.open(dest, 'w') as f: | |
101 | f.write(output) |
|
107 | f.write(output) | |
102 | return dest No newline at end of file |
|
108 | return dest |
General Comments 0
You need to be logged in to leave comments.
Login now