Source code for galgebra.gprinter

from .printer import GaLatexPrinter, isinteractive, Format_cnt, latex
import subprocess
import sys
import shutil
import inspect

from sympy import init_printing

try:
    from IPython.display import display, Math
except ImportError:
    pass

SYS_CMD = {'linux2': {'rm': 'rm', 'evince': 'evince', 'null': ' > /dev/null', '&': '&'},
           'linux': {'rm': 'rm', 'evince': 'evince', 'null': ' > /dev/null', '&': '&'},
           'win32': {'rm': 'del', 'evince': 'start', 'null': ' > NUL', '&': ''},
           'darwin': {'rm': 'rm', 'evince': 'open', 'null': ' > /dev/null', '&': '&'}}


class LaTeX:
    # LaTeX data
    line_sep = """
************************************************************************
"""
    latex_flg = False
    latex_str = ''

    latex_preamble = """
\\pagestyle{empty}
\\usepackage[utf8]{inputenc}
\\usepackage{amsmath}
\\usepackage{amsfonts}
\\usepackage{amssymb}
\\usepackage{amsbsy}
\\usepackage{tensor}
\\usepackage{listings}
\\usepackage{color}
\\usepackage{xcolor}
\\usepackage{bm}
\\usepackage{breqn}
\\definecolor{gray}{rgb}{0.95,0.95,0.95}
\\setlength{\\parindent}{0pt}
\\DeclareMathOperator{\\Tr}{Tr}
\\DeclareMathOperator{\\Adj}{Adj}
\\newcommand{\\bfrac}[2]{\\displaystyle\\frac{#1}{#2}}
\\newcommand{\\lp}{\\left (}
\\newcommand{\\rp}{\\right )}
\\newcommand{\\paren}[1]{\\lp {#1} \\rp}
\\newcommand{\\half}{\\frac{1}{2}}
\\newcommand{\\llt}{\\left <}
\\newcommand{\\rgt}{\\right >}
\\newcommand{\\abs}[1]{\\left |{#1}\\right | }
\\newcommand{\\pdiff}[2]{\\bfrac{\\partial {#1}}{\\partial {#2}}}
\\newcommand{\\lbrc}{\\left \\{}
\\newcommand{\\rbrc}{\\right \\}}
\\newcommand{\\W}{\\wedge}
\\newcommand{\\prm}[1]{{#1}^{\\prime}}
\\newcommand{\\ddt}[1]{\\bfrac{d{#1}}{dt}}
\\newcommand{\\R}{\\dagger}
\\newcommand{\\deriv}[3]{\\bfrac{d^{#3}#1}{d{#2}^{#3}}}
\\newcommand{\\grade}[2]{\\left < {#1} \\right >_{#2}}
\\newcommand{\\f}[2]{{#1}\\lp{#2}\\rp}
\\newcommand{\\eval}[2]{\\left . {#1} \\right |_{#2}}
\\newcommand{\\Nabla}{\\boldsymbol{\\nabla}}
\\newcommand{\\eb}{\\boldsymbol{e}}
\\newcommand{\\bs}[1]{\\boldsymbol{#1}}
\\newcommand{\\grad}{\\bs{\\nabla}}
\\usepackage{float}
\\floatstyle{plain} % optionally change the style of the new float
\\newfloat{Code}{H}{myc}
\\lstloadlanguages{Python}
\\begin{document}

"""

    ip_cmds = \
        [r'$$\DeclareMathOperator{\Tr}{Tr}$$',
            r'$$\DeclareMathOperator{\Adj}{Adj}$$',
            r'$$\newcommand{\bfrac}[2]{\displaystyle\frac{#1}{#2}}$$',
            r'$$\newcommand{\lp}{\left (}$$',
            r'$$\newcommand{\rp}{\right )}$$',
            r'$$\newcommand{\paren}[1]{\lp {#1} \rp}$$',
            r'$$\newcommand{\half}{\frac{1}{2}}$$',
            r'$$\newcommand{\llt}{\left <}$$',
            r'$$\newcommand{\rgt}{\right >}$$',
            r'$$\newcommand{\abs}[1]{\left |{#1}\right | }$$',
            r'$$\newcommand{\pdiff}[2]{\bfrac{\partial {#1}}{\partial {#2}}}$$',
            r'$$\newcommand{\npdiff}[3]{\bfrac{\partial^{#3} {#1}}{\partial {#2}^{#3}}}$$',
            r'$$\newcommand{\lbrc}{\left \{}$$',
            r'$$\newcommand{\rbrc}{\right \}}$$',
            r'$$\newcommand{\W}{\wedge}$$',
            r'$$\newcommand{\prm}[1]{{#1}^{\prime}}$$',
            r'$$\newcommand{\ddt}[1]{\bfrac{d{#1}}{dt}}$$',
            r'$$\newcommand{\R}{\dagger}$$',
            r'$$\newcommand{\deriv}[3]{\bfrac{d^{#3}#1}{d{#2}^{#3}}}$$',
            r'$$\newcommand{\grade}[2]{\left < {#1} \right >_{#2}}$$',
            r'$$\newcommand{\f}[2]{{#1}\lp {#2} \rp}$$',
            r'$$\newcommand{\eval}[2]{\left . {#1} \right |_{#2}}$$',
            r'$$\newcommand{\bs}[1]{\boldsymbol{#1}}$$',
            r'$$\newcommand{\grad}{\bs{\nabla}}$$']

# ***********************************************************************


[docs] def gFormat(Fmode: bool = True, Dmode: bool = True, inverse='full'): r""" Turns on latex printing with configurable options. This redirects printer output so that latex compiler can capture it. ``Format()`` is also required for printing from *ipython notebook* (note that ``xpdf()`` is not needed to print from *ipython notebook*). Parameters ---------- Fmode: Value for the ``omit_function_args`` setting of :class:`GaLatexPrinter`. Dmode: Value for the ``omit_partial_derivative_fraction`` setting of :class:`GaLatexPrinter`. """ global Format_cnt GaLatexPrinter.set_global_settings( omit_partial_derivative_fraction=Dmode, omit_function_args=Fmode, inv_trig_style=inverse, ) if Format_cnt == 0: Format_cnt += 1 LaTeX.latex_flg = True if isinteractive(): init_printing(use_latex='mathjax') from IPython.display import Math, display cmds = '\n'.join(LaTeX.ip_cmds) display(Math(cmds)) return
[docs] def gprint(*xargs): """ Print latex or text from python script or latex from Jupyter Notebook/Lab """ x = [] fstr = '' new_eq_flg = False i = 0 for xi in xargs: if isinstance(xi, str): if r'\\' in xi and i > 0: if isinteractive(): xi_rep = xi.replace(r'\\', r'\end{equation*}@\begin{equation*} ') else: xi_rep = xi.replace(r'\\', r'\end{equation*}'+'\n'+r'\begin{equation*} ') new_eq_flg = True fstr += xi_rep else: fstr += xi elif isinstance(xi, type): if LaTeX.latex_flg: fstr += r' \text{'+str(xi)+'} ' else: fstr += str(xi) else: if LaTeX.latex_flg: x.append(latex(xi)) if new_eq_flg: new_eq_flg = False fstr += r' %s ' else: x.append(str(xi)) fstr += r' %s ' i += 1 if LaTeX.latex_flg: if isinteractive(): lstr = fstr % tuple(x) if '@' in lstr: lines = lstr.split('@') lines[0] = r'\begin{equation*} '+lines[0] lines[-1] += r'\end{equation*}' for line in lines: display(Math(line)) else: display(Math(lstr)) else: LaTeX.latex_str += r'\begin{equation*} ' + (fstr % tuple(x)) + r'\end{equation*} '+'\n' else: print(fstr % tuple(x)) return
[docs] def gxpdf(filename=None, paper=(14, 11), crop=False, png=False, prog=False, debug=False, pt='10pt', pdfprog='pdflatex', evince=True, rm=True, null=True, documentclass='book'): """ Post processes LaTeX output (see comments below), adds preamble and postscript, generates tex file, inputs file to latex, displays resulting pdf file. Arg Value Result pdfprog 'pdflatex' Use pdfprog to generate pdf output, only generate tex if pdfprog is None crop True Use "pdfcrop" to crop output file (pdfcrop must be installed, linux only) png True Use "convert" to produce png output (imagemagick must be installed, linux only) We assume that if gxpdf() is called then gFormat() has been called at the beginning of the program. """ latex_str = paper_format(paper, pt, documentclass)+LaTeX.latex_preamble+LaTeX.latex_str+r'\end{document}' # Clean up the latex string after printing LaTeX.latex_str = '' if filename is None: pyfilename = sys.argv[0] rootfilename = pyfilename.replace('.py', '') tex_filename = rootfilename + '.tex' pdf_filename = rootfilename + '.pdf' else: tex_filename = filename pdf_filename = tex_filename.replace('.tex', '.pdf') rootfilename = tex_filename.replace('.tex', '') if debug: print('latex file =', filename) with open(tex_filename, 'w') as latex_file: latex_file.write(latex_str) if pdfprog is not None: sys_cmd = SYS_CMD[sys.platform] pdflatex = shutil.which(pdfprog) if debug: # Display latex excution output for debugging purposes print('pdflatex path =', pdflatex) # os.system(pdfprog + ' ' + filename[:-4]) else: # Works for Linux don't know about Windows if null: subprocess.call([pdfprog, tex_filename, sys_cmd['null']]) else: subprocess.call([pdfprog, tex_filename]) # os.system(pdfprog + ' ' + filename[:-4] + sys_cmd['null']) if evince: subprocess.call([sys_cmd['evince'], pdf_filename]) # eval(input('!!!!Return to continue!!!!\n')) if rm: if debug: subprocess.call([sys_cmd['rm'], rootfilename+'.aux ', rootfilename+'.log']) else: subprocess.call([sys_cmd['rm'], rootfilename+'.aux ', rootfilename+'.log ', rootfilename+'.tex']) if crop: subprocess.call(['pdfcrop', pdf_filename]) subprocess.call(['rm', pdf_filename]) subprocess.call(['mv', rootfilename+'-crop.pdf', pdf_filename]) if png: subprocess.call(['Pdf2Png', rootfilename]) return
def paper_format(paper, pt, documentclass='book'): # Set size of paper and font size if paper == 'letter': paper_size = """ \\documentclass[@10pt@,fleqn]{%s} """ % documentclass else: paper_size = """ \\documentclass[@10pt@,fleqn]{%s} \\usepackage[vcentering]{geometry} """ % documentclass if paper == 'landscape': paper = [11, 8.5] paper_size += '\\geometry{papersize={' + str(paper[0]) + \ 'in,' + str(paper[1]) + 'in},total={' + str(paper[0] - 1) + \ 'in,' + str(paper[1] - 1) + 'in}}\n' paper_size = paper_size.replace('@10pt@', pt) return paper_size
[docs] def gPrint_Function(): """ Print out the source of the current function """ tmp_str = inspect.getsource(inspect.currentframe().f_back) if LaTeX.latex_flg: LaTeX.latex_str += r'\begin{lstlisting}[language=Python,showspaces=false,showstringspaces=false,backgroundcolor=\color{gray},frame=single]%s\end{lstlisting}\text{Code Output:}' % tmp_str else: print('\n' + 80 * '*') print(tmp_str) print('Code output:\n') return