Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 45 additions & 48 deletions mathicsscript/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

import networkx as nx
from mathics.core.atoms import String
from mathics.core.evaluation import Evaluation
from mathics.core.expression import BoxError, Expression
from mathics.core.symbols import Symbol
from mathics.core.systemsymbols import (
SymbolAborted,
SymbolExport,
SymbolExportString,
SymbolFailed,
SymbolFullForm,
Expand All @@ -36,7 +36,7 @@
try:
from matplotlib import __version__ as matplotlib_version
except ImportError:
matplotlib_version = None
matplotlib_version = "??"

try:
import matplotlib.pyplot as plt
Expand All @@ -63,34 +63,34 @@
asymptote_graph.size(200)


def format_output(obj, expr, format=None):
def format_output(evaluation: Evaluation, expr, format=None):
"""
Handle unformatted output using the *specific* capabilities of mathicsscript

evaluation.py format_output() from which this was derived is similar but
it can't make use of a front-ends specific capabilities.
"""

def eval_boxed(result, fn: Callable, obj, **options):
def eval_boxed(result, fn: Callable, evaluation, **options):
try:
boxed = fn(evaluation=obj, **options)
boxed = fn(evaluation=evaluation, **options)
except BoxError:
boxed = None
if not hasattr(obj, "seen_box_error"):
obj.seen_box_error = True
obj.message(
if not hasattr(evaluation, "seen_box_error"):
evaluation.seen_box_error = True
evaluation.message(
"General",
"notboxes",
Expression(SymbolFullForm, result).evaluate(obj),
Expression(SymbolFullForm, result).evaluate(evaluation),
)

return boxed

if format is None:
format = obj.format
format = evaluation.format

if isinstance(format, dict):
return dict((k, obj.format_output(expr, f)) for k, f in format.items())
return dict((k, evaluation.format_output(expr, f)) for k, f in format.items())

expr_type = expr.get_head_name()
expr_head = expr.get_head()
Expand All @@ -106,17 +106,17 @@ def eval_boxed(result, fn: Callable, obj, **options):
if len(elements) == 1:
expr = elements[0]
render_TeXForm = get_settings_value(
obj.definitions, "Settings`$UseMatplotlib"
) and get_settings_value(obj.definitions, "Settings`$RenderTeXForm")
evaluation.definitions, "Settings`$UseMatplotlib"
) and get_settings_value(evaluation.definitions, "Settings`$RenderTeXForm")
if render_TeXForm:
boxed = format_element(expr, obj, SymbolTeXForm)
boxed = format_element(expr, evaluation, SymbolTeXForm)
if hasattr(boxed, "head") and boxed.head is SymbolInterpretationBox:
inner_box = boxed.elements[0]
box_str_sans_quotes = inner_box.value[1:-1]
box_str_display_math = rf"${box_str_sans_quotes}$"
try:
# Create a figure and axis with no visible borders
fig, ax = plt.subplots(figsize=(3, 2))
_, ax = plt.subplots(figsize=(3, 2))
ax.axis("off")
# Render the LaTeX string in the center
# 'transform=ax.transAxes' ensures 0.5 is the exact middle of the window
Expand All @@ -136,34 +136,27 @@ def eval_boxed(result, fn: Callable, obj, **options):

elif (
expr_head is SymbolImage
and get_settings_value(obj.definitions, "Settings`$UseMatplotlib")
and get_settings_value(evaluation.definitions, "Settings`$UseMatplotlib")
and plt
and mpimg
):
temp_png = NamedTemporaryFile(
mode="w+b", suffix=".png", prefix="mathicsscript-"
)
try:
png_expr = Expression(
SymbolExport, String(temp_png.name), expr, String("PNG")
)
png_expr.evaluate(obj)
plt.axes().set_axis_off()
img = mpimg.imread(temp_png)
if hasattr(expr, "pil") and not hasattr(expr, "pillow"):
expr.pillow = expr.pil()

if hasattr(expr, "pillow"):
cmap = "gray" if expr.color_space == "Grayscale" else None
plt.imshow(img, cmap=cmap)
plt.axes().set_axis_off()
plt.imshow(expr.pillow, cmap=cmap)
plt.show()
except: # noqa
pass
temp_png.close()

elif (
expr_head in (SymbolGraphics, SymbolPlot)
and get_settings_value(obj.definitions, "Settings`$UseMatplotlib")
and get_settings_value(evaluation.definitions, "Settings`$UseMatplotlib")
and plt
and svg2png
):
svg_expr = Expression(SymbolExportString, expr, String("SVG"))
svg_str = svg_expr.evaluate(obj).to_python(string_quotes=False)
svg_str = svg_expr.evaluate(evaluation).to_python(string_quotes=False)
temp_png = NamedTemporaryFile(
mode="w+b", suffix=".png", prefix="mathicsscript-"
)
Expand All @@ -180,10 +173,10 @@ def eval_boxed(result, fn: Callable, obj, **options):
elif (
expr_head in (SymbolGraphics, SymbolPlot, SymbolGraphics3D)
and have_asymptote
and get_settings_value(obj.definitions, "Settings`$UseAsymptote")
and get_settings_value(evaluation.definitions, "Settings`$UseAsymptote")
):
asy_expr = Expression(SymbolExportString, expr, String("asy"))
asy_str = asy_expr.evaluate(obj).to_python(string_quotes=False)
asy_str = asy_expr.evaluate(evaluation).to_python(string_quotes=False)

# Alternate older version
# asymptote_graph.erase()
Expand All @@ -193,42 +186,46 @@ def eval_boxed(result, fn: Callable, obj, **options):
return expr_type

if expr is SymbolAborted:
obj.out = ["$Aborted"]
obj.last_eval = SymbolAborted
evaluation.out = ["$Aborted"]
evaluation.last_eval = SymbolAborted
return "$Aborted"
elif expr is SymbolFailed:
obj.out = ["$Failed"]
obj.last_eval = SymbolFailed
evaluation.out = ["$Failed"]
evaluation.last_eval = SymbolFailed
return "$Failed"
if format == "text":
if isinstance(expr, String):
return expr.value
result = expr.format(obj, SymbolOutputForm)
result = expr.format(evaluation, SymbolOutputForm)
elif format == "xml":
result = Expression(SymbolStandardForm, expr).format(obj, SymbolMathMLForm)
result = Expression(SymbolStandardForm, expr).format(
evaluation, SymbolMathMLForm
)
elif format == "tex":
result = Expression(SymbolStandardForm, expr).format(obj, SymbolTeXForm)
result = Expression(SymbolStandardForm, expr).format(evaluation, SymbolTeXForm)
elif format == "error":
# We may do fancier things in the future.
if isinstance(expr, String):
return expr.value
result = expr.format(obj, SymbolOutputForm)
result = expr.format(evaluation, SymbolOutputForm)
elif format == "unformatted":
if expr_head is PyMathicsGraph and hasattr(expr, "G"):
return format_graph(expr.G)
else:
result = expr.format(obj, SymbolOutputForm)
result = expr.format(evaluation, SymbolOutputForm)
else:
raise ValueError

try:
boxes = result.to_text(evaluation=obj)
boxes = result.to_text(evaluation=evaluation)
except BoxError:
boxes = None
if not hasattr(obj, "seen_box_error"):
obj.seen_box_error = True
obj.message(
"General", "notboxes", Expression(SymbolFullForm, result).evaluate(obj)
if not hasattr(evaluation, "seen_box_error"):
evaluation.seen_box_error = True
evaluation.message(
"General",
"notboxes",
Expression(SymbolFullForm, result).evaluate(evaluation),
)
return boxes

Expand Down
Loading