##// END OF EJS Templates
pylint
Matthias BUSSONNIER -
Show More
@@ -1,224 +1,223 b''
1 """Base classes for the notebook conversion pipeline.
1 """Base classes for the notebook conversion pipeline.
2
2
3 This module defines ConverterTemplate, a highly configurable converter
3 This module defines ConverterTemplate, a highly configurable converter
4 that uses Jinja2 to convert notebook files into different format.
4 that uses Jinja2 to convert notebook files into different format.
5
5
6 You can register both pre-transformers that will act on the notebook format
6 You can register both pre-transformers that will act on the notebook format
7 befor conversion and jinja filter that would then be availlable in the templates
7 befor conversion and jinja filter that would then be availlable in the templates
8 """
8 """
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2013, the IPython Development Team.
10 # Copyright (c) 2013, the IPython Development Team.
11 #
11 #
12 # Distributed under the terms of the Modified BSD License.
12 # Distributed under the terms of the Modified BSD License.
13 #
13 #
14 # The full license is in the file COPYING.txt, distributed with this software.
14 # The full license is in the file COPYING.txt, distributed with this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 from __future__ import print_function, absolute_import
21 from __future__ import print_function, absolute_import
22
22
23 # Stdlib imports
23 # Stdlib imports
24 import io
24 import io
25
25
26 # IPython imports
26 # IPython imports
27 from IPython.utils.traitlets import MetaHasTraits
27 from IPython.utils.traitlets import MetaHasTraits
28 from IPython.utils.traitlets import (Unicode, List, Bool)
28 from IPython.utils.traitlets import (Unicode, List, Bool)
29 from IPython.config.configurable import Configurable
29 from IPython.config.configurable import Configurable
30 from IPython.nbformat import current as nbformat
30 from IPython.nbformat import current as nbformat
31
31
32 # other libs/dependencies
32 # other libs/dependencies
33 from jinja2 import Environment, FileSystemLoader
33 from jinja2 import Environment, FileSystemLoader
34
34
35
35
36 # local import (pre-transformers)
36 # local import (pre-transformers)
37 import converters.transformers as trans
37 import converters.transformers as trans
38
38
39 # some jinja filters
39 # some jinja filters
40 from converters.jinja_filters import (python_comment, indent,
40 from converters.jinja_filters import (python_comment, indent,
41 rm_fake, remove_ansi, markdown, highlight,
41 rm_fake, remove_ansi, markdown, highlight,
42 ansi2html, markdown2latex, escape_tex, FilterDataType)
42 ansi2html, markdown2latex, escape_tex, FilterDataType)
43
43
44 from converters.utils import markdown2rst
44 from converters.utils import markdown2rst
45 from converters.config import GlobalConfigurable
46
45
47
46
48
47
49 # define differents environemnt with different
48 # define differents environemnt with different
50 # delimiters not to conflict with languages inside
49 # delimiters not to conflict with languages inside
51
50
52 env = Environment(
51 env = Environment(
53 loader=FileSystemLoader([
52 loader=FileSystemLoader([
54 './templates/',
53 './templates/',
55 './templates/skeleton/',
54 './templates/skeleton/',
56 ]),
55 ]),
57 extensions=['jinja2.ext.loopcontrols']
56 extensions=['jinja2.ext.loopcontrols']
58 )
57 )
59
58
60 texenv = Environment(
59 texenv = Environment(
61 loader=FileSystemLoader([
60 loader=FileSystemLoader([
62 './templates/tex/',
61 './templates/tex/',
63 './templates/skeleton/tex/',
62 './templates/skeleton/tex/',
64 ]),
63 ]),
65 extensions=['jinja2.ext.loopcontrols']
64 extensions=['jinja2.ext.loopcontrols']
66 )
65 )
67
66
68
67
69 texenv.block_start_string = '((*'
68 texenv.block_start_string = '((*'
70 texenv.block_end_string = '*))'
69 texenv.block_end_string = '*))'
71
70
72 texenv.variable_start_string = '((('
71 texenv.variable_start_string = '((('
73 texenv.variable_end_string = ')))'
72 texenv.variable_end_string = ')))'
74
73
75 texenv.comment_start_string = '((='
74 texenv.comment_start_string = '((='
76 texenv.comment_end_string = '=))'
75 texenv.comment_end_string = '=))'
77
76
78 texenv.filters['escape_tex'] = escape_tex
77 texenv.filters['escape_tex'] = escape_tex
79
78
80 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
81 # Class declarations
80 # Class declarations
82 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
83 class ConversionException(Exception):
82 class ConversionException(Exception):
84 pass
83 pass
85
84
86 class ConverterTemplate(Configurable):
85 class ConverterTemplate(Configurable):
87 """ A Jinja2 base converter templates
86 """ A Jinja2 base converter templates
88
87
89 Preprocess the ipynb files, feed it throug jinja templates,
88 Preprocess the ipynb files, feed it throug jinja templates,
90 and spit an converted files and a data object with other data
89 and spit an converted files and a data object with other data
91
90
92 shoudl be mostly configurable
91 shoudl be mostly configurable
93 """
92 """
94
93
95 pre_transformer_order = List(['haspyout_transformer'],
94 pre_transformer_order = List(['haspyout_transformer'],
96 config=True,
95 config=True,
97 help= """
96 help= """
98 An ordered list of pre transformer to apply to the ipynb
97 An ordered list of pre transformer to apply to the ipynb
99 file befor running through templates
98 file befor running through templates
100 """
99 """
101 )
100 )
102
101
103 tex_environement = Bool(False,
102 tex_environement = Bool(False,
104 config=True,
103 config=True,
105 help=""" is this a tex environment or not """)
104 help=""" is this a tex environment or not """)
106
105
107 template_file = Unicode('',
106 template_file = Unicode('',
108 config=True,
107 config=True,
109 help=""" Name of the template file to use """ )
108 help=""" Name of the template file to use """ )
110 #-------------------------------------------------------------------------
109 #-------------------------------------------------------------------------
111 # Instance-level attributes that are set in the constructor for this
110 # Instance-level attributes that are set in the constructor for this
112 # class.
111 # class.
113 #-------------------------------------------------------------------------
112 #-------------------------------------------------------------------------
114
113
115
114
116 preprocessors = []
115 preprocessors = []
117
116
118 def __init__(self, preprocessors={}, jinja_filters={}, config=None, **kw):
117 def __init__(self, preprocessors={}, jinja_filters={}, config=None, **kw):
119 """ Init a new converter.
118 """ Init a new converter.
120
119
121 config: the Configurable config object to pass around.
120 config: the Configurable config object to pass around.
122
121
123 preprocessors: dict of **availlable** key/value function to run on
122 preprocessors: dict of **availlable** key/value function to run on
124 ipynb json data before conversion to extract/inline file.
123 ipynb json data before conversion to extract/inline file.
125 See `transformer.py` and `ConfigurableTransformers`
124 See `transformer.py` and `ConfigurableTransformers`
126
125
127 set the order in which the transformers should apply
126 set the order in which the transformers should apply
128 with the `pre_transformer_order` trait of this class
127 with the `pre_transformer_order` trait of this class
129
128
130 transformers registerd by this key will take precedence on
129 transformers registerd by this key will take precedence on
131 default one.
130 default one.
132
131
133
132
134 jinja_filters: dict of supplementary jinja filter that should be made
133 jinja_filters: dict of supplementary jinja filter that should be made
135 availlable in template. If those are of Configurable Class type,
134 availlable in template. If those are of Configurable Class type,
136 they will be instanciated with the config object as argument.
135 they will be instanciated with the config object as argument.
137
136
138 user defined filter will overwrite the one availlable by default.
137 user defined filter will overwrite the one availlable by default.
139 """
138 """
140 super(ConverterTemplate, self).__init__(config=config, **kw)
139 super(ConverterTemplate, self).__init__(config=config, **kw)
141
140
142 # variable parameters depending on the pype of jinja environement
141 # variable parameters depending on the pype of jinja environement
143 self.env = texenv if self.tex_environement else env
142 self.env = texenv if self.tex_environement else env
144 self.ext = '.tplx' if self.tex_environement else '.tpl'
143 self.ext = '.tplx' if self.tex_environement else '.tpl'
145
144
146 for name in self.pre_transformer_order:
145 for name in self.pre_transformer_order:
147 # get the user-defined transformer first
146 # get the user-defined transformer first
148 transformer = getattr(preprocessors, name, getattr(trans, name, None))
147 transformer = getattr(preprocessors, name, getattr(trans, name, None))
149 if isinstance(transformer, MetaHasTraits):
148 if isinstance(transformer, MetaHasTraits):
150 transformer = transformer(config=config)
149 transformer = transformer(config=config)
151 self.preprocessors.append(transformer)
150 self.preprocessors.append(transformer)
152
151
153 ## for compat, remove later
152 ## for compat, remove later
154 self.preprocessors.append(trans.coalesce_streams)
153 self.preprocessors.append(trans.coalesce_streams)
155 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
154 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
156 self.preprocessors.append(trans.RevealHelpTransformer(config=config))
155 self.preprocessors.append(trans.RevealHelpTransformer(config=config))
157 self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config))
156 self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config))
158
157
159 ##
158 ##
160 self.env.filters['filter_data_type'] = FilterDataType(config=config)
159 self.env.filters['filter_data_type'] = FilterDataType(config=config)
161 self.env.filters['pycomment'] = python_comment
160 self.env.filters['pycomment'] = python_comment
162 self.env.filters['indent'] = indent
161 self.env.filters['indent'] = indent
163 self.env.filters['rm_fake'] = rm_fake
162 self.env.filters['rm_fake'] = rm_fake
164 self.env.filters['rm_ansi'] = remove_ansi
163 self.env.filters['rm_ansi'] = remove_ansi
165 self.env.filters['markdown'] = markdown
164 self.env.filters['markdown'] = markdown
166 self.env.filters['highlight'] = highlight
165 self.env.filters['highlight'] = highlight
167 self.env.filters['ansi2html'] = ansi2html
166 self.env.filters['ansi2html'] = ansi2html
168 self.env.filters['markdown2latex'] = markdown2latex
167 self.env.filters['markdown2latex'] = markdown2latex
169 self.env.filters['markdown2rst'] = markdown2rst
168 self.env.filters['markdown2rst'] = markdown2rst
170
169
171 ## user filter will overwrite
170 ## user filter will overwrite
172 for key, filtr in jinja_filters.iteritems():
171 for key, filtr in jinja_filters.iteritems():
173 if isinstance(filtr, MetaHasTraits):
172 if isinstance(filtr, MetaHasTraits):
174 self.env.filters[key] = filtr(config=config)
173 self.env.filters[key] = filtr(config=config)
175 else :
174 else :
176 self.env.filters[key] = filtr
175 self.env.filters[key] = filtr
177
176
178 self.template = self.env.get_template(self.template_file+self.ext)
177 self.template = self.env.get_template(self.template_file+self.ext)
179
178
180
179
181 def process(self, nb):
180 def process(self, nb):
182 """
181 """
183 preprocess the notebook json for easier use with the templates.
182 preprocess the notebook json for easier use with the templates.
184 will call all the `preprocessor`s in order before returning it.
183 will call all the `preprocessor`s in order before returning it.
185 """
184 """
186
185
187 # dict of 'resources' that could be made by the preprocessors
186 # dict of 'resources' that could be made by the preprocessors
188 # like key/value data to extract files from ipynb like in latex conversion
187 # like key/value data to extract files from ipynb like in latex conversion
189 resources = {}
188 resources = {}
190
189
191 for preprocessor in self.preprocessors:
190 for preprocessor in self.preprocessors:
192 nb, resources = preprocessor(nb, resources)
191 nb, resources = preprocessor(nb, resources)
193
192
194 return nb, resources
193 return nb, resources
195
194
196 def convert(self, nb):
195 def convert(self, nb):
197 """ convert the ipynb file
196 """ convert the ipynb file
198
197
199 return both the converted ipynb file and a dict containing potential
198 return both the converted ipynb file and a dict containing potential
200 other resources
199 other resources
201 """
200 """
202 nb, resources = self.process(nb)
201 nb, resources = self.process(nb)
203 return self.template.render(nb=nb, resources=resources), resources
202 return self.template.render(nb=nb, resources=resources), resources
204
203
205
204
206 def from_filename(self, filename):
205 def from_filename(self, filename):
207 """read and convert a notebook from a file name"""
206 """read and convert a notebook from a file name"""
208 with io.open(filename) as f:
207 with io.open(filename) as f:
209 return self.convert(nbformat.read(f, 'json'))
208 return self.convert(nbformat.read(f, 'json'))
210
209
211 def from_file(self, filelike):
210 def from_file(self, filelike):
212 """read and convert a notebook from a filelike object
211 """read and convert a notebook from a filelike object
213
212
214 filelike object will just be "read" and should be json format..
213 filelike object will just be "read" and should be json format..
215 """
214 """
216 return self.convert(nbformat.read(filelike, 'json'))
215 return self.convert(nbformat.read(filelike, 'json'))
217
216
218 def from_json(self, json):
217 def from_json(self, json):
219 """ not implemented
218 """ not implemented
220
219
221 Should convert from a json object
220 Should convert from a json object
222 """
221 """
223 raise NotImplementedError('not implemented (yet?)')
222 raise NotImplementedError('not implemented (yet?)')
224
223
@@ -1,271 +1,271 b''
1 """
1 """
2 Module that regroups transformer that woudl be applied to ipynb files
2 Module that regroups transformer that woudl be applied to ipynb files
3 before going through the templating machinery.
3 before going through the templating machinery.
4
4
5 It exposes convenient classes to inherit from to access configurability
5 It exposes convenient classes to inherit from to access configurability
6 as well as decorator to simplify tasks.
6 as well as decorator to simplify tasks.
7 """
7 """
8
8
9 from __future__ import print_function
9 from __future__ import print_function
10
10
11 from IPython.config.configurable import Configurable
11 from IPython.config.configurable import Configurable
12 from IPython.utils.traitlets import Unicode, Bool, Dict, List
12 from IPython.utils.traitlets import Unicode, Bool, Dict, List
13
13
14 from converters.config import GlobalConfigurable
14 from converters.config import GlobalConfigurable
15
15
16 class ConfigurableTransformers(GlobalConfigurable):
16 class ConfigurableTransformers(GlobalConfigurable):
17 """ A configurable transformer
17 """ A configurable transformer
18
18
19 Inherit from this class if you wish to have configurability for your
19 Inherit from this class if you wish to have configurability for your
20 transformer.
20 transformer.
21
21
22 Any configurable traitlets this class exposed will be configurable in profiles
22 Any configurable traitlets this class exposed will be configurable in profiles
23 using c.SubClassName.atribute=value
23 using c.SubClassName.atribute=value
24
24
25 you can overwrite cell_transform to apply a transformation independently on each cell
25 you can overwrite cell_transform to apply a transformation independently on each cell
26 or __call__ if you prefer your own logic. See orresponding docstring for informations.
26 or __call__ if you prefer your own logic. See orresponding docstring for informations.
27
27
28
28
29 """
29 """
30
30
31 def __init__(self, config=None, **kw):
31 def __init__(self, config=None, **kw):
32 super(ConfigurableTransformers, self).__init__(config=config, **kw)
32 super(ConfigurableTransformers, self).__init__(config=config, **kw)
33
33
34 def __call__(self, nb, other):
34 def __call__(self, nb, other):
35 """transformation to apply on each notebook.
35 """transformation to apply on each notebook.
36
36
37 received a handle to the current notebook as well as a dict of resources
37 received a handle to the current notebook as well as a dict of resources
38 which structure depends on the transformer.
38 which structure depends on the transformer.
39
39
40 You should return modified nb, other.
40 You should return modified nb, other.
41
41
42 If you wish to apply on each cell, you might want to overwrite cell_transform method.
42 If you wish to apply on each cell, you might want to overwrite cell_transform method.
43 """
43 """
44 try :
44 try :
45 for worksheet in nb.worksheets :
45 for worksheet in nb.worksheets :
46 for index, cell in enumerate(worksheet.cells):
46 for index, cell in enumerate(worksheet.cells):
47 worksheet.cells[index], other = self.cell_transform(cell, other, index)
47 worksheet.cells[index], other = self.cell_transform(cell, other, index)
48 return nb, other
48 return nb, other
49 except NotImplementedError:
49 except NotImplementedError:
50 raise NotImplementedError('should be implemented by subclass')
50 raise NotImplementedError('should be implemented by subclass')
51
51
52 def cell_transform(self, cell, other, index):
52 def cell_transform(self, cell, other, index):
53 """
53 """
54 Overwrite if you want to apply a transformation on each cell,
54 Overwrite if you want to apply a transformation on each cell,
55
55
56 receive the current cell, the resource dict and the index of current cell as parameter.
56 receive the current cell, the resource dict and the index of current cell as parameter.
57
57
58 You should return modified cell and resource dict.
58 You should return modified cell and resource dict.
59 """
59 """
60 raise NotImplementedError('should be implemented by subclass')
60 raise NotImplementedError('should be implemented by subclass')
61 return cell, other
61 return cell, other
62
62
63
63
64 class ActivatableTransformer(ConfigurableTransformers):
64 class ActivatableTransformer(ConfigurableTransformers):
65 """A simple ConfigurableTransformers that have an enabled flag
65 """A simple ConfigurableTransformers that have an enabled flag
66
66
67 Inherit from that if you just want to have a transformer which is
67 Inherit from that if you just want to have a transformer which is
68 no-op by default but can be activated in profiles with
68 no-op by default but can be activated in profiles with
69
69
70 c.YourTransformerName.enabled = True
70 c.YourTransformerName.enabled = True
71 """
71 """
72
72
73 enabled = Bool(False, config=True)
73 enabled = Bool(False, config=True)
74
74
75 def __call__(self, nb, other):
75 def __call__(self, nb, other):
76 if not self.enabled :
76 if not self.enabled :
77 return nb, other
77 return nb, other
78 else :
78 else :
79 return super(ActivatableTransformer, self).__call__(nb, other)
79 return super(ActivatableTransformer, self).__call__(nb, other)
80
80
81
81
82 def cell_preprocessor(function):
82 def cell_preprocessor(function):
83 """ wrap a function to be executed on all cells of a notebook
83 """ wrap a function to be executed on all cells of a notebook
84
84
85 wrapped function parameters :
85 wrapped function parameters :
86 cell : the cell
86 cell : the cell
87 other : external resources
87 other : external resources
88 index : index of the cell
88 index : index of the cell
89 """
89 """
90 def wrappedfunc(nb, other):
90 def wrappedfunc(nb, other):
91 for worksheet in nb.worksheets :
91 for worksheet in nb.worksheets :
92 for index, cell in enumerate(worksheet.cells):
92 for index, cell in enumerate(worksheet.cells):
93 worksheet.cells[index], other = function(cell, other, index)
93 worksheet.cells[index], other = function(cell, other, index)
94 return nb, other
94 return nb, other
95 return wrappedfunc
95 return wrappedfunc
96
96
97
97
98 @cell_preprocessor
98 @cell_preprocessor
99 def haspyout_transformer(cell, other, count):
99 def haspyout_transformer(cell, other, count):
100 """
100 """
101 Add a haspyout flag to cell that have it
101 Add a haspyout flag to cell that have it
102
102
103 Easier for templating, where you can't know in advance
103 Easier for templating, where you can't know in advance
104 wether to write the out prompt
104 wether to write the out prompt
105
105
106 """
106 """
107 cell.type = cell.cell_type
107 cell.type = cell.cell_type
108 cell.haspyout = False
108 cell.haspyout = False
109 for out in cell.get('outputs', []):
109 for out in cell.get('outputs', []):
110 if out.output_type == 'pyout':
110 if out.output_type == 'pyout':
111 cell.haspyout = True
111 cell.haspyout = True
112 break
112 break
113 return cell, other
113 return cell, other
114
114
115 @cell_preprocessor
115 @cell_preprocessor
116 def coalesce_streams(cell, other, count):
116 def coalesce_streams(cell, other, count):
117 """merge consecutive sequences of stream output into single stream
117 """merge consecutive sequences of stream output into single stream
118
118
119 to prevent extra newlines inserted at flush calls
119 to prevent extra newlines inserted at flush calls
120
120
121 TODO: handle \r deletion
121 TODO: handle \r deletion
122 """
122 """
123 outputs = cell.get('outputs', [])
123 outputs = cell.get('outputs', [])
124 if not outputs:
124 if not outputs:
125 return cell, other
125 return cell, other
126 new_outputs = []
126 new_outputs = []
127 last = outputs[0]
127 last = outputs[0]
128 new_outputs = [last]
128 new_outputs = [last]
129 for output in outputs[1:]:
129 for output in outputs[1:]:
130 if (output.output_type == 'stream' and
130 if (output.output_type == 'stream' and
131 last.output_type == 'stream' and
131 last.output_type == 'stream' and
132 last.stream == output.stream
132 last.stream == output.stream
133 ):
133 ):
134 last.text += output.text
134 last.text += output.text
135 else:
135 else:
136 new_outputs.append(output)
136 new_outputs.append(output)
137
137
138 cell.outputs = new_outputs
138 cell.outputs = new_outputs
139 return cell, other
139 return cell, other
140
140
141 class ExtractFigureTransformer(ActivatableTransformer):
141 class ExtractFigureTransformer(ActivatableTransformer):
142
142
143
143
144 extra_ext_map = Dict({},
144 extra_ext_map = Dict({},
145 config=True,
145 config=True,
146 help="""extra map to override extension based on type.
146 help="""extra map to override extension based on type.
147 Usefull for latex where svg will be converted to pdf before inclusion
147 Usefull for latex where svg will be converted to pdf before inclusion
148 """
148 """
149 )
149 )
150
150
151 key_format_map = Dict({},
151 key_format_map = Dict({},
152 config=True,
152 config=True,
153 )
153 )
154
154
155 figname_format_map = Dict({},
155 figname_format_map = Dict({},
156 config=True,
156 config=True,
157 )
157 )
158
158
159
159
160 #to do change this to .format {} syntax
160 #to do change this to .format {} syntax
161 default_key_tpl = Unicode('_fig_{count:02d}.{ext}', config=True)
161 default_key_tpl = Unicode('_fig_{count:02d}.{ext}', config=True)
162
162
163 def _get_ext(self, ext):
163 def _get_ext(self, ext):
164 if ext in self.extra_ext_map :
164 if ext in self.extra_ext_map :
165 return self.extra_ext_map[ext]
165 return self.extra_ext_map[ext]
166 return ext
166 return ext
167
167
168 def _new_figure(self, data, fmt, count):
168 def _new_figure(self, data, fmt, count):
169 """Create a new figure file in the given format.
169 """Create a new figure file in the given format.
170
170
171 """
171 """
172 tplf = self.figname_format_map.get(fmt,self.default_key_tpl)
172 tplf = self.figname_format_map.get(fmt, self.default_key_tpl)
173 tplk = self.key_format_map.get(fmt,self.default_key_tpl)
173 tplk = self.key_format_map.get(fmt, self.default_key_tpl)
174
174
175 # option to pass the hash as data ?
175 # option to pass the hash as data ?
176 figname = tplf.format(count=count, ext=self._get_ext(fmt))
176 figname = tplf.format(count=count, ext=self._get_ext(fmt))
177 key = tplk.format(count=count, ext=self._get_ext(fmt))
177 key = tplk.format(count=count, ext=self._get_ext(fmt))
178
178
179 # Binary files are base64-encoded, SVG is already XML
179 # Binary files are base64-encoded, SVG is already XML
180 if fmt in ('png', 'jpg', 'pdf'):
180 if fmt in ('png', 'jpg', 'pdf'):
181 data = data.decode('base64')
181 data = data.decode('base64')
182
182
183 return figname, key, data
183 return figname, key, data
184
184
185
185
186 def cell_transform(self, cell, other, count):
186 def cell_transform(self, cell, other, count):
187 if other.get('figures', None) is None :
187 if other.get('figures', None) is None :
188 other['figures'] = {}
188 other['figures'] = {}
189 for out in cell.get('outputs', []):
189 for out in cell.get('outputs', []):
190 for out_type in self.display_data_priority:
190 for out_type in self.display_data_priority:
191 if out.hasattr(out_type):
191 if out.hasattr(out_type):
192 figname, key, data = self._new_figure(out[out_type], out_type, count)
192 figname, key, data = self._new_figure(out[out_type], out_type, count)
193 out['key_'+out_type] = figname
193 out['key_'+out_type] = figname
194 other['figures'][key] = data
194 other['figures'][key] = data
195 count = count+1
195 count = count+1
196 return cell, other
196 return cell, other
197
197
198
198
199 class RevealHelpTransformer(ConfigurableTransformers):
199 class RevealHelpTransformer(ConfigurableTransformers):
200
200
201 def __call__(self, nb, other):
201 def __call__(self, nb, other):
202 for worksheet in nb.worksheets :
202 for worksheet in nb.worksheets :
203 for i, cell in enumerate(worksheet.cells):
203 for i, cell in enumerate(worksheet.cells):
204 cell.metadata.slide_type = cell.metadata.get('slideshow', {}).get('slide_type', None)
204 cell.metadata.slide_type = cell.metadata.get('slideshow', {}).get('slide_type', None)
205 if cell.metadata.slide_type is None:
205 if cell.metadata.slide_type is None:
206 cell.metadata.slide_type = '-'
206 cell.metadata.slide_type = '-'
207 if cell.metadata.slide_type in ['slide']:
207 if cell.metadata.slide_type in ['slide']:
208 worksheet.cells[i - 1].metadata.slide_helper = 'slide_end'
208 worksheet.cells[i - 1].metadata.slide_helper = 'slide_end'
209 if cell.metadata.slide_type in ['subslide']:
209 if cell.metadata.slide_type in ['subslide']:
210 worksheet.cells[i - 1].metadata.slide_helper = 'subslide_end'
210 worksheet.cells[i - 1].metadata.slide_helper = 'subslide_end'
211 return nb, other
211 return nb, other
212
212
213
213
214 class CSSHtmlHeaderTransformer(ActivatableTransformer):
214 class CSSHtmlHeaderTransformer(ActivatableTransformer):
215
215
216 def __call__(self, nb, resources):
216 def __call__(self, nb, resources):
217 """Fetch and add css to the resource dict
217 """Fetch and add css to the resource dict
218
218
219 Fetch css from IPython adn Pygment to add at the beginning
219 Fetch css from IPython adn Pygment to add at the beginning
220 of the html files.
220 of the html files.
221
221
222 Add this css in resources in the "inlining.css" key
222 Add this css in resources in the "inlining.css" key
223 """
223 """
224 resources['inlining'] = {}
224 resources['inlining'] = {}
225 resources['inlining']['css'] = self.header
225 resources['inlining']['css'] = self.header
226 return nb, resources
226 return nb, resources
227
227
228 header = []
228 header = []
229
229
230 def __init__(self, config=None, **kw):
230 def __init__(self, config=None, **kw):
231 super(CSSHtmlHeaderTransformer, self).__init__(config=config, **kw)
231 super(CSSHtmlHeaderTransformer, self).__init__(config=config, **kw)
232 if self.enabled :
232 if self.enabled :
233 self.regen_header()
233 self.regen_header()
234
234
235 def regen_header(self):
235 def regen_header(self):
236 ## lazy load asa this might not be use in many transformers
236 ## lazy load asa this might not be use in many transformers
237 import os
237 import os
238 from IPython.utils import path
238 from IPython.utils import path
239 import io
239 import io
240 from pygments.formatters import HtmlFormatter
240 from pygments.formatters import HtmlFormatter
241 header = []
241 header = []
242 static = os.path.join(path.get_ipython_package_dir(),
242 static = os.path.join(path.get_ipython_package_dir(),
243 'frontend', 'html', 'notebook', 'static',
243 'frontend', 'html', 'notebook', 'static',
244 )
244 )
245 here = os.path.split(os.path.realpath(__file__))[0]
245 here = os.path.split(os.path.realpath(__file__))[0]
246 css = os.path.join(static, 'css')
246 css = os.path.join(static, 'css')
247 for sheet in [
247 for sheet in [
248 # do we need jquery and prettify?
248 # do we need jquery and prettify?
249 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
249 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
250 # 'jquery-ui.min.css'),
250 # 'jquery-ui.min.css'),
251 # os.path.join(static, 'prettify', 'prettify.css'),
251 # os.path.join(static, 'prettify', 'prettify.css'),
252 os.path.join(css, 'boilerplate.css'),
252 os.path.join(css, 'boilerplate.css'),
253 os.path.join(css, 'fbm.css'),
253 os.path.join(css, 'fbm.css'),
254 os.path.join(css, 'notebook.css'),
254 os.path.join(css, 'notebook.css'),
255 os.path.join(css, 'renderedhtml.css'),
255 os.path.join(css, 'renderedhtml.css'),
256 os.path.join(css, 'style.min.css'),
256 os.path.join(css, 'style.min.css'),
257 # our overrides:
257 # our overrides:
258 os.path.join(here, '..', 'css', 'static_html.css'),
258 os.path.join(here, '..', 'css', 'static_html.css'),
259 ]:
259 ]:
260 try:
260 try:
261 with io.open(sheet, encoding='utf-8') as f:
261 with io.open(sheet, encoding='utf-8') as f:
262 s = f.read()
262 s = f.read()
263 header.append(s)
263 header.append(s)
264 except IOError:
264 except IOError:
265 # new version of ipython with style.min.css, pass
265 # new version of ipython with style.min.css, pass
266 pass
266 pass
267
267
268 pygments_css = HtmlFormatter().get_style_defs('.highlight')
268 pygments_css = HtmlFormatter().get_style_defs('.highlight')
269 header.append(pygments_css)
269 header.append(pygments_css)
270 self.header = header
270 self.header = header
271
271
General Comments 0
You need to be logged in to leave comments. Login now