##// END OF EJS Templates
Removed defaults set to config, from now on they will...
Jonathan Frederic -
Show More
@@ -1,274 +1,257 b''
1 1 """Exporter for the notebook conversion pipeline.
2 2
3 3 This module defines Exporter, a highly configurable converter
4 4 that uses Jinja2 to export notebook files into different format.
5 5
6 6 You can register both pre-transformers that will act on the notebook format
7 7 befor conversion and jinja filter that would then be availlable in the templates
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (c) 2013, the IPython Development Team.
12 12 #
13 13 # Distributed under the terms of the Modified BSD License.
14 14 #
15 15 # The full license is in the file COPYING.txt, distributed with this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21 from __future__ import print_function, absolute_import
22 22
23 23 # Stdlib imports
24 24 import io
25 25 import os
26 26
27 27 # IPython imports
28 28 from IPython.config.configurable import Configurable
29 29 from IPython.nbformat import current as nbformat
30 30 from IPython.utils.traitlets import MetaHasTraits, Unicode, List, Bool
31 31 from IPython.utils.text import indent
32 32
33 33 # other libs/dependencies
34 34 from jinja2 import Environment, FileSystemLoader
35 35 from markdown import markdown
36 36
37 37 # local import
38 38 import filters.strings
39 39 import filters.markdown
40 40 import filters.latex
41 41 import filters.datatypefilter
42 42 import filters.pygments
43 43 import filters.ansi
44 44
45 45 import transformers.extractfigure
46 46 import transformers.csshtmlheader
47 47 import transformers.revealhelp
48 48 import transformers.coalescestreams
49 49
50 50
51 51 #-----------------------------------------------------------------------------
52 52 # Globals and constants
53 53 #-----------------------------------------------------------------------------
54 54
55 55 #Standard Jinja2 environment constants
56 56 TEMPLATE_PATH = "/../templates/"
57 57 TEMPLATE_SKELETON_PATH = "/../templates/skeleton/"
58 58 TEMPLATE_EXTENSION = ".tpl"
59 59
60 60 #Jinja2 extensions to load.
61 61 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
62 62
63 63 #-----------------------------------------------------------------------------
64 64 # Classes and functions
65 65 #-----------------------------------------------------------------------------
66 66 class Exporter(Configurable):
67 67 """ A Jinja2 base converter templates
68 68
69 69 Pre-process the IPYNB files, feed it through Jinja2 templates,
70 70 and spit an converted files and a data object with other data
71 71 should be mostly configurable
72 72 """
73 73
74 74 pre_transformer_order = List(['haspyout_transformer'],
75 75 config=True,
76 76 help= """
77 77 An ordered list of pre-transformer to apply to the IPYNB
78 78 file before running through templates
79 79 """
80 80 )
81 81
82 82 template_file = Unicode(
83 83 '', config=True,
84 84 help="Name of the template file to use")
85 85
86 86 fileext = Unicode(
87 87 'txt', config=True,
88 88 help="Extension of the file that should be written to disk"
89 89 )
90 90
91 91 stdout = Bool(
92 92 True, config=True,
93 93 help="""Whether to print the converted IPYNB file to stdout
94 94 "use full do diff files without actually writing a new file"""
95 95 )
96 96
97 97 write = Bool(
98 98 False, config=True,
99 99 help="""Should the converted notebook file be written to disk
100 100 along with potential extracted resources."""
101 101 )
102 102
103 103 #Processors that process the input data prior to the export, set in the
104 104 #constructor for this class.
105 105 preprocessors = []
106 106
107 def __init__(self, preprocessors=None, jinja_filters=None, config=None, export_format, **kw):
107 def __init__(self, preprocessors=None, jinja_filters=None, config=None, **kw):
108 108 """ Init a new converter.
109 109
110 110 config: the Configurable config object to pass around.
111 111
112 preprocessors: dict of **availlable** key/value function to run on
113 ipynb json data before conversion to extract/inline file.
112 preprocessors: dict of **available** key/value function to run on
113 ipynb json data before conversion to extract/in-line file.
114 114 See `transformer.py` and `ConfigurableTransformers`
115 115
116 116 set the order in which the transformers should apply
117 117 with the `pre_transformer_order` trait of this class
118 118
119 transformers registerd by this key will take precedence on
119 transformers registered by this key will take precedence on
120 120 default one.
121 121
122 122 jinja_filters: dict of supplementary jinja filter that should be made
123 availlable in template. If those are of Configurable Class type,
123 available in template. If those are of Configurable Class type,
124 124 they will be instanciated with the config object as argument.
125 125
126 user defined filter will overwrite the one availlable by default.
127 """
128
129 #Set the default options for the exporter.
130 default_config = self.config
131
132 #Set properties that must be set in the config class in order to
133 #propagate to other classes.
134 default_config.GlobalConfigurable.display_data_priority =['svg', 'png', 'latex', 'jpg', 'jpeg','text']
135 default_config.ExtractFigureTransformer.display_data_priority=['svg', 'png', 'latex', 'jpg', 'jpeg','text']
136
137 #Set default properties of the exporter.
138 #For most (or all cases), the template file name matches the format name.
139 self.display_data_priority= ['svg', 'png', 'latex', 'jpg', 'jpeg','text']
140 self.template_file = export_format
141
142 if not config == None:
143 default_config._merge(config)
144 config = default_config
126 user defined filter will overwrite the one available by default.
127 """
145 128
146 129 #Call the base class constructor
147 130 super(Exporter, self).__init__(config=config, **kw)
148 131
149 132 #Standard environment
150 133 self.ext = TEMPLATE_EXTENSION
151 134 self._init_environment()
152 135
153 136 #TODO: Implement reflection style methods to get user transformers.
154 137 #if not preprocessors is None:
155 138 # for name in self.pre_transformer_order:
156 139 # # get the user-defined transformer first
157 140 # transformer = preprocessors.get(name, getattr(trans, name, None))
158 141 # if isinstance(transformer, MetaHasTraits):
159 142 # transformer = transformer(config=config)
160 143 # self.preprocessors.append(transformer)
161 144
162 145 #For compatibility, TODO: remove later.
163 146 self.preprocessors.append(transformers.coalescestreams.coalesce_streams)
164 147 self.preprocessors.append(transformers.extractfigure.ExtractFigureTransformer(config=config))
165 148 self.preprocessors.append(transformers.revealhelp.RevealHelpTransformer(config=config))
166 149 self.preprocessors.append(transformers.csshtmlheader.CSSHtmlHeaderTransformer(config=config))
167 150
168 151 #Add filters to the Jinja2 environment
169 152 self._register_filters()
170 153
171 154 #Load user filters. Overwrite existing filters if need be.
172 155 if not jinja_filters is None:
173 156 for key, user_filter in jinja_filters.iteritems():
174 157 if isinstance(user_filter, MetaHasTraits):
175 158 self.env.filters[key] = user_filter(config=config)
176 159 else:
177 160 self.env.filters[key] = user_filter
178 161
179 162 #Load the template file.
180 163 self.template = self.env.get_template(self.template_file+self.ext)
181 164
182 165
183 166 def from_notebook_node(self, nb):
184 167 """Export NotebookNode instance
185 168
186 169 nb: NotebookNode to export.
187 170
188 171 Returns both the converted ipynb file and a dict containing the
189 172 resources created along the way via the transformers and Jinja2
190 173 processing.
191 174 """
192 175
193 176 nb, resources = self._preprocess(nb)
194 177 return self.template.render(nb=nb, resources=resources), resources
195 178
196 179
197 180 def from_filename(self, filename):
198 181 """Read and export a notebook from a filename
199 182
200 183 filename: Filename of the notebook file to export.
201 184
202 185 Returns both the converted ipynb file and a dict containing the
203 186 resources created along the way via the transformers and Jinja2
204 187 processing.
205 188 """
206 189 with io.open(filename) as f:
207 190 return self.from_notebook_node(nbformat.read(f, 'json'))
208 191
209 192
210 193 def from_file(self, file_stream):
211 194 """Read and export a notebook from a file stream
212 195
213 196 file_stream: File handle of file that contains notebook data.
214 197
215 198 Returns both the converted ipynb file and a dict containing the
216 199 resources created along the way via the transformers and Jinja2
217 200 processing.
218 201 """
219 202
220 203 return self.from_notebook_node(nbformat.read(file_stream, 'json'))
221 204
222 205
223 206 def register_filter(self, name, filter):
224 207 if MetaHasTraits(filter):
225 208 self.env.filters[name] = filter(config=self.config)
226 209 else:
227 210 self.env.filters[name] = filter
228 211
229 212
230 213 def _register_filters(self):
231 214 self.register_filter('indent', indent)
232 215 self.register_filter('markdown', markdown)
233 216 self.register_filter('ansi2html', filters.ansi.ansi2html)
234 217 self.register_filter('filter_data_type', filters.datatypefilter.DataTypeFilter)
235 218 self.register_filter('get_lines', filters.strings.get_lines)
236 219 self.register_filter('highlight', filters.pygments.highlight)
237 220 self.register_filter('highlight2html', filters.pygments.highlight)
238 221 self.register_filter('highlight2latex', filters.pygments.highlight2latex)
239 222 self.register_filter('markdown2latex', filters.markdown.markdown2latex)
240 223 self.register_filter('markdown2rst', filters.markdown.markdown2rst)
241 224 self.register_filter('pycomment', filters.strings.python_comment)
242 225 self.register_filter('rm_ansi', filters.ansi.remove_ansi)
243 226 self.register_filter('rm_dollars', filters.strings.strip_dollars)
244 227 self.register_filter('rm_fake', filters.strings.rm_fake)
245 228 self.register_filter('rm_math_space', filters.latex.rm_math_space)
246 229 self.register_filter('wrap', filters.strings.wrap)
247 230
248 231
249 232 def _init_environment(self):
250 233 self.env = Environment(
251 234 loader=FileSystemLoader([
252 235 os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_PATH,
253 236 os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_SKELETON_PATH,
254 237 ]),
255 238 extensions=JINJA_EXTENSIONS
256 239 )
257 240
258 241
259 242 def _preprocess(self, nb):
260 243 """ Preprocess the notebook using the transformers specific
261 244 for the current export format.
262 245
263 246 nb: Notebook to preprocess
264 247 """
265 248
266 249 #Dict of 'resources' that can be filled by the preprocessors.
267 250 resources = {}
268 251
269 252 #Run each transformer on the notebook. Carry the output along
270 253 #to each transformer
271 254 for transformer in self.preprocessors:
272 255 nb, resources = transformer(nb, resources)
273 256 return nb, resources
274 257
General Comments 0
You need to be logged in to leave comments. Login now