|
@@
-1,281
+1,287
|
|
1
|
"""Base classes for the notebook conversion pipeline.
|
|
1
|
"""Base classes for the notebook conversion pipeline.
|
|
2
|
|
|
2
|
|
|
3
|
This module defines Converter, from which all objects designed to implement
|
|
3
|
This module defines Converter, from which all objects designed to implement
|
|
4
|
a conversion of IPython notebooks to some other format should inherit.
|
|
4
|
a conversion of IPython notebooks to some other format should inherit.
|
|
5
|
"""
|
|
5
|
"""
|
|
6
|
#-----------------------------------------------------------------------------
|
|
6
|
#-----------------------------------------------------------------------------
|
|
7
|
# Copyright (c) 2012, the IPython Development Team.
|
|
7
|
# Copyright (c) 2012, the IPython Development Team.
|
|
8
|
#
|
|
8
|
#
|
|
9
|
# Distributed under the terms of the Modified BSD License.
|
|
9
|
# Distributed under the terms of the Modified BSD License.
|
|
10
|
#
|
|
10
|
#
|
|
11
|
# The full license is in the file COPYING.txt, distributed with this software.
|
|
11
|
# The full license is in the file COPYING.txt, distributed with this software.
|
|
12
|
#-----------------------------------------------------------------------------
|
|
12
|
#-----------------------------------------------------------------------------
|
|
13
|
|
|
13
|
|
|
14
|
#-----------------------------------------------------------------------------
|
|
14
|
#-----------------------------------------------------------------------------
|
|
15
|
# Imports
|
|
15
|
# Imports
|
|
16
|
#-----------------------------------------------------------------------------
|
|
16
|
#-----------------------------------------------------------------------------
|
|
17
|
|
|
17
|
|
|
18
|
from __future__ import print_function, absolute_import
|
|
18
|
from __future__ import print_function, absolute_import
|
|
19
|
|
|
19
|
|
|
20
|
# Stdlib imports
|
|
20
|
# Stdlib imports
|
|
21
|
import io
|
|
21
|
import io
|
|
22
|
import os
|
|
22
|
import os
|
|
23
|
import re
|
|
23
|
import re
|
|
24
|
from IPython.utils import path
|
|
24
|
from IPython.utils import path
|
|
25
|
|
|
25
|
|
|
26
|
from jinja2 import Environment, FileSystemLoader
|
|
26
|
from jinja2 import Environment, FileSystemLoader
|
|
27
|
env = Environment(
|
|
27
|
env = Environment(
|
|
28
|
loader=FileSystemLoader('./templates/'),
|
|
28
|
loader=FileSystemLoader([
|
|
|
|
|
29
|
'./templates/',
|
|
|
|
|
30
|
'./templates/skeleton/',
|
|
|
|
|
31
|
]),
|
|
29
|
extensions=['jinja2.ext.loopcontrols']
|
|
32
|
extensions=['jinja2.ext.loopcontrols']
|
|
30
|
)
|
|
33
|
)
|
|
31
|
|
|
34
|
|
|
32
|
texenv = Environment(
|
|
35
|
texenv = Environment(
|
|
33
|
loader=FileSystemLoader('./templates/tex/'),
|
|
36
|
loader=FileSystemLoader([
|
|
|
|
|
37
|
'./templates/tex/',
|
|
|
|
|
38
|
'./templates/skeleton/tex/',
|
|
|
|
|
39
|
]),
|
|
34
|
extensions=['jinja2.ext.loopcontrols']
|
|
40
|
extensions=['jinja2.ext.loopcontrols']
|
|
35
|
)
|
|
41
|
)
|
|
36
|
|
|
42
|
|
|
37
|
# IPython imports
|
|
43
|
# IPython imports
|
|
38
|
from IPython.nbformat import current as nbformat
|
|
44
|
from IPython.nbformat import current as nbformat
|
|
39
|
from IPython.config.configurable import Configurable
|
|
45
|
from IPython.config.configurable import Configurable
|
|
40
|
from IPython.utils.traitlets import ( Unicode, Any, List, Bool)
|
|
46
|
from IPython.utils.traitlets import ( Unicode, Any, List, Bool)
|
|
41
|
|
|
47
|
|
|
42
|
# Our own imports
|
|
48
|
# Our own imports
|
|
43
|
from IPython.utils.text import indent
|
|
49
|
from IPython.utils.text import indent
|
|
44
|
from .utils import remove_ansi
|
|
50
|
from .utils import remove_ansi
|
|
45
|
from markdown import markdown
|
|
51
|
from markdown import markdown
|
|
46
|
from .utils import highlight, ansi2html
|
|
52
|
from .utils import highlight, ansi2html
|
|
47
|
from .utils import markdown2latex
|
|
53
|
from .utils import markdown2latex
|
|
48
|
#-----------------------------------------------------------------------------
|
|
54
|
#-----------------------------------------------------------------------------
|
|
49
|
# Class declarations
|
|
55
|
# Class declarations
|
|
50
|
#-----------------------------------------------------------------------------
|
|
56
|
#-----------------------------------------------------------------------------
|
|
51
|
def rm_fake(strng):
|
|
57
|
def rm_fake(strng):
|
|
52
|
return strng.replace('/files/', '')
|
|
58
|
return strng.replace('/files/', '')
|
|
53
|
|
|
59
|
|
|
54
|
class ConversionException(Exception):
|
|
60
|
class ConversionException(Exception):
|
|
55
|
pass
|
|
61
|
pass
|
|
56
|
|
|
62
|
|
|
57
|
|
|
63
|
|
|
58
|
def python_comment(string):
|
|
64
|
def python_comment(string):
|
|
59
|
return '# '+'\n# '.join(string.split('\n'))
|
|
65
|
return '# '+'\n# '.join(string.split('\n'))
|
|
60
|
|
|
66
|
|
|
61
|
|
|
67
|
|
|
62
|
|
|
68
|
|
|
63
|
def header_body():
|
|
69
|
def header_body():
|
|
64
|
"""Return the body of the header as a list of strings."""
|
|
70
|
"""Return the body of the header as a list of strings."""
|
|
65
|
|
|
71
|
|
|
66
|
from pygments.formatters import HtmlFormatter
|
|
72
|
from pygments.formatters import HtmlFormatter
|
|
67
|
|
|
73
|
|
|
68
|
header = []
|
|
74
|
header = []
|
|
69
|
static = os.path.join(path.get_ipython_package_dir(),
|
|
75
|
static = os.path.join(path.get_ipython_package_dir(),
|
|
70
|
'frontend', 'html', 'notebook', 'static',
|
|
76
|
'frontend', 'html', 'notebook', 'static',
|
|
71
|
)
|
|
77
|
)
|
|
72
|
here = os.path.split(os.path.realpath(__file__))[0]
|
|
78
|
here = os.path.split(os.path.realpath(__file__))[0]
|
|
73
|
css = os.path.join(static, 'css')
|
|
79
|
css = os.path.join(static, 'css')
|
|
74
|
for sheet in [
|
|
80
|
for sheet in [
|
|
75
|
# do we need jquery and prettify?
|
|
81
|
# do we need jquery and prettify?
|
|
76
|
# os.path.join(static, 'jquery', 'css', 'themes', 'base',
|
|
82
|
# os.path.join(static, 'jquery', 'css', 'themes', 'base',
|
|
77
|
# 'jquery-ui.min.css'),
|
|
83
|
# 'jquery-ui.min.css'),
|
|
78
|
# os.path.join(static, 'prettify', 'prettify.css'),
|
|
84
|
# os.path.join(static, 'prettify', 'prettify.css'),
|
|
79
|
os.path.join(css, 'boilerplate.css'),
|
|
85
|
os.path.join(css, 'boilerplate.css'),
|
|
80
|
os.path.join(css, 'fbm.css'),
|
|
86
|
os.path.join(css, 'fbm.css'),
|
|
81
|
os.path.join(css, 'notebook.css'),
|
|
87
|
os.path.join(css, 'notebook.css'),
|
|
82
|
os.path.join(css, 'renderedhtml.css'),
|
|
88
|
os.path.join(css, 'renderedhtml.css'),
|
|
83
|
# our overrides:
|
|
89
|
# our overrides:
|
|
84
|
os.path.join(here, '..', 'css', 'static_html.css'),
|
|
90
|
os.path.join(here, '..', 'css', 'static_html.css'),
|
|
85
|
]:
|
|
91
|
]:
|
|
86
|
|
|
92
|
|
|
87
|
with io.open(sheet, encoding='utf-8') as f:
|
|
93
|
with io.open(sheet, encoding='utf-8') as f:
|
|
88
|
s = f.read()
|
|
94
|
s = f.read()
|
|
89
|
header.append(s)
|
|
95
|
header.append(s)
|
|
90
|
|
|
96
|
|
|
91
|
pygments_css = HtmlFormatter().get_style_defs('.highlight')
|
|
97
|
pygments_css = HtmlFormatter().get_style_defs('.highlight')
|
|
92
|
header.append(pygments_css)
|
|
98
|
header.append(pygments_css)
|
|
93
|
return header
|
|
99
|
return header
|
|
94
|
|
|
100
|
|
|
95
|
# todo, make the key part configurable.
|
|
101
|
# todo, make the key part configurable.
|
|
96
|
def _new_figure(data, fmt, count):
|
|
102
|
def _new_figure(data, fmt, count):
|
|
97
|
"""Create a new figure file in the given format.
|
|
103
|
"""Create a new figure file in the given format.
|
|
98
|
|
|
104
|
|
|
99
|
Returns a path relative to the input file.
|
|
105
|
Returns a path relative to the input file.
|
|
100
|
"""
|
|
106
|
"""
|
|
101
|
figname = '_fig_%02i.%s' % (count, fmt)
|
|
107
|
figname = '_fig_%02i.%s' % (count, fmt)
|
|
102
|
|
|
108
|
|
|
103
|
# Binary files are base64-encoded, SVG is already XML
|
|
109
|
# Binary files are base64-encoded, SVG is already XML
|
|
104
|
if fmt in ('png', 'jpg', 'pdf'):
|
|
110
|
if fmt in ('png', 'jpg', 'pdf'):
|
|
105
|
data = data.decode('base64')
|
|
111
|
data = data.decode('base64')
|
|
106
|
|
|
112
|
|
|
107
|
return figname,data
|
|
113
|
return figname,data
|
|
108
|
|
|
114
|
|
|
109
|
|
|
115
|
|
|
110
|
|
|
116
|
|
|
111
|
|
|
117
|
|
|
112
|
inlining = {}
|
|
118
|
inlining = {}
|
|
113
|
inlining['css'] = header_body()
|
|
119
|
inlining['css'] = header_body()
|
|
114
|
|
|
120
|
|
|
115
|
LATEX_SUBS = (
|
|
121
|
LATEX_SUBS = (
|
|
116
|
(re.compile(r'\\'), r'\\textbackslash'),
|
|
122
|
(re.compile(r'\\'), r'\\textbackslash'),
|
|
117
|
(re.compile(r'([{}_#%&$])'), r'\\\1'),
|
|
123
|
(re.compile(r'([{}_#%&$])'), r'\\\1'),
|
|
118
|
(re.compile(r'~'), r'\~{}'),
|
|
124
|
(re.compile(r'~'), r'\~{}'),
|
|
119
|
(re.compile(r'\^'), r'\^{}'),
|
|
125
|
(re.compile(r'\^'), r'\^{}'),
|
|
120
|
(re.compile(r'"'), r"''"),
|
|
126
|
(re.compile(r'"'), r"''"),
|
|
121
|
(re.compile(r'\.\.\.+'), r'\\ldots'),
|
|
127
|
(re.compile(r'\.\.\.+'), r'\\ldots'),
|
|
122
|
)
|
|
128
|
)
|
|
123
|
|
|
129
|
|
|
124
|
def escape_tex(value):
|
|
130
|
def escape_tex(value):
|
|
125
|
newval = value
|
|
131
|
newval = value
|
|
126
|
for pattern, replacement in LATEX_SUBS:
|
|
132
|
for pattern, replacement in LATEX_SUBS:
|
|
127
|
newval = pattern.sub(replacement, newval)
|
|
133
|
newval = pattern.sub(replacement, newval)
|
|
128
|
return newval
|
|
134
|
return newval
|
|
129
|
|
|
135
|
|
|
130
|
texenv.block_start_string = '((*'
|
|
136
|
texenv.block_start_string = '((*'
|
|
131
|
texenv.block_end_string = '*))'
|
|
137
|
texenv.block_end_string = '*))'
|
|
132
|
texenv.variable_start_string = '((('
|
|
138
|
texenv.variable_start_string = '((('
|
|
133
|
texenv.variable_end_string = ')))'
|
|
139
|
texenv.variable_end_string = ')))'
|
|
134
|
texenv.comment_start_string = '((='
|
|
140
|
texenv.comment_start_string = '((='
|
|
135
|
texenv.comment_end_string = '=))'
|
|
141
|
texenv.comment_end_string = '=))'
|
|
136
|
texenv.filters['escape_tex'] = escape_tex
|
|
142
|
texenv.filters['escape_tex'] = escape_tex
|
|
137
|
|
|
143
|
|
|
138
|
def cell_preprocessor(function):
|
|
144
|
def cell_preprocessor(function):
|
|
139
|
""" wrap a function to be executed on all cells of a notebook
|
|
145
|
""" wrap a function to be executed on all cells of a notebook
|
|
140
|
|
|
146
|
|
|
141
|
wrapped function parameters :
|
|
147
|
wrapped function parameters :
|
|
142
|
cell : the cell
|
|
148
|
cell : the cell
|
|
143
|
other : external resources
|
|
149
|
other : external resources
|
|
144
|
index : index of the cell
|
|
150
|
index : index of the cell
|
|
145
|
"""
|
|
151
|
"""
|
|
146
|
def wrappedfunc(nb,other):
|
|
152
|
def wrappedfunc(nb,other):
|
|
147
|
for worksheet in nb.worksheets :
|
|
153
|
for worksheet in nb.worksheets :
|
|
148
|
for index, cell in enumerate(worksheet.cells):
|
|
154
|
for index, cell in enumerate(worksheet.cells):
|
|
149
|
worksheet.cells[index],other= function(cell,other,index)
|
|
155
|
worksheet.cells[index],other= function(cell,other,index)
|
|
150
|
return nb,other
|
|
156
|
return nb,other
|
|
151
|
return wrappedfunc
|
|
157
|
return wrappedfunc
|
|
152
|
|
|
158
|
|
|
153
|
|
|
159
|
|
|
154
|
|
|
160
|
|
|
155
|
@cell_preprocessor
|
|
161
|
@cell_preprocessor
|
|
156
|
def haspyout_transformer(cell, other, count):
|
|
162
|
def haspyout_transformer(cell, other, count):
|
|
157
|
"""
|
|
163
|
"""
|
|
158
|
Add a haspyout flag to cell that have it
|
|
164
|
Add a haspyout flag to cell that have it
|
|
159
|
|
|
165
|
|
|
160
|
Easier for templating, where you can't know in advance
|
|
166
|
Easier for templating, where you can't know in advance
|
|
161
|
wether to write the out prompt
|
|
167
|
wether to write the out prompt
|
|
162
|
|
|
168
|
|
|
163
|
"""
|
|
169
|
"""
|
|
164
|
cell.type = cell.cell_type
|
|
170
|
cell.type = cell.cell_type
|
|
165
|
cell.haspyout = False
|
|
171
|
cell.haspyout = False
|
|
166
|
for out in cell.get('outputs', []):
|
|
172
|
for out in cell.get('outputs', []):
|
|
167
|
if out.output_type == 'pyout':
|
|
173
|
if out.output_type == 'pyout':
|
|
168
|
cell.haspyout = True
|
|
174
|
cell.haspyout = True
|
|
169
|
break
|
|
175
|
break
|
|
170
|
return cell,other
|
|
176
|
return cell,other
|
|
171
|
|
|
177
|
|
|
172
|
|
|
178
|
|
|
173
|
@cell_preprocessor
|
|
179
|
@cell_preprocessor
|
|
174
|
def extract_figure_transformer(cell,other,count):
|
|
180
|
def extract_figure_transformer(cell,other,count):
|
|
175
|
for i,out in enumerate(cell.get('outputs', [])):
|
|
181
|
for i,out in enumerate(cell.get('outputs', [])):
|
|
176
|
for type in ['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg']:
|
|
182
|
for type in ['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg']:
|
|
177
|
if out.hasattr(type):
|
|
183
|
if out.hasattr(type):
|
|
178
|
figname,data = _new_figure(out[type], type,count)
|
|
184
|
figname,data = _new_figure(out[type], type,count)
|
|
179
|
cell.outputs[i][type] = figname
|
|
185
|
cell.outputs[i][type] = figname
|
|
180
|
out['key_'+type] = figname
|
|
186
|
out['key_'+type] = figname
|
|
181
|
other[figname] = data
|
|
187
|
other[figname] = data
|
|
182
|
count = count+1
|
|
188
|
count = count+1
|
|
183
|
return cell,other
|
|
189
|
return cell,other
|
|
184
|
|
|
190
|
|
|
185
|
|
|
191
|
|
|
186
|
class ConverterTemplate(Configurable):
|
|
192
|
class ConverterTemplate(Configurable):
|
|
187
|
""" A Jinja2 base converter templates"""
|
|
193
|
""" A Jinja2 base converter templates"""
|
|
188
|
|
|
194
|
|
|
189
|
display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
|
|
195
|
display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
|
|
190
|
config=True,
|
|
196
|
config=True,
|
|
191
|
help= """
|
|
197
|
help= """
|
|
192
|
A list of ast.NodeTransformer subclass instances, which will be applied
|
|
198
|
A list of ast.NodeTransformer subclass instances, which will be applied
|
|
193
|
to user input before code is run.
|
|
199
|
to user input before code is run.
|
|
194
|
"""
|
|
200
|
"""
|
|
195
|
)
|
|
201
|
)
|
|
196
|
|
|
202
|
|
|
197
|
extract_figures = Bool(False,
|
|
203
|
extract_figures = Bool(False,
|
|
198
|
config=True,
|
|
204
|
config=True,
|
|
199
|
help= """
|
|
205
|
help= """
|
|
200
|
wether to remove figure data from ipynb and store them in auxiliary
|
|
206
|
wether to remove figure data from ipynb and store them in auxiliary
|
|
201
|
dictionnary
|
|
207
|
dictionnary
|
|
202
|
"""
|
|
208
|
"""
|
|
203
|
)
|
|
209
|
)
|
|
204
|
#-------------------------------------------------------------------------
|
|
210
|
#-------------------------------------------------------------------------
|
|
205
|
# Instance-level attributes that are set in the constructor for this
|
|
211
|
# Instance-level attributes that are set in the constructor for this
|
|
206
|
# class.
|
|
212
|
# class.
|
|
207
|
#-------------------------------------------------------------------------
|
|
213
|
#-------------------------------------------------------------------------
|
|
208
|
infile = Any()
|
|
214
|
infile = Any()
|
|
209
|
|
|
215
|
|
|
210
|
|
|
216
|
|
|
211
|
infile_dir = Unicode()
|
|
217
|
infile_dir = Unicode()
|
|
212
|
|
|
218
|
|
|
213
|
def filter_data_type(self,output):
|
|
219
|
def filter_data_type(self,output):
|
|
214
|
for fmt in self.display_data_priority:
|
|
220
|
for fmt in self.display_data_priority:
|
|
215
|
if fmt in output:
|
|
221
|
if fmt in output:
|
|
216
|
return [fmt]
|
|
222
|
return [fmt]
|
|
217
|
|
|
223
|
|
|
218
|
def __init__(self, tplfile='fullhtml', preprocessors=[], config=None,tex_environement=False, **kw):
|
|
224
|
def __init__(self, tplfile='fullhtml', preprocessors=[], config=None,tex_environement=False, **kw):
|
|
219
|
"""
|
|
225
|
"""
|
|
220
|
tplfile : jinja template file to process.
|
|
226
|
tplfile : jinja template file to process.
|
|
221
|
|
|
227
|
|
|
222
|
config: the Configurable confg object to pass around
|
|
228
|
config: the Configurable confg object to pass around
|
|
223
|
|
|
229
|
|
|
224
|
preprocessors: list of function to run on ipynb json data before conversion
|
|
230
|
preprocessors: list of function to run on ipynb json data before conversion
|
|
225
|
to extract/inline file,
|
|
231
|
to extract/inline file,
|
|
226
|
|
|
232
|
|
|
227
|
"""
|
|
233
|
"""
|
|
228
|
super(ConverterTemplate, self).__init__(config=config, **kw)
|
|
234
|
super(ConverterTemplate, self).__init__(config=config, **kw)
|
|
229
|
self.env = texenv if tex_environement else env
|
|
235
|
self.env = texenv if tex_environement else env
|
|
230
|
self.ext = '.tplx' if tex_environement else '.tpl'
|
|
236
|
self.ext = '.tplx' if tex_environement else '.tpl'
|
|
231
|
self.nb = None
|
|
237
|
self.nb = None
|
|
232
|
self.preprocessors = preprocessors
|
|
238
|
self.preprocessors = preprocessors
|
|
233
|
self.preprocessors.append(haspyout_transformer)
|
|
239
|
self.preprocessors.append(haspyout_transformer)
|
|
234
|
if self.extract_figures:
|
|
240
|
if self.extract_figures:
|
|
235
|
self.preprocessors.append(extract_figure_transformer)
|
|
241
|
self.preprocessors.append(extract_figure_transformer)
|
|
236
|
|
|
242
|
|
|
237
|
self.env.filters['filter_data_type'] = self.filter_data_type
|
|
243
|
self.env.filters['filter_data_type'] = self.filter_data_type
|
|
238
|
self.env.filters['pycomment'] = python_comment
|
|
244
|
self.env.filters['pycomment'] = python_comment
|
|
239
|
self.env.filters['indent'] = indent
|
|
245
|
self.env.filters['indent'] = indent
|
|
240
|
self.env.filters['rm_fake'] = rm_fake
|
|
246
|
self.env.filters['rm_fake'] = rm_fake
|
|
241
|
self.env.filters['rm_ansi'] = remove_ansi
|
|
247
|
self.env.filters['rm_ansi'] = remove_ansi
|
|
242
|
self.env.filters['markdown'] = markdown
|
|
248
|
self.env.filters['markdown'] = markdown
|
|
243
|
self.env.filters['highlight'] = highlight
|
|
249
|
self.env.filters['highlight'] = highlight
|
|
244
|
self.env.filters['ansi2html'] = ansi2html
|
|
250
|
self.env.filters['ansi2html'] = ansi2html
|
|
245
|
self.env.filters['markdown2latex'] = markdown2latex
|
|
251
|
self.env.filters['markdown2latex'] = markdown2latex
|
|
246
|
|
|
252
|
|
|
247
|
self.template = self.env.get_template(tplfile+self.ext)
|
|
253
|
self.template = self.env.get_template(tplfile+self.ext)
|
|
248
|
|
|
254
|
|
|
249
|
|
|
255
|
|
|
250
|
|
|
256
|
|
|
251
|
def process(self):
|
|
257
|
def process(self):
|
|
252
|
"""
|
|
258
|
"""
|
|
253
|
preprocess the notebook json for easier use with the templates.
|
|
259
|
preprocess the notebook json for easier use with the templates.
|
|
254
|
will call all the `preprocessor`s in order before returning it.
|
|
260
|
will call all the `preprocessor`s in order before returning it.
|
|
255
|
"""
|
|
261
|
"""
|
|
256
|
nb = self.nb
|
|
262
|
nb = self.nb
|
|
257
|
|
|
263
|
|
|
258
|
# dict of 'resources' that could be made by the preprocessors
|
|
264
|
# dict of 'resources' that could be made by the preprocessors
|
|
259
|
# like key/value data to extract files from ipynb like in latex conversion
|
|
265
|
# like key/value data to extract files from ipynb like in latex conversion
|
|
260
|
resources = {}
|
|
266
|
resources = {}
|
|
261
|
|
|
267
|
|
|
262
|
for preprocessor in self.preprocessors:
|
|
268
|
for preprocessor in self.preprocessors:
|
|
263
|
nb,resources = preprocessor(nb,resources)
|
|
269
|
nb,resources = preprocessor(nb,resources)
|
|
264
|
|
|
270
|
|
|
265
|
return nb, resources
|
|
271
|
return nb, resources
|
|
266
|
|
|
272
|
|
|
267
|
def convert(self):
|
|
273
|
def convert(self):
|
|
268
|
""" convert the ipynb file
|
|
274
|
""" convert the ipynb file
|
|
269
|
|
|
275
|
|
|
270
|
return both the converted ipynb file and a dict containing potential
|
|
276
|
return both the converted ipynb file and a dict containing potential
|
|
271
|
other resources
|
|
277
|
other resources
|
|
272
|
"""
|
|
278
|
"""
|
|
273
|
nb,resources = self.process()
|
|
279
|
nb,resources = self.process()
|
|
274
|
return self.template.render(nb=nb, inlining=inlining), resources
|
|
280
|
return self.template.render(nb=nb, inlining=inlining), resources
|
|
275
|
|
|
281
|
|
|
276
|
|
|
282
|
|
|
277
|
def read(self, filename):
|
|
283
|
def read(self, filename):
|
|
278
|
"read and parse notebook into NotebookNode called self.nb"
|
|
284
|
"read and parse notebook into NotebookNode called self.nb"
|
|
279
|
with io.open(filename) as f:
|
|
285
|
with io.open(filename) as f:
|
|
280
|
self.nb = nbformat.read(f, 'json')
|
|
286
|
self.nb = nbformat.read(f, 'json')
|
|
281
|
|
|
287
|
|