##// END OF EJS Templates
Refine package caching in GitHub actions. (#13985)
Refine package caching in GitHub actions. (#13985)

File last commit:

r28090:eccb95c2
r28178:e26539d6 merge
Show More
latextools.py
257 lines | 8.0 KiB | text/x-python | PythonLexer
Brian Granger
More improvements to the display system....
r3279 # -*- coding: utf-8 -*-
Min RK
make lib.latextools accept unicode...
r19562 """Tools for handling LaTeX."""
Brian Granger
More improvements to the display system....
r3279
Min RK
make lib.latextools accept unicode...
r19562 # Copyright (c) IPython Development Team.
Brian Granger
More improvements to the display system....
r3279 # Distributed under the terms of the Modified BSD License.
Min RK
make lib.latextools accept unicode...
r19562 from io import BytesIO, open
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306 import os
import tempfile
import shutil
import subprocess
Srinivas Reddy Thatiparthy
remove code specific to python2
r23063 from base64 import encodebytes
Matthias Bussonnier
Use explicit fully qualified name instead of uncommon alias....
r25162 import textwrap
Brian Granger
More improvements to the display system....
r3279
Matthias Bussonnier
try ruff to find unused imports
r27764 from pathlib import Path
Romulo Filho
Use pathlib in latextools.py
r26059
Takafumi Arakaki
Check if latex/dvipng exist before calling them
r7330 from IPython.utils.process import find_cmd, FindCmdError
Min RK
update dependency imports...
r21253 from traitlets.config import get_config
from traitlets.config.configurable import SingletonConfigurable
from traitlets import List, Bool, Unicode
Srinivas Reddy Thatiparthy
remove python2 specific cast_unicode_py2 function
r23669 from IPython.utils.py3compat import cast_unicode
Matthias Bussonnier
Remove deprecated encodestring infavor of encodebytes
r21869
Brian Granger
More improvements to the display system....
r3279
Takafumi Arakaki
Make lib.latextools configurable...
r7861 class LaTeXTool(SingletonConfigurable):
"""An object to store configuration of the LaTeX tool."""
Min RK
hook up latex tools config to global instance...
r19565 def _config_default(self):
return get_config()
Oscar Gustafsson
Enable changing the font color for LaTeX rendering
r25160
Takafumi Arakaki
Make lib.latextools configurable...
r7861 backends = List(
Jason Grout
Fix one more deprecated trait type vs. instance case
r21538 Unicode(), ["matplotlib", "dvipng"],
Takafumi Arakaki
Make lib.latextools configurable...
r7861 help="Preferred backend to draw LaTeX math equations. "
"Backends in the list are checked one by one and the first "
"usable one is used. Note that `matplotlib` backend "
"is usable only for inline style equations. To draw "
"display style equations, `dvipng` backend must be specified. ",
# It is a List instead of Enum, to make configuration more
# flexible. For example, to use matplotlib mainly but dvipng
# for display style, the default ["matplotlib", "dvipng"] can
# be used. To NOT use dvipng so that other repr such as
# unicode pretty printing is used, you can use ["matplotlib"].
Matthias Bussonnier
Update /IPython/lib/latextool.py to use new traitlets API.
r22343 ).tag(config=True)
Takafumi Arakaki
Make lib.latextools configurable...
r7861
Min RK
make lib.latextools accept unicode...
r19562 use_breqn = Bool(
Takafumi Arakaki
Make lib.latextools configurable...
r7861 True,
help="Use breqn.sty to automatically break long equations. "
"This configuration takes effect only for dvipng backend.",
Matthias Bussonnier
Update /IPython/lib/latextool.py to use new traitlets API.
r22343 ).tag(config=True)
Takafumi Arakaki
Make lib.latextools configurable...
r7861
packages = List(
['amsmath', 'amsthm', 'amssymb', 'bm'],
help="A list of packages to use for dvipng backend. "
"'breqn' will be automatically appended when use_breqn=True.",
Matthias Bussonnier
Update /IPython/lib/latextool.py to use new traitlets API.
r22343 ).tag(config=True)
Takafumi Arakaki
Make lib.latextools configurable...
r7861
Min RK
make lib.latextools accept unicode...
r19562 preamble = Unicode(
Takafumi Arakaki
Make lib.latextools configurable...
r7861 help="Additional preamble to use when generating LaTeX source "
"for dvipng backend.",
Matthias Bussonnier
Update /IPython/lib/latextool.py to use new traitlets API.
r22343 ).tag(config=True)
Takafumi Arakaki
Make lib.latextools configurable...
r7861
Oscar Gustafsson
Better color options and added scale
r25161 def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black',
scale=1.0):
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306 """Render a LaTeX string to PNG.
Brian Granger
More improvements to the display system....
r3279
Parameters
----------
klonuo
Fix argument type in docsting
r22484 s : str
Brian Granger
More improvements to the display system....
r3279 The raw string containing valid inline LaTeX.
encode : bool, optional
Min RK
make lib.latextools accept unicode...
r19562 Should the PNG data base64 encoded to make it JSON'able.
Takafumi Arakaki
Make lib.latextools configurable...
r7861 backend : {matplotlib, dvipng}
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306 Backend for producing PNG data.
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 wrap : bool
If true, Automatically wrap `s` as a LaTeX equation.
Oscar Gustafsson
Enable changing the font color for LaTeX rendering
r25160 color : string
Oscar Gustafsson
Better color options and added scale
r25161 Foreground color name among dvipsnames, e.g. 'Maroon' or on hex RGB
format, e.g. '#AA20FA'.
scale : float
Scale factor for the resulting PNG.
Takafumi Arakaki
latex_to_png returns None when the backend cannot be used...
r7309 None is returned when the backend cannot be used.
Brian Granger
More improvements to the display system....
r3279 """
Min RK
make lib.latextools accept unicode...
r19562 s = cast_unicode(s)
Takafumi Arakaki
Make lib.latextools configurable...
r7861 allowed_backends = LaTeXTool.instance().backends
if backend is None:
backend = allowed_backends[0]
if backend not in allowed_backends:
return None
if backend == 'matplotlib':
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306 f = latex_to_png_mpl
elif backend == 'dvipng':
f = latex_to_png_dvipng
Oscar Gustafsson
Better color options and added scale
r25161 if color.startswith('#'):
# Convert hex RGB color to LaTeX RGB color.
if len(color) == 7:
try:
color = "RGB {}".format(" ".join([str(int(x, 16)) for x in
Matthias Bussonnier
Use explicit fully qualified name instead of uncommon alias....
r25162 textwrap.wrap(color[1:], 2)]))
Ram Rachum
Fix exception causes all over the codebase
r25833 except ValueError as e:
raise ValueError('Invalid color specification {}.'.format(color)) from e
Oscar Gustafsson
Better color options and added scale
r25161 else:
raise ValueError('Invalid color specification {}.'.format(color))
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306 else:
raise ValueError('No such backend {0}'.format(backend))
Oscar Gustafsson
Better color options and added scale
r25161 bin_data = f(s, wrap, color, scale)
Takafumi Arakaki
latex_to_png returns None when the backend cannot be used...
r7309 if encode and bin_data:
Matthias Bussonnier
Remove deprecated encodestring infavor of encodebytes
r21869 bin_data = encodebytes(bin_data)
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306 return bin_data
Oscar Gustafsson
Better color options and added scale
r25161 def latex_to_png_mpl(s, wrap, color='Black', scale=1.0):
Takafumi Arakaki
latex_to_png returns None when the backend cannot be used...
r7309 try:
Jake VanderPlas
latex_to_png: avoid deprecated matplotlib functions
r26423 from matplotlib import figure, font_manager, mathtext
from matplotlib.backends import backend_agg
Carlos Cordoba
Latextools: Use the right exceptions to catch errors
r22075 from pyparsing import ParseFatalException
Takafumi Arakaki
latex_to_png returns None when the backend cannot be used...
r7309 except ImportError:
return None
Carlos Cordoba
Latextools: Use the right exceptions to catch errors
r22075
Min RK
mpl mathtext doesn't support display math...
r19564 # mpl mathtext doesn't support display math, force inline
s = s.replace('$$', '$')
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 if wrap:
Min RK
make lib.latextools accept unicode...
r19562 s = u'${0}$'.format(s)
Carlos Cordoba
Latextools: Make latex_to_png_mpl not fail on errors...
r22050
try:
Jake VanderPlas
latex_to_png: avoid deprecated matplotlib functions
r26423 prop = font_manager.FontProperties(size=12)
dpi = 120 * scale
buffer = BytesIO()
# Adapted from mathtext.math_to_image
parser = mathtext.MathTextParser("path")
width, height, depth, _, _ = parser.parse(s, dpi=72, prop=prop)
fig = figure.Figure(figsize=(width / 72, height / 72))
fig.text(0, depth / height, s, fontproperties=prop, color=color)
backend_agg.FigureCanvasAgg(fig)
fig.savefig(buffer, dpi=dpi, format="png", transparent=True)
return buffer.getvalue()
Carlos Cordoba
Latextools: Use the right exceptions to catch errors
r22075 except (ValueError, RuntimeError, ParseFatalException):
Carlos Cordoba
Latextools: Make latex_to_png_mpl not fail on errors...
r22050 return None
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306
Oscar Gustafsson
Better color options and added scale
r25161 def latex_to_png_dvipng(s, wrap, color='Black', scale=1.0):
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306 try:
Takafumi Arakaki
Check if latex/dvipng exist before calling them
r7330 find_cmd('latex')
find_cmd('dvipng')
except FindCmdError:
return None
Pieter Eendebak
prevent popup windows during execution of latex_to_png_dvipng
r27699
startupinfo = None
Pieter Eendebak
darker
r27700 if os.name == "nt":
Pieter Eendebak
prevent popup windows during execution of latex_to_png_dvipng
r27699 # prevent popup-windows
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
Takafumi Arakaki
Check if latex/dvipng exist before calling them
r7330 try:
Matthias Bussonnier
Remove yield test that are not support by pytest anymore...
r26183 workdir = Path(tempfile.mkdtemp())
Pieter Eendebak
use relative filename in latex and dvips commands
r27702 tmpfile = "tmp.tex"
dvifile = "tmp.dvi"
outfile = "tmp.png"
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306
Pieter Eendebak
use relative filename in latex and dvips commands
r27702 with workdir.joinpath(tmpfile).open("w", encoding="utf8") as f:
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 f.writelines(genelatex(s, wrap))
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306
Yann Pellegrini
Replace usage of os.devnull with subprocess.DEVNULL
r28090 subprocess.check_call(
["latex", "-halt-on-error", "-interaction", "batchmode", tmpfile],
cwd=workdir,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
startupinfo=startupinfo,
)
resolution = round(150 * scale)
subprocess.check_call(
[
"dvipng",
"-T",
"tight",
"-D",
str(resolution),
"-z",
"9",
"-bg",
"Transparent",
"-o",
outfile,
dvifile,
"-fg",
color,
],
cwd=workdir,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
startupinfo=startupinfo,
)
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306
Pieter Eendebak
use relative filename in latex and dvips commands
r27702 with workdir.joinpath(outfile).open("rb") as f:
Abhinav Upadhyay
Avoid temprary variable assignment by returning value directly from try...
r12883 return f.read()
Carlos Cordoba
Latextools: Use the right exceptions to catch errors
r22075 except subprocess.CalledProcessError:
Carlos Cordoba
Latextools: Make latex_to_png_mpl not fail on errors...
r22050 return None
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306 finally:
shutil.rmtree(workdir)
Brian Granger
More improvements to the display system....
r3279
Brian Granger
Added mdboom's math_to_image from matplotlib.
r3881
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 def kpsewhich(filename):
"""Invoke kpsewhich command with an argument `filename`."""
try:
find_cmd("kpsewhich")
proc = subprocess.Popen(
["kpsewhich", filename],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
Min RK
make lib.latextools accept unicode...
r19562 return stdout.strip().decode('utf8', 'replace')
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 except FindCmdError:
pass
def genelatex(body, wrap):
"""Generate LaTeX document for dvipng backend."""
Takafumi Arakaki
Make lib.latextools configurable...
r7861 lt = LaTeXTool.instance()
breqn = wrap and lt.use_breqn and kpsewhich("breqn.sty")
Srinivas Reddy Thatiparthy
remove python2 specific cast_unicode_py2 function
r23669 yield r'\documentclass{article}'
Takafumi Arakaki
Make lib.latextools configurable...
r7861 packages = lt.packages
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 if breqn:
Takafumi Arakaki
Make lib.latextools configurable...
r7861 packages = packages + ['breqn']
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 for pack in packages:
Srinivas Reddy Thatiparthy
remove python2 specific cast_unicode_py2 function
r23669 yield r'\usepackage{{{0}}}'.format(pack)
yield r'\pagestyle{empty}'
Takafumi Arakaki
Make lib.latextools configurable...
r7861 if lt.preamble:
yield lt.preamble
Srinivas Reddy Thatiparthy
remove python2 specific cast_unicode_py2 function
r23669 yield r'\begin{document}'
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 if breqn:
Srinivas Reddy Thatiparthy
remove python2 specific cast_unicode_py2 function
r23669 yield r'\begin{dmath*}'
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 yield body
Srinivas Reddy Thatiparthy
remove python2 specific cast_unicode_py2 function
r23669 yield r'\end{dmath*}'
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 elif wrap:
Min RK
make lib.latextools accept unicode...
r19562 yield u'$${0}$$'.format(body)
Takafumi Arakaki
Use breqn.sty in dvipng backend if possible
r7852 else:
yield body
Matthias Bussonnier
fix some other syntax warnings
r24780 yield u'\\end{document}'
Takafumi Arakaki
Add dvipng backend to latex_to_png
r7306
Min RK
make lib.latextools accept unicode...
r19562 _data_uri_template_png = u"""<img src="data:image/png;base64,%s" alt=%s />"""
Brian Granger
More improvements to the display system....
r3279
def latex_to_html(s, alt='image'):
"""Render LaTeX to HTML with embedded PNG data using data URIs.
Parameters
----------
s : str
The raw string containing valid inline LateX.
alt : str
The alt text to use for the HTML.
"""
Min RK
make lib.latextools accept unicode...
r19562 base64_data = latex_to_png(s, encode=True).decode('ascii')
Takafumi Arakaki
latex_to_png returns None when the backend cannot be used...
r7309 if base64_data:
return _data_uri_template_png % (base64_data, alt)
Brian Granger
More improvements to the display system....
r3279
Brian Granger
Added mdboom's math_to_image from matplotlib.
r3881