diff --git a/mathics/builtin/box/layout.py b/mathics/builtin/box/layout.py index d198db8b2..d3b7a075b 100644 --- a/mathics/builtin/box/layout.py +++ b/mathics/builtin/box/layout.py @@ -390,6 +390,13 @@ class RowBox(BoxExpression): summary_text = "horizontal arrange of boxes" + def __init__(self, *args, **kwargs): + super().__init__(args, kwargs) + + # TODO Describe why inside row and inside list are needed. + self.inside_row = False + self.inside_list = False + def __repr__(self): return f"RowBox[{self.elements[0].__repr__()}]" diff --git a/mathics/format/render/mathml.py b/mathics/format/render/mathml.py index 70c641e4c..c1ff6733c 100644 --- a/mathics/format/render/mathml.py +++ b/mathics/format/render/mathml.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- """ -Mathics3 Graphics3D box rendering to MathML strings. +Mathics3 Box rendering to MathML strings. -MathML formatting is usually initiated in Mathics via MathMLForm[]. +MathML rendering is usually initiated via MathMLForm[]. """ import base64 @@ -169,12 +169,11 @@ def pane_box(box: PaneBox, **options): def fractionbox(box: FractionBox, **options) -> str: - _options = box.box_options.copy() - _options.update(options) - options = _options + # Note: values set in `options` take precedence over `box_options` + child_options = {**options, **box.box_options} return "%s %s" % ( - lookup_conversion_method(box.num, "mathml")(box.num, **options), - lookup_conversion_method(box.den, "mathml")(box.den, **options), + lookup_conversion_method(box.num, "mathml")(box.num, **child_options), + lookup_conversion_method(box.den, "mathml")(box.den, **child_options), ) @@ -204,15 +203,17 @@ def boxes_to_mathml(box, **options): raise BoxConstructError joined_attrs = " ".join(f'{name}="{value}"' for name, value in attrs.items()) result = f"\n" - new_box_options = box_options.copy() - new_box_options["inside_list"] = True for row in items: result += "" if isinstance(row, tuple): for item in row: - result += f"{boxes_to_mathml(item, **new_box_options)}" + item.inside_list = True + result += ( + f"{boxes_to_mathml(item, **options)}" + ) else: - result += f"{boxes_to_mathml(row, **new_box_options)}" + row.inside_list = True + result += f"{boxes_to_mathml(row, **options)}" result += "\n" result += "" # print(f"gridbox: {result}") @@ -223,13 +224,14 @@ def boxes_to_mathml(box, **options): def sqrtbox(box: SqrtBox, **options): - _options = box.box_options.copy() - _options.update(options) - options = _options + # Note: values set in `options` take precedence over `box_options` + child_options = {**options, **box.box_options} if box.index: return " %s %s " % ( - lookup_conversion_method(box.radicand, "mathml")(box.radicand, **options), - lookup_conversion_method(box.index, "mathml")(box.index, **options), + lookup_conversion_method(box.radicand, "mathml")( + box.radicand, **child_options + ), + lookup_conversion_method(box.index, "mathml")(box.index, **child_options), ) return " %s " % lookup_conversion_method(box.radicand, "mathml")( @@ -241,12 +243,11 @@ def sqrtbox(box: SqrtBox, **options): def subscriptbox(box: SubscriptBox, **options): - _options = box.box_options.copy() - _options.update(options) - options = _options + # Note: values set in `options` take precedence over `box_options` + child_options = {**options, **box.box_options} return "%s %s" % ( - lookup_conversion_method(box.base, "mathml")(box.base, **options), - lookup_conversion_method(box.subindex, "mathml")(box.subindex, **options), + lookup_conversion_method(box.base, "mathml")(box.base, **child_options), + lookup_conversion_method(box.subindex, "mathml")(box.subindex, **child_options), ) @@ -254,12 +255,13 @@ def subscriptbox(box: SubscriptBox, **options): def superscriptbox(box: SuperscriptBox, **options): - _options = box.box_options.copy() - _options.update(options) - options = _options + # Note: values set in `options` take precedence over `box_options` + child_options = {**options, **box.box_options} return "%s %s" % ( - lookup_conversion_method(box.base, "mathml")(box.base, **options), - lookup_conversion_method(box.superindex, "mathml")(box.superindex, **options), + lookup_conversion_method(box.base, "mathml")(box.base, **child_options), + lookup_conversion_method(box.superindex, "mathml")( + box.superindex, **child_options + ), ) @@ -267,14 +269,15 @@ def superscriptbox(box: SuperscriptBox, **options): def subsuperscriptbox(box: SubsuperscriptBox, **options): - _options = box.box_options.copy() - _options.update(options) - options = _options - options["inside_row"] = True + # Note: values set in `options` take precedence over `box_options` + child_options = {**box.box_options, **options} + box.base.inside_row = box.subindex.inside_row = box.superindex.inside_row = True return "%s %s %s" % ( - 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), + lookup_conversion_method(box.base, "mathml")(box.base, **child_options), + lookup_conversion_method(box.subindex, "mathml")(box.subindex, **child_options), + lookup_conversion_method(box.superindex, "mathml")( + box.superindex, **child_options + ), ) @@ -282,13 +285,10 @@ def subsuperscriptbox(box: SubsuperscriptBox, **options): def rowbox(box: RowBox, **options) -> str: - _options = box.box_options.copy() - _options.update(options) - options = _options + # Note: values set in `options` take precedence over `box_options` + child_options = {**box.box_options, **options} result = [] - inside_row = options.get("inside_row") - # inside_list = options.get('inside_list') - options = options.copy() + inside_row = box.inside_row def is_list_interior(content): if all(element.get_string_value() == "," for element in content[1::2]): @@ -309,13 +309,14 @@ def is_list_interior(content): if not inside_row and is_list_interior(box.items): is_list_row = True - if is_list_row: - options["inside_list"] = True - else: - options["inside_row"] = True + nest_field = "inside_list" if is_list_row else "inside_row" for element in box.items: - result.append(lookup_conversion_method(element, "mathml")(element, **options)) + if hasattr(element, nest_field): + setattr(element, nest_field, True) + result.append( + lookup_conversion_method(element, "mathml")(element, **child_options) + ) # print(f"mrow: {result}") @@ -326,10 +327,8 @@ def is_list_interior(content): def stylebox(box: StyleBox, **options) -> str: - _options = box.box_options.copy() - _options.update(options) - options = _options - return lookup_conversion_method(box.boxes, "mathml")(box.boxes, **options) + child_options = {**options, **box.box_options} + return lookup_conversion_method(box.boxes, "mathml")(box.boxes, **child_options) add_conversion_fn(StyleBox, stylebox)