##// END OF EJS Templates
Cleaning of reveal converter to make the PR
damianavila -
Show More
@@ -1,339 +1,207 b''
1 1 from __future__ import absolute_import
2 2
3 3 from converters.html import ConverterHTML
4 from converters.utils import text_cell#, output_container
5 from converters.utils import highlight, coalesce_streams#, ansi2html
6
7 #from IPython.utils import path
8 #from IPython.utils.text import indent, dedent
4 from converters.utils import text_cell
5 from converters.utils import highlight, coalesce_streams
9 6 from markdown import markdown
7
10 8 import os
11 9 import io
12 10 import itertools
13 11
14 12
15 13 class ConverterReveal(ConverterHTML):
16 14 #"""
17 15 #Convert a notebook to a html slideshow.
18 16
19 #It generates a static html slideshow based in markdown and reveal.js.
20 #The delimiters for each slide, subslide, and fragment are retrieved
21 #from the 'slideshow' metadata.
17 #It generates a static html slideshow based reveal.js.
18 #The delimiters for each "Header slide", "Slide"", and "Fragment"
19 #are retrieved from the 'slideshow' metadata.
22 20 #"""
23 21
24 #def __init__(self):
25 #super(ConverterReveal, self).__init__()
26
27 #extension = 'html'
28 #blank_symbol = ' '
29
30 #def in_tag(self, tag, src, attrs=None):
31 #"""Return a list of elements bracketed by the given tag"""
32 #attr_s = '' if attrs is None else \
33 #' '.join("%s=%s" % (attr, value)
34 #for attr, value in attrs.iteritems())
35 #return ['<%s %s>' % (tag, attr_s), src, '</%s>' % tag]
36
37 #def _ansi_colored(self, text):
38 #return ['<pre>%s</pre>' % ansi2html(text)]
39
40 #def _stylesheet(self, fname):
41 #with io.open(fname, encoding='utf-8') as f:
42 #s = f.read()
43 #return self.in_tag('style', s, dict(type='"text/css"'))
44
45 #def _out_prompt(self, output):
46 #if output.output_type == 'pyout':
47 #content = 'Out[%s]:' % self._get_prompt_number(output)
48 #else:
49 #content = ''
50 #return ['<div class="prompt output_prompt">%s</div>' % content]
51
52 #def header_body(self):
53 #"""Return the body of the header as a list of strings."""
54
55 #from pygments.formatters import HtmlFormatter
56
57 #header = []
58 #static = os.path.join(path.get_ipython_package_dir(),
59 #'frontend', 'html', 'notebook', 'static',
60 #)
61 #here = os.path.split(os.path.realpath(__file__))[0]
62 #css = os.path.join(static, 'css')
63 #for sheet in [
64 ## do we need jquery and prettify?
65 ## os.path.join(static, 'jquery', 'css', 'themes', 'base',
66 ## 'jquery-ui.min.css'),
67 ## os.path.join(static, 'prettify', 'prettify.css'),
68 #os.path.join(css, 'boilerplate.css'),
69 #os.path.join(css, 'fbm.css'),
70 #os.path.join(css, 'notebook.css'),
71 #os.path.join(css, 'renderedhtml.css'),
72 ## our overrides:
73 #os.path.join(here, '..', 'css', 'static_html.css'),
74 #]:
75 #header.extend(self._stylesheet(sheet))
76
77 ## pygments css
78 #pygments_css = HtmlFormatter().get_style_defs('.highlight')
79 #header.extend(['<meta charset="UTF-8">'])
80 #header.extend(self.in_tag('style', pygments_css,
81 #dict(type='"text/css"')))
82
83 ## TODO: this should be allowed to use local mathjax:
84 #header.extend(self.in_tag('script', '', {'type': '"text/javascript"',
85 #'src': '"https://c328740.ssl.cf1.rackcdn.com/mathjax/'
86 #'latest/MathJax.js?config=TeX-AMS_HTML"',
87 #}))
88 #with io.open(os.path.join(here, '..', 'js', 'initmathjax.js'),
89 #encoding='utf-8') as f:
90 #header.extend(self.in_tag('script', f.read(),
91 #{'type': '"text/javascript"'}))
92 #return header
93
94 #def optional_header(self):
95 #return ['<html>', '<head>'] + self.header_body() + \
96 #['</head>', '<body>']
97
98 #def optional_footer(self):
99 #return ['</body>', '</html>']
100
101 22 @text_cell
102 23 def render_heading(self, cell):
103 24 marker = cell.level
104 25 return [self.meta2str(cell.metadata),
105 26 u'<h{1}>\n {0}\n</h{1}>'.format(cell.source, marker)]
106 27
107 28 def render_code(self, cell):
108 29 if not cell.input:
109 30 return []
110 31
111 32 lines = []
112 33 meta_code = self.meta2str(cell.metadata)
113 34 lines.extend([meta_code])
114 35
115 36 lines.extend(['<div class="cell border-box-sizing code_cell vbox">'])
116 37
117 38 lines.append('<div class="input hbox">')
118 39 n = self._get_prompt_number(cell)
119 40 lines.append(
120 41 '<div class="prompt input_prompt">In&nbsp;[%s]:</div>' % n
121 42 )
122 43 lines.append('<div class="input_area box-flex1">')
123 44 lines.append(highlight(cell.input))
124 45 lines.append('</div>') # input_area
125 46 lines.append('</div>') # input
126 47
127 48 if cell.outputs:
128 49 lines.append('<div class="vbox output_wrapper">')
129 50 lines.append('<div class="output vbox">')
130 51
131 52 for output in coalesce_streams(cell.outputs):
132 53 conv_fn = self.dispatch(output.output_type)
133 54 lines.extend(conv_fn(output))
134 55
135 56 lines.append('</div>') # output
136 57 lines.append('</div>') # output_wrapper
137 58
138 59 lines.append('</div>') # cell
139 60
140 61 return lines
141 62
142 63 @text_cell
143 64 def render_markdown(self, cell):
144 65 return [self.meta2str(cell.metadata), markdown(cell.source)]
145 66
146 67 def render_raw(self, cell):
147 68 if self.raw_as_verbatim:
148 69 return [self.in_tag('pre', self.meta2str(cell.metadata)),
149 self.in_tag('pre', cell.source)] # testing
70 self.in_tag('pre', cell.source)]
150 71 else:
151 72 return [self.meta2str(cell.metadata), cell.source]
152 73
153 #@output_container
154 #def render_pyout(self, output):
155 #for fmt in ['html', 'latex', 'png', 'jpeg', 'svg', 'text']:
156 #if fmt in output:
157 #conv_fn = self.dispatch_display_format(fmt)
158 #return conv_fn(output)
159 #return []
160
161 #render_display_data = render_pyout
162
163 #@output_container
164 #def render_stream(self, output):
165 #return self._ansi_colored(output.text)
166
167 #@output_container
168 #def render_pyerr(self, output):
169 ## Note: a traceback is a *list* of frames.
170 ## lines = []
171
172 ## stb =
173 #return self._ansi_colored('\n'.join(output.traceback))
174
175 #def _img_lines(self, img_file):
176 #return ['<img src="%s">' % img_file, '</img>']
177
178 #def _unknown_lines(self, data):
179 #return ['<h2>Warning:: Unknown cell</h2>'] + self.in_tag('pre', data)
180
181 #def render_display_format_png(self, output):
182 #return ['<img src="data:image/png;base64,%s"></img>' % output.png]
183
184 #def render_display_format_svg(self, output):
185 #return [output.svg]
186
187 #def render_display_format_jpeg(self, output):
188 #return ['<img src="data:image/jpeg;base64,%s"></img>' % output.jpeg]
189
190 #def render_display_format_text(self, output):
191 #return self._ansi_colored(output.text)
192
193 #def render_display_format_html(self, output):
194 #return [output.html]
195
196 #def render_display_format_latex(self, output):
197 #return [output.latex]
198
199 #def render_display_format_json(self, output):
200 ## html ignores json
201 #return []
202
203 #def render_display_format_javascript(self, output):
204 #return [output.javascript]
205
206 74 def meta2str(self, meta):
207 75 "transform metadata dict (containing slides delimiters) to string "
208 76 try:
209 77 meta_tuple = meta[u'slideshow'].items()
210 78 except KeyError as e: # if there is not slideshow metadata
211 79 meta_tuple = [(u'slide_type', u'untouched')]
212 80 meta_list = [[x + ' = ' + unicode(y)] for x, y in meta_tuple]
213 81 return u'\n'.join(list(itertools.chain(*meta_list)))
214 82
215 83 def convert(self, cell_separator='\n'):
216 84 """
217 85 Specific method to converts notebook to a string representation.
218 86
219 87 Parameters
220 88 ----------
221 89 cell_separator : string
222 90 Character or string to join cells with. Default is "\n"
223 91
224 92 Returns
225 93 -------
226 94 out : string
227 95 """
228 96
229 97 lines = []
230 98 lines.extend(self.optional_header())
231 99 begin = ['<div class="reveal"><div class="slides">']
232 100 lines.extend(begin)
233 101 slides_list = self.build_slides()
234 102 lines.extend(slides_list)
235 103 end = ['</div></div>']
236 104 lines.extend(end)
237 105 lines.extend(self.optional_footer())
238 106 return u'\n'.join(lines)
239 107
240 108 def clean_text(self, cell_separator='\n'):
241 109 "clean and reorganize the text list to be slided"
242 110 text = self.main_body(cell_separator)
243 111 self.delim = [u'slide_type = untouched',
244 112 u'slide_type = -',
245 113 u'slide_type = header_slide',
246 114 u'slide_type = slide',
247 115 u'slide_type = fragment',
248 116 u'slide_type = skip']
249 117 text_cell_render = \
250 118 u'<div class="text_cell_render border-box-sizing rendered_html">'
251 119 for i, j in enumerate(text):
252 120 if j in self.delim and text[i - 1] == text_cell_render:
253 121 if j == self.delim[0]:
254 122 text[i - 1] = self.delim[0]
255 123 elif j == self.delim[1]:
256 124 text[i - 1] = self.delim[1]
257 125 elif j == self.delim[2]:
258 126 text[i - 1] = self.delim[2]
259 127 elif j == self.delim[3]:
260 128 text[i - 1] = self.delim[3]
261 129 elif j == self.delim[4]:
262 130 text[i - 1] = self.delim[4]
263 131 else:
264 132 text[i - 1] = self.delim[5]
265 133 text[i] = text_cell_render
266 134 text[0] = u'slide_type = header_slide' # defensive code
267 135 text.append(u'slide_type = untouched') # to end search of skipped
268 136 return text
269 137
270 138 def build_slides(self):
271 139 "build the slides structure from text list and delimiters"
272 140 text = self.clean_text()
273 141 left = '<section>'
274 142 right = '</section>'
275 143 set_delim = self.delim[:5]
276 144 #elimination of skipped cells
277 145 for i, j in enumerate(text):
278 146 if j == u'slide_type = skip':
279 147 text.pop(i)
280 148 while not text[i] in set_delim:
281 149 text.pop(i)
282 150 # elimination of none names
283 151 for i, j in enumerate(text):
284 152 if j in [u'slide_type = untouched', u'slide_type = -']:
285 153 text.pop(i)
286 154 #generation of slides as a list of list
287 155 slides = [list(x[1]) for x in itertools.groupby(text,
288 156 lambda x: x == u'slide_type = header_slide') if not x[0]]
289 157 for slide in slides:
290 158 slide.insert(0, left)
291 159 slide.append(right)
292 160 # encapsulation of each fragment
293 161 for i, j in enumerate(slide):
294 162 if j == u'slide_type = fragment':
295 163 slide.pop(i)
296 164 slide[i] = slide[i][:4] + ' class="fragment"' + slide[i][4:]
297 165 # encapsulation of each nested slide
298 166 if u'slide_type = slide' in slide:
299 167 slide.insert(0, '<section>')
300 168 slide.append('</section>')
301 169 for i, j in enumerate(slide):
302 170 if j == u'slide_type = slide':
303 171 slide[i] = right + left
304 172 return list(itertools.chain(*slides))
305 173
306 174 def save(self, outfile=None, encoding=None):
307 175 "read and parse notebook into self.nb"
308 176 if outfile is None:
309 177 outfile = self.outbase + '_slides.' + 'html'
310 178 if encoding is None:
311 179 encoding = self.default_encoding
312 180 with io.open(outfile, 'w', encoding=encoding) as f:
313 181 f.write(self.output)
314 182 return os.path.abspath(outfile)
315 183
316 184 def template_read(self):
317 185 "read the reveal_template.html"
318 186 here = os.path.split(os.path.realpath(__file__))[0]
319 187 reveal_template = os.path.join(here, '..', 'templates',
320 188 'reveal_base.html')
321 189 with io.open(reveal_template, 'r', encoding='utf-8') as f:
322 190 template = f.readlines()
323 191 template = [s.strip() for s in template]
324 192 return template
325 193
326 194 def template_split(self):
327 195 "split the reveal_template.html in header and footer lists"
328 196 temp = self.template_read()
329 197 splitted_temp = [list(x[1]) for x in itertools.groupby(temp,
330 198 lambda x: x == u'%slides%') if not x[0]]
331 199 return splitted_temp
332 200
333 201 def optional_header(self):
334 202 optional_header_body = self.template_split()
335 203 return optional_header_body[0]
336 204
337 205 def optional_footer(self):
338 206 optional_footer_body = self.template_split()
339 207 return optional_footer_body[1] No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now