##// END OF EJS Templates
Fixed extract figure, rename from count to index
Jonathan Frederic -
Show More
@@ -1,190 +1,195 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 Commandline interface for the NBConvert conversion utility. Read the
4 Commandline interface for the NBConvert conversion utility. Read the
5 readme.rst for usage information
5 readme.rst for usage information
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 #Copyright (c) 2013, the IPython Development Team.
8 #Copyright (c) 2013, the IPython Development Team.
9 #
9 #
10 #Distributed under the terms of the Modified BSD License.
10 #Distributed under the terms of the Modified BSD License.
11 #
11 #
12 #The full license is in the file COPYING.txt, distributed with this software.
12 #The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 #Imports
16 #Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #Stdlib imports
19 #Stdlib imports
20 from __future__ import print_function
20 from __future__ import print_function
21 import sys
21 import sys
22 import io
22 import io
23 import os
23 import os
24
24
25 #From IPython
25 #From IPython
26 #All the stuff needed for the configurable things
26 #All the stuff needed for the configurable things
27 from IPython.config.application import Application
27 from IPython.config.application import Application
28 from IPython.utils.traitlets import (Bool)
28 from IPython.utils.traitlets import (Bool)
29
29
30 #Local imports
30 #Local imports
31 from nbconvert.api.convert import export_by_name
31 from nbconvert.api.convert import export_by_name
32 from nbconvert.api.exporter import Exporter
32 from nbconvert.api.exporter import Exporter
33 from nbconvert.transformers import extractfigure
33 from nbconvert.transformers import extractfigure
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 #Globals and constants
36 #Globals and constants
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 #'Keys in resources' user prompt.
39 #'Keys in resources' user prompt.
40 KEYS_PROMPT_HEAD = "====================== Keys in Resources =================================="
40 KEYS_PROMPT_HEAD = "====================== Keys in Resources =================================="
41 KEYS_PROMPT_BODY = """
41 KEYS_PROMPT_BODY = """
42 ===========================================================================
42 ===========================================================================
43 You are responsible for writting these files into the appropriate
43 You are responsible for writting these files into the appropriate
44 directorie(s) if need be. If you do not want to see this message, enable
44 directorie(s) if need be. If you do not want to see this message, enable
45 the 'write' (boolean) flag of the converter.
45 the 'write' (boolean) flag of the converter.
46 ===========================================================================
46 ===========================================================================
47 """
47 """
48
48
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50 #Classes and functions
50 #Classes and functions
51 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
52
52
53 class NbConvertApp(Application):
53 class NbConvertApp(Application):
54 """Application used to convert to and from notebook file type (*.ipynb)"""
54 """Application used to convert to and from notebook file type (*.ipynb)"""
55
55
56 stdout = Bool(
56 stdout = Bool(
57 True, config=True,
57 True, config=True,
58 help="""Whether to print the converted IPYNB file to stdout
58 help="""Whether to print the converted IPYNB file to stdout
59 use full do diff files without actually writing a new file"""
59 use full do diff files without actually writing a new file"""
60 )
60 )
61
61
62 write = Bool(
62 write = Bool(
63 False, config=True,
63 False, config=True,
64 help="""Should the converted notebook file be written to disk
64 help="""Should the converted notebook file be written to disk
65 along with potential extracted resources."""
65 along with potential extracted resources."""
66 )
66 )
67
67
68
68
69 def __init__(self, **kwargs):
69 def __init__(self, **kwargs):
70 """Public constructor"""
70 """Public constructor"""
71
71
72 #Call base class
72 #Call base class
73 super(NbConvertApp, self).__init__(**kwargs)
73 super(NbConvertApp, self).__init__(**kwargs)
74
74
75 #Register class here to have help with help all
75 #Register class here to have help with help all
76 self.classes.insert(0, Exporter)
76 self.classes.insert(0, Exporter)
77
77
78
78
79 def start(self, argv=None):
79 def start(self, argv=None):
80 """Entrypoint of NbConvert application.
80 """Entrypoint of NbConvert application.
81
81
82 Parameters
82 Parameters
83 ----------
83 ----------
84 argv : list
84 argv : list
85 Commandline arguments
85 Commandline arguments
86 """
86 """
87
87
88 #Parse the commandline options.
88 #Parse the commandline options.
89 self.parse_command_line(argv)
89 self.parse_command_line(argv)
90
90
91 #Call base
91 #Call base
92 super(NbConvertApp, self).start()
92 super(NbConvertApp, self).start()
93
93
94 #The last arguments in list will be used by nbconvert
94 #The last arguments in list will be used by nbconvert
95 export_type = (self.extra_args)[1]
95 export_type = (self.extra_args)[1]
96 ipynb_file = (self.extra_args)[2]
96 ipynb_file = (self.extra_args)[2]
97
97
98 #Export
98 #Export
99 output, resources, exporter = export_by_name(ipynb_file, export_type)
99 return_value = export_by_name(ipynb_file, export_type)
100 if return_value is None:
101 print("Error: '%s' template not found." % export_type)
102 return
103 else:
104 (output, resources, exporter) = return_value
100
105
101 #TODO: Allow user to set output directory and file.
106 #TODO: Allow user to set output directory and file.
102 destination_filename = None
107 destination_filename = None
103 destination_directory = None
108 destination_directory = None
104 if self.write:
109 if self.write:
105
110
106 #Get the file name without the '.ipynb' (6 chars) extension and then
111 #Get the file name without the '.ipynb' (6 chars) extension and then
107 #remove any addition periods and spaces. The resulting name will
112 #remove any addition periods and spaces. The resulting name will
108 #be used to create the directory that the files will be exported
113 #be used to create the directory that the files will be exported
109 #into.
114 #into.
110 out_root = ipynb_file[:-6].replace('.', '_').replace(' ', '_')
115 out_root = ipynb_file[:-6].replace('.', '_').replace(' ', '_')
111 destination_filename = os.path.join(out_root+'.'+exporter.fileext)
116 destination_filename = os.path.join(out_root+'.'+exporter.file_extension)
112
117
113 destination_directory = out_root+'_files'
118 destination_directory = out_root+'_files'
114 if not os.path.exists(destination_directory):
119 if not os.path.exists(destination_directory):
115 os.mkdir(destination_directory)
120 os.mkdir(destination_directory)
116
121
117 #Write the results
122 #Write the results
118 if self.stdout or not (destination_filename is None and destination_directory is None):
123 if self.stdout or not (destination_filename is None and destination_directory is None):
119 self._write_results(output, resources, self.stdout, destination_filename, destination_directory)
124 self._write_results(output, resources, self.stdout, destination_filename, destination_directory)
120
125
121
126
122 def _write_results(self, output, resources, stdout=False, destination_filename=None, destination_directory=None):
127 def _write_results(self, output, resources, stdout=False, destination_filename=None, destination_directory=None):
123 """Output the conversion results to the console and/or filesystem
128 """Output the conversion results to the console and/or filesystem
124
129
125 Parameters
130 Parameters
126 ----------
131 ----------
127 output : str
132 output : str
128 Output of conversion
133 Output of conversion
129 resources : dictionary
134 resources : dictionary
130 Additional input/output used by the transformers. For
135 Additional input/output used by the transformers. For
131 example, the ExtractFigure transformer outputs the
136 example, the ExtractFigure transformer outputs the
132 figures it extracts into this dictionary. This method
137 figures it extracts into this dictionary. This method
133 relies on the figures being in this dictionary when
138 relies on the figures being in this dictionary when
134 attempting to write the figures to the file system.
139 attempting to write the figures to the file system.
135 stdout : bool, Optional
140 stdout : bool, Optional
136 Whether or not to echo output to console
141 Whether or not to echo output to console
137 destination_filename : str, Optional
142 destination_filename : str, Optional
138 Filename to write output into. If None, output is not
143 Filename to write output into. If None, output is not
139 written to a file.
144 written to a file.
140 destination_directory : str, Optional
145 destination_directory : str, Optional
141 Directory to write notebook data (i.e. figures) to. If
146 Directory to write notebook data (i.e. figures) to. If
142 None, figures are not written to the file system.
147 None, figures are not written to the file system.
143 """
148 """
144
149
145 if stdout:
150 if stdout:
146 print(output.encode('utf-8'))
151 print(output.encode('utf-8'))
147
152
148 #Write file output from conversion.
153 #Write file output from conversion.
149 if not destination_filename is None:
154 if not destination_filename is None:
150 with io.open(destination_filename, 'w') as f:
155 with io.open(destination_filename, 'w') as f:
151 f.write(output)
156 f.write(output)
152
157
153 #Get the key names used by the extract figure transformer
158 #Get the key names used by the extract figure transformer
154 figures_key = extractfigure.FIGURES_KEY
159 figures_key = extractfigure.FIGURES_KEY
155 binary_key = extractfigure.BINARY_KEY
160 binary_key = extractfigure.BINARY_KEY
156 text_key = extractfigure.TEXT_KEY
161 text_key = extractfigure.TEXT_KEY
157
162
158 #Output any associate figures into the same "root" directory.
163 #Output any associate figures into the same "root" directory.
159 binkeys = resources.get(figures_key, {}).get(binary_key,{}).keys()
164 binkeys = resources.get(figures_key, {}).get(binary_key,{}).keys()
160 textkeys = resources.get(figures_key, {}).get(text_key,{}).keys()
165 textkeys = resources.get(figures_key, {}).get(text_key,{}).keys()
161 if binkeys or textkeys :
166 if binkeys or textkeys :
162 if not destination_directory is None:
167 if not destination_directory is None:
163 for key in binkeys:
168 for key in binkeys:
164 with io.open(os.path.join(destination_directory, key), 'wb') as f:
169 with io.open(os.path.join(destination_directory, key), 'wb') as f:
165 f.write(resources[figures_key][binary_key][key])
170 f.write(resources[figures_key][binary_key][key])
166 for key in textkeys:
171 for key in textkeys:
167 with io.open(os.path.join(destination_directory, key), 'w') as f:
172 with io.open(os.path.join(destination_directory, key), 'w') as f:
168 f.write(resources[figures_key][text_key][key])
173 f.write(resources[figures_key][text_key][key])
169
174
170 #Figures that weren't exported which will need to be created by the
175 #Figures that weren't exported which will need to be created by the
171 #user. Tell the user what figures these are.
176 #user. Tell the user what figures these are.
172 if stdout:
177 if stdout:
173 print(KEYS_PROMPT_HEAD)
178 print(KEYS_PROMPT_HEAD)
174 print(resources[figures_key].keys())
179 print(resources[figures_key].keys())
175 print(KEYS_PROMPT_BODY)
180 print(KEYS_PROMPT_BODY)
176
181
177 #-----------------------------------------------------------------------------
182 #-----------------------------------------------------------------------------
178 #Script main
183 #Script main
179 #-----------------------------------------------------------------------------
184 #-----------------------------------------------------------------------------
180
185
181 def main():
186 def main():
182 """Application entry point"""
187 """Application entry point"""
183
188
184 app = NbConvertApp.instance()
189 app = NbConvertApp.instance()
185 app.description = __doc__
190 app.description = __doc__
186 app.start(argv=sys.argv)
191 app.start(argv=sys.argv)
187
192
188 #Check to see if python is calling this file directly.
193 #Check to see if python is calling this file directly.
189 if __name__ == '__main__':
194 if __name__ == '__main__':
190 main() No newline at end of file
195 main()
@@ -1,55 +1,55 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
17 from IPython.utils.traitlets import Unicode
18
18
19 import nbconvert.transformers.csshtmlheader
19 import nbconvert.transformers.csshtmlheader
20
20
21 # local import
21 # local import
22 import exporter
22 import exporter
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Classes
25 # Classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 class BasicHtmlExporter(exporter.Exporter):
28 class BasicHtmlExporter(exporter.Exporter):
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 tranformers/filters. If you don't need custom tranformers/
32 custom transformers/filters. If you don't need custom transformers/
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 template_file = Unicode(
41 template_file = Unicode(
42 'basichtml', config=True,
42 'basichtml', config=True,
43 help="Name of the template file to use")
43 help="Name of the template file to use")
44
44
45 def _register_transformers(self):
45 def _register_transformers(self):
46 """
46 """
47 Register all of the transformers needed for this exporter.
47 Register all of the transformers needed for this exporter.
48 """
48 """
49
49
50 #Register the transformers of the base class.
50 #Register the transformers of the base class.
51 super(BasicHtmlExporter, self)._register_transformers()
51 super(BasicHtmlExporter, self)._register_transformers()
52
52
53 #Register latex transformer
53 #Register latex transformer
54 self.register_transformer(nbconvert.transformers.csshtmlheader.CSSHtmlHeaderTransformer)
54 self.register_transformer(nbconvert.transformers.csshtmlheader.CSSHtmlHeaderTransformer)
55 No newline at end of file
55
@@ -1,127 +1,126 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 from IPython.utils.traitlets import (Dict, List, Unicode)
16 from IPython.utils.traitlets import (Dict, List, Unicode)
17 from .activatable import ActivatableTransformer
17 from .activatable import ActivatableTransformer
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Constants
20 # Constants
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 FIGURES_KEY = "figures"
23 FIGURES_KEY = "figures"
24 BINARY_KEY = "binary"
24 BINARY_KEY = "binary"
25 TEXT_KEY = "text"
25 TEXT_KEY = "text"
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Classes
28 # Classes
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 class ExtractFigureTransformer(ActivatableTransformer):
31 class ExtractFigureTransformer(ActivatableTransformer):
32 """
32 """
33 Extracts all of the figures from the notebook file. The extracted
33 Extracts all of the figures from the notebook file. The extracted
34 figures are returned in the 'resources' dictionary.
34 figures are returned in the 'resources' dictionary.
35 """
35 """
36
36
37 extra_extension_map = Dict({},
37 extra_extension_map = Dict({},
38 config=True,
38 config=True,
39 help="""Extra map to override extension based on type.
39 help="""Extra map to override extension based on type.
40 Useful for latex where SVG will be converted to PDF before inclusion
40 Useful for latex where SVG will be converted to PDF before inclusion
41 """)
41 """)
42
42
43 key_format_map = Dict({}, config=True,)
43 key_format_map = Dict({}, config=True,)
44 figure_name_format_map = Dict({}, config=True)
44 figure_name_format_map = Dict({}, config=True)
45
45
46 display_data_priority = List(['svg', 'png', 'latex', 'jpg', 'jpeg','text'])
46 display_data_priority = List(['svg', 'png', 'latex', 'jpg', 'jpeg','text'])
47
47
48 #TODO: Change this to .format {} syntax
48 #TODO: Change this to .format {} syntax
49 default_key_template = Unicode('_fig_{count:02d}.{ext}', config=True)
49 default_key_template = Unicode('_fig_{index:02d}.{ext}', config=True)
50
50
51 def cell_transform(self, cell, resources, index):
51 def cell_transform(self, cell, resources, index):
52 """
52 """
53 Apply a transformation on each cell,
53 Apply a transformation on each cell,
54
54
55 Parameters
55 Parameters
56 ----------
56 ----------
57 cell : NotebookNode cell
57 cell : NotebookNode cell
58 Notebook cell being processed
58 Notebook cell being processed
59 resources : dictionary
59 resources : dictionary
60 Additional resources used in the conversion process. Allows
60 Additional resources used in the conversion process. Allows
61 transformers to pass variables into the Jinja engine.
61 transformers to pass variables into the Jinja engine.
62 index : int
62 index : int
63 Modified index of the cell being processed (see base.py)
63 Modified index of the cell being processed (see base.py)
64 """
64 """
65
65
66 if resources.get(FIGURES_KEY, None) is None :
66 if resources.get(FIGURES_KEY, None) is None :
67 resources[FIGURES_KEY] = {TEXT_KEY:{},BINARY_KEY:{}}
67 resources[FIGURES_KEY] = {TEXT_KEY:{},BINARY_KEY:{}}
68
68
69 for out in cell.get('outputs', []):
69 for out in cell.get('outputs', []):
70 for out_type in self.display_data_priority:
70 for out_type in self.display_data_priority:
71
71
72 if out.hasattr(out_type):
72 if out.hasattr(out_type):
73 figname, key, data, binary = self._new_figure(out[out_type], out_type, index)
73 figname, key, data, binary = self._new_figure(out[out_type], out_type, index)
74 out['key_'+out_type] = figname
74 out['key_'+out_type] = figname
75
75
76 if binary :
76 if binary :
77 resources[FIGURES_KEY][BINARY_KEY][key] = data
77 resources[FIGURES_KEY][BINARY_KEY][key] = data
78 else :
78 else :
79 resources[FIGURES_KEY][TEXT_KEY][key] = data
79 resources[FIGURES_KEY][TEXT_KEY][key] = data
80
80
81 index += 1
81 index += 1
82 return cell, resources
82 return cell, resources
83
83
84
84
85 def _get_override_extension(self, extension):
85 def _get_override_extension(self, extension):
86 """Gets the overriden extension if it exists, else returns extension.
86 """Gets the overriden extension if it exists, else returns extension.
87
87
88 Parameters
88 Parameters
89 ----------
89 ----------
90 extension : str
90 extension : str
91 File extension.
91 File extension.
92 """
92 """
93
93
94 if extension in self.extra_extension_map :
94 if extension in self.extra_extension_map :
95 return self.extra_extension_map[extension]
95 return self.extra_extension_map[extension]
96
96
97 return extension
97 return extension
98
98
99
99
100 def _new_figure(self, data, format, index):
100 def _new_figure(self, data, format, index):
101 """Create a new figure file in the given format.
101 """Create a new figure file in the given format.
102
102
103 Parameters
103 Parameters
104 ----------
104 ----------
105 data : str
105 data : str
106 Cell data (from Notebook node cell)
106 Cell data (from Notebook node cell)
107 resources : dictionary
107 format : str
108 Additional resources used in the conversion process. Allows
108 Figure format
109 transformers to pass variables into the Jinja engine.
110 index : int
109 index : int
111 Modified index of the cell being processed (see base.py)
110 Modified index of the cell being processed (see base.py)
112 """
111 """
113
112
114 figure_name_template = self.figure_name_format_map.get(format, self.default_key_template)
113 figure_name_template = self.figure_name_format_map.get(format, self.default_key_template)
115 key_template = self.key_format_map.get(format, self.default_key_template)
114 key_template = self.key_format_map.get(format, self.default_key_template)
116
115
117 #TODO: option to pass the hash as data?
116 #TODO: option to pass the hash as data?
118 figure_name = figure_name_template.format(index=index, ext=self._get_override_extension(format))
117 figure_name = figure_name_template.format(index=index, ext=self._get_override_extension(format))
119 key = key_template.format(index=index, ext=self._get_override_extension(format))
118 key = key_template.format(index=index, ext=self._get_override_extension(format))
120
119
121 #Binary files are base64-encoded, SVG is already XML
120 #Binary files are base64-encoded, SVG is already XML
122 binary = False
121 binary = False
123 if format in ('png', 'jpg', 'pdf'):
122 if format in ('png', 'jpg', 'pdf'):
124 data = data.decode('base64')
123 data = data.decode('base64')
125 binary = True
124 binary = True
126
125
127 return figure_name, key, data, binary
126 return figure_name, key, data, binary
General Comments 0
You need to be logged in to leave comments. Login now