From 80590a336b3ceef39e12d7306d8eda7a7261ffde Mon Sep 17 00:00:00 2001 From: mmatera Date: Sun, 1 Dec 2024 17:42:08 -0300 Subject: [PATCH 1/2] now at least loads --- pymathics/asy/__init__.py | 44 ++++++++++------- pymathics/asy/__main__.py | 3 -- pymathics/asy/exportasy.py | 65 ++++++++++++++----------- pymathics/asy/graphics.py | 99 ++++++++++++++++++-------------------- pymathics/asy/version.py | 2 +- 5 files changed, 110 insertions(+), 103 deletions(-) diff --git a/pymathics/asy/__init__.py b/pymathics/asy/__init__.py index ca81c75..a043be0 100644 --- a/pymathics/asy/__init__.py +++ b/pymathics/asy/__init__.py @@ -6,25 +6,33 @@ """ -import pkg_resources import os -from pymathics.asy.version import __version__ -from pymathics.asy.exportasy import (ExportToJPG, - ExportToPNG, - ExportToSVG, - ExportToPDF) -from pymathics.asy.graphics import (AsyGraphicsBox) -from mathics.core.expression import Expression, String, SymbolTrue -from mathics.core.evaluation import Evaluation +import pkg_resources from mathics.builtin.files_io.importexport import Export as MathicsExport -__all__ = ("__version__", "ExportToJPG", "ExportToPNG", "ExportToSVG", "ExportToPDF", - "AsyGraphicsBox", "pymathics_version_data", "asy_path") +from mathics.core.evaluation import Evaluation +from mathics.core.expression import Expression, String, SymbolTrue +from pymathics.asy.exportasy import ExportToJPG, ExportToPDF, ExportToPNG, ExportToSVG +from pymathics.asy.graphics import AsyGraphicsBox +from pymathics.asy.version import __version__ -ROOT_DIR = pkg_resources.resource_filename('pymathics.asy', '') +__all__ = ( + "__version__", + "ExportToJPG", + "ExportToPNG", + "ExportToSVG", + "ExportToPDF", + "AsyGraphicsBox", + "pymathics_version_data", + "asy_path", +) + + +ROOT_DIR = pkg_resources.resource_filename("pymathics.asy", "") import shutil + try: asy_path = shutil.which("asy") print("asy found in ", asy_path) @@ -32,26 +40,26 @@ print("asy path couldn't be found. Set to asy") asy_path = "asy" + def onload(definitions): -# from mathics.builtin import box_constructs -# box_constructs["System`GraphicsBox"] = AsyGraphicsBox(expression=False) -# box_constructs["System`Graphics3DBox"] = AsyGraphics3DBox(expression=False) + # from mathics.builtin import box_constructs + # box_constructs["System`GraphicsBox"] = AsyGraphicsBox(expression=False) + # box_constructs["System`Graphics3DBox"] = AsyGraphics3DBox(expression=False) MathicsExport._extdict["pdf"] = "PDF" definitions.set_ownvalue("Settings`UseAsyForGraphics2D", SymbolTrue) for root, dirs, files in os.walk(os.path.join(ROOT_DIR, "autoload")): for path in [os.path.join(root, f) for f in files if f.endswith(".m")]: Expression("Get", String(path)).evaluate(Evaluation(definitions)) + # To be recognized as an external mathics module, the following variable # is required: # - - pymathics_version_data = { "author": "The Mathics Team", "version": __version__, "requires": [], - "onload" : onload + "onload": onload, } diff --git a/pymathics/asy/__main__.py b/pymathics/asy/__main__.py index 78966a2..d7232ee 100644 --- a/pymathics/asy/__main__.py +++ b/pymathics/asy/__main__.py @@ -1,5 +1,2 @@ # -*- coding: utf-8 -*- from mathics.builtin.base import Builtin, String - - - diff --git a/pymathics/asy/exportasy.py b/pymathics/asy/exportasy.py index 72e2abc..21ed004 100644 --- a/pymathics/asy/exportasy.py +++ b/pymathics/asy/exportasy.py @@ -8,70 +8,75 @@ # # -import tempfile import os +import tempfile from subprocess import DEVNULL, STDOUT, check_call -from mathics.core.expression import (Expression, String, BoxError, SymbolFailed, SymbolNull) + +from mathics.builtin.image.base import Image +from mathics.core.builtin import Builtin +from mathics.core.expression import BoxError, Expression, String +from mathics.core.symbols import SymbolNull +from mathics.core.systemsymbols import SymbolFailed from mathics_scanner import replace_wl_with_plain_text -from mathics.builtin.drawing.image import Image -from mathics.builtin import Builtin + class _AsyExporter(Builtin): - attributes = ("HoldRest", ) + attributes = ("HoldRest",) - messages = {"boxerr": "Not able to interpret box `1`", - "nowrtacs": "ExportToPDF requires write access.", - "asyfld" : "Asymptote failed to generate the file", + messages = { + "boxerr": "Not able to interpret box `1`", + "nowrtacs": "ExportToPDF requires write access.", + "asyfld": "Asymptote failed to generate the file", } extension = None def apply_asy(self, filename, expr, evaluation, **options): - '%(name)s[filename_String, expr_, OptionsPattern[%(name)s]]' + "%(name)s[filename_String, expr_, OptionsPattern[%(name)s]]" if expr.get_head_name() == "System`Image": - res = Expression("System`ImageExport", filename, expr) + res = Expression("System`ImageExport", filename, expr) return res.evaluate(evaluation) filename = filename.value if expr.get_head_name() not in ("System`Graphics", "System`Graphics3D"): expr = Expression("Text", expr) - expr = Expression("Graphics", - Expression("List", - expr) - ) + expr = Expression("Graphics", Expression("List", expr)) asy_code = Expression("MakeBoxes", expr).evaluate(evaluation) try: asy_code = asy_code.boxes_to_tex(evaluation=evaluation) except BoxError as e: - evaluation.message(self.get_name(),"boxerr", e.box) + evaluation.message(self.get_name(), "boxerr", e.box) return SymbolFailed asy_code = asy_code[13:-10] asy_code = replace_wl_with_plain_text(asy_code, False) # TODO: Handle properly WL characters to latex commands asy_code = asy_code.replace("\\[DifferentialD]", "d ") - fin = os.path.join(tempfile._get_default_tempdir(), - next(tempfile._get_candidate_names())) + fin = os.path.join( + tempfile._get_default_tempdir(), next(tempfile._get_candidate_names()) + ) from pymathics.asy import asy_path + try: - with open(fin, 'w+') as borrador: + with open(fin, "w+") as borrador: borrador.write(asy_code) except: - evaluation.message(self.get_name(),"nowrtacs") + evaluation.message(self.get_name(), "nowrtacs") return SymbolFailed if self.extension == "svg": - cmdline = [asy_path, '-f', self.extension, - '--svgemulation' , - '-o', - filename, - fin] + cmdline = [ + asy_path, + "-f", + self.extension, + "--svgemulation", + "-o", + filename, + fin, + ] else: - cmdline = [asy_path, '-f', self.extension, - '-o', - filename, - fin] + cmdline = [asy_path, "-f", self.extension, "-o", filename, fin] try: check_call(cmdline, stdout=DEVNULL, stderr=DEVNULL) except: @@ -91,6 +96,7 @@ class ExportToSVG(_AsyExporter): Then, from the asy set of instructions, a pdf is built """ + extension = "svg" context = "System`Convert`TextDump`" @@ -122,6 +128,7 @@ class ExportToPNG(_AsyExporter): Then, from the asy set of instructions, a pdf is built """ + extension = "png" context = "System`Convert`Image`" @@ -137,6 +144,6 @@ class ExportToJPG(_AsyExporter): Then, from the asy set of instructions, a pdf is built """ + extension = "jpeg" context = "System`Convert`Image`" - diff --git a/pymathics/asy/graphics.py b/pymathics/asy/graphics.py index b8fe357..fc631d1 100644 --- a/pymathics/asy/graphics.py +++ b/pymathics/asy/graphics.py @@ -7,56 +7,44 @@ """ -from math import floor, ceil, log10, sin, cos, pi, sqrt, atan2, degrees, radians, exp -import json import base64 -from itertools import chain +import json import numbers +from itertools import chain +from math import atan2, ceil, cos, degrees, exp, floor, log10, pi, radians, sin, sqrt - - -from mathics.builtin.base import ( - Builtin, - InstanceableBuiltin, - BoxConstruct, - BoxConstructError, +from mathics.builtin.drawing.graphics3d import Graphics3D, Graphics3DElements +from mathics.builtin.box.graphics import( GraphicsBox,) +from mathics.builtin.graphics import ( + GRAPHICS_OPTIONS, + Graphics, + RGBColor, ) from mathics.builtin.options import options_to_rules -from mathics.core.expression import ( - Expression, +from mathics.core.atoms import ( Integer, Rational, Real, String, Symbol, - SymbolTrue, - SymbolFalse, - strip_context, - system_symbols, - system_symbols_dict, - from_python, ) - -from mathics.builtin.graphics import (GRAPHICS_OPTIONS, - GraphicsBox, - Graphics, - asy_number, - RGBColor) - -from mathics.formatter.asy import asy_create_pens -from mathics.builtin.drawing.graphics3d import Graphics3D, Graphics3DElements +from mathics.core.convert.python import from_python +from mathics.core.builtin import Builtin, BuiltinElement +from mathics.core.expression import Expression +from mathics.core.symbols import Symbol, SymbolFalse, SymbolTrue, strip_context +from mathics.format.asy import asy_create_pens class AsyGraphicsBox(GraphicsBox): - context="System`" + context = "System`" options = Graphics.options _graphics = Graphics(expression=False) attributes = ("HoldAll", "ReadProtected") messages = { - "asynotav": 'Asymptote is not available in this system. Using the buggy backend.', - "noasyfile": 'Asy requires write permisions over a temporary file, but it was not available. Using the buggy backend', - "asyfail": 'Asymptote failed building the svg picture. Using the buggy backend.', + "asynotav": "Asymptote is not available in this system. Using the buggy backend.", + "noasyfile": "Asy requires write permisions over a temporary file, but it was not available. Using the buggy backend", + "asyfail": "Asymptote failed building the svg picture. Using the buggy backend.", } def apply_makeboxes(self, content, evaluation, options): @@ -82,8 +70,8 @@ def boxes_to_tex(self, leaves=None, **options): endline = widthheight.find("\n") widthheight = widthheight[:endline] width, height = widthheight.split(",") - width = float(width[:-2])*60 - height = float(height[:-4])*60 + width = float(width[:-2]) * 60 + height = float(height[:-4]) * 60 return (tex, width, height) def boxes_to_mathml(self, leaves=None, **options): @@ -92,27 +80,35 @@ def boxes_to_mathml(self, leaves=None, **options): evaluation = options.get("evaluation", None) check_asy = False if evaluation: - check_asy = evaluation.definitions.get_ownvalue("Settings`UseAsyForGraphics2D") + check_asy = evaluation.definitions.get_ownvalue( + "Settings`UseAsyForGraphics2D" + ) if check_asy: check_asy = check_asy.replace.is_true() if check_asy: import os + import tempfile from subprocess import DEVNULL, STDOUT, check_call + from pymathics.asy import asy_path - import tempfile + try: - check_call([asy_path, '--version'], stdout=DEVNULL, stderr=DEVNULL) + check_call([asy_path, "--version"], stdout=DEVNULL, stderr=DEVNULL) except: check_asy = False evaluation.message("AsyGraphicsBox", "asynotav") - Expression("Set", Symbol("Settings`UseAsyForGraphics2D"), SymbolFalse).evaluate(evaluation) + Expression( + "Set", Symbol("Settings`UseAsyForGraphics2D"), SymbolFalse + ).evaluate(evaluation) if check_asy: asy, width, height = self.boxes_to_tex(leaves, forxml=True, **options) - fin = os.path.join(tempfile._get_default_tempdir(), next(tempfile._get_candidate_names())) + fin = os.path.join( + tempfile._get_default_tempdir(), next(tempfile._get_candidate_names()) + ) fout = fin + ".png" try: - with open(fin, 'w+') as borrador: + with open(fin, "w+") as borrador: borrador.write(asy) except: evaluation.message("AsyGraphicsBox", "noasyfile") @@ -121,26 +117,25 @@ def boxes_to_mathml(self, leaves=None, **options): if check_asy: try: # check_call(['asy', '-f', 'svg', '--svgemulation' ,'-o', fout, fin], stdout=DEVNULL, stderr=DEVNULL) - check_call([asy_path, '-f', 'png', '-render', '16', '-o', fout, fin], stdout=DEVNULL, stderr=DEVNULL) + check_call( + [asy_path, "-f", "png", "-render", "16", "-o", fout, fin], + stdout=DEVNULL, + stderr=DEVNULL, + ) except: evaluation.message("AsyGraphicsBox", "asyfail") check_asy = False if check_asy: - with open(fout, 'rb') as ff: + with open(fout, "rb") as ff: png = ff.read() - return ( - ''' - ''' - % ( - int(width), - int(height), - base64.b64encode(png).decode("utf8"), -# base64.b64encode(svg.encode("utf8")).decode("utf8"), - ) + return """ + """ % ( + int(width), + int(height), + base64.b64encode(png).decode("utf8"), + # base64.b64encode(svg.encode("utf8")).decode("utf8"), ) # Not using asymptote. Continue with the buggy backend... return super(AsyGraphicsBox, self).boxes_to_mathml(leaves=leaves, **options) - - diff --git a/pymathics/asy/version.py b/pymathics/asy/version.py index b14a045..20720e6 100644 --- a/pymathics/asy/version.py +++ b/pymathics/asy/version.py @@ -5,4 +5,4 @@ # This file is suitable for sourcing inside POSIX shell as # well as importing into Python. That's why there is no # space around "=" below. -__version__="1.0.0" +__version__ = "1.0.0" From e4dc66c8c8cf09ae842fd4a6abb55739328cf3dc Mon Sep 17 00:00:00 2001 From: mmatera Date: Sun, 1 Dec 2024 17:59:07 -0300 Subject: [PATCH 2/2] fixing some compatibility issues --- pymathics/asy/__init__.py | 7 +++++-- pymathics/asy/exportasy.py | 4 ++-- pymathics/asy/graphics.py | 24 +++++++----------------- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/pymathics/asy/__init__.py b/pymathics/asy/__init__.py index a043be0..b852d1a 100644 --- a/pymathics/asy/__init__.py +++ b/pymathics/asy/__init__.py @@ -10,8 +10,11 @@ import pkg_resources from mathics.builtin.files_io.importexport import Export as MathicsExport +from mathics.core.atoms import String from mathics.core.evaluation import Evaluation -from mathics.core.expression import Expression, String, SymbolTrue +from mathics.core.expression import Expression +from mathics.core.symbols import Symbol, SymbolTrue +from mathics.core.systemsymbols import SymbolGet from pymathics.asy.exportasy import ExportToJPG, ExportToPDF, ExportToPNG, ExportToSVG from pymathics.asy.graphics import AsyGraphicsBox @@ -49,7 +52,7 @@ def onload(definitions): definitions.set_ownvalue("Settings`UseAsyForGraphics2D", SymbolTrue) for root, dirs, files in os.walk(os.path.join(ROOT_DIR, "autoload")): for path in [os.path.join(root, f) for f in files if f.endswith(".m")]: - Expression("Get", String(path)).evaluate(Evaluation(definitions)) + Expression(SymbolGet, String(path)).evaluate(Evaluation(definitions)) # To be recognized as an external mathics module, the following variable diff --git a/pymathics/asy/exportasy.py b/pymathics/asy/exportasy.py index 21ed004..ffe3a03 100644 --- a/pymathics/asy/exportasy.py +++ b/pymathics/asy/exportasy.py @@ -18,10 +18,10 @@ from mathics.core.symbols import SymbolNull from mathics.core.systemsymbols import SymbolFailed from mathics_scanner import replace_wl_with_plain_text - +from mathics.core.attributes import A_HOLD_REST class _AsyExporter(Builtin): - attributes = ("HoldRest",) + attributes = A_HOLD_REST messages = { "boxerr": "Not able to interpret box `1`", diff --git a/pymathics/asy/graphics.py b/pymathics/asy/graphics.py index fc631d1..008ebe0 100644 --- a/pymathics/asy/graphics.py +++ b/pymathics/asy/graphics.py @@ -13,33 +13,23 @@ from itertools import chain from math import atan2, ceil, cos, degrees, exp, floor, log10, pi, radians, sin, sqrt +from mathics.builtin.box.graphics import GraphicsBox from mathics.builtin.drawing.graphics3d import Graphics3D, Graphics3DElements -from mathics.builtin.box.graphics import( GraphicsBox,) -from mathics.builtin.graphics import ( - GRAPHICS_OPTIONS, - Graphics, - RGBColor, -) +from mathics.builtin.graphics import GRAPHICS_OPTIONS, Graphics, RGBColor from mathics.builtin.options import options_to_rules -from mathics.core.atoms import ( - Integer, - Rational, - Real, - String, - Symbol, -) -from mathics.core.convert.python import from_python +from mathics.core.atoms import Integer, Rational, Real, String from mathics.core.builtin import Builtin, BuiltinElement +from mathics.core.convert.python import from_python from mathics.core.expression import Expression -from mathics.core.symbols import Symbol, SymbolFalse, SymbolTrue, strip_context +from mathics.core.symbols import Symbol, SymbolFalse, SymbolTrue, strip_context from mathics.format.asy import asy_create_pens - +from mathics.core.attributes import A_HOLD_ALL, A_READ_PROTECTED class AsyGraphicsBox(GraphicsBox): context = "System`" options = Graphics.options _graphics = Graphics(expression=False) - attributes = ("HoldAll", "ReadProtected") + attributes = A_HOLD_ALL| A_READ_PROTECTED messages = { "asynotav": "Asymptote is not available in this system. Using the buggy backend.",