##// END OF EJS Templates
Merge pull request #4313 from minrk/remove-math-space...
Matthias Bussonnier -
r12910:68c851f3 merge
parent child Browse files
Show More
@@ -1,316 +1,315 b''
1 1 """This module defines Exporter, a highly configurable converter
2 2 that uses Jinja2 to export notebook files into different formats.
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from __future__ import print_function, absolute_import
18 18
19 19 # Stdlib imports
20 20 import os
21 21
22 22 # other libs/dependencies
23 23 from jinja2 import Environment, FileSystemLoader, ChoiceLoader, TemplateNotFound
24 24
25 25 # IPython imports
26 26 from IPython.utils.traitlets import MetaHasTraits, Unicode, List, Dict, Any
27 27 from IPython.utils.importstring import import_item
28 28 from IPython.utils import py3compat, text
29 29
30 30 from IPython.nbconvert import filters
31 31 from .exporter import Exporter
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Globals and constants
35 35 #-----------------------------------------------------------------------------
36 36
37 37 #Jinja2 extensions to load.
38 38 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
39 39
40 40 default_filters = {
41 41 'indent': text.indent,
42 42 'markdown2html': filters.markdown2html,
43 43 'ansi2html': filters.ansi2html,
44 44 'filter_data_type': filters.DataTypeFilter,
45 45 'get_lines': filters.get_lines,
46 46 'highlight2html': filters.highlight2html,
47 47 'highlight2latex': filters.highlight2latex,
48 48 'ipython2python': filters.ipython2python,
49 49 'posix_path': filters.posix_path,
50 50 'markdown2latex': filters.markdown2latex,
51 51 'markdown2rst': filters.markdown2rst,
52 52 'comment_lines': filters.comment_lines,
53 53 'strip_ansi': filters.strip_ansi,
54 54 'strip_dollars': filters.strip_dollars,
55 55 'strip_files_prefix': filters.strip_files_prefix,
56 56 'html2text' : filters.html2text,
57 57 'add_anchor': filters.add_anchor,
58 58 'ansi2latex': filters.ansi2latex,
59 'strip_math_space': filters.strip_math_space,
60 59 'wrap_text': filters.wrap_text,
61 60 'escape_latex': filters.escape_latex,
62 61 'citation2latex': filters.citation2latex,
63 62 'path2url': filters.path2url,
64 63 'add_prompts': filters.add_prompts,
65 64 }
66 65
67 66 #-----------------------------------------------------------------------------
68 67 # Class
69 68 #-----------------------------------------------------------------------------
70 69
71 70 class TemplateExporter(Exporter):
72 71 """
73 72 Exports notebooks into other file formats. Uses Jinja 2 templating engine
74 73 to output new formats. Inherit from this class if you are creating a new
75 74 template type along with new filters/preprocessors. If the filters/
76 75 preprocessors provided by default suffice, there is no need to inherit from
77 76 this class. Instead, override the template_file and file_extension
78 77 traits via a config file.
79 78
80 79 {filters}
81 80 """
82 81
83 82 # finish the docstring
84 83 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
85 84
86 85
87 86 template_file = Unicode(u'default',
88 87 config=True,
89 88 help="Name of the template file to use")
90 89 def _template_file_changed(self, name, old, new):
91 90 if new == 'default':
92 91 self.template_file = self.default_template
93 92 else:
94 93 self.template_file = new
95 94 self.template = None
96 95 self._load_template()
97 96
98 97 default_template = Unicode(u'')
99 98 template = Any()
100 99 environment = Any()
101 100
102 101 template_path = List(['.'], config=True)
103 102 def _template_path_changed(self, name, old, new):
104 103 self._load_template()
105 104
106 105 default_template_path = Unicode(
107 106 os.path.join("..", "templates"),
108 107 help="Path where the template files are located.")
109 108
110 109 template_skeleton_path = Unicode(
111 110 os.path.join("..", "templates", "skeleton"),
112 111 help="Path where the template skeleton files are located.")
113 112
114 113 #Jinja block definitions
115 114 jinja_comment_block_start = Unicode("", config=True)
116 115 jinja_comment_block_end = Unicode("", config=True)
117 116 jinja_variable_block_start = Unicode("", config=True)
118 117 jinja_variable_block_end = Unicode("", config=True)
119 118 jinja_logic_block_start = Unicode("", config=True)
120 119 jinja_logic_block_end = Unicode("", config=True)
121 120
122 121 #Extension that the template files use.
123 122 template_extension = Unicode(".tpl", config=True)
124 123
125 124 filters = Dict(config=True,
126 125 help="""Dictionary of filters, by name and namespace, to add to the Jinja
127 126 environment.""")
128 127
129 128
130 129 def __init__(self, config=None, extra_loaders=None, **kw):
131 130 """
132 131 Public constructor
133 132
134 133 Parameters
135 134 ----------
136 135 config : config
137 136 User configuration instance.
138 137 extra_loaders : list[of Jinja Loaders]
139 138 ordered list of Jinja loader to find templates. Will be tried in order
140 139 before the default FileSystem ones.
141 140 template : str (optional, kw arg)
142 141 Template to use when exporting.
143 142 """
144 143 if not config:
145 144 config = self.default_config
146 145
147 146 super(Exporter, self).__init__(config=config, **kw)
148 147
149 148 #Init
150 149 self._init_template()
151 150 self._init_environment(extra_loaders=extra_loaders)
152 151 self._init_preprocessors()
153 152 self._init_filters()
154 153
155 154
156 155 def _load_template(self):
157 156 """Load the Jinja template object from the template file
158 157
159 158 This is a no-op if the template attribute is already defined,
160 159 or the Jinja environment is not setup yet.
161 160
162 161 This is triggered by various trait changes that would change the template.
163 162 """
164 163 if self.template is not None:
165 164 return
166 165 # called too early, do nothing
167 166 if self.environment is None:
168 167 return
169 168 # Try different template names during conversion. First try to load the
170 169 # template by name with extension added, then try loading the template
171 170 # as if the name is explicitly specified, then try the name as a
172 171 # 'flavor', and lastly just try to load the template by module name.
173 172 module_name = self.__module__.rsplit('.', 1)[-1]
174 173 try_names = []
175 174 if self.template_file:
176 175 try_names.extend([
177 176 self.template_file + self.template_extension,
178 177 self.template_file,
179 178 module_name + '_' + self.template_file + self.template_extension,
180 179 ])
181 180 try_names.append(module_name + self.template_extension)
182 181 for try_name in try_names:
183 182 self.log.debug("Attempting to load template %s", try_name)
184 183 try:
185 184 self.template = self.environment.get_template(try_name)
186 185 except (TemplateNotFound, IOError):
187 186 pass
188 187 except Exception as e:
189 188 self.log.warn("Unexpected exception loading template: %s", try_name, exc_info=True)
190 189 else:
191 190 self.log.info("Loaded template %s", try_name)
192 191 break
193 192
194 193 def from_notebook_node(self, nb, resources=None, **kw):
195 194 """
196 195 Convert a notebook from a notebook node instance.
197 196
198 197 Parameters
199 198 ----------
200 199 nb : Notebook node
201 200 resources : dict (**kw)
202 201 of additional resources that can be accessed read/write by
203 202 preprocessors and filters.
204 203 """
205 204 nb_copy, resources = super(TemplateExporter, self).from_notebook_node(nb, resources, **kw)
206 205
207 206 self._load_template()
208 207
209 208 if self.template is not None:
210 209 output = self.template.render(nb=nb_copy, resources=resources)
211 210 else:
212 211 raise IOError('template file "%s" could not be found' % self.template_file)
213 212 return output, resources
214 213
215 214
216 215 def register_filter(self, name, jinja_filter):
217 216 """
218 217 Register a filter.
219 218 A filter is a function that accepts and acts on one string.
220 219 The filters are accesible within the Jinja templating engine.
221 220
222 221 Parameters
223 222 ----------
224 223 name : str
225 224 name to give the filter in the Jinja engine
226 225 filter : filter
227 226 """
228 227 if jinja_filter is None:
229 228 raise TypeError('filter')
230 229 isclass = isinstance(jinja_filter, type)
231 230 constructed = not isclass
232 231
233 232 #Handle filter's registration based on it's type
234 233 if constructed and isinstance(jinja_filter, py3compat.string_types):
235 234 #filter is a string, import the namespace and recursively call
236 235 #this register_filter method
237 236 filter_cls = import_item(jinja_filter)
238 237 return self.register_filter(name, filter_cls)
239 238
240 239 if constructed and hasattr(jinja_filter, '__call__'):
241 240 #filter is a function, no need to construct it.
242 241 self.environment.filters[name] = jinja_filter
243 242 return jinja_filter
244 243
245 244 elif isclass and isinstance(jinja_filter, MetaHasTraits):
246 245 #filter is configurable. Make sure to pass in new default for
247 246 #the enabled flag if one was specified.
248 247 filter_instance = jinja_filter(parent=self)
249 248 self.register_filter(name, filter_instance )
250 249
251 250 elif isclass:
252 251 #filter is not configurable, construct it
253 252 filter_instance = jinja_filter()
254 253 self.register_filter(name, filter_instance)
255 254
256 255 else:
257 256 #filter is an instance of something without a __call__
258 257 #attribute.
259 258 raise TypeError('filter')
260 259
261 260
262 261 def _init_template(self):
263 262 """
264 263 Make sure a template name is specified. If one isn't specified, try to
265 264 build one from the information we know.
266 265 """
267 266 self._template_file_changed('template_file', self.template_file, self.template_file)
268 267
269 268
270 269 def _init_environment(self, extra_loaders=None):
271 270 """
272 271 Create the Jinja templating environment.
273 272 """
274 273 here = os.path.dirname(os.path.realpath(__file__))
275 274 loaders = []
276 275 if extra_loaders:
277 276 loaders.extend(extra_loaders)
278 277
279 278 paths = self.template_path
280 279 paths.extend([os.path.join(here, self.default_template_path),
281 280 os.path.join(here, self.template_skeleton_path)])
282 281 loaders.append(FileSystemLoader(paths))
283 282
284 283 self.environment = Environment(
285 284 loader= ChoiceLoader(loaders),
286 285 extensions=JINJA_EXTENSIONS
287 286 )
288 287
289 288 #Set special Jinja2 syntax that will not conflict with latex.
290 289 if self.jinja_logic_block_start:
291 290 self.environment.block_start_string = self.jinja_logic_block_start
292 291 if self.jinja_logic_block_end:
293 292 self.environment.block_end_string = self.jinja_logic_block_end
294 293 if self.jinja_variable_block_start:
295 294 self.environment.variable_start_string = self.jinja_variable_block_start
296 295 if self.jinja_variable_block_end:
297 296 self.environment.variable_end_string = self.jinja_variable_block_end
298 297 if self.jinja_comment_block_start:
299 298 self.environment.comment_start_string = self.jinja_comment_block_start
300 299 if self.jinja_comment_block_end:
301 300 self.environment.comment_end_string = self.jinja_comment_block_end
302 301
303 302
304 303 def _init_filters(self):
305 304 """
306 305 Register all of the filters required for the exporter.
307 306 """
308 307
309 308 #Add default filters to the Jinja2 environment
310 309 for key, value in default_filters.items():
311 310 self.register_filter(key, value)
312 311
313 312 #Load user filters. Overwrite existing filters if need be.
314 313 if self.filters:
315 314 for key, user_filter in self.filters.items():
316 315 self.register_filter(key, user_filter)
@@ -1,123 +1,63 b''
1 1 """Latex filters.
2 2
3 3 Module of useful filters for processing Latex within Jinja latex templates.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 import re
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Globals and constants
20 20 #-----------------------------------------------------------------------------
21 21
22 22 LATEX_RE_SUBS = (
23 23 (re.compile(r'\.\.\.+'), r'\\ldots'),
24 24 )
25 25
26 26 # Latex substitutions for escaping latex.
27 27 # see: http://stackoverflow.com/questions/16259923/how-can-i-escape-latex-special-characters-inside-django-templates
28 28
29 29 LATEX_SUBS = {
30 30 '&': r'\&',
31 31 '%': r'\%',
32 32 '$': r'\$',
33 33 '#': r'\#',
34 34 '_': r'\_',
35 35 '{': r'\{',
36 36 '}': r'\}',
37 37 '~': r'\textasciitilde{}',
38 38 '^': r'\^{}',
39 39 '\\': r'\textbackslash{}',
40 40 }
41 41
42 42
43 43 #-----------------------------------------------------------------------------
44 44 # Functions
45 45 #-----------------------------------------------------------------------------
46 46
47 __all__ = ['escape_latex',
48 'strip_math_space']
47 __all__ = ['escape_latex']
49 48
50 49 def escape_latex(text):
51 50 """
52 51 Escape characters that may conflict with latex.
53 52
54 53 Parameters
55 54 ----------
56 55 text : str
57 56 Text containing characters that may conflict with Latex
58 57 """
59 58 text = ''.join(LATEX_SUBS.get(c, c) for c in text)
60 59 for pattern, replacement in LATEX_RE_SUBS:
61 60 text = pattern.sub(replacement, text)
62 61
63 62 return text
64
65
66 def strip_math_space(text):
67 """
68 Remove the space between latex math commands and enclosing $ symbols.
69 This filter is important because latex isn't as flexible as the notebook
70 front end when it comes to flagging math using ampersand symbols.
71
72 Parameters
73 ----------
74 text : str
75 Text to filter.
76 """
77
78 # First, scan through the markdown looking for $. If
79 # a $ symbol is found, without a preceding \, assume
80 # it is the start of a math block. UNLESS that $ is
81 # not followed by another within two math_lines.
82 math_regions = []
83 math_lines = 0
84 within_math = False
85 math_start_index = 0
86 ptext = ''
87 last_character = ""
88 skip = False
89 for index, char in enumerate(text):
90
91 #Make sure the character isn't preceeded by a backslash
92 if (char == "$" and last_character != "\\"):
93
94 # Close the math region if this is an ending $
95 if within_math:
96 within_math = False
97 skip = True
98 ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$'
99 math_regions.append([math_start_index, index+1])
100 else:
101
102 # Start a new math region
103 within_math = True
104 math_start_index = index
105 math_lines = 0
106
107 # If we are in a math region, count the number of lines parsed.
108 # Cancel the math region if we find two line breaks!
109 elif char == "\n":
110 if within_math:
111 math_lines += 1
112 if math_lines > 1:
113 within_math = False
114 ptext = ptext+text[math_start_index:index]
115 63
116 # Remember the last character so we can easily watch
117 # for backslashes
118 last_character = char
119 if not within_math and not skip:
120 ptext = ptext+char
121 if skip:
122 skip = False
123 return ptext
@@ -1,66 +1,45 b''
1 1 """
2 2 Module with tests for Latex
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from ...tests.base import TestsBase
18 from ..latex import escape_latex, strip_math_space
18 from ..latex import escape_latex
19 19
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Class
23 23 #-----------------------------------------------------------------------------
24 24
25 25 class TestLatex(TestsBase):
26 26
27 27
28 28 def test_escape_latex(self):
29 29 """escape_latex test"""
30 30 tests = [
31 31 (r'How are \you doing today?', r'How are \textbackslash{}you doing today?'),
32 32 (r'\escapechar=`\A\catcode`\|=0 |string|foo', r'\textbackslash{}escapechar=`\textbackslash{}A\textbackslash{}catcode`\textbackslash{}|=0 |string|foo'),
33 33 (r'# $ % & ~ _ ^ \ { }', r'\# \$ \% \& \textasciitilde{} \_ \^{} \textbackslash{} \{ \}'),
34 34 ('...', r'\ldots'),
35 35 ('','')]
36 36
37 37 for test in tests:
38 38 self._try_escape_latex(test[0], test[1])
39 39
40 40
41 41 def _try_escape_latex(self, test, result):
42 42 """Try to remove latex from string"""
43 43 self.assertEqual(escape_latex(test), result)
44 44
45 45
46 def test_strip_math_space(self):
47 """strip_math_space test"""
48 tests = [
49 ('$e$','$e$'),
50 ('$ e $','$e$'),
51 ('xxx$e^i$yyy','xxx$e^i$yyy'),
52 ('xxx$ e^i $yyy','xxx$e^i$yyy'),
53 ('xxx$e^i $yyy','xxx$e^i$yyy'),
54 ('xxx$ e^i$yyy','xxx$e^i$yyy'),
55 ('\$ e $ e $','\$ e $e$'),
56 ('','')]
57
58 for test in tests:
59 self._try_strip_math_space(test[0], test[1])
60
61
62 def _try_strip_math_space(self, test, result):
63 """
64 Try to remove spaces between dollar symbols and contents correctly
65 """
66 self.assertEqual(strip_math_space(test), result)
@@ -1,74 +1,47 b''
1 1 """Module that allows latex output notebooks to be conditioned before
2 2 they are converted.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2013, the IPython Development Team.
6 6 #
7 7 # Distributed under the terms of the Modified BSD License.
8 8 #
9 9 # The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15
16 16 from __future__ import print_function, absolute_import
17 import os
18 17
19 # Third-party import, needed for Pygments latex definitions.
20 from pygments.formatters import LatexFormatter
21
22 # ipy imports
23 from .base import (Preprocessor)
24 from IPython.nbconvert import filters
18 from .base import Preprocessor
25 19
26 20 #-----------------------------------------------------------------------------
27 21 # Classes
28 22 #-----------------------------------------------------------------------------
29 23
30 24 class LatexPreprocessor(Preprocessor):
31 """
32 Converter for latex destined documents.
25 """Preprocessor for latex destined documents.
26
27 Mainly populates the `latex` key in the resources dict,
28 adding definitions for pygments highlight styles.
33 29 """
34 30
35 31 def preprocess(self, nb, resources):
36 """
37 Preprocessing to apply on each notebook.
32 """Preprocessing to apply on each notebook.
38 33
39 34 Parameters
40 35 ----------
41 36 nb : NotebookNode
42 37 Notebook being converted
43 38 resources : dictionary
44 39 Additional resources used in the conversion process. Allows
45 40 preprocessors to pass variables into the Jinja engine.
46 41 """
47 # Generate Pygments definitions for Latex
48 resources["latex"] = {}
49 resources["latex"]["pygments_definitions"] = LatexFormatter().get_style_defs()
50 return super(LatexPreprocessor, self).preprocess(nb, resources)
51
52
53 def preprocess_cell(self, cell, resources, index):
54 """
55 Apply a transformation on each cell,
56
57 Parameters
58 ----------
59 cell : NotebookNode cell
60 Notebook cell being processed
61 resources : dictionary
62 Additional resources used in the conversion process. Allows
63 preprocessors to pass variables into the Jinja engine.
64 index : int
65 Modified index of the cell being processed (see base.py)
66 """
42 # Generate Pygments definitions for Latex
43 from pygments.formatters import LatexFormatter
67 44
68 #If the cell is a markdown cell, preprocess the ampersands used to
69 #remove the space between them and their contents. Latex will complain
70 #if spaces exist between the ampersands and the math content.
71 #See filters.latex.rm_math_space for more information.
72 if hasattr(cell, "source") and cell.cell_type == "markdown":
73 cell.source = filters.strip_math_space(cell.source)
74 return cell, resources
45 resources.setdefault("latex", {})
46 resources["latex"].setdefault("pygments_definitions", LatexFormatter().get_style_defs())
47 return nb, resources
@@ -1,51 +1,51 b''
1 1 """
2 2 Module with tests for the latex preprocessor
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from .base import PreprocessorTestsBase
18 18 from ..latex import LatexPreprocessor
19 19
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Class
23 23 #-----------------------------------------------------------------------------
24 24
25 25 class TestLatex(PreprocessorTestsBase):
26 26 """Contains test functions for latex.py"""
27 27
28 28
29 29 def build_preprocessor(self):
30 30 """Make an instance of a preprocessor"""
31 31 preprocessor = LatexPreprocessor()
32 32 preprocessor.enabled = True
33 33 return preprocessor
34 34
35 35 def test_constructor(self):
36 36 """Can a LatexPreprocessor be constructed?"""
37 37 self.build_preprocessor()
38 38
39 39
40 40 def test_output(self):
41 41 """Test the output of the LatexPreprocessor"""
42 42 nb = self.build_notebook()
43 43 res = self.build_resources()
44 44 preprocessor = self.build_preprocessor()
45 45 nb, res = preprocessor(nb, res)
46 46
47 47 # Make sure the code cell wasn't modified.
48 48 self.assertEqual(nb.worksheets[0].cells[0].input, '$ e $')
49 49
50 # Verify that the markdown cell was processed.
51 self.assertEqual(nb.worksheets[0].cells[1].source, '$e$')
50 # Verify that the markdown cell wasn't processed.
51 self.assertEqual(nb.worksheets[0].cells[1].source, '$ e $')
@@ -1,148 +1,148 b''
1 1 {%- extends 'display_priority.tpl' -%}
2 2
3 3
4 4 {% block codecell %}
5 5 <div class="cell border-box-sizing code_cell vbox">
6 6 {{ super() }}
7 7 </div>
8 8 {%- endblock codecell %}
9 9
10 10 {% block input_group -%}
11 11 <div class="input hbox">
12 12 {{ super() }}
13 13 </div>
14 14 {% endblock input_group %}
15 15
16 16 {% block output_group %}
17 17 <div class="vbox output_wrapper">
18 18 <div class="output vbox">
19 19 {{ super() }}
20 20 </div>
21 21 </div>
22 22 {% endblock output_group %}
23 23
24 24 {% block in_prompt -%}
25 25 <div class="prompt input_prompt">
26 26 In&nbsp;[{{ cell.prompt_number }}]:
27 27 </div>
28 28 {%- endblock in_prompt %}
29 29
30 30 {#
31 31 output_prompt doesn't do anything in HTML,
32 32 because there is a prompt div in each output area (see output block)
33 33 #}
34 34 {% block output_prompt %}
35 35 {% endblock output_prompt %}
36 36
37 37 {% block input %}
38 38 <div class="input_area box-flex1">
39 39 {{ cell.input | highlight2html(metadata=cell.metadata) }}
40 40 </div>
41 41 {%- endblock input %}
42 42
43 43 {% block output %}
44 44 <div class="hbox output_area">
45 45 {%- if output.output_type == 'pyout' -%}
46 46 <div class="prompt output_prompt">
47 47 Out[{{ cell.prompt_number }}]:
48 48 {%- else -%}
49 49 <div class="prompt">
50 50 {%- endif -%}
51 51 </div>
52 52 {{ super() }}
53 53 </div>
54 54 {% endblock output %}
55 55
56 56 {% block markdowncell scoped %}
57 57 <div class="text_cell_render border-box-sizing rendered_html">
58 {{ cell.source | strip_math_space | markdown2html | strip_files_prefix }}
58 {{ cell.source | markdown2html | strip_files_prefix }}
59 59 </div>
60 60 {%- endblock markdowncell %}
61 61
62 62 {% block headingcell scoped %}
63 63 <div class="text_cell_render border-box-sizing rendered_html">
64 {{ ("#" * cell.level + cell.source) | replace('\n', ' ') | strip_math_space | markdown2html | strip_files_prefix | add_anchor }}
64 {{ ("#" * cell.level + cell.source) | replace('\n', ' ') | markdown2html | strip_files_prefix | add_anchor }}
65 65 </div>
66 66 {% endblock headingcell %}
67 67
68 68 {% block rawcell scoped %}
69 69 {{ cell.source }}
70 70 {% endblock rawcell %}
71 71
72 72 {% block unknowncell scoped %}
73 73 unknown type {{ cell.type }}
74 74 {% endblock unknowncell %}
75 75
76 76 {% block pyout -%}
77 77 <div class="box-flex1 output_subarea output_pyout">
78 78 {% block data_priority scoped %}
79 79 {{ super() }}
80 80 {% endblock %}
81 81 </div>
82 82 {%- endblock pyout %}
83 83
84 84 {% block stream_stdout -%}
85 85 <div class="box-flex1 output_subarea output_stream output_stdout">
86 86 <pre>
87 87 {{ output.text | ansi2html }}
88 88 </pre>
89 89 </div>
90 90 {%- endblock stream_stdout %}
91 91
92 92 {% block stream_stderr -%}
93 93 <div class="box-flex1 output_subarea output_stream output_stderr">
94 94 <pre>
95 95 {{ output.text | ansi2html }}
96 96 </pre>
97 97 </div>
98 98 {%- endblock stream_stderr %}
99 99
100 100 {% block data_svg -%}
101 101 {{ output.svg }}
102 102 {%- endblock data_svg %}
103 103
104 104 {% block data_html -%}
105 105 <div class="output_html rendered_html">
106 106 {{ output.html }}
107 107 </div>
108 108 {%- endblock data_html %}
109 109
110 110 {% block data_png %}
111 111 <img src="data:image/png;base64,{{ output.png }}">
112 112 {%- endblock data_png %}
113 113
114 114 {% block data_jpg %}
115 115 <img src="data:image/jpeg;base64,{{ output.jpeg }}">
116 116 {%- endblock data_jpg %}
117 117
118 118 {% block data_latex %}
119 119 {{ output.latex }}
120 120 {%- endblock data_latex %}
121 121
122 122 {% block pyerr -%}
123 123 <div class="box-flex1 output_subarea output_pyerr">
124 124 <pre>{{ super() }}</pre>
125 125 </div>
126 126 {%- endblock pyerr %}
127 127
128 128 {%- block traceback_line %}
129 129 {{ line | ansi2html }}
130 130 {%- endblock traceback_line %}
131 131
132 132 {%- block data_text %}
133 133 <pre>
134 134 {{ output.text | ansi2html }}
135 135 </pre>
136 136 {%- endblock -%}
137 137
138 138 {%- block data_javascript %}
139 139 <script type="text/javascript">
140 140 {{ output.javascript }}
141 141 </script>
142 142 {%- endblock -%}
143 143
144 144 {%- block display_data scoped -%}
145 145 <div class="box-flex1 output_subarea output_display_data">
146 146 {{ super() }}
147 147 </div>
148 148 {%- endblock display_data -%} No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now