Skip to content

Commit 385c5fb

Browse files
committed
Move towards segregating box from eval
* Some long lines split * some linting * correct a wrong symbol
1 parent 11fc371 commit 385c5fb

File tree

2 files changed

+123
-99
lines changed

2 files changed

+123
-99
lines changed

mathics/builtin/layout.py

Lines changed: 98 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# -*- coding: utf-8 -*-
22

33
"""
4-
This module contains symbols used to define the high level layout for
4+
This module contains symbols used to define the high level layout for \
55
expression formatting.
66
7-
For instance, to represent a set of consecutive expressions in a row,
8-
we can use ``Row``
7+
For instance, to represent a set of consecutive expressions in a row, \
8+
we can use ``Row``.
99
1010
"""
1111
from typing import Optional, Union
@@ -18,48 +18,51 @@
1818
from mathics.core.atoms import Integer, Integer1, Real, String
1919
from mathics.core.convert.op import operator_to_ascii, operator_to_unicode
2020
from mathics.core.element import BaseElement
21+
from mathics.core.evaluation import Evaluation
2122
from mathics.core.expression import Expression
2223
from mathics.core.list import ListExpression
2324
from mathics.core.symbols import Atom, Symbol
2425
from mathics.core.systemsymbols import (
2526
SymbolFullForm,
26-
SymbolInfix,
2727
SymbolInputForm,
2828
SymbolLeft,
2929
SymbolMakeBoxes,
3030
SymbolNone,
3131
SymbolOutputForm,
3232
SymbolRight,
33+
SymbolRowBox,
3334
)
34-
from mathics.eval.makeboxes import (
35-
eval_fullform_makeboxes,
36-
format_element,
37-
make_boxes_infix,
38-
)
35+
from mathics.eval.makeboxes import eval_fullform_makeboxes, format_element, parenthesize
3936

4037
SymbolNonAssociative = Symbol("System`NonAssociative")
4138
SymbolSubscriptBox = Symbol("System`SubscriptBox")
4239

4340

44-
def eval_makeboxes_infix(
41+
####################################################################
42+
# This section might get moved to mathics.box
43+
#
44+
# Some of the code below get replace Mathics code or may get put in
45+
# collection of boxing modules,
46+
# e.g. ``mathics.box.boxes_operators.box_infix()``.
47+
#
48+
####################################################################
49+
50+
51+
def box_infix(
4552
expr: Expression,
4653
operator: BaseElement,
4754
form: Symbol,
48-
evaluation,
49-
precedence_value: Optional[int] = None,
55+
evaluation: Evaluation,
56+
precedence_value: Optional[int] = 0,
5057
grouping: Optional[str] = None,
51-
):
52-
"""Implements MakeBoxes[Infix[...]]."""
53-
54-
# Actually, this function implements one part of the evaluation:
55-
# the one that should be done at the "format" level. In that point,
56-
# the operators are processed to add spaces and use the right
57-
# encoding. This should be done at the level of the formatter, not
58-
# in the "MakeBoxes" step.
59-
# Then, the true implementation is done
60-
# in ```mathics.eval.makeboxes.make_boxes_infix```.
61-
62-
## FIXME: this should go into a some formatter.
58+
) -> Optional[Expression]:
59+
"""Implements MakeBoxes[Infix[...]].
60+
This function kicks off boxing for Infix operators.
61+
62+
Operators are processed to add spaces and to use the right encoding.
63+
"""
64+
65+
# FIXME: this should go into a some formatter.
6366
def format_operator(operator) -> Union[String, BaseElement]:
6467
"""
6568
Format infix operator `operator`. To do this outside parameter form is used.
@@ -95,7 +98,7 @@ def format_operator(operator) -> Union[String, BaseElement]:
9598
if len(elements) > 1:
9699
if operator.has_form("List", len(elements) - 1):
97100
operator = [format_operator(op) for op in operator.elements]
98-
return make_boxes_infix(
101+
return box_infix_elements(
99102
elements, operator, precedence_value, grouping, form
100103
)
101104
else:
@@ -113,17 +116,50 @@ def format_operator(operator) -> Union[String, BaseElement]:
113116
String(operator_to_unicode.get(op_str, op_str))
114117
)
115118

116-
return make_boxes_infix(elements, operator, precedence_value, grouping, form)
119+
return box_infix_elements(elements, operator, precedence_value, grouping, form)
117120

118121
elif len(elements) == 1:
119122
return MakeBoxes(elements[0], form)
120123
else:
121124
return MakeBoxes(expr, form)
122125

123126

127+
# FIXME: op should be a string, so remove the Union.
128+
def box_infix_elements(
129+
elements, op: Union[String, list], precedence: int, grouping, form: Symbol
130+
) -> Expression:
131+
result = []
132+
for index, element in enumerate(elements):
133+
if index > 0:
134+
if isinstance(op, list):
135+
result.append(op[index - 1])
136+
else:
137+
result.append(op)
138+
parenthesized = False
139+
if grouping == "System`NonAssociative":
140+
parenthesized = True
141+
elif grouping == "System`Left" and index > 0:
142+
parenthesized = True
143+
elif grouping == "System`Right" and index == 0:
144+
parenthesized = True
145+
146+
element_boxes = Expression(SymbolMakeBoxes, element, form)
147+
element = parenthesize(precedence, element, element_boxes, parenthesized)
148+
149+
result.append(element)
150+
return Expression(SymbolRowBox, ListExpression(*result))
151+
152+
153+
####################################################################
154+
# End of section of code that might be in mathics.box.
155+
####################################################################
156+
157+
124158
class Center(Builtin):
125159
"""
126-
<url>:WMA link:https://reference.wolfram.com/language/ref/Center.html</url>
160+
<url>
161+
:WMA link:
162+
https://reference.wolfram.com/language/ref/Center.html</url>
127163
128164
<dl>
129165
<dt>'Center'
@@ -189,7 +225,7 @@ class Grid(Builtin):
189225
options = GridBox.options
190226
summary_text = " 2D layout containing arbitrary objects"
191227

192-
def apply_makeboxes(self, array, f, evaluation, options) -> Expression:
228+
def eval_makeboxes(self, array, f, evaluation: Evaluation, options) -> Expression:
193229
"""MakeBoxes[Grid[array_?MatrixQ, OptionsPattern[Grid]],
194230
f:StandardForm|TraditionalForm|OutputForm]"""
195231
return GridBox(
@@ -250,23 +286,23 @@ class Infix(Builtin):
250286

251287
# the right rule should be
252288
# mbexpression:MakeBoxes[Infix[___], form]
253-
def eval_makeboxes(self, expression, form, evaluation):
289+
def eval_makeboxes(self, expression, form, evaluation: Evaluation):
254290
"""MakeBoxes[Infix[___],
255291
form:StandardForm|TraditionalForm|OutputForm|InputForm]"""
256292
infix_expr = expression.elements[0]
257293
elements = list(infix_expr.elements)
258294
num_parms = len(elements)
259295

260296
if num_parms == 0 or num_parms > 4:
261-
evaluation.message("Infix", "argb", Integer(len(parms.get_sequence())))
297+
evaluation.message("Infix", "argb", Integer(num_parms))
262298
return eval_fullform_makeboxes(infix_expr, evaluation, form)
263299

264300
if num_parms == 1:
265301
expr = elements[0]
266-
return eval_makeboxes_infix(expr, String("~"), form, evaluation)
302+
return box_infix(expr, String("~"), form, evaluation)
267303
if num_parms == 2:
268304
expr, operator = elements
269-
return eval_makeboxes_infix(expr, operator, form, evaluation)
305+
return box_infix(expr, operator, form, evaluation)
270306

271307
expr, operator, precedence = elements[:3]
272308
if not isinstance(precedence, Integer):
@@ -279,11 +315,9 @@ def eval_makeboxes(self, expression, form, evaluation):
279315

280316
grouping = SymbolNone if num_parms < 4 else elements[3]
281317
if grouping is SymbolNone:
282-
return eval_makeboxes_infix(
283-
expr, operator, form, evaluation, precedence.value
284-
)
318+
return box_infix(expr, operator, form, evaluation, precedence.value)
285319
if grouping in (SymbolNonAssociative, SymbolLeft, SymbolRight):
286-
return eval_makeboxes_infix(
320+
return box_infix(
287321
expr, operator, form, evaluation, precedence.value, grouping.get_name()
288322
)
289323

@@ -297,7 +331,8 @@ class Left(Builtin):
297331
298332
<dl>
299333
<dt>'Left'
300-
<dd>is used with operator formatting constructs to specify a left-associative operator.
334+
<dd>is used with operator formatting constructs to specify a \
335+
left-associative operator.
301336
</dl>
302337
"""
303338

@@ -312,7 +347,8 @@ class NonAssociative(Builtin):
312347
313348
<dl>
314349
<dt>'NonAssociative'
315-
<dd>is used with operator formatting constructs to specify a non-associative operator.
350+
<dd>is used with operator formatting constructs to specify a \
351+
non-associative operator.
316352
</dl>
317353
"""
318354

@@ -371,7 +407,7 @@ class Precedence(Builtin):
371407

372408
summary_text = "an object to be parenthesized with a given precedence level"
373409

374-
def apply(self, expr, evaluation) -> Real:
410+
def eval(self, expr, evaluation) -> Real:
375411
"Precedence[expr_]"
376412

377413
name = expr.get_name()
@@ -429,7 +465,8 @@ class Right(Builtin):
429465
430466
<dl>
431467
<dt>'Right'
432-
<dd>is used with operator formatting constructs to specify a right-associative operator.
468+
<dd>is used with operator formatting constructs to specify a \
469+
right-associative operator.
433470
</dl>
434471
"""
435472

@@ -448,21 +485,21 @@ class Row(Builtin):
448485

449486
summary_text = "1D layouts containing arbitrary objects in a row"
450487

451-
def apply_makeboxes(self, items, sep, f, evaluation):
488+
def eval_makeboxes(self, items, sep, form, evaluation: Evaluation):
452489
"""MakeBoxes[Row[{items___}, sep_:""],
453-
f:StandardForm|TraditionalForm|OutputForm]"""
490+
form:StandardForm|TraditionalForm|OutputForm]"""
454491

455492
items = items.get_sequence()
456493
if not isinstance(sep, String):
457-
sep = MakeBoxes(sep, f)
494+
sep = MakeBoxes(sep, form)
458495
if len(items) == 1:
459-
return MakeBoxes(items[0], f)
496+
return MakeBoxes(items[0], form)
460497
else:
461498
result = []
462499
for index, item in enumerate(items):
463500
if index > 0 and not sep.sameQ(String("")):
464501
result.append(to_boxes(sep, evaluation))
465-
item = MakeBoxes(item, f).evaluate(evaluation)
502+
item = MakeBoxes(item, form).evaluate(evaluation)
466503
item = to_boxes(item, evaluation)
467504
result.append(item)
468505
return RowBox(*result)
@@ -475,22 +512,31 @@ class Style(Builtin):
475512
<dl>
476513
<dt>'Style[$expr$, options]'
477514
<dd>displays $expr$ formatted using the specified option settings.
515+
478516
<dt>'Style[$expr$, "style"]'
479517
<dd> uses the option settings for the specified style in the current notebook.
518+
480519
<dt>'Style[$expr$, $color$]'
481520
<dd>displays using the specified color.
521+
482522
<dt>'Style[$expr$, $Bold$]'
483523
<dd>displays with fonts made bold.
524+
484525
<dt>'Style[$expr$, $Italic$]'
485526
<dd>displays with fonts made italic.
527+
486528
<dt>'Style[$expr$, $Underlined$]'
487529
<dd>displays with fonts underlined.
530+
488531
<dt>'Style[$expr$, $Larger$]
489532
<dd>displays with fonts made larger.
533+
490534
<dt>'Style[$expr$, $Smaller$]'
491535
<dd>displays with fonts made smaller.
536+
492537
<dt>'Style[$expr$, $n$]'
493538
<dd>displays with font size n.
539+
494540
<dt>'Style[$expr$, $Tiny$]'
495541
<dt>'Style[$expr$, $Small$]', etc.
496542
<dd>display with fonts that are tiny, small, etc.
@@ -523,7 +569,7 @@ class Subscript(Builtin):
523569

524570
summary_text = "format an expression with a subscript"
525571

526-
def apply_makeboxes(self, x, y, f, evaluation) -> Expression:
572+
def eval_makeboxes(self, x, y, f, evaluation) -> Expression:
527573
"MakeBoxes[Subscript[x_, y__], f:StandardForm|TraditionalForm]"
528574

529575
y = y.get_sequence()
@@ -536,7 +582,9 @@ def apply_makeboxes(self, x, y, f, evaluation) -> Expression:
536582

537583
class Subsuperscript(Builtin):
538584
"""
539-
<url>:WMA link:https://reference.wolfram.com/language/ref/Subsuperscript.html</url>
585+
<url>
586+
:WMA link:
587+
https://reference.wolfram.com/language/ref/Subsuperscript.html</url>
540588
541589
<dl>
542590
<dt>'Subsuperscript[$a$, $b$, $c$]'
@@ -558,7 +606,9 @@ class Subsuperscript(Builtin):
558606

559607
class Superscript(Builtin):
560608
"""
561-
<url>:WMA link:https://reference.wolfram.com/language/ref/Superscript.html</url>
609+
<url>
610+
:WMA link:
611+
https://reference.wolfram.com/language/ref/Superscript.html</url>
562612
563613
<dl>
564614
<dt>'Superscript[$x$, $y$]'

0 commit comments

Comments
 (0)