diff --git a/mathics/autoload/formats/SVG/Export.m b/mathics/autoload/formats/SVG/Export.m index a1ca73ed28..a57b5ba956 100644 --- a/mathics/autoload/formats/SVG/Export.m +++ b/mathics/autoload/formats/SVG/Export.m @@ -4,13 +4,17 @@ SVGExport[filename_, expr_, opts___] := - Module[{strm, data}, + Module[{strm, data, p, q, expr2}, strm = OpenWrite[filename]; If[strm === $Failed, Return[$Failed]]; - If[System`$UseSansSerif, - data = StringTake[ToString[MathMLForm[expr]],{23,-8}], - data = StringTake[ToString[MathMLForm[expr]],{23,-8}]]; - WriteString[strm, "" <> data <> ""]; + expr2 = If[Head[expr]=!=System`Graphics, System`Graphics[{System`Inset[ToString[expr]]}], expr]; + expr2= MathMLForm[expr2]; + data=ToString[expr2]; + p = StringPosition[data, "data:image/svg+xml;base64"][[1]][[2]]; + (*Let's assume that the end of the string is reached just before the last quote. *) + q = StringPosition[data,"\""][[-1]][[-2]]; + data = StringTake[data ,{p+2,q-1}]; + WriteString[strm, System`Convert`B64Dump`B64Decode[data]]; Close[strm]; ] diff --git a/mathics/builtin/base.py b/mathics/builtin/base.py index a4cc55063f..75e8cc112a 100644 --- a/mathics/builtin/base.py +++ b/mathics/builtin/base.py @@ -707,13 +707,13 @@ def get_option_values(self, leaves, **options): default[option] = parse_builtin_rule(value) return default - def boxes_to_text(self, leaves, **options) -> str: + def _boxes_to_text(self, leaves, **options) -> str: raise BoxConstructError - def boxes_to_xml(self, leaves, **options) -> str: + def _boxes_to_mathml(self, leaves, **options) -> str: raise BoxConstructError - def boxes_to_tex(self, leaves, **options) -> str: + def _boxes_to_tex(self, leaves, **options) -> str: raise BoxConstructError diff --git a/mathics/builtin/compilation.py b/mathics/builtin/compilation.py index b10d89a1e3..33233ec673 100644 --- a/mathics/builtin/compilation.py +++ b/mathics/builtin/compilation.py @@ -193,17 +193,17 @@ class CompiledCodeBox(BoxConstruct): Used internally by CompileCode[]. """ - def boxes_to_text(self, leaves=None, **options): + def _boxes_to_text(self, leaves=None, **options): if leaves is None: leaves = self._leaves return leaves[0].value - def boxes_to_xml(self, leaves=None, **options): + def _boxes_to_mathml(self, leaves=None, **options): if leaves is None: leaves = self._leaves return leaves[0].value - def boxes_to_tex(self, leaves=None, **options): + def _boxes_to_tex(self, leaves=None, **options): if leaves is None: leaves = self._leaves return leaves[0].value diff --git a/mathics/builtin/graphics.py b/mathics/builtin/graphics.py index bcf2404423..61c29913d8 100644 --- a/mathics/builtin/graphics.py +++ b/mathics/builtin/graphics.py @@ -2577,7 +2577,7 @@ def init(self, graphics, style, item=None, content=None, pos=None, opos=(0, 0)): self.content = content self.pos = pos self.opos = opos - self.content_text = self.content.boxes_to_text( + self.content_text = self.content._boxes_to_text( evaluation=self.graphics.evaluation ) @@ -2592,17 +2592,29 @@ def extent(self): def to_svg(self): x, y = self.pos.pos() - content = self.content.boxes_to_xml(evaluation=self.graphics.evaluation) - style = create_css(font_color=self.color) - svg = ( - '' - "%s" - ) % (x, y, self.opos[0], self.opos[1], style, content) + content = self.content._boxes_to_text(evaluation=self.graphics.evaluation) + style = create_css( + font_color=self.color, edge_color=self.color, face_color=self.color + ) + + # content = self.content._boxes_to_mathml(evaluation=self.graphics.evaluation) + # style = create_css(font_color=self.color) + # svg = ( + # '' + # "%s") + svg = ('' "%s" "") % ( + x, + y, + self.opos[0], + self.opos[1], + style, + content, + ) return svg def to_asy(self): x, y = self.pos.pos() - content = self.content.boxes_to_tex(evaluation=self.graphics.evaluation) + content = self.content._boxes_to_tex(evaluation=self.graphics.evaluation) pen = create_pens(edge_color=self.color) asy = 'label("$%s$", (%s,%s), (%s,%s), %s);' % ( content, @@ -2933,7 +2945,7 @@ class GraphicsBox(BoxConstruct): attributes = ("HoldAll", "ReadProtected") - def boxes_to_text(self, leaves=None, **options): + def _boxes_to_text(self, leaves=None, **options): if not leaves: leaves = self._leaves @@ -3140,7 +3152,7 @@ def get_range(min, max): return elements, calc_dimensions - def boxes_to_tex(self, leaves=None, **options): + def _boxes_to_tex(self, leaves=None, **options): if not leaves: leaves = self._leaves elements, calc_dimensions = self._prepare_elements( @@ -3195,7 +3207,7 @@ def boxes_to_tex(self, leaves=None, **options): return tex - def boxes_to_xml(self, leaves=None, **options): + def _boxes_to_mathml(self, leaves=None, **options): if not leaves: leaves = self._leaves elements, calc_dimensions = self._prepare_elements(leaves, options, neg_y=True) @@ -3234,11 +3246,13 @@ def boxes_to_xml(self, leaves=None, **options): # mglyph, which is what we have been using, is bad because MathML standard changed. # metext does not work because the way in which we produce the svg images is also based on this outdated mglyph behaviour. - # template = "" + # template = '' template = ( '' ) return template % ( + # int(width), + # int(height), int(width), int(height), base64.b64encode(svg_xml.encode("utf8")).decode("utf8"), diff --git a/mathics/builtin/graphics3d.py b/mathics/builtin/graphics3d.py index 833c09fe47..8069a29220 100644 --- a/mathics/builtin/graphics3d.py +++ b/mathics/builtin/graphics3d.py @@ -625,7 +625,7 @@ def boxes_to_tex(self, leaves=None, **options): ) return tex - def boxes_to_xml(self, leaves=None, **options): + def _boxes_to_mathml(self, leaves=None, **options): if not leaves: leaves = self._leaves diff --git a/mathics/builtin/image.py b/mathics/builtin/image.py index 57a2438043..9279770d2b 100644 --- a/mathics/builtin/image.py +++ b/mathics/builtin/image.py @@ -2102,10 +2102,10 @@ def test(self, expr): class ImageBox(BoxConstruct): - def boxes_to_text(self, leaves=None, **options): + def _boxes_to_text(self, leaves=None, **options): return "-Image-" - def boxes_to_xml(self, leaves=None, **options): + def _boxes_to_mathml(self, leaves=None, **options): if leaves is None: leaves = self._leaves # see https://tools.ietf.org/html/rfc2397 @@ -2115,7 +2115,7 @@ def boxes_to_xml(self, leaves=None, **options): leaves[2].get_int_value(), ) - def boxes_to_tex(self, leaves=None, **options): + def _boxes_to_tex(self, leaves=None, **options): return "-Image-" diff --git a/mathics/builtin/importexport.py b/mathics/builtin/importexport.py index a52ed85bdf..57ad378d93 100644 --- a/mathics/builtin/importexport.py +++ b/mathics/builtin/importexport.py @@ -1917,8 +1917,8 @@ class ExportString(Builtin): . 2, . 3, . 4, - >> ExportString[Integrate[f[x],{x,0,2}], "SVG"] - = ... + >> ExportString[Integrate[f[x],{x,0,2}], "SVG"]//Head + = String """ options = { diff --git a/mathics/builtin/inout.py b/mathics/builtin/inout.py index 0b1cd5438f..2c9ea11a20 100644 --- a/mathics/builtin/inout.py +++ b/mathics/builtin/inout.py @@ -845,7 +845,7 @@ def boxes_to_tex(self, leaves=None, **box_options) -> str: result += r"\end{array}" return result - def boxes_to_xml(self, leaves=None, **box_options) -> str: + def _boxes_to_mathml(self, leaves=None, **box_options) -> str: if not leaves: leaves = self._leaves evaluation = box_options.get("evaluation") @@ -872,7 +872,7 @@ def boxes_to_xml(self, leaves=None, **box_options) -> str: for item in row: result += "{1}".format( joined_attrs, - item.evaluate(evaluation).boxes_to_xml(**new_box_options), + item.evaluate(evaluation)._boxes_to_mathml(**new_box_options), ) result += "\n" result += "" @@ -2084,7 +2084,7 @@ def apply_mathml(self, expr, evaluation) -> Expression: boxes = MakeBoxes(expr).evaluate(evaluation) try: - xml = boxes.boxes_to_xml(evaluation=evaluation) + xml = boxes._boxes_to_mathml(evaluation=evaluation) except BoxError: evaluation.message( "General", @@ -2092,12 +2092,15 @@ def apply_mathml(self, expr, evaluation) -> Expression: Expression("FullForm", boxes).evaluate(evaluation), ) xml = "" + is_a_picture = xml[:6] == " str: + def _boxes_to_text(self, **options) -> str: is_style, options = self.process_style_box(options) if is_style: return self._leaves[0].boxes_to_text(**options) @@ -1468,10 +1468,10 @@ def boxes_to_text(self, **options) -> str: else: raise BoxError(self, "text") - def boxes_to_xml(self, **options) -> str: + def _boxes_to_mathml(self, **options) -> str: is_style, options = self.process_style_box(options) if is_style: - return self._leaves[0].boxes_to_xml(**options) + return self._leaves[0]._boxes_to_mathml(**options) name = self._head.get_name() if ( name == "System`RowBox" @@ -1510,40 +1510,40 @@ def is_list_interior(content): options["inside_row"] = True for leaf in self._leaves[0].get_leaves(): - result.append(leaf.boxes_to_xml(**options)) + result.append(leaf._boxes_to_mathml(**options)) return "%s" % " ".join(result) else: options = options.copy() options["inside_row"] = True if name == "System`SuperscriptBox" and len(self._leaves) == 2: return "%s %s" % ( - self._leaves[0].boxes_to_xml(**options), - self._leaves[1].boxes_to_xml(**options), + self._leaves[0]._boxes_to_mathml(**options), + self._leaves[1]._boxes_to_mathml(**options), ) if name == "System`SubscriptBox" and len(self._leaves) == 2: return "%s %s" % ( - self._leaves[0].boxes_to_xml(**options), - self._leaves[1].boxes_to_xml(**options), + self._leaves[0]._boxes_to_mathml(**options), + self._leaves[1]._boxes_to_mathml(**options), ) if name == "System`SubsuperscriptBox" and len(self._leaves) == 3: return "%s %s %s" % ( - self._leaves[0].boxes_to_xml(**options), - self._leaves[1].boxes_to_xml(**options), - self._leaves[2].boxes_to_xml(**options), + self._leaves[0]._boxes_to_mathml(**options), + self._leaves[1]._boxes_to_mathml(**options), + self._leaves[2]._boxes_to_mathml(**options), ) elif name == "System`FractionBox" and len(self._leaves) == 2: return "%s %s" % ( - self._leaves[0].boxes_to_xml(**options), - self._leaves[1].boxes_to_xml(**options), + self._leaves[0]._boxes_to_mathml(**options), + self._leaves[1]._boxes_to_mathml(**options), ) elif name == "System`SqrtBox" and len(self._leaves) == 1: - return "%s" % (self._leaves[0].boxes_to_xml(**options)) + return "%s" % (self._leaves[0]._boxes_to_mathml(**options)) elif name == "System`GraphBox": - return "%s" % (self._leaves[0].boxes_to_xml(**options)) + return "%s" % (self._leaves[0]._boxes_to_mathml(**options)) else: raise BoxError(self, "xml") - def boxes_to_tex(self, **options) -> str: + def _boxes_to_tex(self, **options) -> str: def block(tex, only_subsup=False): if len(tex) == 1: return tex @@ -1905,7 +1905,7 @@ def __str__(self) -> str: def do_copy(self) -> "Symbol": return Symbol(self.name) - def boxes_to_text(self, **options) -> str: + def _boxes_to_text(self, **options) -> str: return str(self.name) def atom_to_boxes(self, f, evaluation) -> "String": @@ -2105,13 +2105,13 @@ def __new__(cls, value) -> "Integer": self.value = n return self - def boxes_to_text(self, **options) -> str: + def _boxes_to_text(self, **options) -> str: return str(self.value) - def boxes_to_xml(self, **options) -> str: - return self.make_boxes("MathMLForm").boxes_to_xml(**options) + def _boxes_to_mathml(self, **options) -> str: + return self.make_boxes("MathMLForm")._boxes_to_mathml(**options) - def boxes_to_tex(self, **options) -> str: + def _boxes_to_tex(self, **options) -> str: return str(self.value) def make_boxes(self, form) -> "String": @@ -2291,13 +2291,13 @@ def __new__(cls, value, p=None) -> "Real": else: return PrecisionReal.__new__(PrecisionReal, value) - def boxes_to_text(self, **options) -> str: + def _boxes_to_text(self, **options) -> str: return self.make_boxes("System`OutputForm").boxes_to_text(**options) - def boxes_to_xml(self, **options) -> str: - return self.make_boxes("System`MathMLForm").boxes_to_xml(**options) + def _boxes_to_mathml(self, **options) -> str: + return self.make_boxes("System`MathMLForm")._boxes_to_mathml(**options) - def boxes_to_tex(self, **options) -> str: + def _boxes_to_tex(self, **options) -> str: return self.make_boxes("System`TeXForm").boxes_to_tex(**options) def atom_to_boxes(self, f, evaluation): @@ -2715,7 +2715,7 @@ def __new__(cls, value): def __str__(self) -> str: return '"%s"' % self.value - def boxes_to_text(self, show_string_characters=False, **options) -> str: + def _boxes_to_text(self, show_string_characters=False, **options) -> str: value = self.value if ( @@ -2727,7 +2727,7 @@ def boxes_to_text(self, show_string_characters=False, **options) -> str: return value - def boxes_to_xml(self, show_string_characters=False, **options) -> str: + def _boxes_to_mathml(self, show_string_characters=False, **options) -> str: from mathics.core.parser import is_symbol_name from mathics.builtin import builtins_by_module @@ -2774,7 +2774,7 @@ def render(format, string): outtext += render("%s", line) return outtext - def boxes_to_tex(self, show_string_characters=False, **options) -> str: + def _boxes_to_tex(self, show_string_characters=False, **options) -> str: from mathics.builtin import builtins_by_module operators = set() @@ -2894,13 +2894,13 @@ def __new__(cls, value): def __str__(self) -> str: return base64.b64encode(self.value).decode("utf8") - def boxes_to_text(self, **options) -> str: + def _boxes_to_text(self, **options) -> str: return '"' + self.__str__() + '"' - def boxes_to_xml(self, **options) -> str: + def _boxes_to_mathml(self, **options) -> str: return encode_mathml(String('"' + self.__str__() + '"')) - def boxes_to_tex(self, **options) -> str: + def _boxes_to_tex(self, **options) -> str: return encode_tex(String('"' + self.__str__() + '"')) def atom_to_boxes(self, f, evaluation):