##// END OF EJS Templates
Merge pull request #5272 from minrk/highlight-language-metadata...
Min RK -
r15681:9cea9c07 merge
parent child Browse files
Show More
@@ -1,275 +1,278 b''
1 """This module defines a base Exporter class. For Jinja template-based export,
1 """This module defines a base Exporter class. For Jinja template-based export,
2 see templateexporter.py.
2 see templateexporter.py.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import print_function, absolute_import
17 from __future__ import print_function, absolute_import
18
18
19 # Stdlib imports
19 # Stdlib imports
20 import io
20 import io
21 import os
21 import os
22 import copy
22 import copy
23 import collections
23 import collections
24 import datetime
24 import datetime
25
25
26
26
27 # IPython imports
27 # IPython imports
28 from IPython.config.configurable import LoggingConfigurable
28 from IPython.config.configurable import LoggingConfigurable
29 from IPython.config import Config
29 from IPython.config import Config
30 from IPython.nbformat import current as nbformat
30 from IPython.nbformat import current as nbformat
31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
32 from IPython.utils.importstring import import_item
32 from IPython.utils.importstring import import_item
33 from IPython.utils import text, py3compat
33 from IPython.utils import text, py3compat
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Class
36 # Class
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 class ResourcesDict(collections.defaultdict):
39 class ResourcesDict(collections.defaultdict):
40 def __missing__(self, key):
40 def __missing__(self, key):
41 return ''
41 return ''
42
42
43
43
44 class Exporter(LoggingConfigurable):
44 class Exporter(LoggingConfigurable):
45 """
45 """
46 Class containing methods that sequentially run a list of preprocessors on a
46 Class containing methods that sequentially run a list of preprocessors on a
47 NotebookNode object and then return the modified NotebookNode object and
47 NotebookNode object and then return the modified NotebookNode object and
48 accompanying resources dict.
48 accompanying resources dict.
49 """
49 """
50
50
51 file_extension = Unicode(
51 file_extension = Unicode(
52 'txt', config=True,
52 'txt', config=True,
53 help="Extension of the file that should be written to disk"
53 help="Extension of the file that should be written to disk"
54 )
54 )
55
55
56 # MIME type of the result file, for HTTP response headers.
56 # MIME type of the result file, for HTTP response headers.
57 # This is *not* a traitlet, because we want to be able to access it from
57 # This is *not* a traitlet, because we want to be able to access it from
58 # the class, not just on instances.
58 # the class, not just on instances.
59 output_mimetype = ''
59 output_mimetype = ''
60
60
61 #Configurability, allows the user to easily add filters and preprocessors.
61 #Configurability, allows the user to easily add filters and preprocessors.
62 preprocessors = List(config=True,
62 preprocessors = List(config=True,
63 help="""List of preprocessors, by name or namespace, to enable.""")
63 help="""List of preprocessors, by name or namespace, to enable.""")
64
64
65 _preprocessors = None
65 _preprocessors = None
66
66
67 default_preprocessors = List(['IPython.nbconvert.preprocessors.coalesce_streams',
67 default_preprocessors = List(['IPython.nbconvert.preprocessors.coalesce_streams',
68 'IPython.nbconvert.preprocessors.SVG2PDFPreprocessor',
68 'IPython.nbconvert.preprocessors.SVG2PDFPreprocessor',
69 'IPython.nbconvert.preprocessors.ExtractOutputPreprocessor',
69 'IPython.nbconvert.preprocessors.ExtractOutputPreprocessor',
70 'IPython.nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
70 'IPython.nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
71 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
71 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
72 'IPython.nbconvert.preprocessors.LatexPreprocessor',
72 'IPython.nbconvert.preprocessors.LatexPreprocessor',
73 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
73 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
74 config=True,
74 config=True,
75 help="""List of preprocessors available by default, by name, namespace,
75 help="""List of preprocessors available by default, by name, namespace,
76 instance, or type.""")
76 instance, or type.""")
77
77
78
78
79 def __init__(self, config=None, **kw):
79 def __init__(self, config=None, **kw):
80 """
80 """
81 Public constructor
81 Public constructor
82
82
83 Parameters
83 Parameters
84 ----------
84 ----------
85 config : config
85 config : config
86 User configuration instance.
86 User configuration instance.
87 """
87 """
88 with_default_config = self.default_config
88 with_default_config = self.default_config
89 if config:
89 if config:
90 with_default_config.merge(config)
90 with_default_config.merge(config)
91
91
92 super(Exporter, self).__init__(config=with_default_config, **kw)
92 super(Exporter, self).__init__(config=with_default_config, **kw)
93
93
94 self._init_preprocessors()
94 self._init_preprocessors()
95
95
96
96
97 @property
97 @property
98 def default_config(self):
98 def default_config(self):
99 return Config()
99 return Config()
100
100
101 @nbformat.docstring_nbformat_mod
101 @nbformat.docstring_nbformat_mod
102 def from_notebook_node(self, nb, resources=None, **kw):
102 def from_notebook_node(self, nb, resources=None, **kw):
103 """
103 """
104 Convert a notebook from a notebook node instance.
104 Convert a notebook from a notebook node instance.
105
105
106 Parameters
106 Parameters
107 ----------
107 ----------
108 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
108 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
109 Notebook node
109 Notebook node
110 resources : dict
110 resources : dict
111 Additional resources that can be accessed read/write by
111 Additional resources that can be accessed read/write by
112 preprocessors and filters.
112 preprocessors and filters.
113 **kw
113 **kw
114 Ignored (?)
114 Ignored (?)
115 """
115 """
116 nb_copy = copy.deepcopy(nb)
116 nb_copy = copy.deepcopy(nb)
117 resources = self._init_resources(resources)
117 resources = self._init_resources(resources)
118
119 if 'language' in nb['metadata']:
120 resources['language'] = nb['metadata']['language'].lower()
118
121
119 # Preprocess
122 # Preprocess
120 nb_copy, resources = self._preprocess(nb_copy, resources)
123 nb_copy, resources = self._preprocess(nb_copy, resources)
121
124
122 return nb_copy, resources
125 return nb_copy, resources
123
126
124
127
125 def from_filename(self, filename, resources=None, **kw):
128 def from_filename(self, filename, resources=None, **kw):
126 """
129 """
127 Convert a notebook from a notebook file.
130 Convert a notebook from a notebook file.
128
131
129 Parameters
132 Parameters
130 ----------
133 ----------
131 filename : str
134 filename : str
132 Full filename of the notebook file to open and convert.
135 Full filename of the notebook file to open and convert.
133 """
136 """
134
137
135 # Pull the metadata from the filesystem.
138 # Pull the metadata from the filesystem.
136 if resources is None:
139 if resources is None:
137 resources = ResourcesDict()
140 resources = ResourcesDict()
138 if not 'metadata' in resources or resources['metadata'] == '':
141 if not 'metadata' in resources or resources['metadata'] == '':
139 resources['metadata'] = ResourcesDict()
142 resources['metadata'] = ResourcesDict()
140 basename = os.path.basename(filename)
143 basename = os.path.basename(filename)
141 notebook_name = basename[:basename.rfind('.')]
144 notebook_name = basename[:basename.rfind('.')]
142 resources['metadata']['name'] = notebook_name
145 resources['metadata']['name'] = notebook_name
143
146
144 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
147 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
145 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
148 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
146
149
147 with io.open(filename, encoding='utf-8') as f:
150 with io.open(filename, encoding='utf-8') as f:
148 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
151 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
149
152
150
153
151 def from_file(self, file_stream, resources=None, **kw):
154 def from_file(self, file_stream, resources=None, **kw):
152 """
155 """
153 Convert a notebook from a notebook file.
156 Convert a notebook from a notebook file.
154
157
155 Parameters
158 Parameters
156 ----------
159 ----------
157 file_stream : file-like object
160 file_stream : file-like object
158 Notebook file-like object to convert.
161 Notebook file-like object to convert.
159 """
162 """
160 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
163 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
161
164
162
165
163 def register_preprocessor(self, preprocessor, enabled=False):
166 def register_preprocessor(self, preprocessor, enabled=False):
164 """
167 """
165 Register a preprocessor.
168 Register a preprocessor.
166 Preprocessors are classes that act upon the notebook before it is
169 Preprocessors are classes that act upon the notebook before it is
167 passed into the Jinja templating engine. preprocessors are also
170 passed into the Jinja templating engine. preprocessors are also
168 capable of passing additional information to the Jinja
171 capable of passing additional information to the Jinja
169 templating engine.
172 templating engine.
170
173
171 Parameters
174 Parameters
172 ----------
175 ----------
173 preprocessor : preprocessor
176 preprocessor : preprocessor
174 """
177 """
175 if preprocessor is None:
178 if preprocessor is None:
176 raise TypeError('preprocessor')
179 raise TypeError('preprocessor')
177 isclass = isinstance(preprocessor, type)
180 isclass = isinstance(preprocessor, type)
178 constructed = not isclass
181 constructed = not isclass
179
182
180 # Handle preprocessor's registration based on it's type
183 # Handle preprocessor's registration based on it's type
181 if constructed and isinstance(preprocessor, py3compat.string_types):
184 if constructed and isinstance(preprocessor, py3compat.string_types):
182 # Preprocessor is a string, import the namespace and recursively call
185 # Preprocessor is a string, import the namespace and recursively call
183 # this register_preprocessor method
186 # this register_preprocessor method
184 preprocessor_cls = import_item(preprocessor)
187 preprocessor_cls = import_item(preprocessor)
185 return self.register_preprocessor(preprocessor_cls, enabled)
188 return self.register_preprocessor(preprocessor_cls, enabled)
186
189
187 if constructed and hasattr(preprocessor, '__call__'):
190 if constructed and hasattr(preprocessor, '__call__'):
188 # Preprocessor is a function, no need to construct it.
191 # Preprocessor is a function, no need to construct it.
189 # Register and return the preprocessor.
192 # Register and return the preprocessor.
190 if enabled:
193 if enabled:
191 preprocessor.enabled = True
194 preprocessor.enabled = True
192 self._preprocessors.append(preprocessor)
195 self._preprocessors.append(preprocessor)
193 return preprocessor
196 return preprocessor
194
197
195 elif isclass and isinstance(preprocessor, MetaHasTraits):
198 elif isclass and isinstance(preprocessor, MetaHasTraits):
196 # Preprocessor is configurable. Make sure to pass in new default for
199 # Preprocessor is configurable. Make sure to pass in new default for
197 # the enabled flag if one was specified.
200 # the enabled flag if one was specified.
198 self.register_preprocessor(preprocessor(parent=self), enabled)
201 self.register_preprocessor(preprocessor(parent=self), enabled)
199
202
200 elif isclass:
203 elif isclass:
201 # Preprocessor is not configurable, construct it
204 # Preprocessor is not configurable, construct it
202 self.register_preprocessor(preprocessor(), enabled)
205 self.register_preprocessor(preprocessor(), enabled)
203
206
204 else:
207 else:
205 # Preprocessor is an instance of something without a __call__
208 # Preprocessor is an instance of something without a __call__
206 # attribute.
209 # attribute.
207 raise TypeError('preprocessor')
210 raise TypeError('preprocessor')
208
211
209
212
210 def _init_preprocessors(self):
213 def _init_preprocessors(self):
211 """
214 """
212 Register all of the preprocessors needed for this exporter, disabled
215 Register all of the preprocessors needed for this exporter, disabled
213 unless specified explicitly.
216 unless specified explicitly.
214 """
217 """
215 if self._preprocessors is None:
218 if self._preprocessors is None:
216 self._preprocessors = []
219 self._preprocessors = []
217
220
218 #Load default preprocessors (not necessarly enabled by default).
221 #Load default preprocessors (not necessarly enabled by default).
219 if self.default_preprocessors:
222 if self.default_preprocessors:
220 for preprocessor in self.default_preprocessors:
223 for preprocessor in self.default_preprocessors:
221 self.register_preprocessor(preprocessor)
224 self.register_preprocessor(preprocessor)
222
225
223 #Load user preprocessors. Enable by default.
226 #Load user preprocessors. Enable by default.
224 if self.preprocessors:
227 if self.preprocessors:
225 for preprocessor in self.preprocessors:
228 for preprocessor in self.preprocessors:
226 self.register_preprocessor(preprocessor, enabled=True)
229 self.register_preprocessor(preprocessor, enabled=True)
227
230
228
231
229 def _init_resources(self, resources):
232 def _init_resources(self, resources):
230
233
231 #Make sure the resources dict is of ResourcesDict type.
234 #Make sure the resources dict is of ResourcesDict type.
232 if resources is None:
235 if resources is None:
233 resources = ResourcesDict()
236 resources = ResourcesDict()
234 if not isinstance(resources, ResourcesDict):
237 if not isinstance(resources, ResourcesDict):
235 new_resources = ResourcesDict()
238 new_resources = ResourcesDict()
236 new_resources.update(resources)
239 new_resources.update(resources)
237 resources = new_resources
240 resources = new_resources
238
241
239 #Make sure the metadata extension exists in resources
242 #Make sure the metadata extension exists in resources
240 if 'metadata' in resources:
243 if 'metadata' in resources:
241 if not isinstance(resources['metadata'], ResourcesDict):
244 if not isinstance(resources['metadata'], ResourcesDict):
242 resources['metadata'] = ResourcesDict(resources['metadata'])
245 resources['metadata'] = ResourcesDict(resources['metadata'])
243 else:
246 else:
244 resources['metadata'] = ResourcesDict()
247 resources['metadata'] = ResourcesDict()
245 if not resources['metadata']['name']:
248 if not resources['metadata']['name']:
246 resources['metadata']['name'] = 'Notebook'
249 resources['metadata']['name'] = 'Notebook'
247
250
248 #Set the output extension
251 #Set the output extension
249 resources['output_extension'] = self.file_extension
252 resources['output_extension'] = self.file_extension
250 return resources
253 return resources
251
254
252
255
253 def _preprocess(self, nb, resources):
256 def _preprocess(self, nb, resources):
254 """
257 """
255 Preprocess the notebook before passing it into the Jinja engine.
258 Preprocess the notebook before passing it into the Jinja engine.
256 To preprocess the notebook is to apply all of the
259 To preprocess the notebook is to apply all of the
257
260
258 Parameters
261 Parameters
259 ----------
262 ----------
260 nb : notebook node
263 nb : notebook node
261 notebook that is being exported.
264 notebook that is being exported.
262 resources : a dict of additional resources that
265 resources : a dict of additional resources that
263 can be accessed read/write by preprocessors
266 can be accessed read/write by preprocessors
264 """
267 """
265
268
266 # Do a copy.deepcopy first,
269 # Do a copy.deepcopy first,
267 # we are never safe enough with what the preprocessors could do.
270 # we are never safe enough with what the preprocessors could do.
268 nbc = copy.deepcopy(nb)
271 nbc = copy.deepcopy(nb)
269 resc = copy.deepcopy(resources)
272 resc = copy.deepcopy(resources)
270
273
271 #Run each preprocessor on the notebook. Carry the output along
274 #Run each preprocessor on the notebook. Carry the output along
272 #to each preprocessor
275 #to each preprocessor
273 for preprocessor in self._preprocessors:
276 for preprocessor in self._preprocessors:
274 nbc, resc = preprocessor(nbc, resc)
277 nbc, resc = preprocessor(nbc, resc)
275 return nbc, resc
278 return nbc, resc
@@ -1,189 +1,189 b''
1 {%- extends 'display_priority.tpl' -%}
1 {%- extends 'display_priority.tpl' -%}
2
2
3
3
4 {% block codecell %}
4 {% block codecell %}
5 <div class="cell border-box-sizing code_cell">
5 <div class="cell border-box-sizing code_cell">
6 {{ super() }}
6 {{ super() }}
7 </div>
7 </div>
8 {%- endblock codecell %}
8 {%- endblock codecell %}
9
9
10 {% block input_group -%}
10 {% block input_group -%}
11 <div class="input">
11 <div class="input">
12 {{ super() }}
12 {{ super() }}
13 </div>
13 </div>
14 {% endblock input_group %}
14 {% endblock input_group %}
15
15
16 {% block output_group %}
16 {% block output_group %}
17 <div class="output_wrapper">
17 <div class="output_wrapper">
18 <div class="output">
18 <div class="output">
19 {{ super() }}
19 {{ super() }}
20 </div>
20 </div>
21 </div>
21 </div>
22 {% endblock output_group %}
22 {% endblock output_group %}
23
23
24 {% block in_prompt -%}
24 {% block in_prompt -%}
25 <div class="prompt input_prompt">
25 <div class="prompt input_prompt">
26 In&nbsp;[{{ cell.prompt_number }}]:
26 In&nbsp;[{{ cell.prompt_number }}]:
27 </div>
27 </div>
28 {%- endblock in_prompt %}
28 {%- endblock in_prompt %}
29
29
30 {% block empty_in_prompt -%}
30 {% block empty_in_prompt -%}
31 <div class="prompt input_prompt">
31 <div class="prompt input_prompt">
32 </div>
32 </div>
33 {%- endblock empty_in_prompt %}
33 {%- endblock empty_in_prompt %}
34
34
35 {#
35 {#
36 output_prompt doesn't do anything in HTML,
36 output_prompt doesn't do anything in HTML,
37 because there is a prompt div in each output area (see output block)
37 because there is a prompt div in each output area (see output block)
38 #}
38 #}
39 {% block output_prompt %}
39 {% block output_prompt %}
40 {% endblock output_prompt %}
40 {% endblock output_prompt %}
41
41
42 {% block input %}
42 {% block input %}
43 <div class="input_area box-flex1">
43 <div class="input_area box-flex1">
44 {{ cell.input | highlight2html(metadata=cell.metadata) }}
44 {{ cell.input | highlight2html(language=resources.get('language'), metadata=cell.metadata) }}
45 </div>
45 </div>
46 {%- endblock input %}
46 {%- endblock input %}
47
47
48 {% block output %}
48 {% block output %}
49 <div class="output_area">
49 <div class="output_area">
50 {%- if output.output_type == 'pyout' -%}
50 {%- if output.output_type == 'pyout' -%}
51 <div class="prompt output_prompt">
51 <div class="prompt output_prompt">
52 Out[{{ cell.prompt_number }}]:
52 Out[{{ cell.prompt_number }}]:
53 {%- else -%}
53 {%- else -%}
54 <div class="prompt">
54 <div class="prompt">
55 {%- endif -%}
55 {%- endif -%}
56 </div>
56 </div>
57 {{ super() }}
57 {{ super() }}
58 </div>
58 </div>
59 {% endblock output %}
59 {% endblock output %}
60
60
61 {% block markdowncell scoped %}
61 {% block markdowncell scoped %}
62 <div class="cell border-box-sizing text_cell">
62 <div class="cell border-box-sizing text_cell">
63 <div class="input">
63 <div class="input">
64 {{ self.empty_in_prompt() }}
64 {{ self.empty_in_prompt() }}
65 <div class="inner_cell">
65 <div class="inner_cell">
66 <div class="text_cell_render border-box-sizing rendered_html">
66 <div class="text_cell_render border-box-sizing rendered_html">
67 {{ cell.source | markdown2html | strip_files_prefix }}
67 {{ cell.source | markdown2html | strip_files_prefix }}
68 </div>
68 </div>
69 </div>
69 </div>
70 </div>
70 </div>
71 </div>
71 </div>
72 {%- endblock markdowncell %}
72 {%- endblock markdowncell %}
73
73
74 {% block headingcell scoped %}
74 {% block headingcell scoped %}
75 <div class="cell border-box-sizing text_cell">
75 <div class="cell border-box-sizing text_cell">
76 <div class="input">
76 <div class="input">
77 {{ self.empty_in_prompt() }}
77 {{ self.empty_in_prompt() }}
78 <div class="inner_cell">
78 <div class="inner_cell">
79 <div class="text_cell_render border-box-sizing rendered_html">
79 <div class="text_cell_render border-box-sizing rendered_html">
80 {{ ("#" * cell.level + cell.source) | replace('\n', ' ') | markdown2html | strip_files_prefix | add_anchor }}
80 {{ ("#" * cell.level + cell.source) | replace('\n', ' ') | markdown2html | strip_files_prefix | add_anchor }}
81 </div>
81 </div>
82 </div>
82 </div>
83 </div>
83 </div>
84 </div>
84 </div>
85 {% endblock headingcell %}
85 {% endblock headingcell %}
86
86
87 {% block unknowncell scoped %}
87 {% block unknowncell scoped %}
88 unknown type {{ cell.type }}
88 unknown type {{ cell.type }}
89 {% endblock unknowncell %}
89 {% endblock unknowncell %}
90
90
91 {% block pyout -%}
91 {% block pyout -%}
92 <div class="box-flex1 output_subarea output_pyout">
92 <div class="box-flex1 output_subarea output_pyout">
93 {% block data_priority scoped %}
93 {% block data_priority scoped %}
94 {{ super() }}
94 {{ super() }}
95 {% endblock %}
95 {% endblock %}
96 </div>
96 </div>
97 {%- endblock pyout %}
97 {%- endblock pyout %}
98
98
99 {% block stream_stdout -%}
99 {% block stream_stdout -%}
100 <div class="box-flex1 output_subarea output_stream output_stdout">
100 <div class="box-flex1 output_subarea output_stream output_stdout">
101 <pre>
101 <pre>
102 {{ output.text | ansi2html }}
102 {{ output.text | ansi2html }}
103 </pre>
103 </pre>
104 </div>
104 </div>
105 {%- endblock stream_stdout %}
105 {%- endblock stream_stdout %}
106
106
107 {% block stream_stderr -%}
107 {% block stream_stderr -%}
108 <div class="box-flex1 output_subarea output_stream output_stderr">
108 <div class="box-flex1 output_subarea output_stream output_stderr">
109 <pre>
109 <pre>
110 {{ output.text | ansi2html }}
110 {{ output.text | ansi2html }}
111 </pre>
111 </pre>
112 </div>
112 </div>
113 {%- endblock stream_stderr %}
113 {%- endblock stream_stderr %}
114
114
115 {% block data_svg -%}
115 {% block data_svg -%}
116 {%- if output.svg_filename %}
116 {%- if output.svg_filename %}
117 <img src="{{output.svg_filename | posix_path}}"
117 <img src="{{output.svg_filename | posix_path}}"
118 {%- else %}
118 {%- else %}
119 {{ output.svg }}
119 {{ output.svg }}
120 {%- endif %}
120 {%- endif %}
121 {%- endblock data_svg %}
121 {%- endblock data_svg %}
122
122
123 {% block data_html -%}
123 {% block data_html -%}
124 <div class="output_html rendered_html">
124 <div class="output_html rendered_html">
125 {{ output.html }}
125 {{ output.html }}
126 </div>
126 </div>
127 {%- endblock data_html %}
127 {%- endblock data_html %}
128
128
129 {% block data_png %}
129 {% block data_png %}
130 {%- if output.png_filename %}
130 {%- if output.png_filename %}
131 <img src="{{output.png_filename | posix_path}}"
131 <img src="{{output.png_filename | posix_path}}"
132 {%- else %}
132 {%- else %}
133 <img src="data:image/png;base64,{{ output.png }}"
133 <img src="data:image/png;base64,{{ output.png }}"
134 {%- endif %}
134 {%- endif %}
135 {%- if 'metadata' in output and 'width' in output.metadata.get('png', {}) %}
135 {%- if 'metadata' in output and 'width' in output.metadata.get('png', {}) %}
136 width={{output.metadata['png']['width']}}
136 width={{output.metadata['png']['width']}}
137 {%- endif %}
137 {%- endif %}
138 {%- if 'metadata' in output and 'height' in output.metadata.get('png', {}) %}
138 {%- if 'metadata' in output and 'height' in output.metadata.get('png', {}) %}
139 height={{output.metadata['png']['height']}}
139 height={{output.metadata['png']['height']}}
140 {%- endif %}
140 {%- endif %}
141 >
141 >
142 {%- endblock data_png %}
142 {%- endblock data_png %}
143
143
144 {% block data_jpg %}
144 {% block data_jpg %}
145 {%- if output.jpeg_filename %}
145 {%- if output.jpeg_filename %}
146 <img src="{{output.jpeg_filename | posix_path}}"
146 <img src="{{output.jpeg_filename | posix_path}}"
147 {%- else %}
147 {%- else %}
148 <img src="data:image/jpeg;base64,{{ output.jpeg }}"
148 <img src="data:image/jpeg;base64,{{ output.jpeg }}"
149 {%- endif %}
149 {%- endif %}
150 {%- if 'metadata' in output and 'width' in output.metadata.get('jpeg', {}) %}
150 {%- if 'metadata' in output and 'width' in output.metadata.get('jpeg', {}) %}
151 width={{output.metadata['jpeg']['width']}}
151 width={{output.metadata['jpeg']['width']}}
152 {%- endif %}
152 {%- endif %}
153 {%- if 'metadata' in output and 'height' in output.metadata.get('jpeg', {}) %}
153 {%- if 'metadata' in output and 'height' in output.metadata.get('jpeg', {}) %}
154 height={{output.metadata['jpeg']['height']}}
154 height={{output.metadata['jpeg']['height']}}
155 {%- endif %}
155 {%- endif %}
156 >
156 >
157 {%- endblock data_jpg %}
157 {%- endblock data_jpg %}
158
158
159 {% block data_latex %}
159 {% block data_latex %}
160 {{ output.latex }}
160 {{ output.latex }}
161 {%- endblock data_latex %}
161 {%- endblock data_latex %}
162
162
163 {% block pyerr -%}
163 {% block pyerr -%}
164 <div class="box-flex1 output_subarea output_pyerr">
164 <div class="box-flex1 output_subarea output_pyerr">
165 <pre>{{ super() }}</pre>
165 <pre>{{ super() }}</pre>
166 </div>
166 </div>
167 {%- endblock pyerr %}
167 {%- endblock pyerr %}
168
168
169 {%- block traceback_line %}
169 {%- block traceback_line %}
170 {{ line | ansi2html }}
170 {{ line | ansi2html }}
171 {%- endblock traceback_line %}
171 {%- endblock traceback_line %}
172
172
173 {%- block data_text %}
173 {%- block data_text %}
174 <pre>
174 <pre>
175 {{ output.text | ansi2html }}
175 {{ output.text | ansi2html }}
176 </pre>
176 </pre>
177 {%- endblock -%}
177 {%- endblock -%}
178
178
179 {%- block data_javascript %}
179 {%- block data_javascript %}
180 <script type="text/javascript">
180 <script type="text/javascript">
181 {{ output.javascript }}
181 {{ output.javascript }}
182 </script>
182 </script>
183 {%- endblock -%}
183 {%- endblock -%}
184
184
185 {%- block display_data scoped -%}
185 {%- block display_data scoped -%}
186 <div class="box-flex1 output_subarea output_display_data">
186 <div class="box-flex1 output_subarea output_display_data">
187 {{ super() }}
187 {{ super() }}
188 </div>
188 </div>
189 {%- endblock display_data -%}
189 {%- endblock display_data -%}
@@ -1,21 +1,21 b''
1 ((= Python input/output style =))
1 ((= Python input/output style =))
2
2
3 ((*- extends 'base.tplx' -*))
3 ((*- extends 'base.tplx' -*))
4
4
5 % Custom definitions
5 % Custom definitions
6 ((* block definitions *))
6 ((* block definitions *))
7 ((( super() )))
7 ((( super() )))
8
8
9 % Pygments definitions
9 % Pygments definitions
10 ((( resources.latex.pygments_definitions )))
10 ((( resources.latex.pygments_definitions )))
11 ((* endblock definitions *))
11 ((* endblock definitions *))
12
12
13 %===============================================================================
13 %===============================================================================
14 % Input
14 % Input
15 %===============================================================================
15 %===============================================================================
16
16
17 ((* block input scoped *))
17 ((* block input scoped *))
18 \begin{Verbatim}[commandchars=\\\{\}]
18 \begin{Verbatim}[commandchars=\\\{\}]
19 ((( cell.input | highlight2latex(strip_verbatim=True) | add_prompts )))
19 ((( cell.input | highlight2latex(language=resources.get('language'), strip_verbatim=True) | add_prompts )))
20 \end{Verbatim}
20 \end{Verbatim}
21 ((* endblock input *))
21 ((* endblock input *))
General Comments 0
You need to be logged in to leave comments. Login now