def _html_table_row(self, row, header=False): r""" Print the items of a list as one row of an HTML table. Used by the :meth:`_html_` method. INPUTS: - ``row`` - a list with the same number of entries as each row of the table. - ``header`` (default False) - if True, treat this as a header row, using ``<th>`` instead of ``<td>``. Strings get printed verbatim unless they seem to be LaTeX code, in which case they are enclosed in a ``script`` tag appropriate for MathJax. Sage objects are printed using their LaTeX representations. EXAMPLES:: sage: T = table([['a', 'bb', 'ccccc'], [10, -12, 0], [1, 2, 3]]) sage: T._html_table_row(['a', 2, '$x$']) <td>a</td> <td><script type="math/tex">2</script></td> <td><script type="math/tex">x</script></td> """ from sage.plot.all import Graphics from latex import latex from html import math_parse import types if isinstance(row, types.GeneratorType): row = list(row) elif not isinstance(row, (list, tuple)): row = [row] column_tag = "<th>%s</th>" if header else "<td>%s</td>" if self._options['header_column']: first_column_tag = "<th class=\"ch\">%s</th>" if header else "<td class=\"ch\">%s</td>" else: first_column_tag = column_tag # First entry of row: entry = row[0] if isinstance(entry, Graphics): print first_column_tag % entry.show(linkmode = True) elif isinstance(entry, str): print first_column_tag % math_parse(entry) else: print first_column_tag % ('<script type="math/tex">%s</script>' % latex(entry)) # Other entries: for column in xrange(1,len(row)): if isinstance(row[column], Graphics): print column_tag % row[column].show(linkmode = True) elif isinstance(row[column], str): print column_tag % math_parse(row[column]) else: print column_tag % ('<script type="math/tex">%s</script>' % latex(row[column]))
def _get_output(self, n): x = self._output[n] try: L = latex.latex(x) except: L = "\\mbox{error TeXing object}" single_png = os.path.join(self._images, '%s.png' % n) try: x.png(single_png) except AttributeError: latex.png(x, single_png, debug=self._debug) oi = os.path.join(self._dir, 'images', 'o' + '%s.html' % n) open(oi,'w').write('<pre>OUTPUT:\n%s\n\n\nLATEX:\n%s</pre><img src="%s">'%( x, L, single_png)) extra_img_opts = '' #if sage.plot.all.is_Graphics(x): # extra_img_opts = 'width=300' return """<center> <table border=0 cellpadding=20 cellspacing=2 bgcolor=lightgrey> <tr><td bgcolor=white> <a href="%s"> <img src="%s" alt="%s" %s> </a> </td></tr></table> </center>\n<hr>\n"""%('images/o%s.html'%n, 'images/%s.png'%n, L, extra_img_opts)
def _get_output(self, n): s = '' self._after_output = True if self._in_verbatim: s += '\\end{verbatim}\n' self._in_verbatim = False L = latex.latex(self._output[n]) # If we explicitly ask for LaTeX output, # no need to format L if "latex" in self._input[n-1]: s+= "\\begin{verbatim}%s\\end{verbatim}" %L else: s += '\n\\begin{center}$\\displaystyle %s $\\end{center}\n'%L return s
def _fmtEBPi_latex(t): if t[1] is not None: return "$ \\begin{array}{c}(%s \\\\ \pm %s)\\pi \\end{array} $" % ( _lu.latex(t[0]), _lu.latex(t[1])) else: return _fmtPi_latex(t[0])
def _fmtBold_latex(x): return "\\textbf{%s}" % _lu.latex(x) def _fmtBold_py(x): return "**%s**" % x
def _latex_(self): r""" LaTeX representation of a table. If an entry is a Sage object, it is replaced by its LaTeX representation, delimited by dollar signs (i.e., ``x`` is replaced by ``$latex(x)$``). If an entry is a string, the dollar signs are not automatically added, so tables can include both plain text and mathematics. EXAMPLES:: sage: from sage.misc.table import table sage: a = [[r'$\sin(x)$', '$x$', 'text'], [1,34342,3], [identity_matrix(2),5,6]] sage: latex(table(a)) # indirect doctest \begin{tabular}{lll} $\sin(x)$ & $x$ & text \\ $1$ & $34342$ & $3$ \\ $\left(\begin{array}{rr} 1 & 0 \\ 0 & 1 \end{array}\right)$ & $5$ & $6$ \\ \end{tabular} sage: latex(table(a, frame=True, align='center')) \begin{tabular}{|c|c|c|} \hline $\sin(x)$ & $x$ & text \\ \hline $1$ & $34342$ & $3$ \\ \hline $\left(\begin{array}{rr} 1 & 0 \\ 0 & 1 \end{array}\right)$ & $5$ & $6$ \\ \hline \end{tabular} """ from latex import latex, LatexExpr import types rows = self._rows nc = len(rows[0]) if len(rows) == 0 or nc == 0: return "" align_char = self._options['align'][0] # 'l', 'c', 'r' if self._options['frame']: frame_char = '|' frame_str = ' \\hline' else: frame_char = '' frame_str = '' if self._options['header_column']: head_col_char = '|' else: head_col_char = '' if self._options['header_row']: head_row_str = ' \\hline' else: head_row_str = '' # table header s = "\\begin{tabular}{" s += frame_char + align_char + frame_char + head_col_char s += frame_char.join([align_char] * (nc - 1)) s += frame_char + "}" + frame_str + "\n" # first row s += " & ".join( LatexExpr(x) if isinstance(x, (str, LatexExpr)) else '$' + latex(x).strip() + '$' for x in rows[0]) s += " \\\\" + frame_str + head_row_str + "\n" # other rows for row in rows[1:]: s += " & ".join( LatexExpr(x) if isinstance(x, (str, LatexExpr)) else '$' + latex(x).strip() + '$' for x in row) s += " \\\\" + frame_str + "\n" s += "\\end{tabular}" return s
def preview(expr, output='png', viewer=None, euler=True, packages=(), **latex_settings): r""" View expression or LaTeX markup in PNG, DVI, PostScript or PDF form. If the expr argument is an expression, it will be exported to LaTeX and then compiled using available the TeX distribution. The first argument, 'expr', may also be a LaTeX string. The function will then run the appropriate viewer for the given output format or use the user defined one. By default png output is generated. By default pretty Euler fonts are used for typesetting (they were used to typeset the well known "Concrete Mathematics" book). For that to work, you need the 'eulervm.sty' LaTeX style (in Debian/Ubuntu, install the texlive-fonts-extra package). If you prefer default AMS fonts or your system lacks 'eulervm' LaTeX package then unset the 'euler' keyword argument. To use viewer auto-detection, lets say for 'png' output, issue >>> from sympy import symbols, preview, Symbol >>> x, y = symbols("x,y") >>> preview(x + y, output='png') # doctest: +SKIP This will choose 'pyglet' by default. To select a different one, do >>> preview(x + y, output='png', viewer='gimp') # doctest: +SKIP The 'png' format is considered special. For all other formats the rules are slightly different. As an example we will take 'dvi' output format. If you would run >>> preview(x + y, output='dvi') # doctest: +SKIP then 'view' will look for available 'dvi' viewers on your system (predefined in the function, so it will try evince, first, then kdvi and xdvi). If nothing is found you will need to set the viewer explicitly. >>> preview(x + y, output='dvi', viewer='superior-dvi-viewer') # doctest: +SKIP This will skip auto-detection and will run user specified 'superior-dvi-viewer'. If 'view' fails to find it on your system it will gracefully raise an exception. You may also enter 'file' for the viewer argument. Doing so will cause this function to return a file object in read-only mode. Currently this depends on pexpect, which is not available for windows. Additional keyword args will be passed to the latex call, e.g., the symbol_names flag. >>> phidd = Symbol('phidd') >>> preview(phidd, symbol_names={phidd:r'\ddot{\varphi}'}) # doctest: +SKIP """ # we don't want to depend on anything not in the # standard library with SymPy by default import pexpect special = ['pyglet'] if viewer is None: if output == "png": viewer = "pyglet" else: # sorted in order from most pretty to most ugly # very discussable, but indeed 'gv' looks awful :) candidates = { "dvi": ["evince", "okular", "kdvi", "xdvi"], "ps": ["evince", "okular", "gsview", "gv"], "pdf": ["evince", "okular", "kpdf", "acroread", "xpdf", "gv"], } try: for candidate in candidates[output]: if pexpect.which(candidate): viewer = candidate break else: raise SystemError( "No viewers found for '%s' output format." % output) except KeyError: raise SystemError("Invalid output format: %s" % output) else: if viewer not in special and not pexpect.which(viewer): raise SystemError("Unrecognized viewer: %s" % viewer) actual_packages = packages + ("amsmath", "amsfonts") if euler: actual_packages += ("euler", ) package_includes = "\n".join( ["\\usepackage{%s}" % p for p in actual_packages]) format = r"""\documentclass[12pt]{article} %s \begin{document} \pagestyle{empty} %s \vfill \end{document} """ % (package_includes, "%s") if isinstance(expr, str): latex_string = expr else: latex_string = latex(expr, mode='inline', **latex_settings) tmp = tempfile.mktemp() with open(tmp + ".tex", "w") as tex: tex.write(format % latex_string) cwd = os.getcwd() os.chdir(tempfile.gettempdir()) if os.system("latex -halt-on-error %s.tex" % tmp) != 0: raise SystemError("Failed to generate DVI output.") os.remove(tmp + ".tex") os.remove(tmp + ".aux") os.remove(tmp + ".log") if output != "dvi": command = { "ps": "dvips -o %s.ps %s.dvi", "pdf": "dvipdf %s.dvi %s.pdf", "png": "dvipng -T tight -z 9 " + "--truecolor -o %s.png %s.dvi", } try: if os.system(command[output] % (tmp, tmp)) != 0: raise SystemError("Failed to generate '%s' output." % output) else: os.remove(tmp + ".dvi") except KeyError: raise SystemError("Invalid output format: %s" % output) src = "%s.%s" % (tmp, output) src_file = None if viewer == "file": src_file = open(src, 'rb') elif viewer == "pyglet": try: from pyglet import window, image, gl from pyglet.window import key except ImportError: raise ImportError( "pyglet is required for plotting.\n visit http://www.pyglet.org/" ) if output == "png": from pyglet.image.codecs.png import PNGImageDecoder img = image.load(src, decoder=PNGImageDecoder()) else: raise SystemError("pyglet preview works only for 'png' files.") offset = 25 win = window.Window(width=img.width + 2 * offset, height=img.height + 2 * offset, caption="sympy", resizable=False) win.set_vsync(False) try: def on_close(): win.has_exit = True win.on_close = on_close def on_key_press(symbol, modifiers): if symbol in [key.Q, key.ESCAPE]: on_close() win.on_key_press = on_key_press def on_expose(): gl.glClearColor(1.0, 1.0, 1.0, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) img.blit((win.width - img.width) / 2, (win.height - img.height) / 2) win.on_expose = on_expose while not win.has_exit: win.dispatch_events() win.flip() except KeyboardInterrupt: pass win.close() else: os.system("%s %s &> /dev/null &" % (viewer, src)) time.sleep(2) # wait for the viewer to read data os.remove(src) os.chdir(cwd) if src_file is not None: return src_file
def preview(expr, output='png', viewer=None, euler=True, packages=(), filename=None, outputbuffer=None, preamble=None, dvioptions=None, outputTexFile=None, **latex_settings): r""" View expression or LaTeX markup in PNG, DVI, PostScript or PDF form. If the expr argument is an expression, it will be exported to LaTeX and then compiled using the available TeX distribution. The first argument, 'expr', may also be a LaTeX string. The function will then run the appropriate viewer for the given output format or use the user defined one. By default png output is generated. By default pretty Euler fonts are used for typesetting (they were used to typeset the well known "Concrete Mathematics" book). For that to work, you need the 'eulervm.sty' LaTeX style (in Debian/Ubuntu, install the texlive-fonts-extra package). If you prefer default AMS fonts or your system lacks 'eulervm' LaTeX package then unset the 'euler' keyword argument. To use viewer auto-detection, lets say for 'png' output, issue >>> from sympy import symbols, preview, Symbol >>> x, y = symbols("x,y") >>> preview(x + y, output='png') # doctest: +SKIP This will choose 'pyglet' by default. To select a different one, do >>> preview(x + y, output='png', viewer='gimp') # doctest: +SKIP The 'png' format is considered special. For all other formats the rules are slightly different. As an example we will take 'dvi' output format. If you would run >>> preview(x + y, output='dvi') # doctest: +SKIP then 'view' will look for available 'dvi' viewers on your system (predefined in the function, so it will try evince, first, then kdvi and xdvi). If nothing is found you will need to set the viewer explicitly. >>> preview(x + y, output='dvi', viewer='superior-dvi-viewer') # doctest: +SKIP This will skip auto-detection and will run user specified 'superior-dvi-viewer'. If 'view' fails to find it on your system it will gracefully raise an exception. You may also enter 'file' for the viewer argument. Doing so will cause this function to return a file object in read-only mode, if 'filename' is unset. However, if it was set, then 'preview' writes the genereted file to this filename instead. There is also support for writing to a StringIO like object, which needs to be passed to the 'outputbuffer' argument. >>> from StringIO import StringIO >>> obj = StringIO() >>> preview(x + y, output='png', viewer='StringIO', ... outputbuffer=obj) # doctest: +SKIP The LaTeX preamble can be customized by setting the 'preamble' keyword argument. This can be used, e.g., to set a different font size, use a custom documentclass or import certain set of LaTeX packages. >>> preamble = "\\documentclass[10pt]{article}\n" \ ... "\\usepackage{amsmath,amsfonts}\\begin{document}" >>> preview(x + y, output='png', preamble=preamble) # doctest: +SKIP If the value of 'output' is different from 'dvi' then command line options can be set ('dvioptions' argument) for the execution of the 'dvi'+output conversion tool. These options have to be in the form of a list of strings (see subprocess.Popen). Additional keyword args will be passed to the latex call, e.g., the symbol_names flag. >>> phidd = Symbol('phidd') >>> preview(phidd, symbol_names={phidd:r'\ddot{\varphi}'}) # doctest: +SKIP For post-processing the generated TeX File can be written to a file by passing the desired filename to the 'outputTexFile' keyword argument. To write the TeX code to a file named "sample.tex" and run the default png viewer to display the resulting bitmap, do >>> preview(x+y, output='png', outputTexFile="sample.tex") # doctest: +SKIP """ special = ['pyglet'] if viewer is None: if output == "png": viewer = "pyglet" else: # sorted in order from most pretty to most ugly # very discussable, but indeed 'gv' looks awful :) # TODO add candidates for windows to list candidates = { "dvi": ["evince", "okular", "kdvi", "xdvi"], "ps": ["evince", "okular", "gsview", "gv"], "pdf": ["evince", "okular", "kpdf", "acroread", "xpdf", "gv"], } try: for candidate in candidates[output]: if find_executable(candidate): viewer = candidate break else: raise SystemError( "No viewers found for '%s' output format." % output) except KeyError: raise SystemError("Invalid output format: %s" % output) else: if viewer == "file": if filename is None: SymPyDeprecationWarning( feature="Using viewer=\"file\" without a " "specified filename ", last_supported_version="0.7.3", use_instead="viewer=\"file\" and filename=\"desiredname\"") elif viewer == "StringIO": if outputbuffer is None: raise ValueError("outputbuffer has to be a StringIO " "compatible object if viewer=\"StringIO\"") elif viewer not in special and not find_executable(viewer): raise SystemError("Unrecognized viewer: %s" % viewer) if preamble is None: actual_packages = packages + ("amsmath", "amsfonts") if euler: actual_packages += ("euler", ) package_includes = "\n" + "\n".join( ["\\usepackage{%s}" % p for p in actual_packages]) preamble = r"""\documentclass[12pt]{article} \pagestyle{empty} %s \begin{document} """ % (package_includes) else: if len(packages) > 0: raise ValueError("The \"packages\" keyword must not be set if a " "custom LaTeX preamble was specified") latex_main = preamble + '\n%s\n\n' + r"\end{document}" if isinstance(expr, str): latex_string = expr else: latex_string = latex(expr, mode='inline', **latex_settings) try: workdir = tempfile.mkdtemp() with open(join(workdir, 'texput.tex'), 'w') as fh: fh.write(latex_main % latex_string) if outputTexFile is not None: shutil.copyfile(join(workdir, 'texput.tex'), outputTexFile) with open(os.devnull, 'w') as devnull: check_call(['latex', '-halt-on-error', 'texput.tex'], cwd=workdir, stdout=devnull, stderr=STDOUT) if output != "dvi": defaultoptions = { "ps": [], "pdf": [], "png": ["-T", "tight", "-z", "9", "--truecolor"] } commandend = { "ps": ["-o", "texput.ps", "texput.dvi"], "pdf": ["texput.dvi", "texput.pdf"], "png": ["-o", "texput.png", "texput.dvi"] } cmd = ["dvi" + output] try: if dvioptions is not None: cmd.extend(dvioptions) else: cmd.extend(defaultoptions[output]) cmd.extend(commandend[output]) except KeyError: raise SystemError("Invalid output format: %s" % output) with open(os.devnull, 'w') as devnull: check_call(cmd, cwd=workdir, stdout=devnull, stderr=STDOUT) src = "texput.%s" % (output) if viewer == "file": if filename is None: buffer = StringIO() with open(join(workdir, src), 'rb') as fh: buffer.write(fh.read()) return buffer else: shutil.move(join(workdir, src), filename) elif viewer == "StringIO": with open(join(workdir, src), 'rb') as fh: outputbuffer.write(fh.read()) elif viewer == "pyglet": try: from pyglet import window, image, gl from pyglet.window import key except ImportError: raise ImportError( "pyglet is required for plotting.\n visit http://www.pyglet.org/" ) if output == "png": from pyglet.image.codecs.png import PNGImageDecoder img = image.load(join(workdir, src), decoder=PNGImageDecoder()) else: raise SystemError("pyglet preview works only for 'png' files.") offset = 25 win = window.Window(width=img.width + 2 * offset, height=img.height + 2 * offset, caption="sympy", resizable=False) win.set_vsync(False) try: def on_close(): win.has_exit = True win.on_close = on_close def on_key_press(symbol, modifiers): if symbol in [key.Q, key.ESCAPE]: on_close() win.on_key_press = on_key_press def on_expose(): gl.glClearColor(1.0, 1.0, 1.0, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) img.blit((win.width - img.width) / 2, (win.height - img.height) / 2) win.on_expose = on_expose while not win.has_exit: win.dispatch_events() win.flip() except KeyboardInterrupt: pass win.close() else: with open(os.devnull, 'w') as devnull: check_call([viewer, src], cwd=workdir, stdout=devnull, stderr=STDOUT) finally: try: shutil.rmtree(workdir) # delete directory except OSError, e: if e.errno != 2: # code 2 - no such file or directory raise
def _latex_(self): r""" LaTeX representation of a table. If an entry is a Sage object, it is replaced by its LaTeX representation, delimited by dollar signs (i.e., ``x`` is replaced by ``$latex(x)$``). If an entry is a string, the dollar signs are not automatically added, so tables can include both plain text and mathematics. OUTPUT: String. EXAMPLES:: sage: from sage.misc.table import table sage: a = [[r'$\sin(x)$', '$x$', 'text'], [1,34342,3], [identity_matrix(2),5,6]] sage: latex(table(a)) # indirect doctest \begin{tabular}{lll} $\sin(x)$ & $x$ & text \\ $1$ & $34342$ & $3$ \\ $\left(\begin{array}{rr} 1 & 0 \\ 0 & 1 \end{array}\right)$ & $5$ & $6$ \\ \end{tabular} sage: latex(table(a, frame=True, align='center')) \begin{tabular}{|c|c|c|} \hline $\sin(x)$ & $x$ & text \\ \hline $1$ & $34342$ & $3$ \\ \hline $\left(\begin{array}{rr} 1 & 0 \\ 0 & 1 \end{array}\right)$ & $5$ & $6$ \\ \hline \end{tabular} """ from latex import latex, LatexExpr import types rows = self._rows nc = len(rows[0]) if len(rows) == 0 or nc == 0: return "" align_char = self._options['align'][0] # 'l', 'c', 'r' if self._options['frame']: frame_char = '|' frame_str = ' \\hline' else: frame_char = '' frame_str = '' if self._options['header_column']: head_col_char = '|' else: head_col_char = '' if self._options['header_row']: head_row_str = ' \\hline' else: head_row_str = '' # table header s = "\\begin{tabular}{" s += frame_char + align_char + frame_char + head_col_char s += frame_char.join([align_char] * (nc-1)) s += frame_char + "}" + frame_str + "\n" # first row s += " & ".join(LatexExpr(x) if isinstance(x, (str, LatexExpr)) else '$' + latex(x).strip() + '$' for x in rows[0]) s += " \\\\" + frame_str + head_row_str + "\n" # other rows for row in rows[1:]: s += " & ".join(LatexExpr(x) if isinstance(x, (str, LatexExpr)) else '$' + latex(x).strip() + '$' for x in row) s += " \\\\" + frame_str + "\n" s += "\\end{tabular}" return s
def _fmtSml_latex(x): return "\\small" + _lu.latex(x) def _fmtSml_py(x): return x
def as_latex(self): from latex import latex return latex(self)
def _fmtEBPi_latex(t): if t[1] is not None: return "$ \\begin{array}{c}(%s \\\\ \pm %s)\\pi \\end{array} $" % (_lu.latex(t[0]), _lu.latex(t[1])) else: return _fmtPi_latex(t[0])
def _fmtNml_latex(x): return _lu.latex(x) def _fmtNml_py(x): return x
def _fmtEBvec_latex(t): if t[1] is not None: return "%s $\pm$ %s" % (_lu.latex(t[0]), _lu.latex(t[1])) else: return _lu.latex(t[0])
def _fmtBrk_latex(x): return _lu.latex(x, brackets=True) def _fmtBrk_py(x): return x
def _fmtPi_latex(x): if x == "" or x == "--": return x else: return _lu.latex(x) + "$\\pi$"
def _fmtBold_latex(x): return "\\textbf{%s}" % _lu.latex(x)
def _html_table_row(self, file, row, header=False): r""" Write table row Helper method used by the :meth:`_html_` method. INPUT: - ``file`` -- file-like object. The table row data will be written to it. - ``row`` -- a list with the same number of entries as each row of the table. - ``header`` -- bool (default False). If True, treat this as a header row, using ``<th>`` instead of ``<td>``. OUTPUT: This method returns nothing. All output is written to ``file``. Strings are written verbatim unless they seem to be LaTeX code, in which case they are enclosed in a ``script`` tag appropriate for MathJax. Sage objects are printed using their LaTeX representations. EXAMPLES:: sage: T = table([['a', 'bb', 'ccccc'], [10, -12, 0], [1, 2, 3]]) sage: import StringIO sage: s = StringIO.StringIO() sage: T._html_table_row(s, ['a', 2, '$x$']) sage: print(s.getvalue()) <td>a</td> <td><script type="math/tex">2</script></td> <td><script type="math/tex">x</script></td> """ from sage.plot.all import Graphics from latex import latex from html import math_parse import types if isinstance(row, types.GeneratorType): row = list(row) elif not isinstance(row, (list, tuple)): row = [row] column_tag = "<th>%s</th>\n" if header else "<td>%s</td>\n" if self._options['header_column']: first_column_tag = '<th class="ch">%s</th>\n' if header else '<td class="ch">%s</td>\n' else: first_column_tag = column_tag # First entry of row: entry = row[0] if isinstance(entry, Graphics): file.write(first_column_tag % entry.show(linkmode=True)) elif isinstance(entry, str): file.write(first_column_tag % math_parse(entry)) else: file.write(first_column_tag % ('<script type="math/tex">%s</script>' % latex(entry))) # Other entries: for column in xrange(1, len(row)): if isinstance(row[column], Graphics): file.write(column_tag % row[column].show(linkmode=True)) elif isinstance(row[column], str): file.write(column_tag % math_parse(row[column])) else: file.write(column_tag % ('<script type="math/tex">%s</script>' % latex(row[column])))
def get(self, padName): j = getHtml(padName) r = Response(latex(j['data']['html']), mimetype='application/x-latex') r.headers['Content-Disposition'] = 'attachment; filename=%s.tex' % padName.split('$')[1] return r
def preview(expr, output='png', viewer=None, euler=True, packages=(), **latex_settings): r""" View expression or LaTeX markup in PNG, DVI, PostScript or PDF form. If the expr argument is an expression, it will be exported to LaTeX and then compiled using available the TeX distribution. The first argument, 'expr', may also be a LaTeX string. The function will then run the appropriate viewer for the given output format or use the user defined one. By default png output is generated. By default pretty Euler fonts are used for typesetting (they were used to typeset the well known "Concrete Mathematics" book). For that to work, you need the 'eulervm.sty' LaTeX style (in Debian/Ubuntu, install the texlive-fonts-extra package). If you prefer default AMS fonts or your system lacks 'eulervm' LaTeX package then unset the 'euler' keyword argument. To use viewer auto-detection, lets say for 'png' output, issue >>> from sympy import symbols, preview, Symbol >>> x, y = symbols("x,y") >>> preview(x + y, output='png') # doctest: +SKIP This will choose 'pyglet' by default. To select a different one, do >>> preview(x + y, output='png', viewer='gimp') # doctest: +SKIP The 'png' format is considered special. For all other formats the rules are slightly different. As an example we will take 'dvi' output format. If you would run >>> preview(x + y, output='dvi') # doctest: +SKIP then 'view' will look for available 'dvi' viewers on your system (predefined in the function, so it will try evince, first, then kdvi and xdvi). If nothing is found you will need to set the viewer explicitly. >>> preview(x + y, output='dvi', viewer='superior-dvi-viewer') # doctest: +SKIP This will skip auto-detection and will run user specified 'superior-dvi-viewer'. If 'view' fails to find it on your system it will gracefully raise an exception. You may also enter 'file' for the viewer argument. Doing so will cause this function to return a file object in read-only mode. Currently this depends on pexpect, which is not available for windows. Additional keyword args will be passed to the latex call, e.g., the symbol_names flag. >>> phidd = Symbol('phidd') >>> preview(phidd, symbol_names={phidd:r'\ddot{\varphi}'}) # doctest: +SKIP """ # we don't want to depend on anything not in the # standard library with SymPy by default import pexpect special = [ 'pyglet' ] if viewer is None: if output == "png": viewer = "pyglet" else: # sorted in order from most pretty to most ugly # very discussable, but indeed 'gv' looks awful :) candidates = { "dvi": [ "evince", "okular", "kdvi", "xdvi" ], "ps": [ "evince", "okular", "gsview", "gv" ], "pdf": [ "evince", "okular", "kpdf", "acroread", "xpdf", "gv" ], } try: for candidate in candidates[output]: if pexpect.which(candidate): viewer = candidate break else: raise SystemError( "No viewers found for '%s' output format." % output) except KeyError: raise SystemError("Invalid output format: %s" % output) else: if viewer not in special and not pexpect.which(viewer): raise SystemError("Unrecognized viewer: %s" % viewer) actual_packages = packages + ("amsmath", "amsfonts") if euler: actual_packages += ("euler",) package_includes = "\n".join(["\\usepackage{%s}" % p for p in actual_packages]) format = r"""\documentclass[12pt]{article} %s \begin{document} \pagestyle{empty} %s \vfill \end{document} """ % (package_includes, "%s") if isinstance(expr, str): latex_string = expr else: latex_string = latex(expr, mode='inline', **latex_settings) tmp = tempfile.mktemp() with open(tmp + ".tex", "w") as tex: tex.write(format % latex_string) cwd = os.getcwd() os.chdir(tempfile.gettempdir()) if os.system("latex -halt-on-error %s.tex" % tmp) != 0: raise SystemError("Failed to generate DVI output.") os.remove(tmp + ".tex") os.remove(tmp + ".aux") os.remove(tmp + ".log") if output != "dvi": command = { "ps": "dvips -o %s.ps %s.dvi", "pdf": "dvipdf %s.dvi %s.pdf", "png": "dvipng -T tight -z 9 " + "--truecolor -o %s.png %s.dvi", } try: if os.system(command[output] % (tmp, tmp)) != 0: raise SystemError("Failed to generate '%s' output." % output) else: os.remove(tmp + ".dvi") except KeyError: raise SystemError("Invalid output format: %s" % output) src = "%s.%s" % (tmp, output) src_file = None if viewer == "file": src_file = open(src, 'rb') elif viewer == "pyglet": try: from pyglet import window, image, gl from pyglet.window import key except ImportError: raise ImportError("pyglet is required for plotting.\n visit http://www.pyglet.org/") if output == "png": from pyglet.image.codecs.png import PNGImageDecoder img = image.load(src, decoder=PNGImageDecoder()) else: raise SystemError("pyglet preview works only for 'png' files.") offset = 25 win = window.Window( width=img.width + 2*offset, height=img.height + 2*offset, caption="sympy", resizable=False ) win.set_vsync(False) try: def on_close(): win.has_exit = True win.on_close = on_close def on_key_press(symbol, modifiers): if symbol in [key.Q, key.ESCAPE]: on_close() win.on_key_press = on_key_press def on_expose(): gl.glClearColor(1.0, 1.0, 1.0, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) img.blit( (win.width - img.width) / 2, (win.height - img.height) / 2 ) win.on_expose = on_expose while not win.has_exit: win.dispatch_events() win.flip() except KeyboardInterrupt: pass win.close() else: os.system("%s %s &> /dev/null &" % (viewer, src)) time.sleep(2) # wait for the viewer to read data os.remove(src) os.chdir(cwd) if src_file is not None: return src_file
def preview(expr, output='png', viewer=None, euler=True, packages=(), filename=None, outputbuffer=None, preamble=None, dvioptions=None, outputTexFile=None, **latex_settings): r""" View expression or LaTeX markup in PNG, DVI, PostScript or PDF form. If the expr argument is an expression, it will be exported to LaTeX and then compiled using the available TeX distribution. The first argument, 'expr', may also be a LaTeX string. The function will then run the appropriate viewer for the given output format or use the user defined one. By default png output is generated. By default pretty Euler fonts are used for typesetting (they were used to typeset the well known "Concrete Mathematics" book). For that to work, you need the 'eulervm.sty' LaTeX style (in Debian/Ubuntu, install the texlive-fonts-extra package). If you prefer default AMS fonts or your system lacks 'eulervm' LaTeX package then unset the 'euler' keyword argument. To use viewer auto-detection, lets say for 'png' output, issue >>> from sympy import symbols, preview, Symbol >>> x, y = symbols("x,y") >>> preview(x + y, output='png') This will choose 'pyglet' by default. To select a different one, do >>> preview(x + y, output='png', viewer='gimp') The 'png' format is considered special. For all other formats the rules are slightly different. As an example we will take 'dvi' output format. If you would run >>> preview(x + y, output='dvi') then 'view' will look for available 'dvi' viewers on your system (predefined in the function, so it will try evince, first, then kdvi and xdvi). If nothing is found you will need to set the viewer explicitly. >>> preview(x + y, output='dvi', viewer='superior-dvi-viewer') This will skip auto-detection and will run user specified 'superior-dvi-viewer'. If 'view' fails to find it on your system it will gracefully raise an exception. You may also enter 'file' for the viewer argument. Doing so will cause this function to return a file object in read-only mode, if 'filename' is unset. However, if it was set, then 'preview' writes the genereted file to this filename instead. There is also support for writing to a StringIO like object, which needs to be passed to the 'outputbuffer' argument. >>> from StringIO import StringIO >>> obj = StringIO() >>> preview(x + y, output='png', viewer='StringIO', ... outputbuffer=obj) The LaTeX preamble can be customized by setting the 'preamble' keyword argument. This can be used, e.g., to set a different font size, use a custom documentclass or import certain set of LaTeX packages. >>> preamble = "\\documentclass[10pt]{article}\n" \ ... "\\usepackage{amsmath,amsfonts}\\begin{document}" >>> preview(x + y, output='png', preamble=preamble) If the value of 'output' is different from 'dvi' then command line options can be set ('dvioptions' argument) for the execution of the 'dvi'+output conversion tool. These options have to be in the form of a list of strings (see subprocess.Popen). Additional keyword args will be passed to the latex call, e.g., the symbol_names flag. >>> phidd = Symbol('phidd') >>> preview(phidd, symbol_names={phidd:r'\ddot{\varphi}'}) For post-processing the generated TeX File can be written to a file by passing the desired filename to the 'outputTexFile' keyword argument. To write the TeX code to a file named "sample.tex" and run the default png viewer to display the resulting bitmap, do >>> preview(x+y, outputTexFile="sample.tex") """ special = [ 'pyglet' ] if viewer is None: if output == "png": viewer = "pyglet" else: # sorted in order from most pretty to most ugly # very discussable, but indeed 'gv' looks awful :) # TODO add candidates for windows to list candidates = { "dvi": [ "evince", "okular", "kdvi", "xdvi" ], "ps": [ "evince", "okular", "gsview", "gv" ], "pdf": [ "evince", "okular", "kpdf", "acroread", "xpdf", "gv" ], } try: for candidate in candidates[output]: path = find_executable(candidate) if path is not None: viewer = path break else: raise SystemError( "No viewers found for '%s' output format." % output) except KeyError: raise SystemError("Invalid output format: %s" % output) else: if viewer == "file": if filename is None: SymPyDeprecationWarning(feature="Using viewer=\"file\" without a " "specified filename ", last_supported_version="0.7.3", use_instead="viewer=\"file\" and filename=\"desiredname\"") elif viewer == "StringIO": if outputbuffer is None: raise ValueError("outputbuffer has to be a StringIO " "compatible object if viewer=\"StringIO\"") elif viewer not in special and not find_executable(viewer): raise SystemError("Unrecognized viewer: %s" % viewer) if preamble is None: actual_packages = packages + ("amsmath", "amsfonts") if euler: actual_packages += ("euler",) package_includes = "\n" + "\n".join(["\\usepackage{%s}" % p for p in actual_packages]) preamble = r"""\documentclass[12pt]{article} \pagestyle{empty} %s \begin{document} """ % (package_includes) else: if len(packages) > 0: raise ValueError("The \"packages\" keyword must not be set if a " "custom LaTeX preamble was specified") latex_main = preamble + '\n%s\n\n' + r"\end{document}" if isinstance(expr, str): latex_string = expr else: latex_string = latex(expr, mode='inline', **latex_settings) try: workdir = tempfile.mkdtemp() with open(join(workdir, 'texput.tex'), 'w') as fh: fh.write(latex_main % latex_string) if outputTexFile is not None: shutil.copyfile(join(workdir, 'texput.tex'), outputTexFile) if not find_executable('latex'): raise RuntimeError("latex program is not installed") try: check_output(['latex', '-halt-on-error', '-interaction=nonstopmode', 'texput.tex'], cwd=workdir, stderr=STDOUT) except CalledProcessError, e: raise RuntimeError( "'latex' exited abnormally with the following output:\n%s" % e.output) if output != "dvi": defaultoptions = { "ps": [], "pdf": [], "png": ["-T", "tight", "-z", "9", "--truecolor"] } commandend = { "ps": ["-o", "texput.ps", "texput.dvi"], "pdf": ["texput.dvi", "texput.pdf"], "png": ["-o", "texput.png", "texput.dvi"] } cmd = ["dvi" + output] if not find_executable(cmd[0]): raise RuntimeError("%s is not installed" % cmd[0]) try: if dvioptions is not None: cmd.extend(dvioptions) else: cmd.extend(defaultoptions[output]) cmd.extend(commandend[output]) except KeyError: raise SystemError("Invalid output format: %s" % output) try: check_output(cmd, cwd=workdir, stderr=STDOUT) except CalledProcessError, e: raise RuntimeError( "'%s' exited abnormally with the following output:\n%s" % (' '.join(cmd), e.output))
def preview(expr, output='png', viewer=None, euler=True): """View expression in PNG, DVI, PostScript or PDF form. This will generate LaTeX representation of the given expression and compile it using available TeX distribution. Then it will run appropriate viewer for the given output format or use the user defined one. If you prefer not to use external viewer then you can use combination of 'png' output and 'pyglet' viewer. By default png output is generated. By default pretty Euler fonts are used for typesetting (they were used to typeset the well known "Concrete Mathematics" book). For that to work, you need the 'eulervm.sty' LaTeX style (in Debian/Ubuntu, install the texlive-fonts-extra package). If you prefer default AMS fonts or your system lacks 'eulervm' LaTeX package then unset the 'euler' keyword argument. To use viewer auto-detection, lets say for 'png' output, issue:: >> from sympy import * >> x, y = symbols("xy") >> preview(x + y, output='png') This will choose 'pyglet by default. To select different one:: >> preview(x + y, output='png', viewer='gimp') The 'png' format is considered special. For all other formats the rules are slightly different. As an example we will take 'dvi' output format. If you would run:: >> preview(x + y, output='dvi') then 'view' will look for available 'dvi' viewers on your system (predefined in the function, so it will try evince, first, then kdvi and xdvi). If nothing is found you will need to set the viewer explicitly:: >> preview(x + y, output='dvi', viewer='superior-dvi-viewer') This will skip auto-detection and will run user specified 'superior-dvi-viewer'. If 'view' fails to find it on your system it will gracefully raise an exception. Currently this depends on pexpect, which is not available for windows. """ # we don't want to depend on anything not in the # standard library with SymPy by default import pexpect special = [ 'pyglet' ] if viewer is None: if output == "png": viewer = "pyglet" else: # sorted in order from most pretty to most ugly # very discussable, but indeed 'gv' looks awful :) candidates = { "dvi" : [ "evince", "okular", "kdvi", "xdvi" ], "ps" : [ "evince", "okular", "gsview", "gv" ], "pdf" : [ "evince", "okular", "kpdf", "acroread", "xpdf", "gv" ], } try: for candidate in candidates[output]: if pexpect.which(candidate): viewer = candidate break else: raise SystemError("No viewers found for '%s' output format." % output) except KeyError: raise SystemError("Invalid output format: %s" % output) else: if viewer not in special and not pexpect.which(viewer): raise SystemError("Unrecognized viewer: %s" % viewer) if not euler: format = r"""\documentclass[12pt]{article} \usepackage{amsmath} \begin{document} \pagestyle{empty} %s \vfill \end{document} """ else: format = r"""\documentclass[12pt]{article} \usepackage{amsmath} \usepackage{eulervm} \begin{document} \pagestyle{empty} %s \vfill \end{document} """ if viewer == "pyglet": # import pyglet before we change the current dir, because after that it # would fail: from sympy.thirdparty import import_thirdparty pyglet = import_thirdparty("pyglet") tmp = tempfile.mktemp() tex = open(tmp + ".tex", "w") tex.write(format % latex(expr, mode='inline')) tex.close() cwd = os.getcwd() os.chdir(tempfile.gettempdir()) if os.system("latex -halt-on-error %s.tex" % tmp) != 0: raise SystemError("Failed to generate DVI output.") os.remove(tmp + ".tex") os.remove(tmp + ".aux") os.remove(tmp + ".log") if output != "dvi": command = { "ps" : "dvips -o %s.ps %s.dvi", "pdf" : "dvipdf %s.dvi %s.pdf", "png" : "dvipng -T tight -z 9 " + \ "--truecolor -o %s.png %s.dvi", } try: if os.system(command[output] % (tmp, tmp)) != 0: raise SystemError("Failed to generate '%s' output." % output) else: os.remove(tmp + ".dvi") except KeyError: raise SystemError("Invalid output format: %s" % output) src = "%s.%s" % (tmp, output) if viewer == "pyglet": from pyglet import window, image, gl from pyglet.window import key if output == "png": from pyglet.image.codecs.png import PNGImageDecoder img = image.load(src, decoder=PNGImageDecoder()) else: raise SystemError("pyglet preview works only for 'png' files.") offset = 25 win = window.Window( width = img.width + 2*offset, height = img.height + 2*offset, caption = "sympy", resizable = False ) win.set_vsync(False) try: def on_close(): win.has_exit = True win.on_close = on_close def on_key_press(symbol, modifiers): if symbol in [key.Q, key.ESCAPE]: on_close() win.on_key_press = on_key_press def on_expose(): gl.glClearColor(1.0, 1.0, 1.0, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) img.blit( (win.width - img.width) / 2, (win.height - img.height) / 2 ) win.on_expose = on_expose while not win.has_exit: win.dispatch_events() win.flip() except KeyboardInterrupt: pass win.close() else: os.system("%s %s &> /dev/null &" % (viewer, src)) time.sleep(2) # wait for the viewer to read data os.remove(src) os.chdir(cwd)
def _fmtNml_latex(x): return _lu.latex(x)
def _html_table_row(self, file, row, header=False): r""" Write table row Helper method used by the :meth:`_html_` method. INPUT: - ``file`` -- file-like object. The table row data will be written to it. - ``row`` -- a list with the same number of entries as each row of the table. - ``header`` -- bool (default False). If True, treat this as a header row, using ``<th>`` instead of ``<td>``. OUTPUT: This method returns nothing. All output is written to ``file``. Strings are written verbatim unless they seem to be LaTeX code, in which case they are enclosed in a ``script`` tag appropriate for MathJax. Sage objects are printed using their LaTeX representations. EXAMPLES:: sage: T = table([['a', 'bb', 'ccccc'], [10, -12, 0], [1, 2, 3]]) sage: import StringIO sage: s = StringIO.StringIO() sage: T._html_table_row(s, ['a', 2, '$x$']) sage: print(s.getvalue()) <td>a</td> <td><script type="math/tex">2</script></td> <td><script type="math/tex">x</script></td> """ from sage.plot.all import Graphics from latex import latex from html import math_parse import types if isinstance(row, types.GeneratorType): row = list(row) elif not isinstance(row, (list, tuple)): row = [row] column_tag = "<th>%s</th>\n" if header else "<td>%s</td>\n" if self._options['header_column']: first_column_tag = '<th class="ch">%s</th>\n' if header else '<td class="ch">%s</td>\n' else: first_column_tag = column_tag # First entry of row: entry = row[0] if isinstance(entry, Graphics): file.write(first_column_tag % entry.show(linkmode = True)) elif isinstance(entry, str): file.write(first_column_tag % math_parse(entry)) else: file.write(first_column_tag % ('<script type="math/tex">%s</script>' % latex(entry))) # Other entries: for column in xrange(1,len(row)): if isinstance(row[column], Graphics): file.write(column_tag % row[column].show(linkmode = True)) elif isinstance(row[column], str): file.write(column_tag % math_parse(row[column])) else: file.write(column_tag % ('<script type="math/tex">%s</script>' % latex(row[column])))
def _fmtSml_latex(x): return "\\small" + _lu.latex(x)
def _html_table_row(self, row, header=False): r""" Print the items of a list as one row of an HTML table. Used by the :meth:`_html_` method. INPUTS: - ``row`` - a list with the same number of entries as each row of the table. - ``header`` (default False) - if True, treat this as a header row, using ``<th>`` instead of ``<td>``. Strings get printed verbatim unless they seem to be LaTeX code, in which case they are enclosed in a ``script`` tag appropriate for MathJax. Sage objects are printed using their LaTeX representations. EXAMPLES:: sage: T = table([['a', 'bb', 'ccccc'], [10, -12, 0], [1, 2, 3]]) sage: T._html_table_row(['a', 2, '$x$']) <td>a</td> <td><script type="math/tex">2</script></td> <td><script type="math/tex">x</script></td> """ from sage.plot.all import Graphics from latex import latex from html import math_parse import types if isinstance(row, types.GeneratorType): row = list(row) elif not isinstance(row, (list, tuple)): row = [row] column_tag = "<th>%s</th>" if header else "<td>%s</td>" if self._options['header_column']: first_column_tag = "<th class=\"ch\">%s</th>" if header else "<td class=\"ch\">%s</td>" else: first_column_tag = column_tag # First entry of row: entry = row[0] if isinstance(entry, Graphics): print(first_column_tag % entry.show(linkmode=True)) elif isinstance(entry, str): print(first_column_tag % math_parse(entry)) else: print(first_column_tag % ('<script type="math/tex">%s</script>' % latex(entry))) # Other entries: for column in xrange(1, len(row)): if isinstance(row[column], Graphics): print(column_tag % row[column].show(linkmode=True)) elif isinstance(row[column], str): print(column_tag % math_parse(row[column])) else: print(column_tag % ('<script type="math/tex">%s</script>' % latex(row[column])))
def _fmtBrk_latex(x): return _lu.latex(x, brackets=True)
def preview(expr, output='png', viewer=None, euler=True, packages=(), filename=None, outputbuffer=None, preamble=None, dvioptions=None, outputTexFile=None, **latex_settings): r""" View expression or LaTeX markup in PNG, DVI, PostScript or PDF form. If the expr argument is an expression, it will be exported to LaTeX and then compiled using the available TeX distribution. The first argument, 'expr', may also be a LaTeX string. The function will then run the appropriate viewer for the given output format or use the user defined one. By default png output is generated. By default pretty Euler fonts are used for typesetting (they were used to typeset the well known "Concrete Mathematics" book). For that to work, you need the 'eulervm.sty' LaTeX style (in Debian/Ubuntu, install the texlive-fonts-extra package). If you prefer default AMS fonts or your system lacks 'eulervm' LaTeX package then unset the 'euler' keyword argument. To use viewer auto-detection, lets say for 'png' output, issue >>> from sympy import symbols, preview, Symbol >>> x, y = symbols("x,y") >>> preview(x + y, output='png') This will choose 'pyglet' by default. To select a different one, do >>> preview(x + y, output='png', viewer='gimp') The 'png' format is considered special. For all other formats the rules are slightly different. As an example we will take 'dvi' output format. If you would run >>> preview(x + y, output='dvi') then 'view' will look for available 'dvi' viewers on your system (predefined in the function, so it will try evince, first, then kdvi and xdvi). If nothing is found you will need to set the viewer explicitly. >>> preview(x + y, output='dvi', viewer='superior-dvi-viewer') This will skip auto-detection and will run user specified 'superior-dvi-viewer'. If 'view' fails to find it on your system it will gracefully raise an exception. You may also enter 'file' for the viewer argument. Doing so will cause this function to return a file object in read-only mode, if 'filename' is unset. However, if it was set, then 'preview' writes the genereted file to this filename instead. There is also support for writing to a StringIO like object, which needs to be passed to the 'outputbuffer' argument. >>> from StringIO import StringIO >>> obj = StringIO() >>> preview(x + y, output='png', viewer='StringIO', ... outputbuffer=obj) The LaTeX preamble can be customized by setting the 'preamble' keyword argument. This can be used, e.g., to set a different font size, use a custom documentclass or import certain set of LaTeX packages. >>> preamble = "\\documentclass[10pt]{article}\n" \ ... "\\usepackage{amsmath,amsfonts}\\begin{document}" >>> preview(x + y, output='png', preamble=preamble) If the value of 'output' is different from 'dvi' then command line options can be set ('dvioptions' argument) for the execution of the 'dvi'+output conversion tool. These options have to be in the form of a list of strings (see subprocess.Popen). Additional keyword args will be passed to the latex call, e.g., the symbol_names flag. >>> phidd = Symbol('phidd') >>> preview(phidd, symbol_names={phidd:r'\ddot{\varphi}'}) For post-processing the generated TeX File can be written to a file by passing the desired filename to the 'outputTexFile' keyword argument. To write the TeX code to a file named "sample.tex" and run the default png viewer to display the resulting bitmap, do >>> preview(x + y, outputTexFile="sample.tex") """ special = [ 'pyglet' ] if viewer is None: if output == "png": viewer = "pyglet" else: # sorted in order from most pretty to most ugly # very discussable, but indeed 'gv' looks awful :) # TODO add candidates for windows to list candidates = { "dvi": [ "evince", "okular", "kdvi", "xdvi" ], "ps": [ "evince", "okular", "gsview", "gv" ], "pdf": [ "evince", "okular", "kpdf", "acroread", "xpdf", "gv" ], } try: for candidate in candidates[output]: path = find_executable(candidate) if path is not None: viewer = path break else: raise SystemError( "No viewers found for '%s' output format." % output) except KeyError: raise SystemError("Invalid output format: %s" % output) else: if viewer == "file": if filename is None: SymPyDeprecationWarning(feature="Using viewer=\"file\" without a " "specified filename", deprecated_since_version="0.7.3", useinstead="viewer=\"file\" and filename=\"desiredname\"", issue=3919).warn() elif viewer == "StringIO": if outputbuffer is None: raise ValueError("outputbuffer has to be a StringIO " "compatible object if viewer=\"StringIO\"") elif viewer not in special and not find_executable(viewer): raise SystemError("Unrecognized viewer: %s" % viewer) if preamble is None: actual_packages = packages + ("amsmath", "amsfonts") if euler: actual_packages += ("euler",) package_includes = "\n" + "\n".join(["\\usepackage{%s}" % p for p in actual_packages]) preamble = r"""\documentclass[12pt]{article} \pagestyle{empty} %s \begin{document} """ % (package_includes) else: if len(packages) > 0: raise ValueError("The \"packages\" keyword must not be set if a " "custom LaTeX preamble was specified") latex_main = preamble + '\n%s\n\n' + r"\end{document}" if isinstance(expr, str): latex_string = expr else: latex_string = latex(expr, mode='inline', **latex_settings) try: workdir = tempfile.mkdtemp() with open(join(workdir, 'texput.tex'), 'w') as fh: fh.write(latex_main % latex_string) if outputTexFile is not None: shutil.copyfile(join(workdir, 'texput.tex'), outputTexFile) if not find_executable('latex'): raise RuntimeError("latex program is not installed") try: check_output(['latex', '-halt-on-error', '-interaction=nonstopmode', 'texput.tex'], cwd=workdir, stderr=STDOUT) except CalledProcessError, e: raise RuntimeError( "'latex' exited abnormally with the following output:\n%s" % e.output) if output != "dvi": defaultoptions = { "ps": [], "pdf": [], "png": ["-T", "tight", "-z", "9", "--truecolor"] } commandend = { "ps": ["-o", "texput.ps", "texput.dvi"], "pdf": ["texput.dvi", "texput.pdf"], "png": ["-o", "texput.png", "texput.dvi"] } cmd = ["dvi" + output] if not find_executable(cmd[0]): raise RuntimeError("%s is not installed" % cmd[0]) try: if dvioptions is not None: cmd.extend(dvioptions) else: cmd.extend(defaultoptions[output]) cmd.extend(commandend[output]) except KeyError: raise SystemError("Invalid output format: %s" % output) try: check_output(cmd, cwd=workdir, stderr=STDOUT) except CalledProcessError, e: raise RuntimeError( "'%s' exited abnormally with the following output:\n%s" % (' '.join(cmd), e.output))
def preview(expr, output='png', viewer=None, euler=True, packages=(), filename=None, outputbuffer=None, preamble=None, dvioptions=None, outputTexFile=None, **latex_settings): r""" View expression or LaTeX markup in PNG, DVI, PostScript or PDF form. If the expr argument is an expression, it will be exported to LaTeX and then compiled using the available TeX distribution. The first argument, 'expr', may also be a LaTeX string. The function will then run the appropriate viewer for the given output format or use the user defined one. By default png output is generated. By default pretty Euler fonts are used for typesetting (they were used to typeset the well known "Concrete Mathematics" book). For that to work, you need the 'eulervm.sty' LaTeX style (in Debian/Ubuntu, install the texlive-fonts-extra package). If you prefer default AMS fonts or your system lacks 'eulervm' LaTeX package then unset the 'euler' keyword argument. To use viewer auto-detection, lets say for 'png' output, issue >>> from sympy import symbols, preview, Symbol >>> x, y = symbols("x,y") >>> preview(x + y, output='png') # doctest: +SKIP This will choose 'pyglet' by default. To select a different one, do >>> preview(x + y, output='png', viewer='gimp') # doctest: +SKIP The 'png' format is considered special. For all other formats the rules are slightly different. As an example we will take 'dvi' output format. If you would run >>> preview(x + y, output='dvi') # doctest: +SKIP then 'view' will look for available 'dvi' viewers on your system (predefined in the function, so it will try evince, first, then kdvi and xdvi). If nothing is found you will need to set the viewer explicitly. >>> preview(x + y, output='dvi', viewer='superior-dvi-viewer') # doctest: +SKIP This will skip auto-detection and will run user specified 'superior-dvi-viewer'. If 'view' fails to find it on your system it will gracefully raise an exception. You may also enter 'file' for the viewer argument. Doing so will cause this function to return a file object in read-only mode, if 'filename' is unset. However, if it was set, then 'preview' writes the genereted file to this filename instead. There is also support for writing to a StringIO like object, which needs to be passed to the 'outputbuffer' argument. >>> from StringIO import StringIO >>> obj = StringIO() >>> preview(x + y, output='png', viewer='StringIO', ... outputbuffer=obj) # doctest: +SKIP The LaTeX preamble can be customized by setting the 'preamble' keyword argument. This can be used, e.g., to set a different font size, use a custom documentclass or import certain set of LaTeX packages. >>> preamble = "\\documentclass[10pt]{article}\n" \ ... "\\usepackage{amsmath,amsfonts}\\begin{document}" >>> preview(x + y, output='png', preamble=preamble) # doctest: +SKIP If the value of 'output' is different from 'dvi' then command line options can be set ('dvioptions' argument) for the execution of the 'dvi'+output conversion tool. These options have to be in the form of a list of strings (see subprocess.Popen). Additional keyword args will be passed to the latex call, e.g., the symbol_names flag. >>> phidd = Symbol('phidd') >>> preview(phidd, symbol_names={phidd:r'\ddot{\varphi}'}) # doctest: +SKIP For post-processing the generated TeX File can be written to a file by passing the desired filename to the 'outputTexFile' keyword argument. To write the TeX code to a file named "sample.tex" and run the default png viewer to display the resulting bitmap, do >>> preview(x+y, output='png', outputTexFile="sample.tex") # doctest: +SKIP """ special = [ 'pyglet' ] if viewer is None: if output == "png": viewer = "pyglet" else: # sorted in order from most pretty to most ugly # very discussable, but indeed 'gv' looks awful :) # TODO add candidates for windows to list candidates = { "dvi": [ "evince", "okular", "kdvi", "xdvi" ], "ps": [ "evince", "okular", "gsview", "gv" ], "pdf": [ "evince", "okular", "kpdf", "acroread", "xpdf", "gv" ], } try: for candidate in candidates[output]: if find_executable(candidate): viewer = candidate break else: raise SystemError( "No viewers found for '%s' output format." % output) except KeyError: raise SystemError("Invalid output format: %s" % output) else: if viewer == "file": if filename is None: SymPyDeprecationWarning(feature="Using viewer=\"file\" without a " "specified filename ", last_supported_version="0.7.3", use_instead="viewer=\"file\" and filename=\"desiredname\"") elif viewer == "StringIO": if outputbuffer is None: raise ValueError("outputbuffer has to be a StringIO " "compatible object if viewer=\"StringIO\"") elif viewer not in special and not find_executable(viewer): raise SystemError("Unrecognized viewer: %s" % viewer) if preamble is None: actual_packages = packages + ("amsmath", "amsfonts") if euler: actual_packages += ("euler",) package_includes = "\n" + "\n".join(["\\usepackage{%s}" % p for p in actual_packages]) preamble = r"""\documentclass[12pt]{article} \pagestyle{empty} %s \begin{document} """ % (package_includes) else: if len(packages) > 0: raise ValueError("The \"packages\" keyword must not be set if a " "custom LaTeX preamble was specified") latex_main = preamble + '\n%s\n\n' + r"\end{document}" if isinstance(expr, str): latex_string = expr else: latex_string = latex(expr, mode='inline', **latex_settings) try: workdir = tempfile.mkdtemp() with open(join(workdir, 'texput.tex'), 'w') as fh: fh.write(latex_main % latex_string) if outputTexFile is not None: shutil.copyfile(join(workdir, 'texput.tex'), outputTexFile) with open(os.devnull, 'w') as devnull: check_call(['latex', '-halt-on-error', 'texput.tex'], cwd=workdir, stdout=devnull, stderr=STDOUT) if output != "dvi": defaultoptions = { "ps": [], "pdf": [], "png": ["-T", "tight", "-z", "9", "--truecolor"] } commandend = { "ps": ["-o", "texput.ps", "texput.dvi"], "pdf": ["texput.dvi", "texput.pdf"], "png": ["-o", "texput.png", "texput.dvi"] } cmd = ["dvi" + output] try: if dvioptions is not None: cmd.extend(dvioptions) else: cmd.extend(defaultoptions[output]) cmd.extend(commandend[output]) except KeyError: raise SystemError("Invalid output format: %s" % output) with open(os.devnull, 'w') as devnull: check_call(cmd, cwd=workdir, stdout=devnull, stderr=STDOUT) src = "texput.%s" % (output) if viewer == "file": if filename is None: buffer = StringIO() with open(join(workdir, src), 'rb') as fh: buffer.write(fh.read()) return buffer else: shutil.move(join(workdir,src), filename) elif viewer == "StringIO": with open(join(workdir, src), 'rb') as fh: outputbuffer.write(fh.read()) elif viewer == "pyglet": try: from pyglet import window, image, gl from pyglet.window import key except ImportError: raise ImportError("pyglet is required for plotting.\n visit http://www.pyglet.org/") if output == "png": from pyglet.image.codecs.png import PNGImageDecoder img = image.load(join(workdir, src), decoder=PNGImageDecoder()) else: raise SystemError("pyglet preview works only for 'png' files.") offset = 25 win = window.Window( width=img.width + 2*offset, height=img.height + 2*offset, caption="sympy", resizable=False ) win.set_vsync(False) try: def on_close(): win.has_exit = True win.on_close = on_close def on_key_press(symbol, modifiers): if symbol in [key.Q, key.ESCAPE]: on_close() win.on_key_press = on_key_press def on_expose(): gl.glClearColor(1.0, 1.0, 1.0, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) img.blit( (win.width - img.width) / 2, (win.height - img.height) / 2 ) win.on_expose = on_expose while not win.has_exit: win.dispatch_events() win.flip() except KeyboardInterrupt: pass win.close() else: with open(os.devnull, 'w') as devnull: check_call([viewer, src], cwd=workdir, stdout=devnull, stderr=STDOUT) finally: try: shutil.rmtree(workdir) # delete directory except OSError, e: if e.errno != 2: # code 2 - no such file or directory raise