##// END OF EJS Templates
put figures in subkey
Matthias BUSSONNIER -
Show More
@@ -1,133 +1,135 b''
1 """
1 """
2
2
3 """
3 """
4
4
5 from __future__ import print_function
5 from __future__ import print_function
6
6
7 from IPython.config.configurable import Configurable
7 from IPython.config.configurable import Configurable
8 from IPython.utils.traitlets import Unicode, Bool, Dict, List
8 from IPython.utils.traitlets import Unicode, Bool, Dict, List
9
9
10 class ConfigurableTransformers(Configurable):
10 class ConfigurableTransformers(Configurable):
11 """ A configurable transformer """
11 """ A configurable transformer """
12
12
13 def __init__(self, config=None, **kw):
13 def __init__(self, config=None, **kw):
14 super(ConfigurableTransformers, self).__init__(config=config, **kw)
14 super(ConfigurableTransformers, self).__init__(config=config, **kw)
15
15
16 def __call__(self, nb, other):
16 def __call__(self, nb, other):
17 try :
17 try :
18 for worksheet in nb.worksheets :
18 for worksheet in nb.worksheets :
19 for index, cell in enumerate(worksheet.cells):
19 for index, cell in enumerate(worksheet.cells):
20 worksheet.cells[index], other = self.cell_transform(cell, other, index)
20 worksheet.cells[index], other = self.cell_transform(cell, other, index)
21 return nb, other
21 return nb, other
22 except NotImplementedError as error :
22 except NotImplementedError as error :
23 raise NotImplementedError('should be implemented by subclass')
23 raise NotImplementedError('should be implemented by subclass')
24
24
25 def cell_transform(self, cell, other, index):
25 def cell_transform(self, cell, other, index):
26 """
26 """
27 Overwrite if you want to apply a transformation on each cell
27 Overwrite if you want to apply a transformation on each cell
28 """
28 """
29 raise NotImplementedError('should be implemented by subclass')
29 raise NotImplementedError('should be implemented by subclass')
30
30
31
31
32 class Foobar(ConfigurableTransformers):
32 class Foobar(ConfigurableTransformers):
33 message = Unicode('-- nothing', config=True)
33 message = Unicode('-- nothing', config=True)
34
34
35
35
36 def cell_transform(self, cell, other, index):
36 def cell_transform(self, cell, other, index):
37 return cell, other
37 return cell, other
38
38
39
39
40 def cell_preprocessor(function):
40 def cell_preprocessor(function):
41 """ 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
42
42
43 wrapped function parameters :
43 wrapped function parameters :
44 cell : the cell
44 cell : the cell
45 other : external resources
45 other : external resources
46 index : index of the cell
46 index : index of the cell
47 """
47 """
48 def wrappedfunc(nb, other):
48 def wrappedfunc(nb, other):
49 for worksheet in nb.worksheets :
49 for worksheet in nb.worksheets :
50 for index, cell in enumerate(worksheet.cells):
50 for index, cell in enumerate(worksheet.cells):
51 worksheet.cells[index], other = function(cell, other, index)
51 worksheet.cells[index], other = function(cell, other, index)
52 return nb, other
52 return nb, other
53 return wrappedfunc
53 return wrappedfunc
54
54
55
55
56 @cell_preprocessor
56 @cell_preprocessor
57 def haspyout_transformer(cell, other, count):
57 def haspyout_transformer(cell, other, count):
58 """
58 """
59 Add a haspyout flag to cell that have it
59 Add a haspyout flag to cell that have it
60
60
61 Easier for templating, where you can't know in advance
61 Easier for templating, where you can't know in advance
62 wether to write the out prompt
62 wether to write the out prompt
63
63
64 """
64 """
65 cell.type = cell.cell_type
65 cell.type = cell.cell_type
66 cell.haspyout = False
66 cell.haspyout = False
67 for out in cell.get('outputs', []):
67 for out in cell.get('outputs', []):
68 if out.output_type == 'pyout':
68 if out.output_type == 'pyout':
69 cell.haspyout = True
69 cell.haspyout = True
70 break
70 break
71 return cell, other
71 return cell, other
72
72
73
73
74 # todo, make the key part configurable.
74 # todo, make the key part configurable.
75
75
76 class ExtractFigureTransformer(ConfigurableTransformers):
76 class ExtractFigureTransformer(ConfigurableTransformers):
77 enabled = Bool(False,
77 enabled = Bool(False,
78 config=True,
78 config=True,
79 help=""" If set to false, this transformer will be no-op """
79 help=""" If set to false, this transformer will be no-op """
80 )
80 )
81
81
82 extra_ext_map = Dict({},
82 extra_ext_map = Dict({},
83 config=True,
83 config=True,
84 help="""extra map to override extension based on type.
84 help="""extra map to override extension based on type.
85 Usefull for latex where svg will be converted to pdf before inclusion
85 Usefull for latex where svg will be converted to pdf before inclusion
86 """
86 """
87 )
87 )
88 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
88 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
89 config=True,
89 config=True,
90 help= """
90 help= """
91 An ordered list of prefered output type, the first
91 An ordered list of prefered output type, the first
92 encounterd will usually be used when converting discarding
92 encounterd will usually be used when converting discarding
93 the others.
93 the others.
94 """
94 """
95 )
95 )
96
96
97
97
98 #to do change this to .format {} syntax
98 #to do change this to .format {} syntax
99 key_tpl = Unicode('_fig_%02i.%s', config=True)
99 key_tpl = Unicode('_fig_%02i.%s', config=True)
100
100
101 def _get_ext(self, ext):
101 def _get_ext(self, ext):
102 if ext in self.extra_ext_map :
102 if ext in self.extra_ext_map :
103 return self.extra_ext_map[ext]
103 return self.extra_ext_map[ext]
104 return ext
104 return ext
105
105
106 def _new_figure(self, data, fmt, count):
106 def _new_figure(self, data, fmt, count):
107 """Create a new figure file in the given format.
107 """Create a new figure file in the given format.
108
108
109 Returns a path relative to the input file.
109 Returns a path relative to the input file.
110 """
110 """
111 figname = self.key_tpl % (count, self._get_ext(fmt))
111 figname = self.key_tpl % (count, self._get_ext(fmt))
112 key = self.key_tpl % (count, fmt)
112 key = self.key_tpl % (count, fmt)
113
113
114 # Binary files are base64-encoded, SVG is already XML
114 # Binary files are base64-encoded, SVG is already XML
115 if fmt in ('png', 'jpg', 'pdf'):
115 if fmt in ('png', 'jpg', 'pdf'):
116 data = data.decode('base64')
116 data = data.decode('base64')
117
117
118 return figname, key, data
118 return figname, key, data
119
119
120
120
121 def cell_transform(self, cell, other, count):
121 def cell_transform(self, cell, other, count):
122 if not self.enabled:
122 if not self.enabled:
123 return cell, other
123 return cell, other
124 if other.get('figures',None) is None :
125 other['figures']={}
124 for i, out in enumerate(cell.get('outputs', [])):
126 for i, out in enumerate(cell.get('outputs', [])):
125 for type in self.display_data_priority:
127 for type in self.display_data_priority:
126 if out.hasattr(type):
128 if out.hasattr(type):
127 figname, key, data = self._new_figure(out[type], type, count)
129 figname, key, data = self._new_figure(out[type], type, count)
128 cell.outputs[i][type] = figname
130 cell.outputs[i][type] = figname
129 out['key_'+type] = figname
131 out['key_'+type] = figname
130 other[key] = data
132 other['figures'][key] = data
131 count = count+1
133 count = count+1
132 return cell, other
134 return cell, other
133
135
@@ -1,137 +1,137 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """
2 """
3 ================================================================================
3 ================================================================================
4
4
5 |,---. | | , .| |
5 |,---. | | , .| |
6 ||---', .|--- |---.,---.,---. |\ ||---.,---.,---.,---.. ,,---.,---.|---
6 ||---', .|--- |---.,---.,---. |\ ||---.,---.,---.,---.. ,,---.,---.|---
7 || | || | || || | | \ || || | || | \ / |---'| |
7 || | || | || || | | \ || || | || | \ / |---'| |
8 `` `---|`---'` '`---'` ' ` `'`---'`---'`---'` ' `' `---'` `---'
8 `` `---|`---'` '`---'` ' ` `'`---'`---'`---'` ' `' `---'` `---'
9 `---'
9 `---'
10 ================================================================================
10 ================================================================================
11
11
12 Highly experimental for now
12 Highly experimental for now
13
13
14 """
14 """
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 from __future__ import print_function
18 from __future__ import print_function
19 import sys
19 import sys
20 import io
20 import io
21 import os
21 import os
22
22
23 from converters.template import *
23 from converters.template import *
24 from converters.template import ConverterTemplate
24 from converters.template import ConverterTemplate
25 from converters.html import ConverterHTML
25 from converters.html import ConverterHTML
26 # From IPython
26 # From IPython
27
27
28 # All the stuff needed for the configurable things
28 # All the stuff needed for the configurable things
29 from IPython.config.application import Application
29 from IPython.config.application import Application
30 from IPython.config.loader import ConfigFileNotFound
30 from IPython.config.loader import ConfigFileNotFound
31 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, CaselessStrEnum
31 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, CaselessStrEnum
32
32
33 from converters.transformers import (ConfigurableTransformers,Foobar,ExtractFigureTransformer)
33 from converters.transformers import (ConfigurableTransformers,Foobar,ExtractFigureTransformer)
34
34
35
35
36 class NbconvertApp(Application):
36 class NbconvertApp(Application):
37
37
38 stdout = Bool(True, config=True)
38 stdout = Bool(True, config=True)
39 write = Bool(False, config=True)
39 write = Bool(False, config=True)
40
40
41 fileext = Unicode('txt', config=True)
41 fileext = Unicode('txt', config=True)
42
42
43 aliases = {
43 aliases = {
44 'stdout':'NbconvertApp.stdout',
44 'stdout':'NbconvertApp.stdout',
45 'write':'NbconvertApp.write',
45 'write':'NbconvertApp.write',
46 }
46 }
47
47
48 flags= {}
48 flags= {}
49 flags['no-stdout'] = (
49 flags['no-stdout'] = (
50 {'NbconvertApp' : {'stdout' : False}},
50 {'NbconvertApp' : {'stdout' : False}},
51 """the doc for this flag
51 """the doc for this flag
52
52
53 """
53 """
54 )
54 )
55
55
56 def __init__(self, **kwargs):
56 def __init__(self, **kwargs):
57 super(NbconvertApp, self).__init__(**kwargs)
57 super(NbconvertApp, self).__init__(**kwargs)
58 self.classes.insert(0,ConverterTemplate)
58 self.classes.insert(0,ConverterTemplate)
59 # register class here to have help with help all
59 # register class here to have help with help all
60 self.classes.insert(0,ExtractFigureTransformer)
60 self.classes.insert(0,ExtractFigureTransformer)
61 self.classes.insert(0,Foobar)
61 self.classes.insert(0,Foobar)
62 # ensure those are registerd
62 # ensure those are registerd
63
63
64 def load_config_file(self, profile_name):
64 def load_config_file(self, profile_name):
65 try:
65 try:
66 Application.load_config_file(
66 Application.load_config_file(
67 self,
67 self,
68 profile_name+'.nbcv',
68 profile_name+'.nbcv',
69 path=[os.path.join(os.getcwdu(),'profile')]
69 path=[os.path.join(os.getcwdu(),'profile')]
70 )
70 )
71 except ConfigFileNotFound:
71 except ConfigFileNotFound:
72 self.log.warn("Config file for profile '%s' not found, giving up ",profile_name)
72 self.log.warn("Config file for profile '%s' not found, giving up ",profile_name)
73 exit(1)
73 exit(1)
74
74
75
75
76 def initialize(self, argv=None):
76 def initialize(self, argv=None):
77 self.parse_command_line(argv)
77 self.parse_command_line(argv)
78 cl_config = self.config
78 cl_config = self.config
79 profile_file = sys.argv[1]
79 profile_file = sys.argv[1]
80 self.load_config_file(profile_file)
80 self.load_config_file(profile_file)
81 self.update_config(cl_config)
81 self.update_config(cl_config)
82
82
83
83
84
84
85 def run(self):
85 def run(self):
86 """Convert a notebook to html in one step"""
86 """Convert a notebook to html in one step"""
87 template_file = (self.extra_args or [None])[0]
87 template_file = (self.extra_args or [None])[0]
88 ipynb_file = (self.extra_args or [None])[1]
88 ipynb_file = (self.extra_args or [None])[1]
89
89
90 template_file = sys.argv[1]
90 template_file = sys.argv[1]
91
91
92 C = ConverterTemplate(config=self.config)
92 C = ConverterTemplate(config=self.config)
93 C.read(ipynb_file)
93 C.read(ipynb_file)
94
94
95 output,resources = C.convert()
95 output,resources = C.convert()
96 if self.stdout :
96 if self.stdout :
97 print(output.encode('utf-8'))
97 print(output.encode('utf-8'))
98
98
99 out_root = ipynb_file[:-6].replace('.','_').replace(' ','_')
99 out_root = ipynb_file[:-6].replace('.','_').replace(' ','_')
100
100
101 keys = resources.keys()
101 keys = resources.get('figures',{}).keys()
102 if self.write :
102 if self.write :
103 with io.open(os.path.join(out_root+'.'+self.fileext),'w') as f:
103 with io.open(os.path.join(out_root+'.'+self.fileext),'w') as f:
104 f.write(output)
104 f.write(output)
105 if keys :
105 if keys :
106 if self.write and not os.path.exists(out_root+'_files'):
106 if self.write and not os.path.exists(out_root+'_files'):
107 os.mkdir(out_root+'_files')
107 os.mkdir(out_root+'_files')
108 for key in keys:
108 for key in keys:
109 if self.write:
109 if self.write:
110 with io.open(os.path.join(out_root+'_files',key),'wb') as f:
110 with io.open(os.path.join(out_root+'_files',key),'wb') as f:
111 print(' writing to ',os.path.join(out_root,key))
111 print(' writing to ',os.path.join(out_root,key))
112 f.write(resources[key])
112 f.write(resources['figures'][key])
113 if self.stdout:
113 if self.stdout:
114 print('''
114 print('''
115 ====================== Keys in Resources ==================================
115 ====================== Keys in Resources ==================================
116 ''')
116 ''')
117 print(resources.keys())
117 print(resources['figures'].keys())
118 print("""
118 print("""
119 ===========================================================================
119 ===========================================================================
120 you are responsible from writing those data do a file in the right place if
120 you are responsible from writing those data do a file in the right place if
121 they need to be.
121 they need to be.
122 ===========================================================================
122 ===========================================================================
123 """)
123 """)
124
124
125 def main():
125 def main():
126 """Convert a notebook to html in one step"""
126 """Convert a notebook to html in one step"""
127 app = NbconvertApp.instance()
127 app = NbconvertApp.instance()
128 app.description = __doc__
128 app.description = __doc__
129 app.initialize()
129 app.initialize()
130 app.start()
130 app.start()
131 app.run()
131 app.run()
132 #-----------------------------------------------------------------------------
132 #-----------------------------------------------------------------------------
133 # Script main
133 # Script main
134 #-----------------------------------------------------------------------------
134 #-----------------------------------------------------------------------------
135
135
136 if __name__ == '__main__':
136 if __name__ == '__main__':
137 main()
137 main()
General Comments 0
You need to be logged in to leave comments. Login now