##// 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(
@@ -118,8 +119,8 b' class ConverterTemplate(Configurable):'
118 the others.
119 the others.
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
@@ -22,7 +57,7 b' def cell_preprocessor(function):'
22 def haspyout_transformer(cell, other, count):
57 def haspyout_transformer(cell, other, count):
23 """
58 """
24 Add a haspyout flag to cell that have it
59 Add a haspyout flag to cell that have it
25
60
26 Easier for templating, where you can't know in advance
61 Easier for templating, where you can't know in advance
27 wether to write the out prompt
62 wether to write the out prompt
28
63
@@ -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):
41 """Create a new figure file in the given format.
42
75
43 Returns a path relative to the input file.
76 class ExtractFigureTransformer(ConfigurableTransformers):
44 """
77 enabled = Bool(False,
45 figname = '_fig_%02i.%s' % (count, fmt)
78 config=True,
79 help=""" If set to false, this transformer will be no-op """
80 )
46
81
47 # Binary files are base64-encoded, SVG is already XML
82 extra_ext_map = Dict({},
48 if fmt in ('png', 'jpg', 'pdf'):
83 config=True,
49 data = data.decode('base64')
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 )
50
88
51 return figname, data
52
89
53 @cell_preprocessor
90 #to do change this to .format {} syntax
54 def extract_figure_transformer(cell, other, count):
91 key_tpl = Unicode('_fig_%02i.%s', config=True)
55 for i, out in enumerate(cell.get('outputs', [])):
92
56 for type in ['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg']:
93 def _get_ext(self, ext):
57 if out.hasattr(type):
94 if ext in self.extra_ext_map :
58 figname, data = _new_figure(out[type], type, count)
95 return self.extra_ext_map[ext]
59 cell.outputs[i][type] = figname
96 return ext
60 out['key_'+type] = figname
97
61 other[figname] = data
98 def _new_figure(self, data, fmt, count):
62 count = count+1
99 """Create a new figure file in the given format.
63 return cell, other
100
101 Returns a path relative to the input file.
102 """
103 figname = self.key_tpl % (count, self._get_ext(fmt))
104 key = self.key_tpl % (count, fmt)
105
106 # Binary files are base64-encoded, SVG is already XML
107 if fmt in ('png', 'jpg', 'pdf'):
108 data = data.decode('base64')
109
110 return figname, key, data
111
112
113 def cell_transform(self, cell, other, count):
114 if not self.enabled:
115 return cell, other
116 for i, out in enumerate(cell.get('outputs', [])):
117 for type in ['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg']:
118 if out.hasattr(type):
119 figname, key, data = self._new_figure(out[type], type, count)
120 cell.outputs[i][type] = figname
121 out['key_'+type] = figname
122 other[key] = data
123 count = count+1
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