Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions mathics/builtin/box/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,50 @@ def is_constant_list(list):
return True


class FormBox(BoxExpression):
"""
<url>
:WMA link:
https://reference.wolfram.com/language/ref/FormBox.html</url>

<dl>
<dt>'FormBox[boxes, form]'
<dd> is a low-level box construct that displays as \
boxes and keep information about the form used to generate \
the box representation.
</dl>
"""

attributes = A_PROTECTED | A_READ_PROTECTED
summary_text = "box with an associated form"

def init(self, *elems, **kwargs):
self.box_options = kwargs
self.form = elems[1]
self.boxed = elems[0]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something I notice here and elsewhere in this file is that the parameter in the documentation is called boxes, not boxed. I think that is just a little clearer.

assert isinstance(self.boxed, BoxElementMixin), f"{type(self.boxes)}"

@property
def elements(self):
if self._elements is None:
self._elements = elements_to_expressions(
self,
(
self.boxed,
self.form,
),
self.box_options,
)
return self._elements

def eval_tagbox(self, expr, form: Symbol, evaluation: Evaluation):
"""FormBox[expr_, form_Symbol]"""
options = {}
expr = to_boxes(expr, evaluation, options)
assert isinstance(expr, BoxElementMixin), f"{expr}"
return FormBox(expr, form, **options)


class FractionBox(BoxExpression):
"""
<url>
Expand Down Expand Up @@ -165,15 +209,15 @@ def elements(self):
return self._elements

def init(self, *elems, **kwargs):
self.options = kwargs
self.box_options = kwargs
self.items = elems
self._elements = elems

def get_array(self, elements, evaluation):
if not elements:
raise BoxConstructError

options = self.options
options = self.box_options

expr = elements[0]
if not expr.has_form("List", None):
Expand Down Expand Up @@ -470,8 +514,6 @@ class StyleBox(BoxExpression):
"""

options = {
"ShowStringCharacters": "False",
"ShowSpecialCharacters": "False",
"$OptionSyntax": "Ignore",
}
attributes = A_PROTECTED | A_READ_PROTECTED
Expand Down
2 changes: 1 addition & 1 deletion mathics/builtin/forms/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ class MatrixForm(TableForm):
in_printforms = False
summary_text = "format as a matrix"

def eval_makeboxes_matrix(self, table, form, evaluation, options):
def eval_makeboxes(self, table, form, evaluation, options):
"""MakeBoxes[MatrixForm[table_, OptionsPattern[]],
(form:StandardForm|TraditionalForm)]"""
result = super().eval_makeboxes(table, form, evaluation, options)
Expand Down
93 changes: 36 additions & 57 deletions mathics/builtin/forms/print.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@
below are the functions that appear in '$PrintForms' at startup.
"""

from mathics.builtin.box.layout import InterpretationBox, StyleBox, TagBox
from mathics.builtin.box.layout import InterpretationBox, PaneBox, StyleBox
from mathics.builtin.forms.base import FormBaseClass
from mathics.core.atoms import String
from mathics.core.element import BaseElement
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
from mathics.core.symbols import SymbolFalse, SymbolFullForm, SymbolTrue
from mathics.core.symbols import SymbolFalse, SymbolTrue
from mathics.core.systemsymbols import SymbolInputForm, SymbolOutputForm
from mathics.format.box import (
eval_makeboxes_fullform,
eval_makeboxes_outputform,
eval_mathmlform,
eval_texform,
)
from mathics.format.form import render_input_form
from mathics.format.box.makeboxes import is_print_form_callback
from mathics.format.form import render_input_form, render_output_form

sort_order = "mathics.builtin.forms.general-purpose-forms"

Expand Down Expand Up @@ -52,19 +49,6 @@ class FullForm(FormBaseClass):
in_printforms = False
summary_text = "format expression in underlying M-Expression representation"

def eval_makeboxes(self, expr, fmt, evaluation):
"""MakeBoxes[FullForm[expr_], fmt_]"""
fullform_box = eval_makeboxes_fullform(expr, evaluation)
style_box = StyleBox(
fullform_box,
**{
"System`ShowSpecialCharacters": SymbolFalse,
"System`ShowStringCharacters": SymbolTrue,
"System`NumberMarks": SymbolTrue,
},
)
return TagBox(style_box, SymbolFullForm)


class InputForm(FormBaseClass):
r"""
Expand Down Expand Up @@ -116,26 +100,6 @@ class InputForm(FormBaseClass):
in_printforms = True
summary_text = "format expression suitable for Mathics3 input"

# TODO: eventually, remove OutputForm in the second argument.
def eval_makeboxes(self, expr, evaluation):
"""MakeBoxes[InputForm[expr_], StandardForm|TraditionalForm]"""

inputform = String(render_input_form(expr, evaluation))
inputform = StyleBox(
inputform,
**{
"System`ShowSpecialCharacters": SymbolFalse,
"System`ShowStringCharacters": SymbolTrue,
"System`NumberMarks": SymbolTrue,
},
)
expr = Expression(SymbolInputForm, expr)
return InterpretationBox(
inputform,
expr,
**{"System`Editable": SymbolTrue, "System`AutoDelete": SymbolTrue},
)


class MathMLForm(FormBaseClass):
"""
Expand Down Expand Up @@ -169,10 +133,6 @@ class MathMLForm(FormBaseClass):

summary_text = "format expression as MathML commands"

def eval_mathml(self, expr, evaluation) -> Expression:
"MakeBoxes[MathMLForm[expr_], StandardForm|TraditionalForm]"
return eval_mathmlform(expr, evaluation)


class OutputForm(FormBaseClass):
"""
Expand Down Expand Up @@ -202,13 +162,6 @@ class OutputForm(FormBaseClass):
formats = {"OutputForm[s_String]": "s"}
summary_text = "format expression in plain text"

def eval_makeboxes(self, expr, form, evaluation):
"""MakeBoxes[OutputForm[expr_], form_]"""
pane = eval_makeboxes_outputform(expr, evaluation, form)
return InterpretationBox(
pane, Expression(SymbolOutputForm, expr), **{"System`Editable": SymbolFalse}
)


class StandardForm(FormBaseClass):
"""
Expand Down Expand Up @@ -276,8 +229,34 @@ class TeXForm(FormBaseClass):
in_printforms = True
summary_text = "format expression as LaTeX commands"

def eval_tex(self, expr, evaluation) -> Expression:
"MakeBoxes[TeXForm[expr_], StandardForm|TraditionalForm]"
# TeXForm by default uses `TraditionalForm`

return eval_texform(expr, evaluation)
@is_print_form_callback("System`InputForm")
def eval_makeboxes_inputform(expr: BaseElement, evaluation: Evaluation):
"""MakeBoxes[InputForm[expr_], StandardForm|TraditionalForm]"""
inputform = String(render_input_form(expr, evaluation))
inputform = StyleBox(
inputform,
**{
"System`ShowStringCharacters": SymbolTrue,
"System`NumberMarks": SymbolTrue,
},
)
expr = Expression(SymbolInputForm, expr)
return InterpretationBox(
inputform,
expr,
**{"System`Editable": SymbolTrue, "System`AutoDelete": SymbolTrue},
)


@is_print_form_callback("System`OutputForm")
def eval_makeboxes_outputform(expr: BaseElement, evaluation: Evaluation, **kwargs):
"""
Build a 2D representation of the expression using only keyboard characters.
"""

text_outputform = str(render_output_form(expr, evaluation, **kwargs))
pane = PaneBox(String('"' + text_outputform + '"'))
return InterpretationBox(
pane, Expression(SymbolOutputForm, expr), **{"System`Editable": SymbolFalse}
)
57 changes: 53 additions & 4 deletions mathics/builtin/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@

from mathics.builtin.box.layout import GridBox, PaneBox, RowBox, to_boxes
from mathics.builtin.makeboxes import MakeBoxes
from mathics.core.atoms import Real, String
from mathics.core.atoms import Integer, Real, String
from mathics.core.builtin import Builtin, Operator, PostfixOperator, PrefixOperator
from mathics.core.expression import Evaluation, Expression
from mathics.core.list import ListExpression
from mathics.core.systemsymbols import SymbolMakeBoxes, SymbolSubscriptBox
from mathics.core.symbols import Symbol
from mathics.core.systemsymbols import (
SymbolMakeBoxes,
SymbolPostfix,
SymbolPrefix,
SymbolSubscriptBox,
)
from mathics.eval.lists import list_boxes
from mathics.format.box import format_element
from mathics.format.box import eval_infix, eval_postprefix, format_element, parenthesize


class Center(Builtin):
Expand Down Expand Up @@ -172,8 +178,20 @@ class Infix(Builtin):
= a + b - c
"""

rules = {
(
"MakeBoxes[Infix[head_[elements___]], "
" f:StandardForm|TraditionalForm]"
): ('MakeBoxes[Infix[head[elements], StringForm["~`1`~", head]], f]'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is that "~" again. Sigh.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mmatera This PR does a lot more than just add FormBox. How would you characterize the other changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems it was mixed with another branch. All that I put in this PR should have be inside #1642

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems it was mixed with another branch. All that I put in this PR should have be inside #1642

Can we rebase this or somehow reduce the extraneous changes that are not part of adding FormBox?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked, and what happened was that #1642 was merged here instead of in master. This PR is now the same as in #1642 + the other PRs that we were merging in master. Originally, I opened this with a small part of #1642 (the code for FormBox).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am going to close this and start again in the right order.

}
summary_text = "infix form"

def eval_makeboxes_infix(
self, expr, operator, precedence: Integer, grouping, form: Symbol, evaluation
):
"""MakeBoxes[Infix[expr_, operator_, precedence_:None, grouping_:None], form:StandardForm|TraditionalForm]"""
return eval_infix(self, expr, operator, precedence, grouping, form, evaluation)


class Left(Builtin):
"""
Expand Down Expand Up @@ -278,6 +296,13 @@ class Postfix(PostfixOperator):
operator_display = None
summary_text = "postfix form"

def eval_makeboxes_postfix(self, expr, h, precedence, form, evaluation):
"""MakeBoxes[Postfix[expr_, h_, precedence_:None],
form:StandardForm|TraditionalForm]"""
return eval_postprefix(
self, SymbolPostfix, expr, h, precedence, form, evaluation
)


class Precedence(Builtin):
"""
Expand Down Expand Up @@ -332,8 +357,20 @@ class PrecedenceForm(Builtin):
<dt>'PrecedenceForm'[$expr$, $prec$]
<dd> format $expr$ parenthesized as it would be if it contained an operator of precedence $prec$.
</dl>

>> PrecedenceForm[x/y, 12] - z
= -z + (x / y)

"""

def eval_outerprecedenceform(self, expr, precedence, form, evaluation):
"""MakeBoxes[PrecedenceForm[expr_, precedence_],
form:StandardForm|TraditionalForm]"""

py_precedence = precedence.get_int_value()
boxes = format_element(expr, evaluation, form)
return parenthesize(py_precedence, expr, boxes, True)

summary_text = "parenthesize with a precedence"


Expand Down Expand Up @@ -370,6 +407,13 @@ class Prefix(PrefixOperator):
operator_display = None
summary_text = "prefix form"

def eval_makeboxes_prefix(self, expr, h, precedence, form, evaluation):
"""MakeBoxes[Prefix[expr_, h_, precedence_:None],
form:StandardForm|TraditionalForm]"""
return eval_postprefix(
self, SymbolPrefix, expr, h, precedence, form, evaluation
)


class Right(Builtin):
"""
Expand Down Expand Up @@ -456,7 +500,12 @@ class Style(Builtin):

summary_text = "wrapper for styles and style options to apply"
options = {"ImageSizeMultipliers": "Automatic"}

rules = {
"MakeBoxes[Style[expr_, OptionsPattern[Style]], f_]": (
"StyleBox[MakeBoxes[expr, f], "
"ImageSizeMultipliers -> OptionValue[ImageSizeMultipliers]]"
),
}
rules = {
"MakeBoxes[Style[expr_, OptionsPattern[Style]], f_]": (
"StyleBox[MakeBoxes[expr, f], "
Expand Down
10 changes: 1 addition & 9 deletions mathics/builtin/list/constructing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from itertools import permutations
from typing import Optional, Tuple

from mathics.builtin.box.layout import RowBox
from mathics.core.atoms import ByteArray, Integer, Integer1, is_integer_rational_or_real
from mathics.core.attributes import A_HOLD_FIRST, A_LISTABLE, A_LOCKED, A_PROTECTED
from mathics.core.builtin import BasePattern, Builtin, IterationFunction
Expand All @@ -24,7 +23,7 @@
from mathics.core.list import ListExpression
from mathics.core.symbols import Atom, Symbol
from mathics.core.systemsymbols import SymbolNormal, SymbolTuples
from mathics.eval.lists import get_tuples, list_boxes
from mathics.eval.lists import get_tuples


class Array(Builtin):
Expand Down Expand Up @@ -165,13 +164,6 @@ def eval(self, elements, evaluation: Evaluation):
elements_part_of_elements__ = elements.get_sequence()
return ListExpression(*elements_part_of_elements__)

def eval_makeboxes(self, items, f, evaluation):
"""MakeBoxes[{items___},
(f:StandardForm|TraditionalForm)]"""

items = items.get_sequence()
return RowBox(*list_boxes(items, f, evaluation, "{", "}"))


class Normal(Builtin):
"""
Expand Down
Loading
Loading