Snippets

Adam Labadorf jupyter reveal.js presentation tool

You are viewing an old version of this snippet. View the current version.
Revised by Adam Labadorf f10ed58
import base64
from IPython.display import HTML, Markdown, display
import functools
import io
from matplotlib.figure import Figure
import os
from subprocess import Popen, PIPE


class Tag(object):
    def __init__(self, tag, *elems, **attrs):
        self.tag = tag
        self.content = elems
        # special cases, e.g. can't use class as a kwarg
        if 'cl' in attrs:
            attrs['class'] = attrs['cl']
            del attrs['cl']
        self.attrs = attrs

    def _bytes_to_base64(self,b) :
        b64 = base64.b64encode(b).decode('utf8')
        return b64

    def render(self):
        inner = ''
        for elem in self.content:
            if isinstance(elem, str):
                inner += elem
            elif isinstance(elem, Tag):
                inner += elem.render()
            elif isinstance(elem, list) or isinstance(elem, tuple):
                raise Exception('dont pass lists as tag elements')
            elif isinstance(elem, Figure):  # render as
                from io import BytesIO
                figfile = BytesIO()
                elem.savefig(figfile, format='png')
                figfile.seek(0)  # rewind to beginning of file
                import base64
                inner += '<img src="data:image/png;base64,{}"></img>'.format(
                    self._bytes_to_base64(figfile))
            elif isinstance(elem, bytes): # assume bytes objects are images
                inner += '<img src="data:image/png;base64,{}"></img>'.format(
                    self._bytes_to_base64(elem))
            elif elem == None:
                pass  # sure, whatever
            else:
                print(elem.render())
                raise Exception('invalid content: {}', self.content)
        return '<{tag}{attrs}>{content}</{tag}>'.format(
            tag=self.tag, attrs=''.join(' {}="{}"'.format(*_) for _ in self.attrs.items()), content=inner)


def tag(tag, **kwargs):
    return functools.partial(Tag, tag, **kwargs)


section = tag('section')
h1 = tag('h1')
h2 = tag('h2')
h3 = tag('h3')
h4 = tag('h4')
ul = tag('ul')
ol = tag('ol')
li = tag('li')
lif = tag('li', cl='fragment')
span = tag('span')
spanf = tag('span', cl='fragment')


class Reveal(object):
    tmpl = '''<!doctype html>
    <html>
            <head>
                    <meta charset="utf-8">
                    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

                    <title>reveal.js</title>

                    <link rel="stylesheet" href="css/reveal.css">
                    <link rel="stylesheet" href="css/theme/black.css">

                    <!-- Theme used for syntax highlighting of code -->
                    <link rel="stylesheet" href="lib/css/zenburn.css">

                    <!-- Printing and PDF exports -->
                    <script>
                            var link = document.createElement( 'link' );
                            link.rel = 'stylesheet';
                            link.type = 'text/css';
                            link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
                            document.getElementsByTagName( 'head' )[0].appendChild( link );
                    </script>
            </head>
            <body>
                    <div class="reveal">
                            <div class="slides">
                                   {content}
                            </div>
                    </div>

                    <script src="lib/js/head.min.js"></script>
                    <script src="js/reveal.js"></script>

                    <script>
                            // More info https://github.com/hakimel/reveal.js#configuration
                            Reveal.initialize({{
                                    history: true,

                                    // More info https://github.com/hakimel/reveal.js#dependencies
                                    dependencies: [
                                            {{ src: 'plugin/markdown/marked.js' }},
                                            {{ src: 'plugin/markdown/markdown.js' }},
                                            {{ src: 'plugin/notes/notes.js', async: true }},
                                            {{ src: 'plugin/highlight/highlight.js', async: true, callback: function() {{ hljs.initHighlightingOnLoad(); }} }}
                                    ]
                            }});
                    </script>
            </body>
    </html>'''

    def __init__(self, fn, *content, title='title', debug=False):
        self.content = content
        # terrible, but whatevs
        src = 'https://github.com/hakimel/reveal.js/archive/3.4.1.tar.gz'
        panoct_fn = 'reveal.js-{}'.format(src.split('/')[-1])
        if not os.path.exists(panoct_fn) :
          stdout, stderr = Popen('wget {} -O {}'.format(src,panoct_fn),
                shell=True,stdout=PIPE,stderr=PIPE).communicate()
          debug and print(stderr)

          stdout, stderr = Popen('tar xzf {}'.format(panoct_fn),
            shell=True,stdout=PIPE,stderr=PIPE).communicate()
          debug and print(stderr)

        self.baseurl = os.path.splitext(fn)[0]
        self.fn = '{}/{}'.format(self.baseurl, fn)

    def render(self):
        return Reveal.tmpl.format(
            content=''.join(_.render() for _ in self.content), baseurl=self.baseurl
        )

    def save(self):
        with open(self.fn, 'wt') as fp:
            fp.write(self.render())
        display(Markdown('[{fn}]({fn})'.format(
            baseurl=self.baseurl, fn=self.fn)))

    publish_modes = ('SSH',)
    def publish(self,dest,mode='SSH') :
        if mode not in publish_modes :
            raise Exception('mode must be one of {}'.format(publish_modes))

        if mode == 'SSH' :
            ssh_p = Popen('scp -r {} {}'.format(self.baseurl,dest)
                    ,stdout=PIPE
                    ,stderr=PIPE
                    ,shell=True
            )
            stdout, stderr = ssh_p.communicate()
            debug and print(stdout)
            debug and print(stderr)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.