##// END OF EJS Templates
Added support to render code properly
damianavila -
Show More
@@ -1,158 +1,185 b''
1 1 from converters.markdown import ConverterMarkdown
2 2 from IPython.utils.text import indent
3 3 import io
4 4 import os
5 5 import itertools
6 6
7 7 class ConverterReveal(ConverterMarkdown):
8 8 """
9 9 Convert a notebook to a html slideshow.
10 10
11 11 It generates a static html slideshow based in markdown and reveal.js.
12 12 The delimiters for each slide, subslide, and fragment are retrieved
13 13 from the 'slideshow' metadata.
14 14 """
15 15
16 16 def __init__(self, infile, highlight_source=False, show_prompts=True,
17 17 inline_prompt=True):
18 18 super(ConverterReveal, self).__init__(infile)
19 19 self.highlight_source = highlight_source
20 20 self.show_prompts = show_prompts
21 21 self.inline_prompt = inline_prompt
22 22
23 23 def switch_meta(self, m_list):
24 24 "sort order m_list to [new_section, new_subsection, new_fragment]"
25 25 if len(m_list) > 1:
26 26 # do not sort when m_list = [new_subsection, new_fragment]
27 27 if not (len(m_list) == 2 and m_list[1] == [u'new_fragment = True']):
28 28 m_list[0], m_list[1] = m_list[1], m_list[0]
29 29 return m_list
30 30
31 31 def meta2str(self, meta):
32 32 "transform metadata dict (containing slides delimiters) to string "
33 33 try:
34 34 meta_tuple = meta[u'slideshow'].items()
35 35 except KeyError as e:
36 36 meta_tuple = () # if there is not slideshow metadata
37 37 meta_list = [[x + ' = ' + unicode(y)] for x, y in meta_tuple]
38 38 meta_list = self.switch_meta(meta_list)
39 39 return u'\n'.join(list(itertools.chain(*meta_list)))
40 40
41 41 def render_heading(self, cell):
42 42 return [self.meta2str(cell.metadata),
43 43 '{0} {1}'.format('#' * cell.level, cell.source), '']
44 44
45 def render_code(self, cell):
46 if not cell.input:
47 return []
48 lines = []
49 meta_code = self.meta2str(cell.metadata)
50 lines.extend([meta_code])
51 lines.extend(['<!-- hack -->']) # to be proper parsed
52 n = self._get_prompt_number(cell)
53 if self.show_prompts and not self.inline_prompt:
54 lines.extend(['*In[%s]:*' % n, ''])
55 if self.show_prompts and self.inline_prompt:
56 prompt = 'In[%s]: ' % n
57 input_lines = cell.input.split('\n')
58 src = (prompt + input_lines[0] + '\n' +
59 indent('\n'.join(input_lines[1:]), nspaces=len(prompt)))
60 else:
61 src = cell.input
62 src = highlight(src) if self.highlight_source else indent(src)
63 lines.extend([src, ''])
64 if cell.outputs and self.show_prompts and not self.inline_prompt:
65 lines.extend(['*Out[%s]:*' % n, ''])
66 for output in cell.outputs:
67 conv_fn = self.dispatch(output.output_type)
68 lines.extend(conv_fn(output))
69 #lines.append('')
70 return lines
71
45 72 def render_markdown(self, cell):
46 73 return [self.meta2str(cell.metadata), cell.source, '']
47 74
48 75 def render_raw(self, cell):
49 76 if self.raw_as_verbatim:
50 77 return [indent(self.meta2str(cell.metadata)),
51 78 indent(cell.source), '']
52 79 else:
53 80 return [self.meta2str(cell.metadata), cell.source, '']
54 81
55 82 def convert(self, cell_separator='\n'):
56 83 """
57 84 Specific method to converts notebook to a string representation.
58 85
59 86 Parameters
60 87 ----------
61 88 cell_separator : string
62 89 Character or string to join cells with. Default is "\n"
63 90
64 91 Returns
65 92 -------
66 93 out : string
67 94 """
68 95
69 96 lines = []
70 97 lines.extend(self.optional_header())
71 98 begin = ['<div class="reveal"><div class="slides">']
72 99 lines.extend(begin)
73 100 slides_list = self.build_slides(cell_separator)
74 101 lines.extend(slides_list)
75 102 end = ['</div></div>']
76 103 lines.extend(end)
77 104 lines.extend(self.optional_footer())
78 105 return u'\n'.join(lines)
79 106
80 107 def build_slides(self, cell_separator='\n'):
81 108 "build the slides structure from text list and delimiters"
82 109 text = self.main_body(cell_separator)
83 110 delim_false = [u'new_section = False',
84 111 u'new_subsection = False',
85 112 u'new_fragment = False']
86 113 text = [x for x in text if not x in delim_false]
87 114 left = '<section data-markdown><script type="text/template">'
88 115 right = '</script></section>'
89 116 # build lists representing each slide delimited by new_section
90 117 slides = [list(x[1]) for x in itertools.groupby(text,
91 118 lambda x: x == u'new_section = True') if not x[0]]
92 119 for slide in slides:
93 120 slide.insert(0, u'') # for proper interline in html file
94 121 slide.insert(0, left)
95 122 slide.append(right)
96 123 # build each vertical slide delimited by new_subsection
97 124 if slide[2] == u'new_subsection = True':
98 125 slide.pop(2)
99 126 slide.insert(0, '<section>')
100 127 slide.append('</section>')
101 128 for i, j in enumerate(slide):
102 129 if j == u'new_subsection = True':
103 130 slide[i] = right + left
104 131 slide.insert(i + 1, u'') # for proper interline
105 132 #defensive: if user do not begin new_subsection with a new_section
106 133 elif slide[4] == u'new_subsection = True':
107 134 slide[4] = right
108 135 slide.insert(5, u'') # for proper interline
109 136 slide.insert(5, left)
110 137 slide.insert(5, '<section>')
111 138 slide.append('</section>')
112 139 for i, j in enumerate(slide):
113 140 if j == u'new_subsection = True':
114 141 slide[i] = right + left
115 142 slide.insert(i + 1, u'') # for proper interline
116 143 # build each fragment delimited by new_fragment
117 144 for i, j in enumerate(slide):
118 145 if j == u'new_fragment = True':
119 146 slide[i] = '<p class="fragment">'
120 147 slide[i + 2] = '</p>'
121 148 slide.insert(i + 3, u'') # for proper interline
122 149 return list(itertools.chain(*slides))
123 150
124 151 def save(self, outfile=None, encoding=None):
125 152 "read and parse notebook into self.nb"
126 153 if outfile is None:
127 154 outfile = self.outbase + '_slides.' + 'html'
128 155 if encoding is None:
129 156 encoding = self.default_encoding
130 157 with io.open(outfile, 'w', encoding=encoding) as f:
131 158 f.write(self.output)
132 159 return os.path.abspath(outfile)
133 160
134 161 def template_read(self):
135 162 "read the reveal_template.html"
136 163 here = os.path.split(os.path.realpath(__file__))[0]
137 164 reveal_template = os.path.join(here, '..', 'templates',
138 165 'reveal_base.html')
139 166 with io.open(reveal_template, 'r', encoding='utf-8') as f:
140 167 template = f.readlines()
141 168 template = [s.strip() for s in template]
142 169 return template
143 170
144 171 def template_split(self):
145 172 "split the reveal_template.html in header and footer lists"
146 173 temp = self.template_read()
147 174 splitted_temp = [list(x[1]) for x in itertools.groupby(temp,
148 175 lambda x: x == u'%slides%') if not x[0]]
149 176 return splitted_temp
150 177
151 178 def optional_header(self):
152 179 optional_header_body = self.template_split()
153 180 return optional_header_body[0]
154 181
155 182 def optional_footer(self):
156 183 optional_footer_body = self.template_split()
157 184 return optional_footer_body[1]
158 185
General Comments 0
You need to be logged in to leave comments. Login now