##// END OF EJS Templates
create rst converter and fix some bugs
Matthias BUSSONNIER -
Show More
@@ -1,240 +1,241 b''
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 import converters.transformers as trans
19 import converters.transformers as trans
20 from converters.jinja_filters import (python_comment, indent,
20 from converters.jinja_filters import (python_comment, indent,
21 rm_fake, remove_ansi, markdown, highlight,
21 rm_fake, remove_ansi, markdown, highlight,
22 ansi2html, markdown2latex, escape_tex)
22 ansi2html, markdown2latex, escape_tex)
23
23
24 from converters.utils import markdown2rst
24 from converters.utils import markdown2rst
25
25
26
26
27
27
28 # Stdlib imports
28 # Stdlib imports
29 import io
29 import io
30 import os
30 import os
31 from IPython.utils import path
31 from IPython.utils import path
32 from IPython.utils.traitlets import MetaHasTraits
32 from IPython.utils.traitlets import MetaHasTraits
33
33
34 from jinja2 import Environment, FileSystemLoader
34 from jinja2 import Environment, FileSystemLoader
35 env = Environment(
35 env = Environment(
36 loader=FileSystemLoader([
36 loader=FileSystemLoader([
37 './templates/',
37 './templates/',
38 './templates/skeleton/',
38 './templates/skeleton/',
39 ]),
39 ]),
40 extensions=['jinja2.ext.loopcontrols']
40 extensions=['jinja2.ext.loopcontrols']
41 )
41 )
42
42
43 texenv = Environment(
43 texenv = Environment(
44 loader=FileSystemLoader([
44 loader=FileSystemLoader([
45 './templates/tex/',
45 './templates/tex/',
46 './templates/skeleton/tex/',
46 './templates/skeleton/tex/',
47 ]),
47 ]),
48 extensions=['jinja2.ext.loopcontrols']
48 extensions=['jinja2.ext.loopcontrols']
49 )
49 )
50
50
51 # IPython imports
51 # IPython imports
52 from IPython.nbformat import current as nbformat
52 from IPython.nbformat import current as nbformat
53 from IPython.config.configurable import Configurable
53 from IPython.config.configurable import Configurable
54 from IPython.utils.traitlets import ( Unicode, Any, List, Bool)
54 from IPython.utils.traitlets import ( Unicode, Any, List, Bool)
55
55
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57 # Class declarations
57 # Class declarations
58 #-----------------------------------------------------------------------------
58 #-----------------------------------------------------------------------------
59 class ConversionException(Exception):
59 class ConversionException(Exception):
60 pass
60 pass
61
61
62 #todo move this out
62 #todo move this out
63 def header_body():
63 def header_body():
64 """Return the body of the header as a list of strings."""
64 """Return the body of the header as a list of strings."""
65
65
66 from pygments.formatters import HtmlFormatter
66 from pygments.formatters import HtmlFormatter
67
67
68 header = []
68 header = []
69 static = os.path.join(path.get_ipython_package_dir(),
69 static = os.path.join(path.get_ipython_package_dir(),
70 'frontend', 'html', 'notebook', 'static',
70 'frontend', 'html', 'notebook', 'static',
71 )
71 )
72 here = os.path.split(os.path.realpath(__file__))[0]
72 here = os.path.split(os.path.realpath(__file__))[0]
73 css = os.path.join(static, 'css')
73 css = os.path.join(static, 'css')
74 for sheet in [
74 for sheet in [
75 # do we need jquery and prettify?
75 # do we need jquery and prettify?
76 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
76 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
77 # 'jquery-ui.min.css'),
77 # 'jquery-ui.min.css'),
78 # os.path.join(static, 'prettify', 'prettify.css'),
78 # os.path.join(static, 'prettify', 'prettify.css'),
79 os.path.join(css, 'boilerplate.css'),
79 os.path.join(css, 'boilerplate.css'),
80 os.path.join(css, 'fbm.css'),
80 os.path.join(css, 'fbm.css'),
81 os.path.join(css, 'notebook.css'),
81 os.path.join(css, 'notebook.css'),
82 os.path.join(css, 'renderedhtml.css'),
82 os.path.join(css, 'renderedhtml.css'),
83 # our overrides:
83 # our overrides:
84 os.path.join(here, '..', 'css', 'static_html.css'),
84 os.path.join(here, '..', 'css', 'static_html.css'),
85 ]:
85 ]:
86
86
87 with io.open(sheet, encoding='utf-8') as f:
87 with io.open(sheet, encoding='utf-8') as f:
88 s = f.read()
88 s = f.read()
89 header.append(s)
89 header.append(s)
90
90
91 pygments_css = HtmlFormatter().get_style_defs('.highlight')
91 pygments_css = HtmlFormatter().get_style_defs('.highlight')
92 header.append(pygments_css)
92 header.append(pygments_css)
93 return header
93 return header
94
94
95
95
96
96
97
97
98
98
99 inlining = {}
99 inlining = {}
100 inlining['css'] = header_body()
100 inlining['css'] = header_body()
101
101
102
102
103
103
104 texenv.block_start_string = '((*'
104 texenv.block_start_string = '((*'
105 texenv.block_end_string = '*))'
105 texenv.block_end_string = '*))'
106 texenv.variable_start_string = '((('
106 texenv.variable_start_string = '((('
107 texenv.variable_end_string = ')))'
107 texenv.variable_end_string = ')))'
108 texenv.comment_start_string = '((='
108 texenv.comment_start_string = '((='
109 texenv.comment_end_string = '=))'
109 texenv.comment_end_string = '=))'
110 texenv.filters['escape_tex'] = escape_tex
110 texenv.filters['escape_tex'] = escape_tex
111
111
112
112
113 class ConverterTemplate(Configurable):
113 class ConverterTemplate(Configurable):
114 """ A Jinja2 base converter templates
114 """ A Jinja2 base converter templates
115
115
116 Preprocess the ipynb files, feed it throug jinja templates,
116 Preprocess the ipynb files, feed it throug jinja templates,
117 and spit an converted files and a data object with other data
117 and spit an converted files and a data object with other data
118
118
119 shoudl be mostly configurable
119 shoudl be mostly configurable
120 """
120 """
121
121
122 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
122 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
123 config=True,
123 config=True,
124 help= """
124 help= """
125 An ordered list of prefered output type, the first
125 An ordered list of prefered output type, the first
126 encounterd will usually be used when converting discarding
126 encounterd will usually be used when converting discarding
127 the others.
127 the others.
128 """
128 """
129 )
129 )
130
130
131 pre_transformer_order = List(['haspyout_transformer'],
131 pre_transformer_order = List(['haspyout_transformer'],
132 config=True,
132 config=True,
133 help= """
133 help= """
134 An ordered list of pre transformer to apply to the ipynb
134 An ordered list of pre transformer to apply to the ipynb
135 file befor running through templates
135 file befor running through templates
136 """
136 """
137 )
137 )
138
138
139 extract_figures = Bool(False,
139 extract_figures = Bool(False,
140 config=True,
140 config=True,
141 help= """
141 help= """
142 wether to remove figure data from ipynb and store them in auxiliary
142 wether to remove figure data from ipynb and store them in auxiliary
143 dictionnary
143 dictionnary
144 """
144 """
145 )
145 )
146
146
147 tex_environement = Bool(False,
147 tex_environement = Bool(False,
148 config=True,
148 config=True,
149 help=""" is this a tex environment or not """)
149 help=""" is this a tex environment or not """)
150
150
151 template_file = Unicode('',
151 template_file = Unicode('',
152 config=True,
152 config=True,
153 help=""" Name of the template file to use """ )
153 help=""" Name of the template file to use """ )
154 #-------------------------------------------------------------------------
154 #-------------------------------------------------------------------------
155 # Instance-level attributes that are set in the constructor for this
155 # Instance-level attributes that are set in the constructor for this
156 # class.
156 # class.
157 #-------------------------------------------------------------------------
157 #-------------------------------------------------------------------------
158 infile = Any()
158 infile = Any()
159
159
160
160
161 infile_dir = Unicode()
161 infile_dir = Unicode()
162
162
163 #todo: move to filter
163 #todo: move to filter
164 def filter_data_type(self, output):
164 def filter_data_type(self, output):
165 """ return the first availlable format in priority """
165 """ return the first availlable format in priority """
166 for fmt in self.display_data_priority:
166 for fmt in self.display_data_priority:
167 if fmt in output:
167 if fmt in output:
168 return [fmt]
168 return [fmt]
169 raise Exception("did not found any format I can extract in output, shoudl at lest have one")
169
170
170 preprocessors = []
171 preprocessors = []
171
172
172 def __init__(self, preprocessors={}, jinja_filters={}, config=None, **kw):
173 def __init__(self, preprocessors={}, jinja_filters={}, config=None, **kw):
173 """
174 """
174 config: the Configurable confg object to pass around
175 config: the Configurable confg object to pass around
175
176
176 preprocessors: dict of **availlable** key/value function to run on ipynb json data before conversion
177 preprocessors: dict of **availlable** key/value function to run on ipynb json data before conversion
177 to extract/inline file,
178 to extract/inline file,
178
179
179 """
180 """
180 super(ConverterTemplate, self).__init__(config=config, **kw)
181 super(ConverterTemplate, self).__init__(config=config, **kw)
181 self.env = texenv if self.tex_environement else env
182 self.env = texenv if self.tex_environement else env
182 self.ext = '.tplx' if self.tex_environement else '.tpl'
183 self.ext = '.tplx' if self.tex_environement else '.tpl'
183
184
184 for name in self.pre_transformer_order:
185 for name in self.pre_transformer_order:
185 transformer = getattr(preprocessors, name, getattr(trans, name, None))
186 transformer = getattr(preprocessors, name, getattr(trans, name, None))
186 if isinstance(transformer, MetaHasTraits):
187 if isinstance(transformer, MetaHasTraits):
187 transformer = transformer(config=config)
188 transformer = transformer(config=config)
188 self.preprocessors.append(transformer)
189 self.preprocessors.append(transformer)
189
190
190 ## for compat, remove later
191 ## for compat, remove later
191 if self.extract_figures:
192 if self.extract_figures:
192 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
193 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
193
194
194 ##
195 ##
195 self.env.filters['filter_data_type'] = self.filter_data_type
196 self.env.filters['filter_data_type'] = self.filter_data_type
196 self.env.filters['pycomment'] = python_comment
197 self.env.filters['pycomment'] = python_comment
197 self.env.filters['indent'] = indent
198 self.env.filters['indent'] = indent
198 self.env.filters['rm_fake'] = rm_fake
199 self.env.filters['rm_fake'] = rm_fake
199 self.env.filters['rm_ansi'] = remove_ansi
200 self.env.filters['rm_ansi'] = remove_ansi
200 self.env.filters['markdown'] = markdown
201 self.env.filters['markdown'] = markdown
201 self.env.filters['highlight'] = highlight
202 self.env.filters['highlight'] = highlight
202 self.env.filters['ansi2html'] = ansi2html
203 self.env.filters['ansi2html'] = ansi2html
203 self.env.filters['markdown2latex'] = markdown2latex
204 self.env.filters['markdown2latex'] = markdown2latex
204 self.env.filters['markdown2rst'] = markdown2rst
205 self.env.filters['markdown2rst'] = markdown2rst
205 for k, v in jinja_filters.iteritems():
206 for k, v in jinja_filters.iteritems():
206 self.env.filters[k] = v
207 self.env.filters[k] = v
207
208
208 self.template = self.env.get_template(self.template_file+self.ext)
209 self.template = self.env.get_template(self.template_file+self.ext)
209
210
210
211
211 def process(self, nb):
212 def process(self, nb):
212 """
213 """
213 preprocess the notebook json for easier use with the templates.
214 preprocess the notebook json for easier use with the templates.
214 will call all the `preprocessor`s in order before returning it.
215 will call all the `preprocessor`s in order before returning it.
215 """
216 """
216
217
217 # dict of 'resources' that could be made by the preprocessors
218 # dict of 'resources' that could be made by the preprocessors
218 # like key/value data to extract files from ipynb like in latex conversion
219 # like key/value data to extract files from ipynb like in latex conversion
219 resources = {}
220 resources = {}
220
221
221 for preprocessor in self.preprocessors:
222 for preprocessor in self.preprocessors:
222 nb, resources = preprocessor(nb, resources)
223 nb, resources = preprocessor(nb, resources)
223
224
224 return nb, resources
225 return nb, resources
225
226
226 def convert(self, nb):
227 def convert(self, nb):
227 """ convert the ipynb file
228 """ convert the ipynb file
228
229
229 return both the converted ipynb file and a dict containing potential
230 return both the converted ipynb file and a dict containing potential
230 other resources
231 other resources
231 """
232 """
232 nb, resources = self.process(nb)
233 nb, resources = self.process(nb)
233 return self.template.render(nb=nb, inlining=inlining), resources
234 return self.template.render(nb=nb, inlining=inlining), resources
234
235
235
236
236 def from_filename(self, filename):
237 def from_filename(self, filename):
237 "read and parse notebook into NotebookNode called self.nb"
238 "read and parse notebook into NotebookNode called self.nb"
238 with io.open(filename) as f:
239 with io.open(filename) as f:
239 return self.convert(nbformat.read(f, 'json'))
240 return self.convert(nbformat.read(f, 'json'))
240
241
@@ -1,135 +1,134 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 :
124 if other.get('figures',None) is None :
125 other['figures']={}
125 other['figures']={}
126 for i, out in enumerate(cell.get('outputs', [])):
126 for i, out in enumerate(cell.get('outputs', [])):
127 for type in self.display_data_priority:
127 for type in self.display_data_priority:
128 if out.hasattr(type):
128 if out.hasattr(type):
129 figname, key, data = self._new_figure(out[type], type, count)
129 figname, key, data = self._new_figure(out[type], type, count)
130 cell.outputs[i][type] = figname
131 out['key_'+type] = figname
130 out['key_'+type] = figname
132 other['figures'][key] = data
131 other['figures'][key] = data
133 count = count+1
132 count = count+1
134 return cell, other
133 return cell, other
135
134
@@ -1,7 +1,13 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='rst'
4 c.ConverterTemplate.template_file='rst'
5 c.ConverterTemplate.tex_environement=False
5 c.ConverterTemplate.tex_environement=False
6
6
7 c.NbconvertApp.fileext='rst'
7 c.NbconvertApp.fileext='rst'
8 c.ExtractFigureTransformer.enabled=True
9
10 c.ExtractFigureTransformer.display_data_priority=['svg', 'png', 'latex', 'jpg', 'jpeg','text']
11 c.ConverterTemplate.display_data_priority=['svg', 'png', 'latex', 'jpg', 'jpeg','text']
12
13
@@ -1,69 +1,70 b''
1 {%- extends 'null.tpl' -%}
1 {%- extends 'display_priority.tpl' -%}
2
3 {% block in_prompt -%}
2 {% block in_prompt -%}
4 In[{{cell.prompt_number if cell.prompt_number else ' '}}]:
3 In[{{cell.prompt_number if cell.prompt_number else ' '}}]:
5
4
6 .. code:: python
5 .. code:: python
7
6
8 {% endblock in_prompt %}
7 {% endblock in_prompt %}
9
8
10 {% block output_prompt %}
9 {% block output_prompt %}{% if cell.haspyout -%}
11 Out[{{cell.prompt_number}}]:{% endblock output_prompt %}
10 Out[{{cell.prompt_number}}]:{% endif %}{% endblock output_prompt %}
12
11
13 {% block input %}{{ cell.input | indent}}
12 {% block input %}{{ cell.input | indent}}
14 {% endblock input %}
15
16
13
17 {# Those Two are for error displaying
14 {% endblock input %}
18 even if the first one seem to do nothing,
19 it introduces a new line
20
15
21 #}
22 {% block pyerr %}{{ super() }}
16 {% block pyerr %}{{ super() }}
23 {% endblock pyerr %}
17 {% endblock pyerr %}
24
18
25 {% block traceback_line %}
19 {% block traceback_line %}
26 {{ line |indent| rm_ansi }}{% endblock traceback_line %}
20 {{ line |indent| rm_ansi }}{% endblock traceback_line %}
27 {# .... #}
28
29
21
30 {% block pyout %}
22 {% block pyout %}
31 .. parsed-literal::
23 .. parsed-literal::
32
24
33 {{ output.text| indent }}
25 {{ output.text| indent }}
34 {% endblock pyout %}
26 {% endblock pyout %}
35
27
36 {% block stream %}
28 {% block stream %}
37 .. parsed-literal::
29 .. parsed-literal::
38
30
39 {{ output.text| indent }}
31 {{ output.text| indent }}
40 {% endblock stream %}
32 {% endblock stream %}
41
33
42
34
43
35
44
36
45 {% block display_data scoped %}
37 {% block data_svg %}.. image:: {{output.key_svg}}
46 # image file:
38
47 {% endblock display_data %}
39 {% endblock data_svg %}
48
40
49 {% block markdowncell scoped %}
41 {% block data_png %}.. image:: {{output.key_png}}
50 {{ cell.source | markdown2rst }}
42
43 {% endblock data_png %}
44
45 {% block data_text scoped %}.. parsed-literal::
46
47 {{output.text | indent}}
48
49 {% endblock data_text %}
50
51 {% block markdowncell scoped %}{{ cell.source | markdown2rst }}
51 {% endblock markdowncell %}
52 {% endblock markdowncell %}
52
53
53 {% block headingcell scoped %}
54 {% block headingcell scoped %}
54 {%- set len = cell.source|length -%}
55 {%- set len = cell.source|length -%}
55 {{ cell.source}}
56 {{ cell.source}}
56 {% if cell.level == 1 %}
57 {% if cell.level == 1 %}
57 {{- '=' * len }}
58 {{- '=' * len }}
58 {%- elif cell.level == 2 %}
59 {%- elif cell.level == 2 %}
59 {{- '-' * len }}
60 {{- '-' * len }}
60 {% endif %}
61 {% endif %}
62
61 {% endblock headingcell %}
63 {% endblock headingcell %}
62
64
63 {% block rawcell scoped %}
65 {% block rawcell scoped %}{{ cell.source }}
64 {{ cell.source }}
65 {% endblock rawcell %}
66 {% endblock rawcell %}
66
67
67 {% block unknowncell scoped %}
68 {% block unknowncell scoped %}
68 unknown type {{cell.type}}
69 unknown type {{cell.type}}
69 {% endblock unknowncell %}
70 {% endblock unknowncell %}
General Comments 0
You need to be logged in to leave comments. Login now