diff --git a/mathics/builtin/graphics.py b/mathics/builtin/graphics.py
index b48512075b..d93e6a173a 100644
--- a/mathics/builtin/graphics.py
+++ b/mathics/builtin/graphics.py
@@ -11,6 +11,7 @@
from math import floor, ceil, log10
import json
+import base64
from six.moves import map
from six.moves import range
from six.moves import zip
@@ -1453,14 +1454,19 @@ def boxes_to_xml(self, leaves, **options):
w += 2
h += 2
- xml = (
- '') % (
- width, height, xmin, ymin, w, h, svg)
-
- xml = """%s""" % xml
- return xml
+ svg_xml = '''
+
+ ''' % (' '.join('%f' % t for t in (xmin, ymin, w, h)), svg)
+
+ return '' % (
+ int(width),
+ int(height),
+ base64.b64encode(svg_xml.encode('utf8')).decode('utf8'))
def axis_ticks(self, xmin, xmax):
def round_to_zero(value):
diff --git a/mathics/builtin/inout.py b/mathics/builtin/inout.py
index debfecda2d..87e19c6c08 100644
--- a/mathics/builtin/inout.py
+++ b/mathics/builtin/inout.py
@@ -1732,8 +1732,7 @@ class MathMLForm(Builtin):
=
#> MathMLForm[Graphics[Text["\u03bc"]]]
- =
+ =
## The should contain U+2062 INVISIBLE TIMES
#> MathMLForm[MatrixForm[{{2*a, 0},{0,0}}]]
diff --git a/mathics/core/evaluation.py b/mathics/core/evaluation.py
index 818f0f41e7..fe56a650f0 100644
--- a/mathics/core/evaluation.py
+++ b/mathics/core/evaluation.py
@@ -144,9 +144,23 @@ def get_data(self):
}
+class Output(object):
+ def max_stored_size(self, settings):
+ return settings.MAX_STORED_SIZE
+
+ def out(self, out):
+ pass
+
+ def clear(self, wait):
+ raise NotImplementedError
+
+ def display(self, data, metadata):
+ raise NotImplementedError
+
+
class Evaluation(object):
def __init__(self, definitions=None,
- out_callback=None, format='text', catch_interrupt=True):
+ output=None, format='text', catch_interrupt=True):
from mathics.core.definitions import Definitions
if definitions is None:
@@ -156,7 +170,7 @@ def __init__(self, definitions=None,
self.timeout = False
self.stopped = False
self.out = []
- self.out_callback = out_callback
+ self.output = output if output else Output()
self.listeners = {}
self.options = None
self.predetermined_out = None
@@ -221,7 +235,7 @@ def evaluate():
self.definitions.add_rule('Out', Rule(
Expression('Out', line_no), stored_result))
if result != Symbol('Null'):
- return self.format_output(result)
+ return self.format_output(result, self.format)
else:
return None
try:
@@ -261,7 +275,7 @@ def evaluate():
if exc_result is not None:
self.recursion_depth = 0
if exc_result != Symbol('Null'):
- result = self.format_output(exc_result)
+ result = self.format_output(exc_result, self.format)
result = Result(self.out, result, line_no)
self.out = []
@@ -288,23 +302,31 @@ def get_stored_result(self, result):
# Prevent too large results from being stored, as this can exceed the
# DB's max_allowed_packet size
- data = pickle.dumps(result)
- if len(data) > 10000:
- return Symbol('Null')
+ max_stored_size = self.output.max_stored_size(settings)
+ if max_stored_size is not None:
+ data = pickle.dumps(result)
+ if len(data) > max_stored_size:
+ return Symbol('Null')
return result
def stop(self):
self.stopped = True
- def format_output(self, expr):
+ def format_output(self, expr, format=None):
+ if format is None:
+ format = self.format
+
+ if isinstance(format, dict):
+ return dict((k, self.format_output(expr, f)) for k, f in format.items())
+
from mathics.core.expression import Expression, BoxError
- if self.format == 'text':
+ if format == 'text':
result = expr.format(self, 'System`OutputForm')
- elif self.format == 'xml':
+ elif format == 'xml':
result = Expression(
'StandardForm', expr).format(self, 'System`MathMLForm')
- elif self.format == 'tex':
+ elif format == 'tex':
result = Expression('StandardForm', expr).format(
self, 'System`TeXForm')
else:
@@ -368,20 +390,18 @@ def message(self, symbol, tag, *args):
text = String("Message %s::%s not found." % (symbol_shortname, tag))
text = self.format_output(Expression(
- 'StringForm', text, *(from_python(arg) for arg in args)))
+ 'StringForm', text, *(from_python(arg) for arg in args)), 'text')
self.out.append(Message(symbol_shortname, tag, text))
- if self.out_callback:
- self.out_callback(self.out[-1])
+ self.output.out(self.out[-1])
def print_out(self, text):
from mathics.core.expression import from_python
- text = self.format_output(from_python(text))
+ text = self.format_output(from_python(text), 'text')
self.out.append(Print(text))
- if self.out_callback:
- self.out_callback(self.out[-1])
+ self.output.out(self.out[-1])
if settings.DEBUG_PRINT:
print('OUT: ' + text)
diff --git a/mathics/main.py b/mathics/main.py
index 42070a7d93..e21e4f735e 100644
--- a/mathics/main.py
+++ b/mathics/main.py
@@ -13,7 +13,7 @@
from mathics.core.definitions import Definitions
from mathics.core.expression import strip_context
-from mathics.core.evaluation import Evaluation
+from mathics.core.evaluation import Evaluation, Output
from mathics.core.parser import LineFeeder, FileLineFeeder
from mathics import version_string, license_string, __version__
from mathics import settings
@@ -176,6 +176,14 @@ def empty(self):
return False
+class TerminalOutput(Output):
+ def __init__(self, shell):
+ self.shell = shell
+
+ def out(self, out):
+ return self.shell.out_callback(out)
+
+
def main():
argparser = argparse.ArgumentParser(
prog='mathics',
@@ -238,7 +246,7 @@ def main():
if args.execute:
for expr in args.execute:
print(shell.get_in_prompt() + expr)
- evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback)
+ evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell))
result = evaluation.parse_evaluate(expr, timeout=settings.TIMEOUT)
shell.print_result(result)
@@ -249,7 +257,8 @@ def main():
feeder = FileLineFeeder(args.FILE)
try:
while not feeder.empty():
- evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback, catch_interrupt=False)
+ evaluation = Evaluation(
+ shell.definitions, output=TerminalOutput(shell), catch_interrupt=False)
query = evaluation.parse_feeder(feeder)
if query is None:
continue
@@ -270,7 +279,7 @@ def main():
while True:
try:
- evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback)
+ evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell))
query = evaluation.parse_feeder(shell)
if query is None:
continue
diff --git a/mathics/settings.py b/mathics/settings.py
index c7cc79300a..d49b0f4730 100644
--- a/mathics/settings.py
+++ b/mathics/settings.py
@@ -27,6 +27,10 @@
MAX_RECURSION_DEPTH = 512
+# max pickle.dumps() size for storing results in DB
+# historically 10000 was used on public mathics servers
+MAX_STORED_SIZE = 10000
+
ADMINS = (
('Admin', 'mail@test.com'),
)
diff --git a/mathics/web/media/js/mathics.js b/mathics/web/media/js/mathics.js
index 45e34f3227..02bf3bd374 100644
--- a/mathics/web/media/js/mathics.js
+++ b/mathics/web/media/js/mathics.js
@@ -274,10 +274,38 @@ function translateDOMElement(element, svg) {
return dom;
}
+function convertMathGlyphs(dom) {
+ // convert mglyphs to their classic representation (