diff --git a/Slides/math_helper.py b/Slides/math_helper.py
index cb2adc1..1bb545c 100644
--- a/Slides/math_helper.py
+++ b/Slides/math_helper.py
@@ -1,140 +1,140 @@
#!/usr/bin/env pyton
################################################################
import numpy as np
from sympy import latex
from IPython.display import display, Math
from . import presentation_helper as ph
################################################################
def print_latex(sstr, *argv, ret=False):
args = []
# print argv
for a in argv:
try:
ff = a._repr_latex_()
ff = ff[1:-1]
except Exception:
# print(e)
ff = latex(a)
args.append(ff)
sstr = sstr.format(*args)
# print (sstr)
res = Math(latex(sstr))
display(res)
if ret is True:
return res
################################################################
class ColoredMatrix:
color_def = {
'b': 'blue',
'g': 'green',
'r': 'red',
'p': 'purple'
}
def __init__(self, mat):
if isinstance(mat, ColoredMatrix):
self.mat = mat.mat
else:
self.mat = mat
self.colors = np.zeros(self.mat.shape, dtype='S10')
self.alternative = np.zeros(self.mat.shape, dtype='S10')
self.sym = False
def __len__(self):
return self.mat.__len__()
def dot(self, mat):
return self.mat.dot(mat)
def __mul__(self, n):
return self.mat.__mul__(n)
def __rmul__(self, n):
return n*self.mat
def __div__(self, n):
temp = ColoredMatrix(self.mat.__div__(n))
temp.colors[:] = self.colors[:]
return temp
def evalf(self, *args):
mat_eval = self.mat.evalf(*args)
new_mat = ColoredMatrix(mat_eval)
new_mat.colors = self.colors.copy()
return new_mat
def __getitem__(self, index):
return self.mat.__getitem__(index)
def __setitem__(self, index, value):
return self.mat.__setitem__(index, value)
def _get_coeff(self, i, j=0):
- if self.alternative[i, j] != '':
- return self.alternative[i, j]
+ if self.alternative[i, j].decode('utf8') != '':
+ return self.alternative[i, j].decode('utf8')
else:
return latex(self.mat[i, j])
def _colored_coeff(self, i, j=0):
if self.sym is True:
if i == self.mat.shape[0]-1 and j == 0:
return 'Sym.'
elif i > j:
return ''
- if self.colors[i, j] in self.color_def:
- color = self.color_def[self.colors[i, j]]
+ if self.colors[i, j].decode('utf8') in self.color_def:
+ color = self.color_def[self.colors[i, j].decode('utf8')]
else:
color = 'black'
coeff = self._get_coeff(i, j)
if coeff == '':
return ''
return (r'{\color{' + color + '}{' + coeff + '}}')
def _repr_latex_(self):
m = self.mat.shape[0]
if len(self.mat.shape) > 1 and self.mat.shape[1] > 1:
n = self.mat.shape[1]
result = ''
for i in range(0, m):
row = []
for j in range(0, n):
row.append(self._colored_coeff(i, j))
result += ' & '.join(row)
if i < m-1:
result += r'\\'
result = (r'\left[\begin{array}{' + 'c'*n + '}' +
result + r'\end{array}\right]')
else:
rows = []
for i in range(0, m):
rows.append(self._colored_coeff(i))
result = r'\\'.join(rows)
result = (r'\left\{\begin{matrix}' +
result + r'\end{matrix}\right\}')
- return '$$' + result + '$$'
+ return '$' + result + '$'
################################################################
def init_printing():
ph.registerFormatter(ColoredMatrix, 'image/png', ph._print_latex_png)
################################################################
init_printing()
diff --git a/Slides/snippet_helper.py b/Slides/snippet_helper.py
index 25063fa..d376cd5 100644
--- a/Slides/snippet_helper.py
+++ b/Slides/snippet_helper.py
@@ -1,425 +1,427 @@
#!/usr/bin/env python3
import subprocess
import os
import re
from pygments import highlight
from pygments.lexers import CppLexer
from pygments.lexers import PythonLexer
# from pygments.lexer import RegexLexer
from pygments.lexers import MatlabLexer
from pygments.formatters import HtmlFormatter
from pygments.formatters import LatexFormatter
from pygments import token
from IPython.display import HTML
from tempfile import NamedTemporaryFile
################################################################
class SlicedSnippet(object):
"""
When you slice a snippet, this object is returned
so that all your operations can apply directly to the snippet if need be.
"""
def __init__(self, snippet, slice):
self.start = slice.start
- self.end = slice.stop
+ if slice.start is None:
+ self.start = 1
+ self.end = slice.stop-1
self.snippet = snippet
def pigment(self, **kwargs):
kwargs['start'] = self.start
kwargs['end'] = self.end
return self.snippet.pigment(**kwargs)
class Snippet(object):
"""
Snippet objects manipulate codes.
At construction it can be formatted using clang-format
and it can be compiled to check for consistency.
"""
class CompilationError(Exception):
""" Compilation error """
pass
default_output = 'html'
default_line_numbering = False
def __getitem__(self, slice):
return SlicedSnippet(self, slice)
def __init__(self, inp, format_flag=False,
compile_flag=False, include_paths=None,
language='cpp'):
try:
self.loadfile(inp)
except Exception:
self.content = inp.strip()
if include_paths is None:
self.include_paths = []
else:
self.include_paths = [
os.path.abspath(i) for i in include_paths]
if format_flag:
self.clang_format()
if compile_flag:
self.compile()
if language == 'cpp':
self.lexer = CppLexer()
elif language == 'python':
self.lexer = PythonLexer()
elif language == 'matlab':
self.lexer = MatlabLexer()
def save(self, filename):
"""
Saves the snippet in another file
:param filename: The filename to save the snippet to
"""
f = open(filename, 'w')
f.write(self.content)
f.close()
def loadfile(self, inp):
filename = inp
full_filename = os.path.realpath(filename)
f = open(full_filename)
self.content = f.read()
f.close()
def clang_format(self):
f = NamedTemporaryFile()
f.write(self.content.encode())
f.flush()
p = subprocess.Popen(
'clang-format {0}'.format(f.name),
shell=True, stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode:
raise RuntimeError('Failed to launch clang-format')
formatted_file = stdout
self.content = formatted_file.decode('utf-8')
def execute(self, working_dir='/tmp', args='', libraries=''):
self.compile(working_dir=working_dir)
f = NamedTemporaryFile(suffix='.cpp', delete=False)
f.write(self.content.encode())
f.flush()
working_dir = os.path.dirname(f.name)
# file_dir = os.path.dirname(self.full_filename)
previous_dir = os.getcwd()
os.chdir(working_dir)
include_paths = self.include_paths + [working_dir]
include_paths = ['-I {0}'.format(a) for a in include_paths]
include_paths = ' '.join(include_paths)
p = subprocess.Popen(
'g++ -Wall -Wextra {1} {2} -o exec {0}'.format(
f.name, include_paths, libraries),
shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
ret = p.returncode
if ret != 0:
return ret, stdout, stderr
p = subprocess.Popen(
'./exec {0}'.format(args), shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
ret = p.returncode
os.chdir(previous_dir)
return ret, stdout, stderr
def compile(self, working_dir='/tmp'):
f = NamedTemporaryFile(suffix='.cpp', delete=False)
f.write(self.content.encode())
f.flush()
working_dir = os.path.dirname(f.name)
# file_dir = os.path.dirname(self.full_filename)
previous_dir = os.getcwd()
os.chdir(working_dir)
include_paths = self.include_paths + [working_dir]
include_paths = ['-I {0}'.format(a) for a in include_paths]
include_paths = ' '.join(include_paths)
p = subprocess.Popen(
'g++ -Wall -Wextra {1} -c {0}'.format(f.name, include_paths),
shell=True, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
ret = p.returncode
os.chdir(previous_dir)
if ret != 0:
raise Snippet.CompilationError('compilation failed\n' +
stderr.decode('utf-8'))
os.remove(f.name)
o_file = os.path.splitext(f.name)[0] + '.o'
os.remove(o_file)
def get_lines(self):
return self.content.split('\n')
def get_content(self):
return self.content
def __str__(self):
_content = self.content.split('\n')
ret = ""
for i, line in enumerate(_content):
ret += '{0}: {1}\n'.format(i, line)
return ret
class KeywordLexer(object):
def __init__(self, keyword):
if keyword == 'curly_brackets':
keyword = '{|}'
self.keyword = keyword
def get_tokens(self, text):
pattern = '(' + self.keyword + ')'
splits = re.split(pattern, text)
if len(splits) == 1:
return [(token.Text, text)]
res = []
# print(splits)
# print(token.Keyword.Type)
for count, s in enumerate(splits):
# print(count, s)
if count % 2 == 0:
res.append((token.Text, s))
else:
res.append((token.Keyword.Type, s))
# print(res)
return res
class LineLexer(object):
def __init__(self, line_number):
self.line_number = line_number
def get_tokens(self, text):
splits = text.split('\n')
res = []
splits1 = '\n'.join(splits[:self.line_number]) + '\n'
splits2 = splits[self.line_number] + '\n'
splits3 = '\n' + '\n'.join(splits[self.line_number + 1:]) + '\n'
splits = [splits1] + [splits2] + [splits3]
# print(splits)
for count, s in enumerate(splits):
if count == 1:
res.append((token.Keyword.Type, s))
else:
res.append((token.Text, s))
# print(res)
return res
class CustomLatexFormatter(LatexFormatter):
def __init__(self, **kwargs):
LatexFormatter.__init__(self, **kwargs)
def format(self, tokens, outfile):
res = []
for t, s in tokens:
if t == token.Keyword.Type:
import pygments.formatters.latex as la
s = la.escape_tex(s, self.commandprefix)
s = '\color{red}{\huge{' + s + '}}'
t = token.Escape
res.append((t, s))
LatexFormatter.format(self, res, outfile)
class CustomHtmlFormatter(HtmlFormatter):
def __init__(self, **kwargs):
HtmlFormatter.__init__(self, **kwargs)
def format(self, tokens, outfile_final):
# HtmlFormatter.format(self, tokens, outfile_final)
# return
from io import StringIO
outfile = StringIO()
res = []
ss = []
for t, s in tokens:
if t == token.Keyword.Type:
ss.append(s)
s = 'A' * 24
t = token.Text
res.append((t, s))
# print(res)
HtmlFormatter.format(self, res, outfile)
final = outfile.getvalue()
while ss:
s = ss.pop(0)
final = final.replace(
'A' * 24,
'{0}'.format(
s),
1)
outfile_final.write(final)
def pigment(self,
keyword=None, line_highlight=None,
start=None, end=None,
output=None, line_numbering=None):
_content = self.content.split('\n')
_content = [(c + '\n') for c in _content]
if start is None:
start = 1
if end is None:
end = len(_content)
if output is None:
output = self.default_output
lexer = self.lexer
if keyword is not None:
lexer = self.KeywordLexer(keyword)
elif line_highlight is not None:
if line_highlight < start or line_highlight > end:
raise RuntimeError('line_highlight out of the sub snippet')
line_highlight -= start
lexer = self.LineLexer(line_highlight)
if line_numbering is None:
line_numbering = self.default_line_numbering
if output == 'html':
formatter = HtmlFormatter(
full=False, linenos=line_numbering, linenostart=start)
elif output == 'latex':
formatter = LatexFormatter(
full=False, linenos=line_numbering, linenostart=start)
if (keyword is not None) or (line_highlight is not None):
format_class = self.CustomHtmlFormatter
if output == 'latex':
format_class = self.CustomLatexFormatter
formatter = format_class(
full=False, linenos=line_numbering,
linenostart=start)
snip = _content[start - 1:end]
snip = ''.join(snip)
colored_snippet = highlight(snip, lexer, formatter)
# print(colored_snippet)
if output == 'html':
HTML_TEMPLATE = """
{}
"""
css = formatter.get_style_defs()
colored_snippet = HTML(HTML_TEMPLATE.format(css, colored_snippet))
return colored_snippet
@staticmethod
def getLatexStyleDefs():
return LatexFormatter(full=True).get_style_defs()
################################################################
class SnippetCollection(Snippet):
def __init__(self):
self.functions = dict()
self.func_names = []
def addFunction(self, f_name, code):
if f_name in self.functions:
raise RuntimeError('function already declared')
self.func_names.append(f_name)
self.functions[f_name] = Snippet(code, format_flag=True)
self.compile()
def __getitem__(self, key):
return self.functions[key]
def flatten(self):
global_input = """
#include
#include
#include
#include
""" + '/' * 70 + '\n\n'
for f_name in self.func_names:
global_input += "void {0}(){{\n".format(f_name)
global_input += self.functions[f_name].content
global_input += '\n}\n\n' + '/' * 70 + '\n\n'
global_input += """
int main(int argc, char ** argv){\n"""
for f_name in self.func_names:
global_input += f_name + '();\n'
global_input += '\n}\n'
flat = Snippet(global_input,
format_flag=True)
return flat
def compile(self, **kwargs):
global_snippet = self.flatten()
global_snippet.compile(**kwargs)
def save(self, filename):
global_snippet = self.flatten()
open(filename, 'w').write(global_snippet.content)
def pigment(self, *args):
return self.flatten().pigment(*args)
def last(self):
return self.functions[self.func_names[-1]]
################################################################
# def printMatlab(code):
#
# html_snippet = highlight(
# code, MatlabLexer(),
# HtmlFormatter(full=True, style='colorful',
# classprefix='matlab_'))
#
# display(HTML(html_snippet))
# # return html_snippet
# ## testing
# Snippet.default_output = 'latex'
# Snippet.default_line_numbering = True
#
# snippet = SnippetCollection()
# snippet.addFunction('if_syntax', '''
# int p, q;
# if (p > q) {
# /*
# Statement1;
# Statement2;
# */
# }
# ''')
#
# print (snippet['if_syntax'].pigment())
diff --git a/tests/test_snippet_helper.py b/tests/test_snippet_helper.py
index 12ab815..ea057b9 100644
--- a/tests/test_snippet_helper.py
+++ b/tests/test_snippet_helper.py
@@ -1,71 +1,71 @@
#!/bin/env python3
# -*- coding: utf-8 -*-
from Slides import snippet_helper as sh
def test_cpp_snippet_from_file():
sh.Snippet.default_line_number = True
snip = sh.Snippet('tests/snippet.cpp')
snip.save('snippet2.cpp')
f = open('snippet2.cpp')
snip2 = f.read()
f.close()
if snip.get_content() != snip2:
print('AAA ', snip.get_content())
print('BBB ', snip2)
raise RuntimeError('failed test')
def test_cpp_snippet_format():
sh.Snippet.default_line_number = True
code = """
#include
int main(int argc, char **argv){
return 0;
}
"""
code = code.replace(';\n', ';')
snip = sh.Snippet(code, format_flag=True)
snip.save('snippet2.cpp')
f = open('snippet2.cpp')
snip2 = f.read()
f.close()
assert snip.get_content() == snip2
assert not snip.get_content() == code
def test_cpp_snippet_compile_fail():
sh.Snippet.default_line_number = True
code = """
#include
int main(int argc, char **argv){
return 0
}
"""
code = code.replace(';\n', ';')
try:
sh.Snippet(code, compile_flag=True)
raise RuntimeError("compilation error not detected")
- except sh.Snippet.CompilationError as e:
+ except sh.Snippet.CompilationError:
pass
except Exception as e:
raise RuntimeError('wrong exception:' + str(e))
def test_cpp_snippet_compile():
sh.Snippet.default_line_number = True
code = """
#include
int main(int argc, char **argv){
return 0;
}
"""
code = code.replace(';\n', ';')
try:
sh.Snippet(code, compile_flag=True)
except Exception as e:
raise RuntimeError('should compile: ' + str(e))