diff --git a/mathics/builtin/box/compilation.py b/mathics/builtin/box/compilation.py index ce2a2fe7a..4a45a9b1f 100644 --- a/mathics/builtin/box/compilation.py +++ b/mathics/builtin/box/compilation.py @@ -21,7 +21,7 @@ class CompiledCodeBox(BoxExpression): def init(self, *args, **kwargs): self._elements = args - self.box_options = kwargs + self.box_attributes = kwargs def boxes_to_text(self, elements=None, **options): if elements is None: diff --git a/mathics/builtin/box/layout.py b/mathics/builtin/box/layout.py index 23423eb8d..e34b6c3d8 100644 --- a/mathics/builtin/box/layout.py +++ b/mathics/builtin/box/layout.py @@ -122,7 +122,7 @@ class FormBox(BoxExpression): summary_text = "wrap boxes with an association to a particular form" def init(self, *elems, **kwargs): - self.box_options = kwargs + self.box_attributes = kwargs self.form = elems[1] self.boxes = elems[0] assert isinstance(self.boxes, BoxElementMixin), f"{type(self.boxes)}" @@ -136,7 +136,7 @@ def elements(self): self.boxes, self.form, ), - self.box_options, + self.box_attributes, ) return self._elements @@ -178,7 +178,7 @@ def elements(self): self.num, self.den, ), - self.box_options, + self.box_attributes, ) return self._elements @@ -193,7 +193,7 @@ def eval(self, num, den, evaluation: Evaluation, options: dict): def init(self, num, den, **options): self.num = num self.den = den - self.box_options = options + self.box_attributes = options class GridBox(BoxExpression): @@ -228,11 +228,13 @@ class GridBox(BoxExpression): @property def elements(self): if self._elements is None: - self._elements = elements_to_expressions(self, self.items, self.box_options) + self._elements = elements_to_expressions( + self, self.items, self.box_attributes + ) return self._elements def init(self, *elems, **kwargs): - self.box_options = kwargs + self.box_attributes = kwargs self.items = elems self._elements = elems @@ -240,7 +242,7 @@ def get_array(self, elements, evaluation): if not elements: raise BoxConstructError - options = self.box_options + options = self.box_attributes expr = elements[0] if not expr.has_form("List", None): @@ -293,13 +295,13 @@ class InterpretationBox(BoxExpression): def __repr__(self): result = "InterpretationBox\n " + repr(self.boxes) - result += f"\n {self.box_options}" + result += f"\n {self.box_attributes}" return result def init(self, *expr, **options): self.boxes = expr[0] self.expr = expr[1] - self.box_options = options + self.box_attributes = options @property def elements(self): @@ -310,7 +312,7 @@ def elements(self): self.boxes, self.expr, ), - self.box_options, + self.box_attributes, ) return self._elements @@ -365,13 +367,13 @@ class PaneBox(BoxExpression): def elements(self): if self._elements is None: self._elements = elements_to_expressions( - self, (self.boxes,), self.box_options + self, (self.boxes,), self.box_attributes ) return self._elements def init(self, expr, **options): self.boxes = expr - self.box_options = options + self.box_attributes = options def eval_panebox1(self, expr, evaluation, options): "PaneBox[expr_String, OptionsPattern[]]" @@ -409,6 +411,16 @@ class RowBox(BoxExpression): def __repr__(self): return f"RowBox[{self.elements[0].__repr__()}]" + def __init__(self, *args, **kwargs): + # indent level nesting level used in rendering MathML boxes + self.indent_level: int = 0 + + # Consider adding. + # self.width: int = 0 + + # Pass all arguments to the parent class. + super().__init__(*args, **kwargs) + @property def elements(self): if self._elements is None: @@ -433,7 +445,7 @@ def eval_list(self, boxes, evaluation): def init(self, *items, **kwargs): # TODO: check that each element is an string or a BoxElementMixin - self.box_options = {} + self.box_attributes = {} if len(items) == 0: self.items = tuple() return @@ -509,13 +521,13 @@ def elements(self): if self._elements is None: index = self.index if index is None: - # self.box_options + # self.box_attributes self._elements = elements_to_expressions( - self, (self.radicand,), self.box_options + self, (self.radicand,), self.box_attributes ) else: self._elements = elements_to_expressions( - self, (self.radicand, index), self.box_options + self, (self.radicand, index), self.box_attributes ) return self._elements @@ -535,7 +547,7 @@ def eval(self, radicand, evaluation: Evaluation, options: dict): def init(self, radicand, index=None, **options): self.radicand = radicand self.index = index - self.box_options = options + self.box_attributes = options class StyleBox(BoxExpression): @@ -567,11 +579,11 @@ def elements(self): boxes = self.boxes if style: self._elements = elements_to_expressions( - self, (boxes, style), self.box_options + self, (boxes, style), self.box_attributes ) else: self._elements = elements_to_expressions( - self, (boxes,), self.box_options + self, (boxes,), self.box_attributes ) return self._elements @@ -596,10 +608,10 @@ def get_string_value(self) -> str: def init(self, boxes, style=None, **options): # This implementation supersedes Expression.process_style_box if isinstance(boxes, StyleBox): - options.update(boxes.box_options) + options.update(boxes.box_attributes) boxes = boxes.boxes self.style = style - self.box_options = options + self.box_attributes = options assert options is not None self.boxes = boxes assert isinstance( @@ -635,7 +647,7 @@ class SubscriptBox(BoxExpression): def elements(self): if self._elements is None: self._elements = elements_to_expressions( - self, (self.base, self.subindex), self.box_options + self, (self.base, self.subindex), self.box_attributes ) return self._elements @@ -648,7 +660,7 @@ def eval(self, a, b, evaluation: Evaluation, options: dict): return SubscriptBox(a_box, b_box, **options) def init(self, a, b, **options): - self.box_options = options.copy() + self.box_attributes = options.copy() if not (isinstance(a, BoxElementMixin) and isinstance(b, BoxElementMixin)): raise Exception((a, b), "are not boxes") self.base = a @@ -674,7 +686,7 @@ class SubsuperscriptBox(BoxExpression): @property def elements(self): if self._elements is None: - # self.box_options + # self.box_attributes self._elements = elements_to_expressions( ( self, @@ -682,7 +694,7 @@ def elements(self): self.subindex, self.superindex, ), - self.box_options, + self.box_attributes, ) return self._elements @@ -696,7 +708,7 @@ def eval(self, a, b, c, evaluation: Evaluation, options: dict): return SubsuperscriptBox(a_box, b_box, c_box, **options) def init(self, a, b, c, **options): - self.box_options = options.copy() + self.box_attributes = options.copy() if not all(isinstance(x, BoxElementMixin) for x in (a, b, c)): raise Exception((a, b, c), "are not boxes") self.base = a @@ -729,7 +741,7 @@ def elements(self): self.base, self.superindex, ), - self.box_options, + self.box_attributes, ) return self._elements @@ -742,7 +754,7 @@ def eval(self, a, b, evaluation: Evaluation, options: dict): return SuperscriptBox(a_box, b_box, **options) def init(self, a, b, **options): - self.box_options = options.copy() + self.box_attributes = options.copy() if not all(isinstance(x, BoxElementMixin) for x in (a, b)): raise Exception((a, b), "are not boxes") self.base = a @@ -766,7 +778,7 @@ class TagBox(BoxExpression): summary_text = "box tag with a head" def init(self, *elems, **kwargs): - self.box_options = kwargs + self.box_attributes = kwargs self.form = elems[1] self.boxes = elems[0] assert isinstance(self.boxes, BoxElementMixin), f"{type(self.boxes)}" @@ -780,7 +792,7 @@ def elements(self): self.boxes, self.form, ), - self.box_options, + self.box_attributes, ) return self._elements diff --git a/mathics/format/box/outputforms.py b/mathics/format/box/outputforms.py index a248d127f..09de275d9 100644 --- a/mathics/format/box/outputforms.py +++ b/mathics/format/box/outputforms.py @@ -30,7 +30,7 @@ def eval_mathmlform(expr: BaseElement, evaluation: Evaluation) -> BoxElementMixi boxes = format_element(expr, evaluation, SymbolTraditionalForm) try: - mathml = boxes.boxes_to_mathml(evaluation=evaluation, _indent_level=1) + mathml = boxes.boxes_to_mathml(evaluation=evaluation, indent_level=1) except BoxError: evaluation.message( "General", diff --git a/mathics/format/render/latex.py b/mathics/format/render/latex.py index 8cf27c403..a936ad587 100644 --- a/mathics/format/render/latex.py +++ b/mathics/format/render/latex.py @@ -174,7 +174,7 @@ def interpretation_box(self, **options): def pane_box(self, **options): content = lookup_conversion_method(self.boxes, "latex")(self.boxes, **options) - options = self.box_options + options = self.box_attributes size = options.get("System`ImageSize", SymbolAutomatic).to_python() if size == "System`Automatic": @@ -211,7 +211,7 @@ def pane_box(self, **options): def fractionbox(self, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options return "\\frac{%s}{%s}" % ( @@ -223,17 +223,17 @@ def fractionbox(self, **options) -> str: add_conversion_fn(FractionBox, fractionbox) -def gridbox(self, elements=None, **box_options) -> str: +def gridbox(self, elements=None, **box_attributes) -> str: def boxes_to_tex(box, **options): return lookup_conversion_method(box, "latex")(box, **options) if not elements: elements = self._elements - evaluation = box_options.get("evaluation") + evaluation = box_attributes.get("evaluation") items, options = self.get_array(elements, evaluation) - box_options.update(options) - box_options["inside_list"] = True - column_alignments = box_options["System`ColumnAlignments"].get_name() + box_attributes.update(options) + box_attributes["inside_list"] = True + column_alignments = box_attributes["System`ColumnAlignments"].get_name() try: column_alignments = { "System`Center": "c", @@ -251,12 +251,12 @@ def boxes_to_tex(box, **options): result = r"\begin{array}{%s} " % (column_alignments * column_count) for index, row in enumerate(items): if isinstance(row, tuple): - result += " & ".join(boxes_to_tex(item, **box_options) for item in row) + result += " & ".join(boxes_to_tex(item, **box_attributes) for item in row) else: result += r"\multicolumn{%s}{%s}{%s}" % ( str(column_count), column_alignments, - boxes_to_tex(row, **box_options), + boxes_to_tex(row, **box_attributes), ) if index != len(items) - 1: result += "\\\\ " @@ -268,7 +268,7 @@ def boxes_to_tex(box, **options): def sqrtbox(self, **options): - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options if self.index: @@ -285,7 +285,7 @@ def sqrtbox(self, **options): def superscriptbox(self, **options): - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options base_to_tex = lookup_conversion_method(self.base, "latex") @@ -315,7 +315,7 @@ def superscriptbox(self, **options): def subscriptbox(self, **options): - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options base_to_tex = lookup_conversion_method(self.base, "latex") @@ -330,7 +330,7 @@ def subscriptbox(self, **options): def subsuperscriptbox(self, **options): - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options base_to_tex = lookup_conversion_method(self.base, "latex") @@ -348,7 +348,7 @@ def subsuperscriptbox(self, **options): def rowbox(self, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options parts_str = [ @@ -382,7 +382,7 @@ def rowbox(self, **options) -> str: def stylebox(self, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options return lookup_conversion_method(self.boxes, "latex")(self.boxes, **options) diff --git a/mathics/format/render/mathml.py b/mathics/format/render/mathml.py index c3dc3f6a2..5a943e1d7 100644 --- a/mathics/format/render/mathml.py +++ b/mathics/format/render/mathml.py @@ -1,12 +1,14 @@ # -*- coding: utf-8 -*- """ -Lower-level formatter of Mathics objects as MathML strings. +Lower-level formatter of Mathics3 into MathML strings. MathML formatting is usually initiated in Mathics via MathMLForm[]. -For readability, and following WMA MathML generated code, tags \ +Following WMA MathML generated text, and for readability, MathML tags containing sub-tags are split on several lines, one by -sub element, and indented according to the level of the part. \ +sub element, and indented according to nesting level. The +indentation step size is one space. + For example, the Box expression >> FractionBox[RowBox[{"a", "+", SuperscriptBox["b", "c"]}], "d"] @@ -89,22 +91,21 @@ def encode_mathml(text: str) -> str: } -def string(self, **options) -> str: - text = self.value +def string(s: String, **options) -> str: + text = s.value number_as_text = options.get("number_as_text", None) show_string_characters = ( options.get("System`ShowStringCharacters", None) is SymbolTrue ) - if isinstance(self, BoxElementMixin): - if number_as_text is None: - number_as_text = SymbolFalse + if number_as_text is None: + number_as_text = SymbolFalse - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) indent_spaces = " " * indent_level - def render(format, string): - encoded_text = encode_mathml(string) + def render(format, s): + encoded_text = encode_mathml(s) return indent_spaces + format % encoded_text if text.startswith('"') and text.endswith('"'): @@ -146,9 +147,9 @@ def render(format, string): add_conversion_fn(String, string) -def interpretation_box(self, **options): - boxes = self.boxes - origin = self.expr +def interpretation_box(box: InterpretationBox, **options): + boxes = box.boxes + origin = box.expr if origin.has_form("InputForm", None): # InputForm produce outputs of the form # InterpretationBox[Style[_String, ...], origin_InputForm, opts___] @@ -172,13 +173,13 @@ def interpretation_box(self, **options): add_conversion_fn(InterpretationBox, interpretation_box) -def pane_box(self, **options): - indent_level = options.get("_indent_level", 0) +def pane_box(box, **options): + indent_level = options.get("indent_level", 0) indent_spaces = " " * indent_level - options["_indent_level"] = indent_level + 1 + options["indent_level"] = indent_level + 1 - content = lookup_conversion_method(self.boxes, "mathml")(self.boxes, **options) - options = self.box_options + content = lookup_conversion_method(box.boxes, "mathml")(box.boxes, **options) + options = box.box_attributes size = options.get("System`ImageSize", SymbolAutomatic).to_python() if size is SymbolAutomatic: width = "" @@ -214,30 +215,42 @@ def pane_box(self, **options): add_conversion_fn(PaneBox, pane_box) -def fractionbox(self, **options) -> str: - _options = self.box_options.copy() - _options.update(options) - options = _options - indent_level = options.get("_indent_level", 0) +def fractionbox(box: FractionBox, **options) -> str: + indent_level = box.box_attributes.get( + "indent_level", options.get("indent_level", 0) + ) indent_spaces = " " * indent_level - options["_indent_level"] = indent_level + 1 + indent_level += 1 + has_nonbox_children = False + + for child_box in (box.num, box.den): + if hasattr(child_box, "box_attributes"): + child_box.box_attributes["indent_level"] = indent_level + else: + has_nonbox_children = True + + if has_nonbox_children: + # non_boxed children have to get indent_level information passed down + # via a parameter. Here it is the "options" variable. (Which is a bad name). + child_options = {**options, "indent_level": indent_level} + return f"{indent_spaces}\n%s\n%s\n{indent_spaces}" % ( - lookup_conversion_method(self.num, "mathml")(self.num, **options), - lookup_conversion_method(self.den, "mathml")(self.den, **options), + lookup_conversion_method(box.num, "mathml")(box.num, **child_options), + lookup_conversion_method(box.den, "mathml")(box.den, **child_options), ) add_conversion_fn(FractionBox, fractionbox) -def gridbox(self, elements=None, **box_options) -> str: +def gridbox(box: GridBox, elements=None, **box_attributes) -> str: def boxes_to_mathml(box, **options): return lookup_conversion_method(box, "mathml")(box, **options) if not elements: - elements = self._elements - evaluation = box_options.get("evaluation") - items, options = self.get_array(elements, evaluation) + elements = box._elements + evaluation = box_attributes.get("evaluation") + items, options = box.get_array(elements, evaluation) num_fields = max(len(item) if isinstance(item, tuple) else 1 for item in items) attrs = {} @@ -252,21 +265,21 @@ def boxes_to_mathml(box, **options): # invalid column alignment raise BoxConstructError joined_attrs = " ".join(f'{name}="{value}"' for name, value in attrs.items()) - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) indent_spaces = " " * indent_level result = f"{indent_spaces}\n" - new_box_options = box_options.copy() - new_box_options["inside_list"] = True - new_box_options["_indent_level"] = indent_level + 3 + new_box_attributes = box_attributes.copy() + new_box_attributes["inside_list"] = True + new_box_attributes["indent_level"] = indent_level + 3 for row in items: result += f"{indent_spaces} " if isinstance(row, tuple): for item in row: - new_box_options["_indent_level"] = indent_level + 4 - result += f"\n{indent_spaces} \n{boxes_to_mathml(item, **new_box_options)}\n{indent_spaces} " + new_box_attributes["indent_level"] = indent_level + 4 + result += f"\n{indent_spaces} \n{boxes_to_mathml(item, **new_box_attributes)}\n{indent_spaces} " else: - result += f"\n{indent_spaces} \n{boxes_to_mathml(row, **new_box_options)}\n{indent_spaces} " + result += f"\n{indent_spaces} \n{boxes_to_mathml(row, **new_box_attributes)}\n{indent_spaces} " result += f"\n{indent_spaces} \n" result += f"{indent_spaces}" # print(f"gridbox: {result}") @@ -276,84 +289,84 @@ def boxes_to_mathml(box, **options): add_conversion_fn(GridBox, gridbox) -def sqrtbox(self, **options): - _options = self.box_options.copy() +def sqrtbox(box: SqrtBox, **options): + _options = box.box_attributes.copy() _options.update(options) options = _options - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) indent_spaces = " " * indent_level - options["_indent_level"] = indent_level + 1 + options["indent_level"] = indent_level + 1 - if self.index: + if box.index: return f"{indent_spaces}\n%s\n%s\n{indent_spaces}" % ( - lookup_conversion_method(self.radicand, "mathml")(self.radicand, **options), - lookup_conversion_method(self.index, "mathml")(self.index, **options), + lookup_conversion_method(box.radicand, "mathml")(box.radicand, **options), + lookup_conversion_method(box.index, "mathml")(box.index, **options), ) return ( f"{indent_spaces}\n%s\n{indent_spaces}" - % lookup_conversion_method(self.radicand, "mathml")(self.radicand, **options) + % lookup_conversion_method(box.radicand, "mathml")(box.radicand, **options) ) add_conversion_fn(SqrtBox, sqrtbox) -def subscriptbox(self, **options): - _options = self.box_options.copy() +def subscriptbox(box: SqrtBox, **options): + _options = box.box_attributes.copy() _options.update(options) options = _options - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) indent_spaces = " " * indent_level - options["_indent_level"] = indent_level + 1 + options["indent_level"] = indent_level + 1 return f"{indent_spaces}\n%s\n%s\n{indent_spaces}" % ( - lookup_conversion_method(self.base, "mathml")(self.base, **options), - lookup_conversion_method(self.subindex, "mathml")(self.subindex, **options), + lookup_conversion_method(box.base, "mathml")(box.base, **options), + lookup_conversion_method(box.subindex, "mathml")(box.subindex, **options), ) add_conversion_fn(SubscriptBox, subscriptbox) -def superscriptbox(self, **options): - _options = self.box_options.copy() +def superscriptbox(box: SuperscriptBox, **options): + _options = box.box_attributes.copy() _options.update(options) options = _options - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) indent_spaces = " " * indent_level - options["_indent_level"] = indent_level + 1 + options["indent_level"] = indent_level + 1 return f"{indent_spaces}\n%s\n%s\n{indent_spaces}" % ( - lookup_conversion_method(self.base, "mathml")(self.base, **options), - lookup_conversion_method(self.superindex, "mathml")(self.superindex, **options), + lookup_conversion_method(box.base, "mathml")(box.base, **options), + lookup_conversion_method(box.superindex, "mathml")(box.superindex, **options), ) add_conversion_fn(SuperscriptBox, superscriptbox) -def subsuperscriptbox(self, **options): - _options = self.box_options.copy() +def subsuperscriptbox(box: SubscriptBox, **options): + _options = box.box_attributes.copy() _options.update(options) options = _options options["inside_row"] = True - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) indent_spaces = " " * indent_level - options["_indent_level"] = indent_level + 1 + options["indent_level"] = indent_level + 1 return f"{indent_spaces}\n%s\n%s\n%s\n{indent_spaces}" % ( - lookup_conversion_method(self.base, "mathml")(self.base, **options), - lookup_conversion_method(self.subindex, "mathml")(self.subindex, **options), - lookup_conversion_method(self.superindex, "mathml")(self.superindex, **options), + lookup_conversion_method(box.base, "mathml")(box.base, **options), + lookup_conversion_method(box.subindex, "mathml")(box.subindex, **options), + lookup_conversion_method(box.superindex, "mathml")(box.superindex, **options), ) add_conversion_fn(SubsuperscriptBox, subsuperscriptbox) -def rowbox(self, **options) -> str: - _options = self.box_options.copy() +def rowbox(box: RowBox, **options) -> str: + _options = box.box_attributes.copy() _options.update(options) options = _options result = [] @@ -368,16 +381,16 @@ def is_list_interior(content): is_list_row = False if ( - len(self.items) >= 3 - and self.items[0].get_string_value() == "{" - and self.items[2].get_string_value() == "}" - and self.items[1].has_form("RowBox", 1, None) + len(box.items) >= 3 + and box.items[0].get_string_value() == "{" + and box.items[2].get_string_value() == "}" + and box.items[1].has_form("RowBox", 1, None) ): - content = self.items[1].items + content = box.items[1].items if is_list_interior(content): is_list_row = True - if not inside_row and is_list_interior(self.items): + if not inside_row and is_list_interior(box.items): is_list_row = True if is_list_row: @@ -385,11 +398,13 @@ def is_list_interior(content): else: options["inside_row"] = True - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) indent_spaces = " " * indent_level - options["_indent_level"] = indent_level + 1 + options["indent_level"] = indent_level + 1 - for element in self.items: + for element in box.items: + # Propagate properties down to box children. + # The below test could also be done via isinstance of of Box. result.append(lookup_conversion_method(element, "mathml")(element, **options)) # print(f"mrow: {result}") @@ -399,20 +414,20 @@ def is_list_interior(content): add_conversion_fn(RowBox, rowbox) -def stylebox(self, **options) -> str: - _options = self.box_options.copy() +def stylebox(box: StyleBox, **options) -> str: + _options = box.box_attributes.copy() _options.update(options) options = _options - return lookup_conversion_method(self.boxes, "mathml")(self.boxes, **options) + return lookup_conversion_method(box.boxes, "mathml")(box.boxes, **options) add_conversion_fn(StyleBox, stylebox) -def graphicsbox(self, elements=None, **options) -> str: +def graphicsbox(box: GraphicsBox, elements=None, **options) -> str: # FIXME: SVG is the only thing we can convert MathML into. # Handle other graphics formats. - svg_body = self.boxes_to_svg(elements, **options) + svg_body = box.boxes_to_svg(elements, **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 @@ -424,11 +439,11 @@ def graphicsbox(self, elements=None, **options) -> str: ) # print(svg_body) mathml = template % ( - int(self.width), - int(self.height), + int(box.width), + int(box.height), base64.b64encode(svg_body.encode("utf8")).decode("utf8"), ) - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) if indent_level: mathml = " " * indent_level + mathml @@ -439,12 +454,12 @@ def graphicsbox(self, elements=None, **options) -> str: add_conversion_fn(GraphicsBox, graphicsbox) -def graphics3dbox(self, elements=None, **options) -> str: +def graphics3dbox(box: Graphics3DBox, elements=None, **options) -> str: """Turn the Graphics3DBox into a MathML string""" - json_repr = self.boxes_to_json(elements, **options) + json_repr = box.boxes_to_json(elements, **options) mathml = f'' mathml = f"\n\n\n{mathml}\n\n\n" - indent_level = options.get("_indent_level", 0) + indent_level = options.get("indent_level", 0) if indent_level: mathml = " " * indent_level + mathml return mathml @@ -453,8 +468,8 @@ def graphics3dbox(self, elements=None, **options) -> str: add_conversion_fn(Graphics3DBox, graphics3dbox) -def tag_and_form_box(self, **options): - return lookup_conversion_method(self.boxes, "mathml")(self.boxes, **options) +def tag_and_form_box(box, **options): + return lookup_conversion_method(box.boxes, "mathml")(box.boxes, **options) add_conversion_fn(FormBox, tag_and_form_box) diff --git a/mathics/format/render/text.py b/mathics/format/render/text.py index 249a64dcb..fcd28dfc0 100644 --- a/mathics/format/render/text.py +++ b/mathics/format/render/text.py @@ -61,7 +61,7 @@ def pane_box(self, **options): def fractionbox(self, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options num_text = boxes_to_text(self.num, **options) @@ -77,13 +77,13 @@ def fractionbox(self, **options) -> str: add_conversion_fn(FractionBox, fractionbox) -def gridbox(self, elements=None, **box_options) -> str: +def gridbox(self, elements=None, **box_attributes) -> str: if not elements: elements = self.items - evaluation = box_options.get("evaluation", None) + evaluation = box_attributes.get("evaluation", None) items, options = self.get_array(elements, evaluation) - box_options.update(self.options) + box_attributes.update(self.options) if not items: return "" @@ -92,11 +92,11 @@ def gridbox(self, elements=None, **box_options) -> str: ( [ # TODO: check if this evaluation is necessary. - boxes_to_text(item, **box_options) + boxes_to_text(item, **box_attributes) for item in row ] if isinstance(row, tuple) - else boxes_to_text(row, **box_options) + else boxes_to_text(row, **box_attributes) ) for row in items ] @@ -111,7 +111,7 @@ def gridbox(self, elements=None, **box_options) -> str: def sqrtbox(self, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options if self.index: @@ -126,7 +126,7 @@ def sqrtbox(self, **options) -> str: def superscriptbox(self, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options no_parenthesize = True @@ -150,7 +150,7 @@ def superscriptbox(self, **options) -> str: def subscriptbox(self, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options return "Subscript[%s, %s]" % ( @@ -163,7 +163,7 @@ def subscriptbox(self, **options) -> str: def subsuperscriptbox(self, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options return "Subsuperscript[%s, %s, %s]" % ( @@ -177,7 +177,7 @@ def subsuperscriptbox(self, **options) -> str: def rowbox(self, elements=None, **options) -> str: - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options parts_str = [boxes_to_text(element, **options) for element in self.items] @@ -209,7 +209,7 @@ def rowbox(self, elements=None, **options) -> str: def stylebox(self, **options) -> str: options.pop("evaluation", None) - _options = self.box_options.copy() + _options = self.box_attributes.copy() _options.update(options) options = _options return boxes_to_text(self.boxes, **options) diff --git a/test/format/test_format.py b/test/format/test_format.py index ba469dafc..adf27bbc9 100644 --- a/test/format/test_format.py +++ b/test/format/test_format.py @@ -50,8 +50,6 @@ def load_tests(key): of the final formats ("text", "latex", "mathml") and produce two list: the first with the mandatory tests, and the other with "fragile" tests """ - global all_tests - global MATHML_STRICT def is_fragile(assert_msg: str) -> bool: """