Show More
@@ -16,17 +16,18 b' a conversion of IPython notebooks to some other format should inherit.' | |||
|
16 | 16 | #----------------------------------------------------------------------------- |
|
17 | 17 | |
|
18 | 18 | from __future__ import print_function, absolute_import |
|
19 | from .transformers import extract_figure_transformer | |
|
20 | 19 | import converters.transformers as trans |
|
21 | 20 | from converters.jinja_filters import (python_comment, indent, |
|
22 | 21 | rm_fake, remove_ansi, markdown, highlight, |
|
23 | 22 | ansi2html, markdown2latex, escape_tex) |
|
24 | 23 | |
|
25 | 24 | |
|
25 | ||
|
26 | 26 | # Stdlib imports |
|
27 | 27 | import io |
|
28 | 28 | import os |
|
29 | 29 | from IPython.utils import path |
|
30 | from IPython.utils.traitlets import MetaHasTraits | |
|
30 | 31 | |
|
31 | 32 | from jinja2 import Environment, FileSystemLoader |
|
32 | 33 | env = Environment( |
@@ -118,8 +119,8 b' class ConverterTemplate(Configurable):' | |||
|
118 | 119 | the others. |
|
119 | 120 | """ |
|
120 | 121 | ) |
|
121 | ||
|
122 | pre_transformer_order = List(['haspyout_transformer'], | |
|
122 | ||
|
123 | pre_transformer_order = List(['haspyout_transformer', 'Foobar'], | |
|
123 | 124 | config=True, |
|
124 | 125 | help= """ |
|
125 | 126 | An ordered list of pre transformer to apply to the ipynb |
@@ -169,10 +170,14 b' class ConverterTemplate(Configurable):' | |||
|
169 | 170 | self.ext = '.tplx' if self.tex_environement else '.tpl' |
|
170 | 171 | self.nb = None |
|
171 | 172 | self.preprocessors = preprocessors |
|
173 | ||
|
172 | 174 | for name in self.pre_transformer_order: |
|
173 |
|
|
|
175 | tr = getattr(trans, name) | |
|
176 | if isinstance(tr, MetaHasTraits): | |
|
177 | tr = tr(config=config) | |
|
178 | self.preprocessors.append(tr) | |
|
174 | 179 | if self.extract_figures: |
|
175 |
self.preprocessors.append( |
|
|
180 | self.preprocessors.append(trans.ExtractFigureTransformer(config=config)) | |
|
176 | 181 | |
|
177 | 182 | self.env.filters['filter_data_type'] = self.filter_data_type |
|
178 | 183 | self.env.filters['pycomment'] = python_comment |
@@ -218,3 +223,5 b' class ConverterTemplate(Configurable):' | |||
|
218 | 223 | with io.open(filename) as f: |
|
219 | 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 | 40 | def cell_preprocessor(function): |
|
6 | 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 | 57 | def haspyout_transformer(cell, other, count): |
|
23 | 58 | """ |
|
24 | 59 | Add a haspyout flag to cell that have it |
|
25 | ||
|
60 | ||
|
26 | 61 | Easier for templating, where you can't know in advance |
|
27 | 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 | 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. | |
|
44 | """ | |
|
45 | figname = '_fig_%02i.%s' % (count, fmt) | |
|
76 | class ExtractFigureTransformer(ConfigurableTransformers): | |
|
77 | enabled = Bool(False, | |
|
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 | |
|
48 | if fmt in ('png', 'jpg', 'pdf'): | |
|
49 | data = data.decode('base64') | |
|
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 | ) | |
|
50 | 88 | |
|
51 | return figname, data | |
|
52 | 89 | |
|
53 | @cell_preprocessor | |
|
54 | def extract_figure_transformer(cell, other, count): | |
|
55 | for i, out in enumerate(cell.get('outputs', [])): | |
|
56 | for type in ['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg']: | |
|
57 | if out.hasattr(type): | |
|
58 | figname, data = _new_figure(out[type], type, count) | |
|
59 | cell.outputs[i][type] = figname | |
|
60 | out['key_'+type] = figname | |
|
61 | other[figname] = data | |
|
62 | count = count+1 | |
|
63 | return cell, other | |
|
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): | |
|
99 | """Create a new figure file in the given format. | |
|
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 | 1 | c = get_config() |
|
2 | 2 | |
|
3 | ||
|
3 | 4 | c.ConverterTemplate.extract_figures=False |
|
4 | 5 | c.ConverterTemplate.template_file='fullhtml' |
|
5 | 6 | c.ConverterTemplate.tex_environement=False |
|
7 | ||
|
8 | c.ExtractFigureTransformer.enabled = False |
@@ -1,5 +1,7 b'' | |||
|
1 | 1 | c = get_config() |
|
2 | 2 | |
|
3 |
c.ConverterTemplate.extract_figures= |
|
|
3 | c.ConverterTemplate.extract_figures=True | |
|
4 | 4 | c.ConverterTemplate.template_file='latex_base' |
|
5 | 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 | 17 | from IPython.config.loader import ConfigFileNotFound |
|
18 | 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 | 23 | class NbconvertApp(Application): |
|
22 | 24 | |
@@ -24,6 +26,9 b' class NbconvertApp(Application):' | |||
|
24 | 26 | def __init__(self, **kwargs): |
|
25 | 27 | super(NbconvertApp, self).__init__(**kwargs) |
|
26 | 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 | 32 | # ensure those are registerd |
|
28 | 33 | |
|
29 | 34 | def load_config_file(self, profile_name): |
@@ -54,11 +59,6 b' class NbconvertApp(Application):' | |||
|
54 | 59 | |
|
55 | 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 | 62 | C = ConverterTemplate(tplfile=sys.argv[1], |
|
63 | 63 | config=self.config) |
|
64 | 64 | C.read(ipynb_file) |
@@ -37,7 +37,14 b' it introduces a new line' | |||
|
37 | 37 | |
|
38 | 38 | ((*- block data_png -*)) |
|
39 | 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 | 48 | \par |
|
42 | 49 | \end{center} |
|
43 | 50 | ((*- endblock -*)) |
General Comments 0
You need to be logged in to leave comments.
Login now