from __future__ import absolute_import
from converters.html import ConverterHTML
from converters.utils import text_cell
from converters.utils import highlight, coalesce_streams
from IPython.utils import path
from markdown import markdown
import os
import io
import itertools
class ConverterReveal(ConverterHTML):
#"""
# Convert a ipython notebook to a html slideshow
# based in reveal.js library.
#"""
@text_cell
def render_heading(self, cell):
marker = cell.level
return [self.meta2str(cell.metadata),
u'\n {0}\n'.format(cell.source, marker)]
def render_code(self, cell):
if not cell.input:
return []
lines = []
meta_code = self.meta2str(cell.metadata)
lines.extend([meta_code])
lines.extend(['
'
for i, j in enumerate(text):
if j in self.delim and text[i - 1] == text_cell_render:
if j == self.delim[0]:
text[i - 1] = self.delim[0]
elif j == self.delim[1]:
text[i - 1] = self.delim[1]
elif j == self.delim[2]:
text[i - 1] = self.delim[2]
elif j == self.delim[3]:
text[i - 1] = self.delim[3]
elif j == self.delim[4]:
text[i - 1] = self.delim[4]
elif j == self.delim[5]:
text[i - 1] = self.delim[5]
else:
text[i - 1] = self.delim[6]
text[i] = text_cell_render
text[0] = u'slide_type = header_slide' # defensive code
text.append(u'slide_type = untouched') # to end search of skipped
return text
def build_slides(self):
"build the slides structure from text list and delimiters"
text = self.clean_text()
left = '
'
notes_start = '
'
set_delim_skip = self.delim[:6] # to skip adjacent skkiped cells
set_delim_notes = self.delim[:5] # to show adjacent speaker notes
#elimination of skipped cells
for i, j in enumerate(text):
if j == u'slide_type = skip':
text.pop(i)
while not text[i] in set_delim_skip:
text.pop(i)
#encapsulation of notes cells
for i, j in enumerate(text):
if j == u'slide_type = notes':
text.pop(i)
temp_list = []
while not text[i] in set_delim_notes:
temp_list.append(text.pop(i))
else:
temp_list.insert(0, notes_start)
temp_list.append(notes_end)
text[i:i] = temp_list
# elimination of none names
for i, j in enumerate(text):
if j in [u'slide_type = untouched', u'slide_type = -']:
text.pop(i)
#generation of slides as a list of list
slides = [list(x[1]) for x in itertools.groupby(text,
lambda x: x == u'slide_type = header_slide') if not x[0]]
for slide in slides:
slide.insert(0, left)
slide.append(right)
# encapsulation of each fragment
for i, j in enumerate(slide):
if j == u'slide_type = fragment':
slide.pop(i)
slide[i] = slide[i][:4] + \
' class="fragment"' + slide[i][4:]
# encapsulation of each nested slide
if u'slide_type = slide' in slide:
slide.insert(0, '
')
for i, j in enumerate(slide):
if j == u'slide_type = slide':
slide[i] = right + left
return list(itertools.chain(*slides))
def render(self):
"read, convert, and save self.infile"
self.notes = self.template_notes()
self.notesjs = self.template_notesjs()
if not hasattr(self, 'nb'):
self.read()
self.output = self.convert()
assert(type(self.output) == unicode)
return self.save()
def save(self, outfile=None, encoding=None):
"read and parse notebook into self.nb"
if outfile is None:
outfile = self.outbase + '_slides.' + 'html'
if encoding is None:
encoding = self.default_encoding
with io.open(outfile, 'w', encoding=encoding) as f:
f.write(self.output)
return os.path.abspath(outfile)
def header_body(self):
"return the body of the header as a list of strings"
from pygments.formatters import HtmlFormatter
header = []
static = os.path.join(path.get_ipython_package_dir(),
'frontend', 'html', 'notebook', 'static',)
here = os.path.split(os.path.realpath(__file__))[0]
css = os.path.join(static, 'css')
for sheet in [
# do we need jquery and prettify?
# os.path.join(static, 'jquery', 'css', 'themes', 'base',
# 'jquery-ui.min.css'),
# os.path.join(static, 'prettify', 'prettify.css'),
os.path.join(css, 'boilerplate.css'),
os.path.join(css, 'fbm.css'),
os.path.join(css, 'notebook.css'),
os.path.join(css, 'renderedhtml.css'),
# our overrides:
os.path.join(here, '..', 'css', 'reveal_html.css'),
]:
header.extend(self._stylesheet(sheet))
# pygments css
pygments_css = HtmlFormatter().get_style_defs('.highlight')
header.extend(['
'])
header.extend(self.in_tag('style', pygments_css,
dict(type='"text/css"')))
return header
def template_read(self, templ):
"read the reveal_template.html"
here = os.path.split(os.path.realpath(__file__))[0]
reveal_template = os.path.join(here, '..', 'templates',
templ)
with io.open(reveal_template, 'r', encoding='utf-8') as f:
template = f.readlines()
template = [s.strip() for s in template]
return template
def template_split(self):
"split the reveal_template.html in header and footer lists"
temp = self.template_read('reveal_base.html')
splitted_temp = [list(x[1]) for x in itertools.groupby(temp,
lambda x: x == u'%slides%') if not x[0]]
return splitted_temp
def template_notesjs(self):
#"split the reveal_template.html in header and footer lists"
temp = self.template_read('notes_base.js')
for i, j in enumerate(temp):
if j == u'%source%':
temp[i] = '\'' + self.outbase + '_notes.html\''
here = os.path.split(os.path.realpath(__file__))[0]
path_js = os.path.join(here, '..', 'js', self.outbase + '_notes.js')
with io.open(path_js, 'w',
encoding=self.default_encoding) as f:
f.write('\n'.join(temp))
return []
def template_notes(self):
#"split the reveal_template.html in header and footer lists"
temp = self.template_read('notes_base.html')
for i, j in enumerate(temp):
if j == u'%source%':
temp[i] = 'src=\"' + self.outbase + '_slides.html\"'
with io.open(self.outbase + '_notes.html', 'w',
encoding=self.default_encoding) as f:
f.write('\n'.join(temp))
return []
def optional_header(self):
optional_header_body = self.template_split()
return ['', '', ''] + \
optional_header_body[0] + self.header_body() + \
['', '']
def optional_footer(self):
optional_footer_body = self.template_split()
for i, j in enumerate(optional_footer_body[1]):
if j == u'%source%':
optional_footer_body[1][i] = \
'src: \'js/' + self.outbase + '_notes.js\''
return optional_footer_body[1] + ['', '']