##// END OF EJS Templates
make ExtracfigureTransformer Activable
Matthias BUSSONNIER -
Show More
@@ -1,239 +1,233 b''
1 """
1 """
2
2
3 """
3 """
4
4
5 from __future__ import print_function
5 from __future__ import print_function
6
6
7 from IPython.config.configurable import Configurable
7 from IPython.config.configurable import Configurable
8 from IPython.utils.traitlets import Unicode, Bool, Dict, List
8 from IPython.utils.traitlets import Unicode, Bool, Dict, List
9
9
10 class ConfigurableTransformers(Configurable):
10 class ConfigurableTransformers(Configurable):
11 """ A configurable transformer """
11 """ A configurable transformer """
12
12
13 def __init__(self, config=None, **kw):
13 def __init__(self, config=None, **kw):
14 super(ConfigurableTransformers, self).__init__(config=config, **kw)
14 super(ConfigurableTransformers, self).__init__(config=config, **kw)
15
15
16 def __call__(self, nb, other):
16 def __call__(self, nb, other):
17 try :
17 try :
18 for worksheet in nb.worksheets :
18 for worksheet in nb.worksheets :
19 for index, cell in enumerate(worksheet.cells):
19 for index, cell in enumerate(worksheet.cells):
20 worksheet.cells[index], other = self.cell_transform(cell, other, index)
20 worksheet.cells[index], other = self.cell_transform(cell, other, index)
21 return nb, other
21 return nb, other
22 except NotImplementedError as error :
22 except NotImplementedError as error :
23 raise NotImplementedError('should be implemented by subclass')
23 raise NotImplementedError('should be implemented by subclass')
24
24
25 def cell_transform(self, cell, other, index):
25 def cell_transform(self, cell, other, index):
26 """
26 """
27 Overwrite if you want to apply a transformation on each cell
27 Overwrite if you want to apply a transformation on each cell
28 """
28 """
29 raise NotImplementedError('should be implemented by subclass')
29 raise NotImplementedError('should be implemented by subclass')
30
30
31
31
32 class ActivatableTransformer(ConfigurableTransformers):
32 class ActivatableTransformer(ConfigurableTransformers):
33
33
34 active = Bool(False, config=True)
34 enabled = Bool(False, config=True)
35
35
36 def __call__(self, nb, other):
36 def __call__(self, nb, other):
37 if not self.active :
37 if not self.enabled :
38 return nb,other
38 return nb,other
39 else :
39 else :
40 return super(ActivatableTransformer,self).__call__(nb, other)
40 return super(ActivatableTransformer,self).__call__(nb, other)
41
41
42
42
43 def cell_preprocessor(function):
43 def cell_preprocessor(function):
44 """ wrap a function to be executed on all cells of a notebook
44 """ wrap a function to be executed on all cells of a notebook
45
45
46 wrapped function parameters :
46 wrapped function parameters :
47 cell : the cell
47 cell : the cell
48 other : external resources
48 other : external resources
49 index : index of the cell
49 index : index of the cell
50 """
50 """
51 def wrappedfunc(nb, other):
51 def wrappedfunc(nb, other):
52 for worksheet in nb.worksheets :
52 for worksheet in nb.worksheets :
53 for index, cell in enumerate(worksheet.cells):
53 for index, cell in enumerate(worksheet.cells):
54 worksheet.cells[index], other = function(cell, other, index)
54 worksheet.cells[index], other = function(cell, other, index)
55 return nb, other
55 return nb, other
56 return wrappedfunc
56 return wrappedfunc
57
57
58
58
59 @cell_preprocessor
59 @cell_preprocessor
60 def haspyout_transformer(cell, other, count):
60 def haspyout_transformer(cell, other, count):
61 """
61 """
62 Add a haspyout flag to cell that have it
62 Add a haspyout flag to cell that have it
63
63
64 Easier for templating, where you can't know in advance
64 Easier for templating, where you can't know in advance
65 wether to write the out prompt
65 wether to write the out prompt
66
66
67 """
67 """
68 cell.type = cell.cell_type
68 cell.type = cell.cell_type
69 cell.haspyout = False
69 cell.haspyout = False
70 for out in cell.get('outputs', []):
70 for out in cell.get('outputs', []):
71 if out.output_type == 'pyout':
71 if out.output_type == 'pyout':
72 cell.haspyout = True
72 cell.haspyout = True
73 break
73 break
74 return cell, other
74 return cell, other
75
75
76
76
77 # todo, make the key part configurable.
77 # todo, make the key part configurable.
78
78
79 class ExtractFigureTransformer(ActivatableTransformer):
79 class ExtractFigureTransformer(ActivatableTransformer):
80 enabled = Bool(False,
81 config=True,
82 help=""" If set to false, this transformer will be no-op """
83 )
84
80
85 extra_ext_map = Dict({},
81 extra_ext_map = Dict({},
86 config=True,
82 config=True,
87 help="""extra map to override extension based on type.
83 help="""extra map to override extension based on type.
88 Usefull for latex where svg will be converted to pdf before inclusion
84 Usefull for latex where svg will be converted to pdf before inclusion
89 """
85 """
90 )
86 )
91 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
87 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
92 config=True,
88 config=True,
93 help= """
89 help= """
94 An ordered list of prefered output type, the first
90 An ordered list of prefered output type, the first
95 encounterd will usually be used when converting discarding
91 encounterd will usually be used when converting discarding
96 the others.
92 the others.
97 """
93 """
98 )
94 )
99
95
100
96
101 #to do change this to .format {} syntax
97 #to do change this to .format {} syntax
102 key_tpl = Unicode('_fig_%02i.%s', config=True)
98 key_tpl = Unicode('_fig_%02i.%s', config=True)
103
99
104 def _get_ext(self, ext):
100 def _get_ext(self, ext):
105 if ext in self.extra_ext_map :
101 if ext in self.extra_ext_map :
106 return self.extra_ext_map[ext]
102 return self.extra_ext_map[ext]
107 return ext
103 return ext
108
104
109 def _new_figure(self, data, fmt, count):
105 def _new_figure(self, data, fmt, count):
110 """Create a new figure file in the given format.
106 """Create a new figure file in the given format.
111
107
112 Returns a path relative to the input file.
108 Returns a path relative to the input file.
113 """
109 """
114 figname = self.key_tpl % (count, self._get_ext(fmt))
110 figname = self.key_tpl % (count, self._get_ext(fmt))
115 key = self.key_tpl % (count, fmt)
111 key = self.key_tpl % (count, fmt)
116
112
117 # Binary files are base64-encoded, SVG is already XML
113 # Binary files are base64-encoded, SVG is already XML
118 if fmt in ('png', 'jpg', 'pdf'):
114 if fmt in ('png', 'jpg', 'pdf'):
119 data = data.decode('base64')
115 data = data.decode('base64')
120
116
121 return figname, key, data
117 return figname, key, data
122
118
123
119
124 def cell_transform(self, cell, other, count):
120 def cell_transform(self, cell, other, count):
125 if not self.enabled:
126 return cell, other
127 if other.get('figures',None) is None :
121 if other.get('figures',None) is None :
128 other['figures']={}
122 other['figures']={}
129 for i, out in enumerate(cell.get('outputs', [])):
123 for i, out in enumerate(cell.get('outputs', [])):
130 for type in self.display_data_priority:
124 for type in self.display_data_priority:
131 if out.hasattr(type):
125 if out.hasattr(type):
132 figname, key, data = self._new_figure(out[type], type, count)
126 figname, key, data = self._new_figure(out[type], type, count)
133 out['key_'+type] = figname
127 out['key_'+type] = figname
134 other['figures'][key] = data
128 other['figures'][key] = data
135 count = count+1
129 count = count+1
136 return cell, other
130 return cell, other
137
131
138 class RevealHelpTransformer(ConfigurableTransformers):
132 class RevealHelpTransformer(ConfigurableTransformers):
139
133
140 section_open = False
134 section_open = False
141 subsection_open = False
135 subsection_open = False
142 fragment_open = False
136 fragment_open = False
143
137
144 def open_subsection(self):
138 def open_subsection(self):
145 self.subsection_open = True
139 self.subsection_open = True
146 return True
140 return True
147
141
148 def open_section(self):
142 def open_section(self):
149 self.section_open = True
143 self.section_open = True
150 return True
144 return True
151
145
152 def open_fragment(self):
146 def open_fragment(self):
153 self.fragment_open = True
147 self.fragment_open = True
154 return True
148 return True
155
149
156 # could probaly write those maybe_close/open
150 # could probaly write those maybe_close/open
157 # with a function functor
151 # with a function functor
158 def maybe_close_section(self):
152 def maybe_close_section(self):
159 """return True is already open, false otherwise
153 """return True is already open, false otherwise
160 and change state to close
154 and change state to close
161 """
155 """
162 if self.section_open :
156 if self.section_open :
163 self.section_open = False
157 self.section_open = False
164 return True
158 return True
165 else :
159 else :
166 return False
160 return False
167
161
168 def maybe_open_section(self):
162 def maybe_open_section(self):
169 """return True is already open, false otherwise
163 """return True is already open, false otherwise
170 and change state to close
164 and change state to close
171 """
165 """
172 if not self.section_open :
166 if not self.section_open :
173 self.section_open = True
167 self.section_open = True
174 return True
168 return True
175 else :
169 else :
176 return False
170 return False
177
171
178 def maybe_open_subsection(self):
172 def maybe_open_subsection(self):
179 """return True is already open, false otherwise
173 """return True is already open, false otherwise
180 and change state to close
174 and change state to close
181 """
175 """
182 if not self.subsection_open :
176 if not self.subsection_open :
183 self.subsection_open = True
177 self.subsection_open = True
184 return True
178 return True
185 else :
179 else :
186 return False
180 return False
187
181
188 def maybe_close_subsection(self):
182 def maybe_close_subsection(self):
189 """return True is already open, false otherwise
183 """return True is already open, false otherwise
190 and change state to close
184 and change state to close
191 """
185 """
192 if self.subsection_open :
186 if self.subsection_open :
193 self.subsection_open = False
187 self.subsection_open = False
194 return True
188 return True
195 else :
189 else :
196 return False
190 return False
197
191
198 def maybe_close_fragment(self):
192 def maybe_close_fragment(self):
199 """return True is already open, false otherwise
193 """return True is already open, false otherwise
200 and change state to close
194 and change state to close
201 """
195 """
202 if self.fragment_open :
196 if self.fragment_open :
203 self.fragment_open = False
197 self.fragment_open = False
204 return True
198 return True
205 else :
199 else :
206 return False
200 return False
207
201
208 def cell_transform(self, cell, other,count):
202 def cell_transform(self, cell, other,count):
209 ctype = cell.metadata.get('slideshow',{}).get('slide_type',None)
203 ctype = cell.metadata.get('slideshow',{}).get('slide_type',None)
210 if ctype in [None, '-'] :
204 if ctype in [None, '-'] :
211 cell.metadata.slideshow = {}
205 cell.metadata.slideshow = {}
212 cell.metadata.slideshow['slide_type'] = None
206 cell.metadata.slideshow['slide_type'] = None
213 elif ctype == 'fragment':
207 elif ctype == 'fragment':
214 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
208 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
215 cell.metadata.slideshow.close_subsection = False
209 cell.metadata.slideshow.close_subsection = False
216 cell.metadata.slideshow.close_section = False
210 cell.metadata.slideshow.close_section = False
217
211
218 cell.metadata.slideshow.open_section = self.maybe_open_section()
212 cell.metadata.slideshow.open_section = self.maybe_open_section()
219 cell.metadata.slideshow.open_subsection = self.maybe_open_subsection()
213 cell.metadata.slideshow.open_subsection = self.maybe_open_subsection()
220 cell.metadata.slideshow.open_fragment = self.open_fragment()
214 cell.metadata.slideshow.open_fragment = self.open_fragment()
221
215
222 elif ctype == 'subslide':
216 elif ctype == 'subslide':
223 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
217 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
224 cell.metadata.slideshow.close_subsection = self.maybe_close_subsection()
218 cell.metadata.slideshow.close_subsection = self.maybe_close_subsection()
225 cell.metadata.slideshow.close_section = False
219 cell.metadata.slideshow.close_section = False
226
220
227 cell.metadata.slideshow.open_section = self.maybe_open_section()
221 cell.metadata.slideshow.open_section = self.maybe_open_section()
228 cell.metadata.slideshow.open_subsection = self.open_subsection()
222 cell.metadata.slideshow.open_subsection = self.open_subsection()
229 cell.metadata.slideshow.open_fragment = False
223 cell.metadata.slideshow.open_fragment = False
230 elif ctype == 'slide':
224 elif ctype == 'slide':
231 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
225 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
232 cell.metadata.slideshow.close_subsection = self.maybe_close_subsection()
226 cell.metadata.slideshow.close_subsection = self.maybe_close_subsection()
233 cell.metadata.slideshow.close_section = self.maybe_close_section()
227 cell.metadata.slideshow.close_section = self.maybe_close_section()
234
228
235 cell.metadata.slideshow.open_section = self.open_section()
229 cell.metadata.slideshow.open_section = self.open_section()
236 cell.metadata.slideshow.open_subsection = self.open_subsection()
230 cell.metadata.slideshow.open_subsection = self.open_subsection()
237 cell.metadata.slideshow.open_fragment = False
231 cell.metadata.slideshow.open_fragment = False
238 return cell,other
232 return cell,other
239
233
General Comments 0
You need to be logged in to leave comments. Login now