##// END OF EJS Templates
create configurable preprocessors
Matthias BUSSONNIER -
Show More
@@ -16,17 +16,18 b' a conversion of IPython notebooks to some other format should inherit.'
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 from __future__ import print_function, absolute_import
18 from __future__ import print_function, absolute_import
19 from .transformers import extract_figure_transformer
20 import converters.transformers as trans
19 import converters.transformers as trans
21 from converters.jinja_filters import (python_comment, indent,
20 from converters.jinja_filters import (python_comment, indent,
22 rm_fake, remove_ansi, markdown, highlight,
21 rm_fake, remove_ansi, markdown, highlight,
23 ansi2html, markdown2latex, escape_tex)
22 ansi2html, markdown2latex, escape_tex)
24
23
25
24
25
26 # Stdlib imports
26 # Stdlib imports
27 import io
27 import io
28 import os
28 import os
29 from IPython.utils import path
29 from IPython.utils import path
30 from IPython.utils.traitlets import MetaHasTraits
30
31
31 from jinja2 import Environment, FileSystemLoader
32 from jinja2 import Environment, FileSystemLoader
32 env = Environment(
33 env = Environment(
@@ -119,7 +120,7 b' class ConverterTemplate(Configurable):'
119 """
120 """
120 )
121 )
121
122
122 pre_transformer_order = List(['haspyout_transformer'],
123 pre_transformer_order = List(['haspyout_transformer', 'Foobar'],
123 config=True,
124 config=True,
124 help= """
125 help= """
125 An ordered list of pre transformer to apply to the ipynb
126 An ordered list of pre transformer to apply to the ipynb
@@ -169,10 +170,14 b' class ConverterTemplate(Configurable):'
169 self.ext = '.tplx' if self.tex_environement else '.tpl'
170 self.ext = '.tplx' if self.tex_environement else '.tpl'
170 self.nb = None
171 self.nb = None
171 self.preprocessors = preprocessors
172 self.preprocessors = preprocessors
173
172 for name in self.pre_transformer_order:
174 for name in self.pre_transformer_order:
173 self.preprocessors.append(getattr(trans, name))
175 tr = getattr(trans, name)
176 if isinstance(tr, MetaHasTraits):
177 tr = tr(config=config)
178 self.preprocessors.append(tr)
174 if self.extract_figures:
179 if self.extract_figures:
175 self.preprocessors.append(extract_figure_transformer)
180 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
176
181
177 self.env.filters['filter_data_type'] = self.filter_data_type
182 self.env.filters['filter_data_type'] = self.filter_data_type
178 self.env.filters['pycomment'] = python_comment
183 self.env.filters['pycomment'] = python_comment
@@ -218,3 +223,5 b' class ConverterTemplate(Configurable):'
218 with io.open(filename) as f:
223 with io.open(filename) as f:
219 self.nb = nbformat.read(f, 'json')
224 self.nb = nbformat.read(f, 'json')
220
225
226
227
@@ -2,6 +2,41 b''
2
2
3 """
3 """
4
4
5 from __future__ import print_function
6
7 from IPython.config.configurable import Configurable
8 from IPython.utils.traitlets import Unicode, Bool, Dict
9
10 class ConfigurableTransformers(Configurable):
11 """ A configurable transformer """
12
13 def __init__(self, config=None, **kw):
14 super(ConfigurableTransformers, self).__init__(config=config, **kw)
15
16 def __call__(self, nb, other):
17 try :
18 for worksheet in nb.worksheets :
19 for index, cell in enumerate(worksheet.cells):
20 worksheet.cells[index], other = self.cell_transform(cell, other, index)
21 return nb, other
22 except NotImplementedError as error :
23 raise NotImplementedError('should be implemented by subclass')
24
25 def cell_transform(self, cell, other, index):
26 """
27 Overwrite if you want to apply a transformation on each cell
28 """
29 raise NotImplementedError('should be implemented by subclass')
30
31
32 class Foobar(ConfigurableTransformers):
33 message = Unicode('-- nothing', config=True)
34
35
36 def cell_transform(self, cell, other, index):
37 return cell, other
38
39
5 def cell_preprocessor(function):
40 def cell_preprocessor(function):
6 """ wrap a function to be executed on all cells of a notebook
41 """ wrap a function to be executed on all cells of a notebook
7
42
@@ -37,28 +72,54 b' def haspyout_transformer(cell, other, count):'
37
72
38
73
39 # todo, make the key part configurable.
74 # todo, make the key part configurable.
40 def _new_figure(data, fmt, count):
75
76 class ExtractFigureTransformer(ConfigurableTransformers):
77 enabled = Bool(False,
78 config=True,
79 help=""" If set to false, this transformer will be no-op """
80 )
81
82 extra_ext_map = Dict({},
83 config=True,
84 help="""extra map to override extension based on type.
85 Usefull for latex where svg will be converted to pdf before inclusion
86 """
87 )
88
89
90 #to do change this to .format {} syntax
91 key_tpl = Unicode('_fig_%02i.%s', config=True)
92
93 def _get_ext(self, ext):
94 if ext in self.extra_ext_map :
95 return self.extra_ext_map[ext]
96 return ext
97
98 def _new_figure(self, data, fmt, count):
41 """Create a new figure file in the given format.
99 """Create a new figure file in the given format.
42
100
43 Returns a path relative to the input file.
101 Returns a path relative to the input file.
44 """
102 """
45 figname = '_fig_%02i.%s' % (count, fmt)
103 figname = self.key_tpl % (count, self._get_ext(fmt))
104 key = self.key_tpl % (count, fmt)
46
105
47 # Binary files are base64-encoded, SVG is already XML
106 # Binary files are base64-encoded, SVG is already XML
48 if fmt in ('png', 'jpg', 'pdf'):
107 if fmt in ('png', 'jpg', 'pdf'):
49 data = data.decode('base64')
108 data = data.decode('base64')
50
109
51 return figname, data
110 return figname, key, data
52
111
53 @cell_preprocessor
112
54 def extract_figure_transformer(cell, other, count):
113 def cell_transform(self, cell, other, count):
114 if not self.enabled:
115 return cell, other
55 for i, out in enumerate(cell.get('outputs', [])):
116 for i, out in enumerate(cell.get('outputs', [])):
56 for type in ['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg']:
117 for type in ['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg']:
57 if out.hasattr(type):
118 if out.hasattr(type):
58 figname, data = _new_figure(out[type], type, count)
119 figname, key, data = self._new_figure(out[type], type, count)
59 cell.outputs[i][type] = figname
120 cell.outputs[i][type] = figname
60 out['key_'+type] = figname
121 out['key_'+type] = figname
61 other[figname] = data
122 other[key] = data
62 count = count+1
123 count = count+1
63 return cell, other
124 return cell, other
64
125
@@ -1,5 +1,8 b''
1 c = get_config()
1 c = get_config()
2
2
3
3 c.ConverterTemplate.extract_figures=False
4 c.ConverterTemplate.extract_figures=False
4 c.ConverterTemplate.template_file='fullhtml'
5 c.ConverterTemplate.template_file='fullhtml'
5 c.ConverterTemplate.tex_environement=False
6 c.ConverterTemplate.tex_environement=False
7
8 c.ExtractFigureTransformer.enabled = False
@@ -1,5 +1,7 b''
1 c = get_config()
1 c = get_config()
2
2
3 c.ConverterTemplate.extract_figures=False
3 c.ConverterTemplate.extract_figures=True
4 c.ConverterTemplate.template_file='latex_base'
4 c.ConverterTemplate.template_file='latex_base'
5 c.ConverterTemplate.tex_environement=True
5 c.ConverterTemplate.tex_environement=True
6
7 c.ExtractFigureTransformer.extra_ext_map={'svg':'pdf'}
@@ -17,6 +17,8 b' from IPython.config.application import Application'
17 from IPython.config.loader import ConfigFileNotFound
17 from IPython.config.loader import ConfigFileNotFound
18 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, CaselessStrEnum
18 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, CaselessStrEnum
19
19
20 from converters.transformers import (ConfigurableTransformers,Foobar,ExtractFigureTransformer)
21
20
22
21 class NbconvertApp(Application):
23 class NbconvertApp(Application):
22
24
@@ -24,6 +26,9 b' class NbconvertApp(Application):'
24 def __init__(self, **kwargs):
26 def __init__(self, **kwargs):
25 super(NbconvertApp, self).__init__(**kwargs)
27 super(NbconvertApp, self).__init__(**kwargs)
26 self.classes.insert(0,ConverterTemplate)
28 self.classes.insert(0,ConverterTemplate)
29 # register class here to have help with help all
30 self.classes.insert(0,ExtractFigureTransformer)
31 self.classes.insert(0,Foobar)
27 # ensure those are registerd
32 # ensure those are registerd
28
33
29 def load_config_file(self, profile_name):
34 def load_config_file(self, profile_name):
@@ -54,11 +59,6 b' class NbconvertApp(Application):'
54
59
55 template_file = sys.argv[1]
60 template_file = sys.argv[1]
56
61
57 if template_file.startswith('latex'):
58 tex_environement=True
59 else:
60 tex_environement=False
61
62 C = ConverterTemplate(tplfile=sys.argv[1],
62 C = ConverterTemplate(tplfile=sys.argv[1],
63 config=self.config)
63 config=self.config)
64 C.read(ipynb_file)
64 C.read(ipynb_file)
@@ -37,7 +37,14 b' it introduces a new line'
37
37
38 ((*- block data_png -*))
38 ((*- block data_png -*))
39 \begin{center}
39 \begin{center}
40 \includegraphics[width=0.7\textwidth]{(((output.png)))}
40 \includegraphics[width=0.7\textwidth]{(((output.key_png)))}
41 \par
42 \end{center}
43 ((*- endblock -*))
44
45 ((*- block data_svg -*))
46 \begin{center}
47 \includegraphics[width=0.7\textwidth]{(((output.key_svg)))}
41 \par
48 \par
42 \end{center}
49 \end{center}
43 ((*- endblock -*))
50 ((*- endblock -*))
General Comments 0
You need to be logged in to leave comments. Login now