diff --git a/Slides/__init__.py b/Slides/__init__.py index 33b4c48..6944ecf 100644 --- a/Slides/__init__.py +++ b/Slides/__init__.py @@ -1,5 +1,6 @@ #!/bin/env python import cell_manager import presentation_helper import count_slides +import math_helper diff --git a/Slides/cell_manager.py b/Slides/cell_manager.py index 71ae0ff..f3e04f9 100644 --- a/Slides/cell_manager.py +++ b/Slides/cell_manager.py @@ -1,99 +1,100 @@ #!/bin/env python import os import subprocess import shutil import nbformat ################################################################ class NotFoundNotebooks(Exception): "Could not find the notebooks to treat" ################################################################ def mergeNotebooks(notebook_files, add_cell_number=False, select_cells=None): "Merges several notebooks in a single one named: talk.ipynb" print("Merging notebooks {0}".format(notebook_files)) notebooks = [nbformat.read(f, as_version=4) for f in notebook_files] if len(notebooks) == 0: raise NotFoundNotebooks cells = notebooks[0]['cells'] for n in notebooks[1:]: cells += n['cells'] if select_cells is None: select_cells = set(range(0, len(cells))) select_cells = set(select_cells) discard_cells = set(range(0, len(cells))) - select_cells new_cells = [] for cell_number, c in enumerate(cells): if cell_number in discard_cells: continue # print(c) new_cells.append(c) if add_cell_number: new_cell = nbformat.notebooknode.NotebookNode() new_cell['cell_type'] = 'markdown' new_cell['source'] = 'Cell number {0}'.format(cell_number) new_cell['metadata'] = {} new_cells.append(new_cell) # print(new_cells) notebooks[0]['cells'] = new_cells - nbformat.write(notebooks[0], 'talk.ipynb') ################################################################ def launchSlideServer(options=""): " Launch the HTTP server for reveal slides " reveal_path = './reveal.js' dir_name = os.path.dirname(__file__) slides_config_file = os.path.join(dir_name, 'slides_config.py') - cmd = ('jupyter nbconvert --to=slides --config {1} --post serve ' + - '--ServePostProcessor.open_in_browser=False --reveal-prefix={0} {2} ' + - 'talk.ipynb').format(reveal_path, slides_config_file, options) + cmd = ('jupyter nbconvert --to=slides --config {1} --post serve ' + '--ServePostProcessor.open_in_browser=False' + ' --reveal-prefix={0} {2} talk.ipynb').format( + reveal_path, slides_config_file, options) print cmd subprocess.call(cmd, shell=True) ################################################################ def generateHTML(options=""): " Launch the HTTP server for reveal slides " reveal_path = './reveal.js' dir_name = os.path.dirname(__file__) slides_config_file = os.path.join(dir_name, 'slides_config.py') - cmd = ('jupyter nbconvert --to=slides --config {1} --reveal-prefix={0} {2} ' + - 'talk.ipynb').format(reveal_path, slides_config_file, options) + cmd = ('jupyter nbconvert --to=slides --config {1}' + ' --reveal-prefix={0} {2} talk.ipynb').format( + reveal_path, slides_config_file, options) print cmd subprocess.call(cmd, shell=True) ################################################################ def executeNotebook(filename, options=""): " Request the execution of all cells " print 'execute notebook: ', filename dir_name = os.path.dirname(__file__) slides_config_file = os.path.join(dir_name, 'slides_execute_config.py') - subprocess.call('jupyter nbconvert --to=notebook --output tmp.ipynb --config' + - ' {0} {1}'.format(slides_config_file, filename), shell=True) + subprocess.call('jupyter nbconvert --to=notebook --output tmp.ipynb' + ' --config {0} {1}'.format( + slides_config_file, filename), shell=True) shutil.move('tmp.ipynb', filename) subprocess.call('jupyter trust {0}'.format(filename), shell=True) ################################################################ - diff --git a/Slides/execute_markdown.py b/Slides/execute_markdown.py index 45bc5b8..cf20817 100644 --- a/Slides/execute_markdown.py +++ b/Slides/execute_markdown.py @@ -1,267 +1,263 @@ +#!/bin/env python +################################################################ """Module containing a preprocessor that removes the outputs from code cells""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. +################################################################ import os import re from textwrap import dedent try: from queue import Empty # Py 3 except ImportError: from Queue import Empty # Py 2 from traitlets import List, Unicode, Bool from nbformat.v4 import output_from_msg -from nbconvert.preprocessors import * +from nbconvert.preprocessors import Preprocessor from nbconvert.utils.exceptions import ConversionException from traitlets import Integer class CellExecutionError(ConversionException): """ Custom exception to propagate exceptions that are raised during notebook execution to the caller. This is mostly useful when using nbconvert as a library, since it allows to deal with failures gracefully. """ def __init__(self, traceback): self.traceback = traceback class ExecutePreprocessor(Preprocessor): """ Executes all the cells in a notebook """ - timeout = Integer(30, config=True, - help="The time to wait (in seconds) for output from executions." - ) + timeout = Integer( + 30, config=True, + help="The time to wait (in seconds) for output from executions.") interrupt_on_timeout = Bool( False, config=True, help=dedent( """ If execution of a cell times out, interrupt the kernel and continue executing other cells rather than throwing an error and stopping. """ ) ) allow_errors = Bool( False, config=True, help=dedent( """ If `True`, a `CellExecutionError` is raised if any of the notebook cells raises an exception during execution. Otherwise, execution is continued and the output from the exception is included in the cell output. """ ) ) extra_arguments = List(Unicode()) def preprocess_cells(self, nb, resources): nb_cells = len(nb.cells) for index, cell in enumerate(nb.cells): - print "Doing cell {0}/{1}".format(index,nb_cells) - nb.cells[index], resources = self.preprocess_cell(cell, resources, index) + print "Doing cell {0}/{1}".format(index, nb_cells) + nb.cells[index], resources = self.preprocess_cell(cell, + resources, + index) return nb, resources - def preprocess(self, nb, resources): path = resources.get('metadata', {}).get('path', '') if path == '': path = None from jupyter_client.manager import start_new_kernel kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python') self.log.info("Executing notebook with kernel: %s" % kernel_name) self.km, self.kc = start_new_kernel( kernel_name=kernel_name, extra_arguments=self.extra_arguments, stderr=open(os.devnull, 'w'), cwd=path) self.kc.allow_stdin = False try: nb, resources = self.preprocess_cells(nb, resources) finally: self.kc.stop_channels() self.km.shutdown_kernel(now=True) return nb, resources def preprocess_cell(self, cell, resources, cell_index): """ Apply a transformation on each code cell. See base.py for details. """ if cell.cell_type == 'markdown': - self.run_cell_markdown(cell) + self.run_cell_markdown(cell) return cell, resources if cell.cell_type != 'code': return cell, resources - - outputs = self.run_cell(cell) cell.outputs = outputs if not self.allow_errors: for out in outputs: if out.output_type == 'error': pattern = """\ An error occurred while executing the following cell: ------------------ {cell.source} ------------------ {out.ename}: {out.evalue} """ msg = dedent(pattern).format(out=out, cell=cell) print msg raise CellExecutionError(msg) return cell, resources - def run_cell_markdown(self, cell): - errors = [] + errors = [] if 'variables' not in cell.metadata: cell.metadata.variables = {} - def evaluate_code(code,cell): + def evaluate_code(code, cell): _code = code.group(1) ev = self.run_source(_code) for e in ev[1]: if e['output_type'] == 'display_data': ev = e break if e['output_type'] == 'execute_result': ev = e break - - #print type(ev) - #if type(ev) == tuple: - # print ev - # print ev[1] - + + # print type(ev) + # if type(ev) == tuple: + # print ev + # print ev[1] + if ev.output_type == 'error': cell.metadata.variables[_code] = ev.evalue errors.append(ev.evalue) - if 'data' in ev: + if 'data' in ev: ev = ev['data'] if 'text/html' in ev: cell.metadata.variables[_code] = ev['text/html'] elif 'image/png' in ev: cell.metadata.variables[_code] = r''.format(ev['image/png']) elif 'text/plain' in ev: cell.metadata.variables[_code] = ev['text/plain'] - else: raise Exception('unknown mime type {0} for expression {1}'.format(ev.keys(),_code)) + else: + raise Exception( + 'unknown mime type {0} for expression {1}'.format( + ev.keys(), _code)) return '{{'+_code+'}}' - - #print cell.source - re.sub(r'{{(.*?)}}',lambda c: evaluate_code(c,cell),cell.source) + # print cell.source + re.sub(r'{{(.*?)}}', lambda c: evaluate_code(c, cell), cell.source) if len(errors) > 0: pattern = """\ An error occurred while executing the following cell: ------------------ {0} ------------------ {1} """ msg = dedent(pattern).format(cell.source, "\n".join(errors)) print msg raise CellExecutionError(msg) - #print cell.metadata.variables - #print 'done' - + # print cell.metadata.variables + # print 'done' def run_cell(self, cell): - content,outs = self.run_source(cell.source) + content, outs = self.run_source(cell.source) # set the prompt number for the input and the output if 'execution_count' in content: cell['execution_count'] = content['execution_count'] return outs - - def run_source(self, source): msg_id = self.kc.execute(source) self.log.debug("Executing cell:\n%s", source) # wait for finish, with timeout while True: try: msg = self.kc.shell_channel.get_msg(timeout=self.timeout) except Empty: self.log.error("""Timeout waiting for execute reply (%is). If your cell should take longer than this, you can increase the timeout with: c.ExecutePreprocessor.timeout = SECONDS in jupyter_nbconvert_config.py """ % self.timeout) if self.interrupt_on_timeout: self.log.error("Interrupting kernel") self.km.interrupt_kernel() break else: try: exception = TimeoutError except NameError: exception = RuntimeError raise exception("Cell execution timed out, see log" " for details.") if msg['parent_header'].get('msg_id') == msg_id: break else: # not our reply continue outs = [] while True: try: msg = self.kc.iopub_channel.get_msg(timeout=self.timeout) except Empty: self.log.warn("Timeout waiting for IOPub output") break if msg['parent_header'].get('msg_id') != msg_id: # not an output from our execution continue msg_type = msg['msg_type'] self.log.debug("output: %s", msg_type) content = msg['content'] if msg_type == 'status': if content['execution_state'] == 'idle': break else: continue elif msg_type == 'execute_input': continue elif msg_type == 'clear_output': outs = [] continue elif msg_type.startswith('comm'): continue try: out = output_from_msg(msg) except ValueError: self.log.error("unhandled iopub msg: " + msg_type) else: outs.append(out) - return content,outs - + return content, outs diff --git a/Slides/math_helper.py b/Slides/math_helper.py new file mode 100644 index 0000000..c253aa4 --- /dev/null +++ b/Slides/math_helper.py @@ -0,0 +1,62 @@ +#!/usr/bin/env pyton +################################################################ +import numpy as np +from sympy import latex +from IPython.display import display, Math +################################################################ + + +def print_latex(sstr, *args): + args = [latex(a) for a in args] + sstr = sstr.format(*args) + display(Math(latex(sstr))) + +################################################################ + + +def colorizeMatrix(mat, colors=None): + if colors is None: + return np.zeros(mat.shape, dtype=str) + + m = mat.shape[0] + + color_def = { + 'b': 'blue', + 'g': 'green', + 'r': 'red', + } + + if len(mat.shape) > 1 and mat.shape[1] > 1: + result = '' + for i in range(0, m): + row = [] + for j in range(0, m): + if colors[i, j] in color_def: + color = color_def[colors[i, j]] + else: + color = 'black' + row.append( + r'{\color{' + color + '}{' + latex(mat[i, j]) + '}}') + + result += ' & '.join(row) + if i < m-1: + result += r'\\' + result = r'\left[\begin{matrix}' + result + r'\end{matrix}\right]' + # result = r'{\color{blue}' + result + r'}' + + else: + result = '' + for i in range(0, m): + if colors[i, 0] in color_def: + color = color_def[colors[i, 0]] + else: + color = 'black' + result += r'{\color{' + color + '}{' + latex(mat[i]) + '}}' + if i < m-1: + result += r'\\' + result = r'\left\{\begin{matrix}' + result + r'\end{matrix}\right\}' + # result = r'{\color{blue}' + result + r'}' + + return result + +################################################################ diff --git a/Slides/presentation_helper.py b/Slides/presentation_helper.py index c693f4a..73129ae 100644 --- a/Slides/presentation_helper.py +++ b/Slides/presentation_helper.py @@ -1,357 +1,300 @@ #!/usr/bin/env pyton ################################################################ from sympy import * import numpy as np import sympy import IPython from IPython.display import display, Math from IPython.display import HTML import os import fnmatch import shutil import subprocess import base64 import matplotlib.pyplot as plt import matplotlib.figure from IPython.core.interactiveshell import InteractiveShell from wand.image import Image as WImage from wand.color import Color from io import BytesIO from tempfile import NamedTemporaryFile from tempfile import mkdtemp from pygments import highlight from pygments.lexers import CppLexer from pygments.lexers import MatlabLexer from pygments.formatters import HtmlFormatter - -# from pygments.lexers import PythonLexer -# from matplotlib import animation -# from IPython.display import display_latex, Latex -# from IPython.display import display_png -# from IPython.core.formatters import PNGFormatter ################################################################ def findImageFile(filename): if os.path.isfile(filename): return filename tool_dir = os.path.dirname(__file__) image_dir = os.path.join(tool_dir, '..', 'images') pattern = os.path.basename(filename) found = [] for root, dirnames, filenames in os.walk(image_dir): for filename in fnmatch.filter(filenames, pattern): found.append(os.path.join(root, filename)) if len(found) == 0: raise Exception("file not found: {0}".format(filename)) if len(found) == 1: return found[0] raise Exception("Several files were found:\n{0}".format(found)) ################################################################ def _print_latex_png(o): o = o._repr_latex_() dvioptions = None exprbuffer = BytesIO() # from IPython.core.debugger import Tracer # Tracer()() preview(o, output='png', viewer='BytesIO', outputbuffer=exprbuffer, packages=('xcolor',), dvioptions=dvioptions) return exprbuffer.getvalue() ################################################################ def init_printing(): sympy.init_printing() # f = InteractiveShell.instance().display_formatter f = InteractiveShell.instance().display_formatter.formatters['image/png'] f.for_type(IPython.core.display.Math, func=_print_latex_png) # print f.type_printers ################################################################ -def print_latex(sstr, *args): - args = [latex(a) for a in args] - sstr = sstr.format(*args) - display(Math(latex(sstr))) - -################################################################ - - -def colorizeMatrix(mat, colors=None): - if colors is None: - return np.zeros(mat.shape, dtype=str) - - m = mat.shape[0] - - color_def = { - 'b': 'blue', - 'g': 'green', - 'r': 'red', - } - - if len(mat.shape) > 1 and mat.shape[1] > 1: - result = '' - for i in range(0, m): - row = [] - for j in range(0, m): - if colors[i, j] in color_def: - color = color_def[colors[i, j]] - else: - color = 'black' - row.append(r'{\color{' + color + '}{' + latex(mat[i, j]) + '}}') - - result += ' & '.join(row) - if i < m-1: - result += r'\\' - result = r'\left[\begin{matrix}' + result + r'\end{matrix}\right]' - # result = r'{\color{blue}' + result + r'}' - - else: - result = '' - for i in range(0, m): - if colors[i, 0] in color_def: - color = color_def[colors[i, 0]] - else: - color = 'black' - result += r'{\color{' + color + '}{' + latex(mat[i]) + '}}' - if i < m-1: - result += r'\\' - result = r'\left\{\begin{matrix}' + result + r'\end{matrix}\right\}' - # result = r'{\color{blue}' + result + r'}' - - return result - -################################################################ - VIDEO_TAG = """""" def anim_to_html(anim): if not hasattr(anim, '_encoded_video'): with NamedTemporaryFile(suffix='.mp4') as f: anim.save(f.name, fps=1./(anim._interval*1e-3), extra_args=['-vcodec', 'libx264', '-pix_fmt', 'yuv420p']) video = open(f.name, "rb").read() toto = video.encode("base64") # print anim._encoded_video return VIDEO_TAG.format(toto) ################################################################ def display_animation(anim): plt.close(anim._fig) return HTML(anim_to_html(anim)) ################################################################ def display_images(objs, display_flag=True, **kwargs): htmls = [display_image(o, display_flag=False, **kwargs) for o in objs] width = 100/len(htmls) htmls_withdiv = ["" for h in htmls] for i, h in enumerate(htmls): htmls_withdiv[i] = '
{0}
'.format(h) html = '\n'.join(htmls_withdiv) html = '
' + html + '
' if display_flag: display(HTML(html)) return html def display_image(obj, resolution=150, width=None, height=None, display_flag=True): if type(obj) == matplotlib.figure.Figure: png = InteractiveShell.instance().display_formatter.format(obj) elif type(obj) == str: try: fname = findImageFile(obj) except Exception as e: return str(e) img = WImage(filename=fname, resolution=resolution) img.trim() with Color('#FDFDFD') as white: twenty_percent = int(65535 * 0.2) img.transparent_color(white, alpha=0.0, fuzz=twenty_percent) if (width is None) and (height is None): display(img) return img png = InteractiveShell.instance().display_formatter.format(img) else: raise Exception('unknown obj type for an image') size_tag = "" if width is not None: size_tag += 'width="{0}"'.format(width) if height is not None: size_tag += 'height="{0}"'.format(height) data = png[0]['image/png'] html = r''.format( base64.b64encode(data), size_tag) if display_flag: display(HTML(html)) return html ################################################################ def makeAnimationFromImageFiles(filenames, framerate): temp_dir = mkdtemp() ext = None for idx, f in enumerate(filenames): _dir = os.path.dirname(f) base = os.path.basename(f) base, _ext = os.path.splitext(base) ext = _ext if ext == '.pdf': _png = os.path.join(_dir, base+".png") subprocess.call('convert {0} {1}'.format(f, _png), shell=True) ext = ".png" f = _png new_name = "file{0:05d}{1}".format(idx, ext) new_name = os.path.join(temp_dir, new_name) # print base, ext # print new_name # print "copy {0} to {1}".format(f,new_name) shutil.copyfile(f, new_name) pattern = os.path.join(temp_dir, 'file%05d'+ext) with NamedTemporaryFile(suffix='.mp4') as f: cmd = ('ffmpeg -y -framerate {2} -i {0} -vf "scale=trunc(iw/2)*2:' 'trunc(ih/2)*2" -c:v libx264 -r 30 ' '-pix_fmt yuv420p {1}').format(pattern, f.name, framerate) # print cmd subprocess.call(cmd, shell=True) video = open(f.name, "rb").read() toto = video.encode("base64") shutil.rmtree(temp_dir) return HTML(VIDEO_TAG.format(toto)) ################################################################ class Pigment(object): def __init__(self, lexer=CppLexer(), formatter=HtmlFormatter(full=True), includes=[], header="\n"): self.lexer = lexer self.formatter = formatter self.header = header self.includes = includes self._insertIncludes() def _insertIncludes(self): if len(self.includes) > 0: self.header = ('\n'.join(['#include <{0}>'.format(inc) for inc in self.includes]) + '\n' + self.header) def appendToHeader(self, content): self.header += content def render(self, snippet, embed=False, header=""): colored_snippet = highlight(snippet, self.lexer, self.formatter) f = NamedTemporaryFile(suffix='.cc') # name = f.name # name = '/tmp/test.cc' # f = open(name,'w') if embed is True: snippet = "int main(){\n" + snippet + "\n}\n" snippet = self.header + '\n' + header + '\n' + snippet f.write(snippet) f.flush() p = subprocess.Popen('g++ -I {1} -c {0}'.format(f.name, os.getcwd()), shell=True, stderr=subprocess.PIPE) p.wait() ret = p.returncode if ret != 0: out = p.stderr.read() # return colored_snippet.decode() + '\n' + out print(out) f.delete = False raise Exception('compilation failed') return colored_snippet ################################################################ def printMatlab(code): html_snippet = highlight( code, MatlabLexer(), HtmlFormatter(full=True, style='colorful', classprefix='matlab_')) display(HTML(html_snippet)) # return html_snippet ################################################################ def displayClassDiagram(classes, resolution=150, width=None, height=None): with NamedTemporaryFile(suffix='.classes') as f: f.write(classes) f.flush() with NamedTemporaryFile(suffix='.png') as fout: # print 'class_dumper_dot.py --colaboration_no -c {0} # -o {1} -f png'.format(f.name, fout.name) # ret = subprocess.call('class_dumper_dot.py --colaboration_no # -c {0} -o {1} -f png'.format(f.name, fout.name), shell=True) img = WImage(filename=fout.name, resolution=resolution) with Color('#FDFDFD') as white: twenty_percent = int(65535 * 0.2) img.transparent_color(white, alpha=0.0, fuzz=twenty_percent) png = InteractiveShell.instance().display_formatter.format(img) size_tag = "" if width is not None: size_tag += 'width="{0}"'.format(width) if height is not None: size_tag += 'height="{0}"'.format(height) data = png[0]['image/png'] html = r''.format( base64.b64encode(data), size_tag) display(HTML(html)) return html ################################################################ + + +init_printing()