##// END OF EJS Templates
Added ipython styling through a method inside the converter. Modified the template to adjust to the new method. Rewritten of some css slyling through reveal_html.css.
damianavila -
Show More
@@ -0,0 +1,27 b''
1 /* Overrides of notebook CSS for static HTML export
2
3 */
4
5 .reveal {
6 font-size: 20px;
7 }
8 .reveal pre {
9 width: 100%;
10 padding: 0.2em;
11 margin: 0px auto;
12 font-size: 0.8em;
13 box-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
14 }
15 div.prompt {
16 width: 11ex;
17 padding: 0.0em;
18 margin: 0px;
19 font-family: monospace;
20 }
21 div.output_subarea {
22 padding: 0.0em 0.0em 0.0em 0.0em;
23 }
24 div.output_prompt {
25 /* 5px right shift to account for margin in parent container */
26 margin: 0 5px 0 -5px;
27 }
@@ -1,207 +1,245 b''
1 from __future__ import absolute_import
1 from __future__ import absolute_import
2
2
3 from converters.html import ConverterHTML
3 from converters.html import ConverterHTML
4 from converters.utils import text_cell
4 from converters.utils import text_cell
5 from converters.utils import highlight, coalesce_streams
5 from converters.utils import highlight, coalesce_streams
6
7 from IPython.utils import path
6 from markdown import markdown
8 from markdown import markdown
7
9
8 import os
10 import os
9 import io
11 import io
10 import itertools
12 import itertools
11
13
12
14
13 class ConverterReveal(ConverterHTML):
15 class ConverterReveal(ConverterHTML):
14 #"""
16 #"""
15 #Convert a notebook to a html slideshow.
17 #Convert a notebook to a html slideshow.
16
18
17 #It generates a static html slideshow based reveal.js.
19 #It generates a static html slideshow based reveal.js.
18 #The delimiters for each "Header slide", "Slide"", and "Fragment"
20 #The delimiters for each "Header slide", "Slide"", and "Fragment"
19 #are retrieved from the 'slideshow' metadata.
21 #are retrieved from the 'slideshow' metadata.
20 #"""
22 #"""
21
23
22 @text_cell
24 @text_cell
23 def render_heading(self, cell):
25 def render_heading(self, cell):
24 marker = cell.level
26 marker = cell.level
25 return [self.meta2str(cell.metadata),
27 return [self.meta2str(cell.metadata),
26 u'<h{1}>\n {0}\n</h{1}>'.format(cell.source, marker)]
28 u'<h{1}>\n {0}\n</h{1}>'.format(cell.source, marker)]
27
29
28 def render_code(self, cell):
30 def render_code(self, cell):
29 if not cell.input:
31 if not cell.input:
30 return []
32 return []
31
33
32 lines = []
34 lines = []
33 meta_code = self.meta2str(cell.metadata)
35 meta_code = self.meta2str(cell.metadata)
34 lines.extend([meta_code])
36 lines.extend([meta_code])
35
37
36 lines.extend(['<div class="cell border-box-sizing code_cell vbox">'])
38 lines.extend(['<div class="cell border-box-sizing code_cell vbox">'])
37
39
38 lines.append('<div class="input hbox">')
40 lines.append('<div class="input hbox">')
39 n = self._get_prompt_number(cell)
41 n = self._get_prompt_number(cell)
40 lines.append(
42 lines.append(
41 '<div class="prompt input_prompt">In&nbsp;[%s]:</div>' % n
43 '<div class="prompt input_prompt">In&nbsp;[%s]:</div>' % n
42 )
44 )
43 lines.append('<div class="input_area box-flex1">')
45 lines.append('<div class="input_area box-flex1">')
44 lines.append(highlight(cell.input))
46 lines.append(highlight(cell.input))
45 lines.append('</div>') # input_area
47 lines.append('</div>') # input_area
46 lines.append('</div>') # input
48 lines.append('</div>') # input
47
49
48 if cell.outputs:
50 if cell.outputs:
49 lines.append('<div class="vbox output_wrapper">')
51 lines.append('<div class="vbox output_wrapper">')
50 lines.append('<div class="output vbox">')
52 lines.append('<div class="output vbox">')
51
53
52 for output in coalesce_streams(cell.outputs):
54 for output in coalesce_streams(cell.outputs):
53 conv_fn = self.dispatch(output.output_type)
55 conv_fn = self.dispatch(output.output_type)
54 lines.extend(conv_fn(output))
56 lines.extend(conv_fn(output))
55
57
56 lines.append('</div>') # output
58 lines.append('</div>') # output
57 lines.append('</div>') # output_wrapper
59 lines.append('</div>') # output_wrapper
58
60
59 lines.append('</div>') # cell
61 lines.append('</div>') # cell
60
62
61 return lines
63 return lines
62
64
63 @text_cell
65 @text_cell
64 def render_markdown(self, cell):
66 def render_markdown(self, cell):
65 return [self.meta2str(cell.metadata), markdown(cell.source)]
67 return [self.meta2str(cell.metadata), markdown(cell.source)]
66
68
67 def render_raw(self, cell):
69 def render_raw(self, cell):
68 if self.raw_as_verbatim:
70 if self.raw_as_verbatim:
69 return [self.in_tag('pre', self.meta2str(cell.metadata)),
71 return [self.in_tag('pre', self.meta2str(cell.metadata)),
70 self.in_tag('pre', cell.source)]
72 self.in_tag('pre', cell.source)]
71 else:
73 else:
72 return [self.meta2str(cell.metadata), cell.source]
74 return [self.meta2str(cell.metadata), cell.source]
73
75
74 def meta2str(self, meta):
76 def meta2str(self, meta):
75 "transform metadata dict (containing slides delimiters) to string "
77 "transform metadata dict (containing slides delimiters) to string "
76 try:
78 try:
77 meta_tuple = meta[u'slideshow'].items()
79 meta_tuple = meta[u'slideshow'].items()
78 except KeyError as e: # if there is not slideshow metadata
80 except KeyError as e: # if there is not slideshow metadata
79 meta_tuple = [(u'slide_type', u'untouched')]
81 meta_tuple = [(u'slide_type', u'untouched')]
80 meta_list = [[x + ' = ' + unicode(y)] for x, y in meta_tuple]
82 meta_list = [[x + ' = ' + unicode(y)] for x, y in meta_tuple]
81 return u'\n'.join(list(itertools.chain(*meta_list)))
83 return u'\n'.join(list(itertools.chain(*meta_list)))
82
84
83 def convert(self, cell_separator='\n'):
85 def convert(self, cell_separator='\n'):
84 """
86 """
85 Specific method to converts notebook to a string representation.
87 Specific method to converts notebook to a string representation.
86
88
87 Parameters
89 Parameters
88 ----------
90 ----------
89 cell_separator : string
91 cell_separator : string
90 Character or string to join cells with. Default is "\n"
92 Character or string to join cells with. Default is "\n"
91
93
92 Returns
94 Returns
93 -------
95 -------
94 out : string
96 out : string
95 """
97 """
96
98
97 lines = []
99 lines = []
98 lines.extend(self.optional_header())
100 lines.extend(self.optional_header())
99 begin = ['<div class="reveal"><div class="slides">']
101 begin = ['<div class="reveal"><div class="slides">']
100 lines.extend(begin)
102 lines.extend(begin)
101 slides_list = self.build_slides()
103 slides_list = self.build_slides()
102 lines.extend(slides_list)
104 lines.extend(slides_list)
103 end = ['</div></div>']
105 end = ['</div></div>']
104 lines.extend(end)
106 lines.extend(end)
105 lines.extend(self.optional_footer())
107 lines.extend(self.optional_footer())
106 return u'\n'.join(lines)
108 return u'\n'.join(lines)
107
109
108 def clean_text(self, cell_separator='\n'):
110 def clean_text(self, cell_separator='\n'):
109 "clean and reorganize the text list to be slided"
111 "clean and reorganize the text list to be slided"
110 text = self.main_body(cell_separator)
112 text = self.main_body(cell_separator)
111 self.delim = [u'slide_type = untouched',
113 self.delim = [u'slide_type = untouched',
112 u'slide_type = -',
114 u'slide_type = -',
113 u'slide_type = header_slide',
115 u'slide_type = header_slide',
114 u'slide_type = slide',
116 u'slide_type = slide',
115 u'slide_type = fragment',
117 u'slide_type = fragment',
116 u'slide_type = skip']
118 u'slide_type = skip']
117 text_cell_render = \
119 text_cell_render = \
118 u'<div class="text_cell_render border-box-sizing rendered_html">'
120 u'<div class="text_cell_render border-box-sizing rendered_html">'
119 for i, j in enumerate(text):
121 for i, j in enumerate(text):
120 if j in self.delim and text[i - 1] == text_cell_render:
122 if j in self.delim and text[i - 1] == text_cell_render:
121 if j == self.delim[0]:
123 if j == self.delim[0]:
122 text[i - 1] = self.delim[0]
124 text[i - 1] = self.delim[0]
123 elif j == self.delim[1]:
125 elif j == self.delim[1]:
124 text[i - 1] = self.delim[1]
126 text[i - 1] = self.delim[1]
125 elif j == self.delim[2]:
127 elif j == self.delim[2]:
126 text[i - 1] = self.delim[2]
128 text[i - 1] = self.delim[2]
127 elif j == self.delim[3]:
129 elif j == self.delim[3]:
128 text[i - 1] = self.delim[3]
130 text[i - 1] = self.delim[3]
129 elif j == self.delim[4]:
131 elif j == self.delim[4]:
130 text[i - 1] = self.delim[4]
132 text[i - 1] = self.delim[4]
131 else:
133 else:
132 text[i - 1] = self.delim[5]
134 text[i - 1] = self.delim[5]
133 text[i] = text_cell_render
135 text[i] = text_cell_render
134 text[0] = u'slide_type = header_slide' # defensive code
136 text[0] = u'slide_type = header_slide' # defensive code
135 text.append(u'slide_type = untouched') # to end search of skipped
137 text.append(u'slide_type = untouched') # to end search of skipped
136 return text
138 return text
137
139
138 def build_slides(self):
140 def build_slides(self):
139 "build the slides structure from text list and delimiters"
141 "build the slides structure from text list and delimiters"
140 text = self.clean_text()
142 text = self.clean_text()
141 left = '<section>'
143 left = '<section>'
142 right = '</section>'
144 right = '</section>'
143 set_delim = self.delim[:5]
145 set_delim = self.delim[:5]
144 #elimination of skipped cells
146 #elimination of skipped cells
145 for i, j in enumerate(text):
147 for i, j in enumerate(text):
146 if j == u'slide_type = skip':
148 if j == u'slide_type = skip':
147 text.pop(i)
149 text.pop(i)
148 while not text[i] in set_delim:
150 while not text[i] in set_delim:
149 text.pop(i)
151 text.pop(i)
150 # elimination of none names
152 # elimination of none names
151 for i, j in enumerate(text):
153 for i, j in enumerate(text):
152 if j in [u'slide_type = untouched', u'slide_type = -']:
154 if j in [u'slide_type = untouched', u'slide_type = -']:
153 text.pop(i)
155 text.pop(i)
154 #generation of slides as a list of list
156 #generation of slides as a list of list
155 slides = [list(x[1]) for x in itertools.groupby(text,
157 slides = [list(x[1]) for x in itertools.groupby(text,
156 lambda x: x == u'slide_type = header_slide') if not x[0]]
158 lambda x: x == u'slide_type = header_slide') if not x[0]]
157 for slide in slides:
159 for slide in slides:
158 slide.insert(0, left)
160 slide.insert(0, left)
159 slide.append(right)
161 slide.append(right)
160 # encapsulation of each fragment
162 # encapsulation of each fragment
161 for i, j in enumerate(slide):
163 for i, j in enumerate(slide):
162 if j == u'slide_type = fragment':
164 if j == u'slide_type = fragment':
163 slide.pop(i)
165 slide.pop(i)
164 slide[i] = slide[i][:4] + ' class="fragment"' + slide[i][4:]
166 slide[i] = slide[i][:4] + ' class="fragment"' + slide[i][4:]
165 # encapsulation of each nested slide
167 # encapsulation of each nested slide
166 if u'slide_type = slide' in slide:
168 if u'slide_type = slide' in slide:
167 slide.insert(0, '<section>')
169 slide.insert(0, '<section>')
168 slide.append('</section>')
170 slide.append('</section>')
169 for i, j in enumerate(slide):
171 for i, j in enumerate(slide):
170 if j == u'slide_type = slide':
172 if j == u'slide_type = slide':
171 slide[i] = right + left
173 slide[i] = right + left
172 return list(itertools.chain(*slides))
174 return list(itertools.chain(*slides))
173
175
174 def save(self, outfile=None, encoding=None):
176 def save(self, outfile=None, encoding=None):
175 "read and parse notebook into self.nb"
177 "read and parse notebook into self.nb"
176 if outfile is None:
178 if outfile is None:
177 outfile = self.outbase + '_slides.' + 'html'
179 outfile = self.outbase + '_slides.' + 'html'
178 if encoding is None:
180 if encoding is None:
179 encoding = self.default_encoding
181 encoding = self.default_encoding
180 with io.open(outfile, 'w', encoding=encoding) as f:
182 with io.open(outfile, 'w', encoding=encoding) as f:
181 f.write(self.output)
183 f.write(self.output)
182 return os.path.abspath(outfile)
184 return os.path.abspath(outfile)
183
185
186 def header_body(self):
187 """Return the body of the header as a list of strings."""
188
189 from pygments.formatters import HtmlFormatter
190
191 header = []
192 static = os.path.join(path.get_ipython_package_dir(),
193 'frontend', 'html', 'notebook', 'static',
194 )
195 here = os.path.split(os.path.realpath(__file__))[0]
196 css = os.path.join(static, 'css')
197 for sheet in [
198 # do we need jquery and prettify?
199 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
200 # 'jquery-ui.min.css'),
201 # os.path.join(static, 'prettify', 'prettify.css'),
202 os.path.join(css, 'boilerplate.css'),
203 os.path.join(css, 'fbm.css'),
204 os.path.join(css, 'notebook.css'),
205 os.path.join(css, 'renderedhtml.css'),
206 # our overrides:
207 os.path.join(here, '..', 'css', 'reveal_html.css'),
208 ]:
209 header.extend(self._stylesheet(sheet))
210
211 # pygments css
212 pygments_css = HtmlFormatter().get_style_defs('.highlight')
213 header.extend(['<meta charset="UTF-8">'])
214 header.extend(self.in_tag('style', pygments_css,
215 dict(type='"text/css"')))
216
217 return header
218
184 def template_read(self):
219 def template_read(self):
185 "read the reveal_template.html"
220 "read the reveal_template.html"
186 here = os.path.split(os.path.realpath(__file__))[0]
221 here = os.path.split(os.path.realpath(__file__))[0]
187 reveal_template = os.path.join(here, '..', 'templates',
222 reveal_template = os.path.join(here, '..', 'templates',
188 'reveal_base.html')
223 'reveal_base.html')
189 with io.open(reveal_template, 'r', encoding='utf-8') as f:
224 with io.open(reveal_template, 'r', encoding='utf-8') as f:
190 template = f.readlines()
225 template = f.readlines()
191 template = [s.strip() for s in template]
226 template = [s.strip() for s in template]
192 return template
227 return template
193
228
194 def template_split(self):
229 def template_split(self):
195 "split the reveal_template.html in header and footer lists"
230 "split the reveal_template.html in header and footer lists"
196 temp = self.template_read()
231 temp = self.template_read()
197 splitted_temp = [list(x[1]) for x in itertools.groupby(temp,
232 splitted_temp = [list(x[1]) for x in itertools.groupby(temp,
198 lambda x: x == u'%slides%') if not x[0]]
233 lambda x: x == u'%slides%') if not x[0]]
199 return splitted_temp
234 return splitted_temp
200
235
201 def optional_header(self):
236 def optional_header(self):
202 optional_header_body = self.template_split()
237 optional_header_body = self.template_split()
203 return optional_header_body[0]
238 #return optional_header_body[0]
239 return ['<!DOCTYPE html>', '<html>', '<head>'] + \
240 optional_header_body[0] + self.header_body() + \
241 ['</head>', '<body>']
204
242
205 def optional_footer(self):
243 def optional_footer(self):
206 optional_footer_body = self.template_split()
244 optional_footer_body = self.template_split()
207 return optional_footer_body[1] No newline at end of file
245 return optional_footer_body[1] + ['</body>', '</html>'] No newline at end of file
@@ -1,67 +1,58 b''
1 <!DOCTYPE html>
1
2 <html>
3 <head>
4 <meta charset="utf-8" />
2 <meta charset="utf-8" />
5 <meta http-equiv="X-UA-Compatible" content="chrome=1">
3 <meta http-equiv="X-UA-Compatible" content="chrome=1">
6
4
7 <meta name="apple-mobile-web-app-capable" content="yes" />
5 <meta name="apple-mobile-web-app-capable" content="yes" />
8 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
6 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
9
7
10 <link rel="stylesheet" href="reveal/css/reveal.css">
8 <link rel="stylesheet" href="reveal/css/reveal.css">
11 <link rel="stylesheet" href="reveal/css/theme/default.css" id="theme">
9 <link rel="stylesheet" href="reveal/css/theme/default.css" id="theme">
12
10
13 <link rel="stylesheet" href="css/ipython.css">
14
15 <!-- For syntax highlighting -->
11 <!-- For syntax highlighting -->
16 <link rel="stylesheet" href="reveal/lib/css/zenburn.css">
12 <link rel="stylesheet" href="reveal/lib/css/zenburn.css">
17
13
18 <!-- If the query includes 'print-pdf', use the PDF print sheet -->
14 <!-- If the query includes 'print-pdf', use the PDF print sheet -->
19 <script>
15 <script>
20 document.write( '<link rel="stylesheet" href="reveal/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
16 document.write( '<link rel="stylesheet" href="reveal/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
21 </script>
17 </script>
22
18
23 <!--[if lt IE 9]>
19 <!--[if lt IE 9]>
24 <script src="reveal/lib/js/html5shiv.js"></script>
20 <script src="reveal/lib/js/html5shiv.js"></script>
25 <![endif]-->
21 <![endif]-->
26
22
27 </head>
28
29 %slides%
23 %slides%
30
24
31 <script src="reveal/lib/js/head.min.js"></script>
25 <script src="reveal/lib/js/head.min.js"></script>
32
26
33 <script src="reveal/js/reveal.min.js"></script>
27 <script src="reveal/js/reveal.min.js"></script>
34
28
35 <script>
29 <script>
36
30
37 // Full list of configuration options available here: https://github.com/hakimel/reveal.js#configuration
31 // Full list of configuration options available here: https://github.com/hakimel/reveal.js#configuration
38 Reveal.initialize({
32 Reveal.initialize({
39 controls: true,
33 controls: true,
40 progress: true,
34 progress: true,
41 history: true,
35 history: true,
42
36
43 theme: Reveal.getQueryHash().theme || 'simple', // available themes are in /css/theme
37 theme: Reveal.getQueryHash().theme || 'simple', // available themes are in /css/theme
44 transition: Reveal.getQueryHash().transition || 'linear', // default/cube/page/concave/zoom/linear/none
38 transition: Reveal.getQueryHash().transition || 'linear', // default/cube/page/concave/zoom/linear/none
45
39
46 // Optional libraries used to extend on reveal.js
40 // Optional libraries used to extend on reveal.js
47 dependencies: [
41 dependencies: [
48 { src: 'reveal/lib/js/classList.js', condition: function() { return !document.body.classList; } },
42 { src: 'reveal/lib/js/classList.js', condition: function() { return !document.body.classList; } },
49 { src: 'reveal/plugin/markdown/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
50 { src: 'reveal/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
51 { src: 'reveal/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
43 { src: 'reveal/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
52 { src: 'reveal/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
44 { src: 'reveal/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
53 { src: 'reveal/plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
45 { src: 'reveal/plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
54 { src: 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML', async: true },
46 { src: 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML', async: true },
55 { src: 'js/revealmathjax.js', async: true}
47 { src: 'js/revealmathjax.js', async: true}
56 ]
48 ]
57 });
49 });
58 </script>
50 </script>
59
51
60 <script>
52 <script>
61 Reveal.addEventListener( 'slidechanged', function( event ) {
53 Reveal.addEventListener( 'slidechanged', function( event ) {
62 MathJax.Hub.Rerender(event.currentSlide);
54 MathJax.Hub.Rerender(event.currentSlide);
63 });
55 });
64 </script>
56 </script>
65
57
66 </body>
58
67 </html>
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (739 lines changed) Show them Hide them
General Comments 0
You need to be logged in to leave comments. Login now