##// END OF EJS Templates
Move extracted files into their own subdir
Jonathan Frederic -
Show More
@@ -1,229 +1,230 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 import sys
20 import sys
21 import os
21 import os
22 import glob
22 import glob
23
23
24 #From IPython
24 #From IPython
25 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
25 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
26 from IPython.config import catch_config_error, Configurable
26 from IPython.config import catch_config_error, Configurable
27 from IPython.utils.traitlets import (
27 from IPython.utils.traitlets import (
28 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
28 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
29 )
29 )
30 from IPython.utils.importstring import import_item
30 from IPython.utils.importstring import import_item
31
31
32 from .exporters.export import export_by_name, get_export_names, ExporterNameError
32 from .exporters.export import export_by_name, get_export_names, ExporterNameError
33 from IPython.nbconvert import exporters, transformers, writers
33 from IPython.nbconvert import exporters, transformers, writers
34 from .utils.base import NbConvertBase
34 from .utils.base import NbConvertBase
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 #Classes and functions
37 #Classes and functions
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39
39
40 nbconvert_aliases = {}
40 nbconvert_aliases = {}
41 nbconvert_aliases.update(base_aliases)
41 nbconvert_aliases.update(base_aliases)
42 nbconvert_aliases.update({
42 nbconvert_aliases.update({
43 'format' : 'NbConvertApp.export_format',
43 'format' : 'NbConvertApp.export_format',
44 'notebooks' : 'NbConvertApp.notebooks',
44 'notebooks' : 'NbConvertApp.notebooks',
45 'writer' : 'NbConvertApp.writer_class',
45 'writer' : 'NbConvertApp.writer_class',
46 })
46 })
47
47
48 nbconvert_flags = {}
48 nbconvert_flags = {}
49 nbconvert_flags.update(base_flags)
49 nbconvert_flags.update(base_flags)
50 nbconvert_flags.update({
50 nbconvert_flags.update({
51 'stdout' : (
51 'stdout' : (
52 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
52 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
53 "Write notebook output to stdout instead of files."
53 "Write notebook output to stdout instead of files."
54 )
54 )
55 })
55 })
56
56
57
57
58 class NbConvertApp(BaseIPythonApplication):
58 class NbConvertApp(BaseIPythonApplication):
59 """Application used to convert to and from notebook file type (*.ipynb)"""
59 """Application used to convert to and from notebook file type (*.ipynb)"""
60
60
61 name = 'ipython-nbconvert'
61 name = 'ipython-nbconvert'
62 aliases = nbconvert_aliases
62 aliases = nbconvert_aliases
63 flags = nbconvert_flags
63 flags = nbconvert_flags
64
64
65 def _classes_default(self):
65 def _classes_default(self):
66 classes = [NbConvertBase]
66 classes = [NbConvertBase]
67 for pkg in (exporters, transformers, writers):
67 for pkg in (exporters, transformers, writers):
68 for name in dir(pkg):
68 for name in dir(pkg):
69 cls = getattr(pkg, name)
69 cls = getattr(pkg, name)
70 if isinstance(cls, type) and issubclass(cls, Configurable):
70 if isinstance(cls, type) and issubclass(cls, Configurable):
71 classes.append(cls)
71 classes.append(cls)
72 return classes
72 return classes
73
73
74 description = Unicode(
74 description = Unicode(
75 u"""This application is used to convert notebook files (*.ipynb)
75 u"""This application is used to convert notebook files (*.ipynb)
76 to various other formats.""")
76 to various other formats.""")
77
77
78 examples = Unicode(u"""
78 examples = Unicode(u"""
79 The simplest way to use nbconvert is
79 The simplest way to use nbconvert is
80
80
81 > ipython nbconvert mynotebook.ipynb
81 > ipython nbconvert mynotebook.ipynb
82
82
83 which will convert mynotebook.ipynb to the default format (probably HTML).
83 which will convert mynotebook.ipynb to the default format (probably HTML).
84
84
85 You can specify the export format with `--format`.
85 You can specify the export format with `--format`.
86 Options include {0}
86 Options include {0}
87
87
88 > ipython nbconvert --format latex mynotebook.ipnynb
88 > ipython nbconvert --format latex mynotebook.ipnynb
89
89
90 You can also pipe the output to stdout, rather than a file
90 You can also pipe the output to stdout, rather than a file
91
91
92 > ipython nbconvert mynotebook.ipynb --stdout
92 > ipython nbconvert mynotebook.ipynb --stdout
93
93
94 Multiple notebooks can be given at the command line in a couple of
94 Multiple notebooks can be given at the command line in a couple of
95 different ways:
95 different ways:
96
96
97 > ipython nbconvert notebook*.ipynb
97 > ipython nbconvert notebook*.ipynb
98 > ipython nbconvert notebook1.ipynb notebook2.ipynb
98 > ipython nbconvert notebook1.ipynb notebook2.ipynb
99
99
100 or you can specify the notebooks list in a config file, containing::
100 or you can specify the notebooks list in a config file, containing::
101
101
102 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
102 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
103
103
104 > ipython nbconvert --config mycfg.py
104 > ipython nbconvert --config mycfg.py
105 """.format(get_export_names()))
105 """.format(get_export_names()))
106 #Writer specific variables
106 #Writer specific variables
107 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
107 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
108 help="""Instance of the writer class used to write the
108 help="""Instance of the writer class used to write the
109 results of the conversion.""")
109 results of the conversion.""")
110 writer_class = DottedObjectName('FilesWriter', config=True,
110 writer_class = DottedObjectName('FilesWriter', config=True,
111 help="""Writer class used to write the
111 help="""Writer class used to write the
112 results of the conversion""")
112 results of the conversion""")
113 writer_aliases = {'FilesWriter': 'IPython.nbconvert.writers.files.FilesWriter',
113 writer_aliases = {'FilesWriter': 'IPython.nbconvert.writers.files.FilesWriter',
114 'DebugWriter': 'IPython.nbconvert.writers.debug.DebugWriter',
114 'DebugWriter': 'IPython.nbconvert.writers.debug.DebugWriter',
115 'StdoutWriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
115 'StdoutWriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
116 writer_factory = Type()
116 writer_factory = Type()
117
117
118 def _writer_class_changed(self, name, old, new):
118 def _writer_class_changed(self, name, old, new):
119 if new in self.writer_aliases:
119 if new in self.writer_aliases:
120 new = self.writer_aliases[new]
120 new = self.writer_aliases[new]
121 self.writer_factory = import_item(new)
121 self.writer_factory = import_item(new)
122
122
123
123
124 #Other configurable variables
124 #Other configurable variables
125 export_format = CaselessStrEnum(get_export_names(),
125 export_format = CaselessStrEnum(get_export_names(),
126 default_value="full_html",
126 default_value="full_html",
127 config=True,
127 config=True,
128 help="""The export format to be used."""
128 help="""The export format to be used."""
129 )
129 )
130
130
131 notebooks = List([], config=True, help="""List of notebooks to convert.
131 notebooks = List([], config=True, help="""List of notebooks to convert.
132 Wildcards are supported.
132 Wildcards are supported.
133 Filenames passed positionally will be added to the list.
133 Filenames passed positionally will be added to the list.
134 """)
134 """)
135
135
136 @catch_config_error
136 @catch_config_error
137 def initialize(self, argv=None):
137 def initialize(self, argv=None):
138 super(NbConvertApp, self).initialize(argv)
138 super(NbConvertApp, self).initialize(argv)
139 self.init_notebooks()
139 self.init_notebooks()
140 self.init_writer()
140 self.init_writer()
141
141
142 def init_notebooks(self):
142 def init_notebooks(self):
143 """Construct the list of notebooks.
143 """Construct the list of notebooks.
144 If notebooks are passed on the command-line,
144 If notebooks are passed on the command-line,
145 they override notebooks specified in config files.
145 they override notebooks specified in config files.
146 Glob each notebook to replace notebook patterns with filenames.
146 Glob each notebook to replace notebook patterns with filenames.
147 """
147 """
148
148
149 # Specifying notebooks on the command-line overrides (rather than adds)
149 # Specifying notebooks on the command-line overrides (rather than adds)
150 # the notebook list
150 # the notebook list
151 if self.extra_args:
151 if self.extra_args:
152 patterns = self.extra_args
152 patterns = self.extra_args
153 else:
153 else:
154 patterns = self.notebooks
154 patterns = self.notebooks
155
155
156 #Use glob to replace all the notebook patterns with filenames.
156 #Use glob to replace all the notebook patterns with filenames.
157 filenames = []
157 filenames = []
158 for pattern in patterns:
158 for pattern in patterns:
159 for filename in glob.glob(pattern):
159 for filename in glob.glob(pattern):
160 if not filename in filenames:
160 if not filename in filenames:
161 filenames.append(filename)
161 filenames.append(filename)
162 self.notebooks = filenames
162 self.notebooks = filenames
163
163
164 def init_writer(self):
164 def init_writer(self):
165 """
165 """
166 Initialize the writer (which is stateless)
166 Initialize the writer (which is stateless)
167 """
167 """
168 self._writer_class_changed(None, self.writer_class, self.writer_class)
168 self._writer_class_changed(None, self.writer_class, self.writer_class)
169 self.writer = self.writer_factory(parent=self)
169 self.writer = self.writer_factory(parent=self)
170
170
171 def start(self):
171 def start(self):
172 """
172 """
173 Ran after initialization completed
173 Ran after initialization completed
174 """
174 """
175 super(NbConvertApp, self).start()
175 super(NbConvertApp, self).start()
176 self.convert_notebooks()
176 self.convert_notebooks()
177
177
178 def convert_notebooks(self):
178 def convert_notebooks(self):
179 """
179 """
180 Convert the notebooks in the self.notebook traitlet
180 Convert the notebooks in the self.notebook traitlet
181 """
181 """
182 #Export each notebook
182 #Export each notebook
183 conversion_success = 0
183 conversion_success = 0
184 for notebook_filename in self.notebooks:
184 for notebook_filename in self.notebooks:
185
185
186 #Get a unique key for the notebook and set it in the resources object.
186 #Get a unique key for the notebook and set it in the resources object.
187 basename = os.path.basename(notebook_filename)
187 basename = os.path.basename(notebook_filename)
188 notebook_name = basename[:basename.rfind('.')]
188 notebook_name = basename[:basename.rfind('.')]
189 resources = {}
189 resources = {}
190 resources['unique_key'] = notebook_name
190 resources['unique_key'] = notebook_name
191 resources['output_files_dir'] = '%s_files' % notebook_name
191
192
192 #Try to export
193 #Try to export
193 try:
194 try:
194 output, resources = export_by_name(self.export_format,
195 output, resources = export_by_name(self.export_format,
195 notebook_filename,
196 notebook_filename,
196 resources=resources,
197 resources=resources,
197 config=self.config)
198 config=self.config)
198 except ExporterNameError as e:
199 except ExporterNameError as e:
199 print("Error: '%s' exporter not found." % self.export_format,
200 print("Error: '%s' exporter not found." % self.export_format,
200 file=sys.stderr)
201 file=sys.stderr)
201 print("Known exporters are:",
202 print("Known exporters are:",
202 "\n\t" + "\n\t".join(get_export_names()),
203 "\n\t" + "\n\t".join(get_export_names()),
203 file=sys.stderr)
204 file=sys.stderr)
204 sys.exit(-1)
205 sys.exit(-1)
205 #except Exception as e:
206 #except Exception as e:
206 #print("Error: could not export '%s'" % notebook_filename, file=sys.stderr)
207 #print("Error: could not export '%s'" % notebook_filename, file=sys.stderr)
207 #print(e, file=sys.stderr)
208 #print(e, file=sys.stderr)
208 else:
209 else:
209 self.writer.write(output, resources, notebook_name=notebook_name)
210 self.writer.write(output, resources, notebook_name=notebook_name)
210 conversion_success += 1
211 conversion_success += 1
211
212
212 #If nothing was converted successfully, help the user.
213 #If nothing was converted successfully, help the user.
213 if conversion_success == 0:
214 if conversion_success == 0:
214
215
215 #No notebooks were specified, show help.
216 #No notebooks were specified, show help.
216 if len(self.notebooks) == 0:
217 if len(self.notebooks) == 0:
217 self.print_help()
218 self.print_help()
218
219
219 #Notebooks were specified, but not converted successfully. Show how
220 #Notebooks were specified, but not converted successfully. Show how
220 #to access help.
221 #to access help.
221 else:
222 else:
222 print('For help, use "ipython nbconvert --help"')
223 print('For help, use "ipython nbconvert --help"')
223
224
224
225
225 #-----------------------------------------------------------------------------
226 #-----------------------------------------------------------------------------
226 # Main entry point
227 # Main entry point
227 #-----------------------------------------------------------------------------
228 #-----------------------------------------------------------------------------
228
229
229 launch_new_instance = NbConvertApp.launch_instance
230 launch_new_instance = NbConvertApp.launch_instance
@@ -1,96 +1,101 b''
1 """Module containing a transformer that extracts all of the figures from the
1 """Module containing a transformer that extracts all of the figures from the
2 notebook file. The extracted figures are returned in the 'resources' dictionary.
2 notebook file. The extracted figures are returned in the 'resources' dictionary.
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 import base64
16 import base64
17 import sys
17 import sys
18 import os
18
19
19 from IPython.utils.traitlets import Unicode
20 from IPython.utils.traitlets import Unicode
20 from .base import Transformer
21 from .base import Transformer
21 from IPython.utils import py3compat
22 from IPython.utils import py3compat
22
23
23 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
24 # Classes
25 # Classes
25 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
26
27
27 class ExtractFigureTransformer(Transformer):
28 class ExtractFigureTransformer(Transformer):
28 """
29 """
29 Extracts all of the figures from the notebook file. The extracted
30 Extracts all of the figures from the notebook file. The extracted
30 figures are returned in the 'resources' dictionary.
31 figures are returned in the 'resources' dictionary.
31 """
32 """
32
33
33 figure_filename_template = Unicode(
34 figure_filename_template = Unicode(
34 "{unique_key}_{cell_index}_{index}.{extension}", config=True)
35 "{unique_key}_{cell_index}_{index}.{extension}", config=True)
35
36
36
37
37 def transform_cell(self, cell, resources, cell_index):
38 def transform_cell(self, cell, resources, cell_index):
38 """
39 """
39 Apply a transformation on each cell,
40 Apply a transformation on each cell,
40
41
41 Parameters
42 Parameters
42 ----------
43 ----------
43 cell : NotebookNode cell
44 cell : NotebookNode cell
44 Notebook cell being processed
45 Notebook cell being processed
45 resources : dictionary
46 resources : dictionary
46 Additional resources used in the conversion process. Allows
47 Additional resources used in the conversion process. Allows
47 transformers to pass variables into the Jinja engine.
48 transformers to pass variables into the Jinja engine.
48 cell_index : int
49 cell_index : int
49 Index of the cell being processed (see base.py)
50 Index of the cell being processed (see base.py)
50 """
51 """
51
52
52 #Get the unique key from the resource dict if it exists. If it does not
53 #Get the unique key from the resource dict if it exists. If it does not
53 #exist, use 'figure' as the default.
54 #exist, use 'figure' as the default. Also, get files directory if it
55 #has been specified
54 unique_key = resources.get('unique_key', 'figure')
56 unique_key = resources.get('unique_key', 'figure')
57 output_files_dir = resources.get('output_files_dir', None)
55
58
56 #Make sure figures key exists
59 #Make sure figures key exists
57 if not 'figures' in resources:
60 if not 'figures' in resources:
58 resources['figures'] = {}
61 resources['figures'] = {}
59
62
60 #Loop through all of the outputs in the cell
63 #Loop through all of the outputs in the cell
61 for index, out in enumerate(cell.get('outputs', [])):
64 for index, out in enumerate(cell.get('outputs', [])):
62
65
63 #Get the output in data formats that the template is interested in.
66 #Get the output in data formats that the template is interested in.
64 for out_type in self.display_data_priority:
67 for out_type in self.display_data_priority:
65 if out.hasattr(out_type):
68 if out.hasattr(out_type):
66 data = out[out_type]
69 data = out[out_type]
67
70
68 #Binary files are base64-encoded, SVG is already XML
71 #Binary files are base64-encoded, SVG is already XML
69 if out_type in ('png', 'jpg', 'jpeg', 'pdf'):
72 if out_type in ('png', 'jpg', 'jpeg', 'pdf'):
70 # data is b64-encoded as text (str, unicode)
73 # data is b64-encoded as text (str, unicode)
71 # decodestring only accepts bytes
74 # decodestring only accepts bytes
72 data = py3compat.cast_bytes(data)
75 data = py3compat.cast_bytes(data)
73 data = base64.decodestring(data)
76 data = base64.decodestring(data)
74 elif sys.platform == 'win32':
77 elif sys.platform == 'win32':
75 data = data.replace('\n', '\r\n').encode("UTF-8")
78 data = data.replace('\n', '\r\n').encode("UTF-8")
76 else:
79 else:
77 data = data.encode("UTF-8")
80 data = data.encode("UTF-8")
78
81
79 #Build a figure name
82 #Build a figure name
80 figure_name = self.figure_filename_template.format(
83 filename = self.figure_filename_template.format(
81 unique_key=unique_key,
84 unique_key=unique_key,
82 cell_index=cell_index,
85 cell_index=cell_index,
83 index=index,
86 index=index,
84 extension=out_type)
87 extension=out_type)
85
88
86 #On the cell, make the figure available via
89 #On the cell, make the figure available via
87 # cell.outputs[i].svg_filename ... etc (svg in example)
90 # cell.outputs[i].svg_filename ... etc (svg in example)
88 # Where
91 # Where
89 # cell.outputs[i].svg contains the data
92 # cell.outputs[i].svg contains the data
90 out[out_type + '_filename'] = figure_name
93 if output_files_dir is not None:
94 filename = os.path.join(output_files_dir, filename)
95 out[out_type + '_filename'] = filename
91
96
92 #In the resources, make the figure available via
97 #In the resources, make the figure available via
93 # resources['figures']['filename'] = data
98 # resources['figures']['filename'] = data
94 resources['figures'][figure_name] = data
99 resources['figures'][filename] = data
95
100
96 return cell, resources
101 return cell, resources
General Comments 0
You need to be logged in to leave comments. Login now