Skip to content

Commit 4d68edb

Browse files
committed
Merge abrombo's new printer per #38
1 parent dd1a125 commit 4d68edb

File tree

1 file changed

+143
-42
lines changed

1 file changed

+143
-42
lines changed

galgebra/printer.py

Lines changed: 143 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from sympy.core.function import _coeff_isneg
1414
from sympy.core.operations import AssocOp
1515
from sympy import init_printing
16+
import builtins
1617
from . import utils
1718

1819
try:
@@ -26,34 +27,74 @@
2627

2728
from inspect import getouterframes, currentframe
2829

30+
#Save original print function
31+
old_print = builtins.print
32+
2933
ZERO_STR = ' 0 '
3034

3135
Format_cnt = 0
3236

3337
ip_cmds = \
34-
"""
35-
$\\DeclareMathOperator{\\Tr}{Tr}
36-
\\DeclareMathOperator{\\Adj}{Adj}
37-
\\newcommand{\\bfrac}[2]{\\displaystyle\\frac{#1}{#2}}
38-
\\newcommand{\\lp}{\\left (}
39-
\\newcommand{\\rp}{\\right )}
40-
\\newcommand{\\paren}[1]{\\lp {#1} \\rp}
41-
\\newcommand{\\half}{\\frac{1}{2}}
42-
\\newcommand{\\llt}{\\left <}
43-
\\newcommand{\\rgt}{\\right >}
44-
\\newcommand{\\abs}[1]{\\left |{#1}\\right | }
45-
\\newcommand{\\pdiff}[2]{\\bfrac{\\partial {#1}}{\\partial {#2}}}
46-
\\newcommand{\\npdiff}[3]{\\bfrac{\\partial^{#3} {#1}}{\\partial {#2}^{#3}}}
47-
\\newcommand{\\lbrc}{\\left \\{}
48-
\\newcommand{\\rbrc}{\\right \\}}
49-
\\newcommand{\\W}{\\wedge}
50-
\\newcommand{\\prm}[1]{{#1}'}
51-
\\newcommand{\\ddt}[1]{\\bfrac{d{#1}}{dt}}
52-
\\newcommand{\\R}{\\dagger}
53-
\\newcommand{\\deriv}[3]{\\bfrac{d^{#3}#1}{d{#2}^{#3}}}
54-
\\newcommand{\\grade}[1]{\\left < {#1} \\right >}
55-
\\newcommand{\\f}[2]{{#1}\\lp {#2} \\rp}
56-
\\newcommand{\\eval}[2]{\\left . {#1} \\right |_{#2}}$
38+
r"""
39+
\DeclareMathOperator{\Tr}{Tr}
40+
\DeclareMathOperator{\Adj}{Adj}
41+
\newcommand{\bfrac}[2]{\displaystyle\frac{#1}{#2}}
42+
\newcommand{\lp}{\left (}
43+
\newcommand{\rp}{\right )}
44+
\newcommand{\paren}[1]{\lp {#1} \rp}
45+
\newcommand{\half}{\frac{1}{2}}
46+
\newcommand{\llt}{\left <}
47+
\newcommand{\rgt}{\right >}
48+
\newcommand{\abs}[1]{\left |{#1}\right | }
49+
\newcommand{\pdiff}[2]{\bfrac{\partial {#1}}{\partial {#2}}}
50+
\newcommand{\npdiff}[3]{\bfrac{\partial^{#3} {#1}}{\partial {#2}^{#3}}}
51+
\newcommand{\lbrc}{\left \{}
52+
\newcommand{\rbrc}{\right \}}
53+
\newcommand{\W}{\wedge}
54+
\newcommand{\prm}[1]{{#1}'}
55+
\newcommand{\ddt}[1]{\bfrac{d{#1}}{dt}}
56+
\newcommand{\R}{\dagger}
57+
\newcommand{\deriv}[3]{\bfrac{d^{#3}#1}{d{#2}^{#3}}}
58+
\newcommand{\grd}[1]{\left < {#1} \right >}
59+
\newcommand{\f}[2]{{#1}\lp {#2} \rp}
60+
\newcommand{\eval}[2]{\left . {#1} \right |_{#2}}
61+
\newcommand{\bs}[1]{\boldsymbol{#1}}
62+
\newcommand{\es}[1]{\boldsymbol{e}_{#1}}
63+
\newcommand{\eS}[1]{\boldsymbol{e}^{#1}}
64+
\newcommand{\grade}[2]{\left < {#1} \right >_{#2}}
65+
\newcommand{\lc}{\rfloor}
66+
\newcommand{\rc}{\lfloor}
67+
\newcommand{\T}[1]{\text{#1}}
68+
\newcommand{\lop}[1]{\overleftarrow{#1}}
69+
\newcommand{\rop}[1]{\overrightarrow{#1}}
70+
\newcommand{\ldot}{\lfloor}
71+
\newcommand{\rdot}{\rfloor}
72+
73+
%MacDonald LaTeX macros
74+
75+
\newcommand {\thalf} {\textstyle \frac{1}{2}}
76+
\newcommand {\tthird} {\textstyle \frac{1}{3}}
77+
\newcommand {\tquarter} {\textstyle \frac{1}{4}}
78+
\newcommand {\tsixth} {\textstyle \frac{1}{6}}
79+
80+
\newcommand {\RE} {\mathbb{R}}
81+
\newcommand {\GA} {\mathbb{G}}
82+
\newcommand {\inner} {\mathbin{\pmb{\cdot}}}
83+
\renewcommand {\outer} {\mathbin{\wedge}}
84+
\newcommand {\cross} {\mathbin{\times}}
85+
\newcommand {\meet} {\mathbin{{\,\vee\;}}}
86+
\renewcommand {\iff} {\Leftrightarrow}
87+
\renewcommand {\impliedby}{\Leftarrow}
88+
\renewcommand {\implies} {\Rightarrow}
89+
\newcommand {\perpc} {\perp} % Orthogonal complement
90+
\newcommand {\perpm} {*} % Dual of multivector
91+
\newcommand {\del} {\mathbf{\nabla}} %{\boldsymbol\nabla\!}
92+
\newcommand {\mpart}[2]{\left\langle\, #1 \,\right\rangle_{#2}} % AMS has a \part
93+
\newcommand {\spart}[1]{\mpart{#1}{0}}
94+
\newcommand {\ds} {\displaystyle}
95+
\newcommand {\os} {\overset}
96+
\newcommand {\galgebra} {\mbox{$\mathcal{G\!A}$\hspace{.01in}lgebra}}
97+
\newcommand {\latex} {\LaTeX}
5798
"""
5899

59100
print_replace_old = None
@@ -622,26 +663,21 @@ def sub_split_super_sub(text):
622663

623664
@staticmethod
624665
def redirect():
666+
GaLatexPrinter.latex_str = '' if GaLatexPrinter.latex_str is None else GaLatexPrinter.latex_str
667+
GaLatexPrinter.text_printer = print #Save original print function
668+
builtins.print = latex_print #Redefine original print function
625669
GaLatexPrinter.latex_flg = True
626670
GaLatexPrinter.Basic__str__ = Basic.__str__
627671
GaLatexPrinter.Matrix__str__ = Matrix.__str__
628672
Basic.__str__ = lambda self: GaLatexPrinter().doprint(self)
629673
Matrix.__str__ = lambda self: GaLatexPrinter().doprint(self)
630-
if GaLatexPrinter.ipy:
631-
pass
632-
else:
633-
GaLatexPrinter.stdout = sys.stdout
634-
sys.stdout = utils.StringIO()
635674
return
636675

637676
@staticmethod
638677
def restore():
639678
if GaLatexPrinter.latex_flg:
640-
if not GaLatexPrinter.ipy:
641-
GaLatexPrinter.latex_str += sys.stdout.getvalue()
679+
builtins.print = GaLatexPrinter.text_printer #Redefine orginal print function
642680
GaLatexPrinter.latex_flg = False
643-
if not GaLatexPrinter.ipy:
644-
sys.stdout = GaLatexPrinter.stdout
645681
Basic.__str__ = GaLatexPrinter.Basic__str__
646682
Matrix.__str__ = GaLatexPrinter.Matrix__str__
647683
return
@@ -964,6 +1000,44 @@ def latex(expr, **settings):
9641000
def latex(expr, **settings):
9651001
return GaLatexPrinter(settings).doprint(expr)
9661002

1003+
def latex_print(*s,**kws):
1004+
1005+
s = list(s)
1006+
1007+
GaLatexPrinter.fmt_dict = {'t':False, 'h':False}
1008+
1009+
if utils.isstr(s[0]):
1010+
1011+
if s[0] == 'h':
1012+
GaLatexPrinter.fmt_dict['h'] = True
1013+
s = s[1:]
1014+
1015+
latex_str = ''
1016+
1017+
for arg in s:
1018+
1019+
if utils.isstr(arg):
1020+
if GaLatexPrinter.fmt_dict['t']:
1021+
latex_str += r'\text{' + arg + '} '
1022+
else:
1023+
latex_str += arg + ' '
1024+
else:
1025+
if isinstance(arg, tuple):
1026+
tmp = r'\lp ' + str(arg)[1:-1] + r'\rp '
1027+
latex_str += tmp + ' '
1028+
else:
1029+
latex_str += str(arg) + ' '
1030+
1031+
if GaLatexPrinter.fmt_dict['h']:
1032+
latex_str = r'\begin{array}{c}\hline ' + latex_str + r' \\ \hline \end{array} '
1033+
1034+
latex_str = latex_str.replace('$$', '')
1035+
1036+
if isinteractive():
1037+
return display(Latex('$$ ' + latex_str + ' $$'))
1038+
else:
1039+
GaLatexPrinter.latex_str += latex_str.strip() + '\n'
1040+
return
9671041

9681042
def print_latex(expr, **settings):
9691043
"""Prints LaTeX representation of the given expression."""
@@ -999,6 +1073,9 @@ def Format(Fmode=True, Dmode=True, dop=1, inverse='full'):
9991073

10001074
if isinteractive():
10011075
init_printing(use_latex= 'mathjax')
1076+
from IPython.core.interactiveshell import InteractiveShell
1077+
InteractiveShell.ast_node_interactivity = "all"
1078+
return display(Latex('$$ '+ip_cmds+' $$'))
10021079

10031080
return
10041081

@@ -1010,7 +1087,7 @@ def tex(paper=(14, 11), debug=False, prog=False, pt='10pt'):
10101087
We assume that if tex() is called then Format() has been called at the beginning of the program.
10111088
"""
10121089

1013-
latex_str = GaLatexPrinter.latex_str + sys.stdout.getvalue()
1090+
latex_str = GaLatexPrinter.latex_str # + sys.stdout.getvalue()
10141091
GaLatexPrinter.latex_str = ''
10151092
GaLatexPrinter.restore()
10161093
r"""
@@ -1408,7 +1485,6 @@ def parse_line(line):
14081485
line = unparse_paren(level_lst)
14091486
return line
14101487

1411-
14121488
def GAeval(s, pstr=False):
14131489
"""
14141490
GAeval converts a string to a multivector expression where the
@@ -1425,14 +1501,6 @@ def GAeval(s, pstr=False):
14251501
print(seval)
14261502
return eval(seval, global_dict)
14271503

1428-
r"""
1429-
\begin{array}{c}
1430-
\left ( \begin{array}{c} F,\\ \end{array} \right . \\
1431-
\begin{array}{c} F, \\ \end{array} \\
1432-
\left .\begin{array}{c} F \\ \end{array} \right ) \\
1433-
\end{array}
1434-
"""
1435-
14361504
def Fmt(obj,fmt=0):
14371505
if isinstance(obj,(list,tuple,dict)):
14381506
n = len(obj)
@@ -1502,6 +1570,39 @@ def Fmt(obj,fmt=0):
15021570
else:
15031571
raise TypeError(str(type(obj)) + ' not allowed arg type in Fmt')
15041572

1573+
class Notes(object):
1574+
"""
1575+
Class for annotating LaTeX output. Only use with LaTeX
1576+
"""
1577+
def __init__(self, expr, notes, pos='L'):
1578+
if pos not in ('L','R','T','B'):
1579+
pos = 'L'
1580+
latex_str = r'\begin{array}'
1581+
if pos == 'L':
1582+
latex_str += r'{rl} ' + latex(notes) + r'\!\!\!\! & ' + latex(expr)
1583+
if pos == 'R':
1584+
latex_str += r'{rl} ' + latex(expr) + r' &\!\!!\!\! ' + latex(notes)
1585+
if pos == 'B':
1586+
latex_str += r'{c} ' + latex(expr) + r' \\ ' + latex(notes)
1587+
if pos == 'T':
1588+
latex_str += r'{c} ' + latex(notes) + r' \\ ' + latex(expr)
1589+
latex_str += r' \end{array} '
1590+
self.latex_str = latex_str
1591+
1592+
def __str__(self):
1593+
if GaLatexPrinter.latex_flg:
1594+
Printer = GaLatexPrinter
1595+
else:
1596+
Printer = GaPrinter
1597+
1598+
return Printer().doprint(self)
1599+
1600+
def __repr__(self):
1601+
return str(self)
1602+
1603+
def Notes_latex_str(self, raw=False):
1604+
return self.latex_str
1605+
15051606

15061607
if __name__ == "__main__":
15071608

0 commit comments

Comments
 (0)