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