Skip to content

Commit d93c279

Browse files
authored
First round of DRYing common render code. (#1679)
Actually, before DRYing, I ran into a little issue here that the `boxes` field always only contains a single box, and calling lookup routines for "boxes" is confusing or misleading. So before doing the DRYing, going in small steps, I think it's best to get this out of the way.
1 parent 1d915c5 commit d93c279

8 files changed

Lines changed: 85 additions & 96 deletions

File tree

mathics/builtin/box/expression.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def __new__(cls, *elements, **kwargs):
8383

8484
def __init(self, *args, **kwargs):
8585
super().__init(args, kwargs)
86-
self.boxes = []
86+
self.inner_box = None
8787

8888
def do_format(self, evaluation, format):
8989
return self

mathics/builtin/box/layout.py

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,17 @@ class FormBox(BoxExpression):
108108
def init(self, *elems, **kwargs):
109109
self.box_options = kwargs
110110
self.form = elems[1]
111-
self.boxes = elems[0]
112-
assert isinstance(self.boxes, BoxElementMixin), f"{type(self.boxes)}"
111+
112+
self.inner_box = elems[0]
113+
assert isinstance(self.inner_box, BoxElementMixin), f"{type(self.inner_box)}"
113114

114115
@property
115116
def elements(self):
116117
if self._elements is None:
117118
self._elements = elements_to_expressions(
118119
self,
119120
(
120-
self.boxes,
121+
self.inner_box,
121122
self.form,
122123
),
123124
self.box_options,
@@ -276,12 +277,12 @@ class InterpretationBox(BoxExpression):
276277
summary_text = "box associated to an input expression"
277278

278279
def __repr__(self):
279-
result = "InterpretationBox\n " + repr(self.boxes)
280+
result = "InterpretationBox\n " + repr(self.inner_box)
280281
result += f"\n {self.box_options}"
281282
return result
282283

283284
def init(self, *expr, **options):
284-
self.boxes = expr[0]
285+
self.inner_box = expr[0]
285286
self.expr = expr[1]
286287
self.box_options = options
287288

@@ -291,7 +292,7 @@ def elements(self):
291292
self._elements = elements_to_expressions(
292293
self,
293294
(
294-
self.boxes,
295+
self.inner_box,
295296
self.expr,
296297
),
297298
self.box_options,
@@ -321,11 +322,11 @@ def eval_to_expression2(self, boxexpr, form, evaluation):
321322

322323
def eval_display(self, boxexpr, evaluation):
323324
"""DisplayForm[boxexpr_InterpretationBox]"""
324-
return boxexpr.boxes
325+
return boxexpr.inner_box
325326

326327
@property
327328
def is_multiline(self) -> bool:
328-
return self.boxes.is_multiline
329+
return self.inner_box.is_multiline
329330

330331

331332
class PaneBox(BoxExpression):
@@ -349,12 +350,12 @@ class PaneBox(BoxExpression):
349350
def elements(self):
350351
if self._elements is None:
351352
self._elements = elements_to_expressions(
352-
self, (self.boxes,), self.box_options
353+
self, (self.inner_box,), self.box_options
353354
)
354355
return self._elements
355356

356357
def init(self, expr, **options):
357-
self.boxes = expr
358+
self.inner_box = expr
358359
self.box_options = options
359360

360361
def eval_panebox1(self, expr, evaluation, options):
@@ -373,7 +374,7 @@ def eval_display(boxexpr, evaluation):
373374

374375
@property
375376
def is_multiline(self) -> bool:
376-
return self.boxes.is_multiline
377+
return self.inner_box.is_multiline
377378

378379

379380
class RowBox(BoxExpression):
@@ -555,7 +556,7 @@ def __repr__(self):
555556
def elements(self):
556557
if self._elements is None:
557558
style = self.style
558-
boxes = self.boxes
559+
boxes = self.inner_box
559560
if style:
560561
self._elements = elements_to_expressions(
561562
self, (boxes, style), self.box_options
@@ -579,27 +580,27 @@ def eval_style(self, boxes, style, evaluation: Evaluation, options: dict):
579580
return StyleBox(boxes, style=style, **options)
580581

581582
def get_string_value(self) -> str:
582-
box = self.boxes
583+
box = self.inner_box
583584
if isinstance(box, String):
584585
return box.value
585586
return ""
586587

587-
def init(self, boxes, style=None, **options):
588+
def init(self, box, style=None, **options):
588589
# This implementation supersedes Expression.process_style_box
589-
if isinstance(boxes, StyleBox):
590-
options.update(boxes.box_options)
591-
boxes = boxes.boxes
590+
if isinstance(box, StyleBox):
591+
options.update(box.box_options)
592+
box = box.inner_box
592593
self.style = style
593594
self.box_options = options
594595
assert options is not None
595-
self.boxes = boxes
596+
self.inner_box = box
596597
assert isinstance(
597-
self.boxes, BoxElementMixin
598-
), f"{type(self.boxes)},{self.boxes}"
598+
self.inner_box, BoxElementMixin
599+
), f"{type(self.inner_box)},{self.inner_box}"
599600

600601
@property
601602
def is_multiline(self) -> bool:
602-
return self.boxes.is_multiline
603+
return self.inner_box.is_multiline
603604

604605

605606
class SubscriptBox(BoxExpression):
@@ -759,16 +760,16 @@ class TagBox(BoxExpression):
759760
def init(self, *elems, **kwargs):
760761
self.box_options = kwargs
761762
self.form = elems[1]
762-
self.boxes = elems[0]
763-
assert isinstance(self.boxes, BoxElementMixin), f"{type(self.boxes)}"
763+
self.inner_box = elems[0]
764+
assert isinstance(self.inner_box, BoxElementMixin), f"{type(self.inner_box)}"
764765

765766
@property
766767
def elements(self):
767768
if self._elements is None:
768769
self._elements = elements_to_expressions(
769770
self,
770771
(
771-
self.boxes,
772+
self.inner_box,
772773
self.form,
773774
),
774775
self.box_options,
@@ -784,7 +785,7 @@ def eval_tagbox(self, expr, form: Symbol, evaluation: Evaluation):
784785

785786
@property
786787
def is_multiline(self) -> bool:
787-
return self.boxes.is_multiline
788+
return self.inner_box.is_multiline
788789

789790

790791
class TemplateBox(BoxExpression):

mathics/core/element.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,19 +411,19 @@ class BoxElementMixin(ImmutableValueMixin):
411411
def is_multiline(self) -> bool:
412412
return True
413413

414-
def boxes_to_format(self, format: str, **options) -> str:
415-
from mathics.core.formatter import boxes_to_format
414+
def box_to_format(self, format: str, **options) -> str:
415+
from mathics.core.formatter import box_to_format
416416

417-
return boxes_to_format(self, format, **options)
417+
return box_to_format(self, format, **options)
418418

419419
def boxes_to_mathml(self, **options) -> str:
420420
"""For compatibility deprecated"""
421-
return self.boxes_to_format("mathml", **options)
421+
return self.box_to_format("mathml", **options)
422422

423423
def boxes_to_tex(self, **options) -> str:
424424
"""For compatibility deprecated"""
425-
return self.boxes_to_format("latex", **options)
425+
return self.box_to_format("latex", **options)
426426

427427
def boxes_to_text(self, **options) -> str:
428428
"""For compatibility deprecated"""
429-
return self.boxes_to_format("text", **options)
429+
return self.box_to_format("text", **options)

mathics/core/formatter.py

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,34 +54,22 @@ def replace(match):
5454
return text
5555

5656

57-
extra_operators = set(
58-
(
59-
",",
60-
"(",
61-
")",
62-
"[",
63-
"]",
64-
"{",
65-
"}",
66-
"\u301a",
67-
"\u301b",
68-
"\u00d7",
69-
"\u2032",
70-
"\u2032\u2032",
71-
" ",
72-
"\u2062",
73-
"\u222b",
74-
"\u2146",
75-
)
76-
)
57+
def box_to_format(box, format: str, **options) -> str: # Maybe Union[str, bytearray]
58+
"""
59+
Translates a box structure ``box`` to a file format ``format``.
60+
This is used only at the root Box of a boxed expression.
61+
"""
62+
options["format_type"] = format
63+
return convert_box_to_format(box, **options)
7764

7865

79-
def boxes_to_format(boxes, format, **options) -> str: # Maybe Union[str, bytearray]
66+
def convert_box_to_format(box, **options) -> str:
8067
"""
81-
Translates a box structure ``boxes`` to a file format ``format``.
82-
68+
Translates a box structure ``box`` to a file format ``format``.
69+
This is used at either non-root-level boxes or from the
70+
initial call from box_to_format.
8371
"""
84-
return lookup_method(boxes, format)(boxes, **options)
72+
return lookup_method(box, options["format_type"])(box, **options)
8573

8674

8775
def lookup_method(self, format: str) -> Callable:

mathics/format/render/latex.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,14 @@ def render(format, string_, in_text=False):
239239

240240

241241
def interpretation_box(box: InterpretationBox, **options):
242-
return lookup_conversion_method(box.boxes, "latex")(box.boxes, **options)
242+
return lookup_conversion_method(box.inner_box, "latex")(box.inner_box, **options)
243243

244244

245245
add_conversion_fn(InterpretationBox, interpretation_box)
246246

247247

248248
def pane_box(box: PaneBox, **options):
249-
content = lookup_conversion_method(box.boxes, "latex")(box.boxes, **options)
249+
content = lookup_conversion_method(box.inner_box, "latex")(box.inner_box, **options)
250250
options = box.box_options
251251
size = options.get("System`ImageSize", SymbolAutomatic).to_python()
252252

@@ -487,7 +487,9 @@ def rowbox(box: RowBox, **options) -> str:
487487
def stylebox(box: StyleBox, **options) -> str:
488488
# Note: values set in `options` take precedence over `box_options`
489489
child_options = {**box.box_options, **options}
490-
return lookup_conversion_method(box.boxes, "latex")(box.boxes, **child_options)
490+
return lookup_conversion_method(box.inner_box, "latex")(
491+
box.inner_box, **child_options
492+
)
491493

492494

493495
add_conversion_fn(StyleBox, stylebox)
@@ -775,7 +777,7 @@ def graphics3dbox(box: Graphics3DBox, elements=None, **options) -> str:
775777

776778

777779
def tag_and_form_box(box: BoxExpression, **options):
778-
return lookup_conversion_method(box.boxes, "latex")(box.boxes, **options)
780+
return lookup_conversion_method(box.inner_box, "latex")(box.inner_box, **options)
779781

780782

781783
add_conversion_fn(FormBox, tag_and_form_box)

mathics/format/render/mathml.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,16 @@ def render(format, string):
124124

125125

126126
def interpretation_box(box: InterpretationBox, **options):
127-
return lookup_conversion_method(box.boxes, "mathml")(box.boxes, **options)
127+
return lookup_conversion_method(box.inner_box, "mathml")(box.inner_box, **options)
128128

129129

130130
add_conversion_fn(InterpretationBox, interpretation_box)
131131

132132

133133
def pane_box(box: PaneBox, **options):
134-
content = lookup_conversion_method(box.boxes, "mathml")(box.boxes, **options)
134+
content = lookup_conversion_method(box.inner_box, "mathml")(
135+
box.inner_box, **options
136+
)
135137
options = box.box_options
136138
size = options.get("System`ImageSize", SymbolAutomatic).to_python()
137139
if size is SymbolAutomatic:
@@ -328,7 +330,9 @@ def is_list_interior(content):
328330

329331
def stylebox(box: StyleBox, **options) -> str:
330332
child_options = {**options, **box.box_options}
331-
return lookup_conversion_method(box.boxes, "mathml")(box.boxes, **child_options)
333+
return lookup_conversion_method(box.inner_box, "mathml")(
334+
box.inner_box, **child_options
335+
)
332336

333337

334338
add_conversion_fn(StyleBox, stylebox)
@@ -337,7 +341,7 @@ def stylebox(box: StyleBox, **options) -> str:
337341
def graphicsbox(box: GraphicsBox, elements=None, **options) -> str:
338342
# FIXME: SVG is the only thing we can convert MathML into.
339343
# Handle other graphics formats.
340-
svg_body = box.boxes_to_format("svg", **options)
344+
svg_body = box.box_to_format("svg", **options)
341345

342346
# mglyph, which is what we have been using, is bad because MathML standard changed.
343347
# metext does not work because the way in which we produce the svg images is also based on this outdated mglyph
@@ -371,7 +375,7 @@ def graphics3dbox(box, elements=None, **options) -> str:
371375

372376

373377
def tag_and_form_box(box: BoxExpression, **options):
374-
return lookup_conversion_method(box.boxes, "mathml")(box.boxes, **options)
378+
return lookup_conversion_method(box.inner_box, "mathml")(box.inner_box, **options)
375379

376380

377381
add_conversion_fn(FormBox, tag_and_form_box)

0 commit comments

Comments
 (0)