diff --git a/mathics/builtin/box/layout.py b/mathics/builtin/box/layout.py
index 4c1c33c55..b38ab63ab 100644
--- a/mathics/builtin/box/layout.py
+++ b/mathics/builtin/box/layout.py
@@ -85,6 +85,50 @@ def is_constant_list(list):
return True
+class FormBox(BoxExpression):
+ """
+
+ :WMA link:
+ https://reference.wolfram.com/language/ref/FormBox.html
+
+
+ - 'FormBox[boxes, form]'
+
- is a low-level box construct that displays as \
+ boxes and keep information about the form used to generate \
+ the box representation.
+
+ """
+
+ 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]
+ 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):
"""
@@ -165,7 +209,7 @@ def elements(self):
return self._elements
def init(self, *elems, **kwargs):
- self.options = kwargs
+ self.box_options = kwargs
self.items = elems
self._elements = elems
@@ -173,7 +217,7 @@ 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):
@@ -470,8 +514,6 @@ class StyleBox(BoxExpression):
"""
options = {
- "ShowStringCharacters": "False",
- "ShowSpecialCharacters": "False",
"$OptionSyntax": "Ignore",
}
attributes = A_PROTECTED | A_READ_PROTECTED
diff --git a/mathics/builtin/forms/data.py b/mathics/builtin/forms/data.py
index 6ce2f7d3f..6d042f27d 100644
--- a/mathics/builtin/forms/data.py
+++ b/mathics/builtin/forms/data.py
@@ -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)
diff --git a/mathics/builtin/forms/print.py b/mathics/builtin/forms/print.py
index 59efe7c56..01ca58e8f 100644
--- a/mathics/builtin/forms/print.py
+++ b/mathics/builtin/forms/print.py
@@ -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"
@@ -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"""
@@ -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):
"""
@@ -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):
"""
@@ -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):
"""
@@ -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}
+ )
diff --git a/mathics/builtin/layout.py b/mathics/builtin/layout.py
index a3785cce3..eb9884e32 100644
--- a/mathics/builtin/layout.py
+++ b/mathics/builtin/layout.py
@@ -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):
@@ -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]'),
+ }
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):
"""
@@ -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):
"""
@@ -332,8 +357,20 @@ class PrecedenceForm(Builtin):
'PrecedenceForm'[$expr$, $prec$]
format $expr$ parenthesized as it would be if it contained an operator of precedence $prec$.
+
+ >> 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"
@@ -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):
"""
@@ -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], "
diff --git a/mathics/builtin/list/constructing.py b/mathics/builtin/list/constructing.py
index 2e084b542..9bcd1b64f 100644
--- a/mathics/builtin/list/constructing.py
+++ b/mathics/builtin/list/constructing.py
@@ -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
@@ -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):
@@ -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):
"""
diff --git a/mathics/builtin/makeboxes.py b/mathics/builtin/makeboxes.py
index 8fea8b539..2dea6be10 100644
--- a/mathics/builtin/makeboxes.py
+++ b/mathics/builtin/makeboxes.py
@@ -3,19 +3,9 @@
Low-level Format definitions
"""
-
-from mathics.core.atoms import Integer
from mathics.core.attributes import A_HOLD_ALL_COMPLETE, A_READ_PROTECTED
from mathics.core.builtin import Builtin, Predefined
-from mathics.core.symbols import Symbol
-from mathics.format.box import (
- eval_generic_makeboxes,
- eval_infix,
- eval_makeboxes_fullform,
- eval_postprefix,
- format_element,
- parenthesize,
-)
+from mathics.format.box import format_element
# TODO: Differently from the current implementation, MakeBoxes should only
# accept as its format field the symbols in `$BoxForms`. This is something to
@@ -91,53 +81,15 @@ class MakeBoxes(Builtin):
attributes = A_HOLD_ALL_COMPLETE
rules = {
- "MakeBoxes[Infix[head_[elements___]], "
- " f:StandardForm|TraditionalForm]": (
- 'MakeBoxes[Infix[head[elements], StringForm["~`1`~", head]], f]'
- ),
"MakeBoxes[expr_]": "MakeBoxes[expr, StandardForm]",
# The following rule is temporal.
"MakeBoxes[expr_, form:(TeXForm|MathMLForm)]": "MakeBoxes[form[expr], StandardForm]",
- (
- "MakeBoxes[(form:StandardForm|TraditionalForm)"
- "[expr_], StandardForm|TraditionalForm]"
- ): ("MakeBoxes[expr, form]"),
- # BoxForms goes as second argument
- "MakeBoxes[PrecedenceForm[expr_, prec_], f_]": "MakeBoxes[expr, f]",
- "MakeBoxes[Style[expr_, OptionsPattern[Style]], f_]": (
- "StyleBox[MakeBoxes[expr, f], "
- "ImageSizeMultipliers -> OptionValue[ImageSizeMultipliers]]"
- ),
}
summary_text = "settable low-level translator from expression to display boxes"
- def eval_fullform(self, expr, evaluation):
- """MakeBoxes[expr_, FullForm]"""
- return eval_makeboxes_fullform(expr, evaluation)
-
def eval_general(self, expr, f, evaluation):
- """MakeBoxes[expr_,
- f:TraditionalForm|StandardForm]"""
- return eval_generic_makeboxes(expr, f, evaluation)
-
- def eval_outerprecedenceform(self, expr, precedence, form, evaluation):
- """MakeBoxes[PrecedenceForm[expr_, precedence_],
- form:StandardForm|TraditionalForm]"""
-
- py_precedence = precedence.get_int_value()
- boxes = MakeBoxes(expr, form)
- return parenthesize(py_precedence, expr, boxes, True)
-
- def eval_postprefix(self, p, expr, h, precedence, form, evaluation):
- """MakeBoxes[(p:Prefix|Postfix)[expr_, h_, precedence_:None],
- form:StandardForm|TraditionalForm]"""
- return eval_postprefix(self, p, expr, h, precedence, form, evaluation)
-
- def eval_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)
+ """MakeBoxes[expr_, f:TraditionalForm|StandardForm]"""
+ return format_element(expr, evaluation, f)
class ToBoxes(Builtin):
@@ -169,5 +121,6 @@ def eval(self, expr, form, evaluation):
form_name = form.get_name()
if form_name is None:
evaluation.message("ToBoxes", "boxfmt", form)
+
boxes = format_element(expr, evaluation, form)
return boxes
diff --git a/mathics/builtin/patterns/defaults.py b/mathics/builtin/patterns/defaults.py
index ca38a8ea8..828771360 100644
--- a/mathics/builtin/patterns/defaults.py
+++ b/mathics/builtin/patterns/defaults.py
@@ -72,8 +72,29 @@ class Optional(InfixOperator, PatternObject):
}
grouping = "Right"
rules = {
- "MakeBoxes[Verbatim[Optional][Verbatim[Pattern][symbol_Symbol, Verbatim[_]]], (f:StandardForm|TraditionalForm)]": 'MakeBoxes[symbol, f] <> "_."',
- "MakeBoxes[Verbatim[Optional][Verbatim[_]], (f:StandardForm|TraditionalForm)]": '"_."',
+ (
+ "MakeBoxes[Verbatim[Optional]["
+ "Verbatim[Pattern][symbol_Symbol,"
+ "(kind:(Verbatim[Blank]|Verbatim[BlankSequence]|Verbatim[BlankNullSequence])[])]], "
+ "(f:StandardForm|TraditionalForm)]"
+ ): 'MakeBoxes[symbol, f] <> ToString[kind, f] <>"."',
+ (
+ "MakeBoxes[Verbatim[Optional]["
+ "(kind:(Verbatim[Blank]|Verbatim[BlankSequence]|Verbatim[BlankNullSequence])[])], "
+ "(f:StandardForm|TraditionalForm)]"
+ ): 'ToString[kind, f]<>"."',
+ # Two arguments
+ (
+ "MakeBoxes[Verbatim[Optional]["
+ "Verbatim[Pattern][symbol_Symbol,"
+ "(kind:(Verbatim[Blank]|Verbatim[BlankSequence]|Verbatim[BlankNullSequence])[]), value_]], "
+ "(f:StandardForm|TraditionalForm)]"
+ ): 'RowBox[{MakeBoxes[symbol, f], ToString[kind, f], ":",MakeBoxes[value, f]}]',
+ (
+ "MakeBoxes[Verbatim[Optional]["
+ "(kind:(Verbatim[Blank]|Verbatim[BlankSequence]|Verbatim[BlankNullSequence])[]), value_], "
+ "(f:StandardForm|TraditionalForm)]"
+ ): 'RowBox[{ToString[kind, f], ":", MakeBoxes[value, f]}]',
}
summary_text = "an optional argument with a default value"
diff --git a/mathics/core/atoms/strings.py b/mathics/core/atoms/strings.py
index a58a0a0fe..3243bf475 100644
--- a/mathics/core/atoms/strings.py
+++ b/mathics/core/atoms/strings.py
@@ -9,7 +9,7 @@
from mathics.core.element import BoxElementMixin
from mathics.core.keycomparable import BASIC_ATOM_STRING_ELT_ORDER
-from mathics.core.symbols import Atom, Symbol, SymbolTrue, symbol_set
+from mathics.core.symbols import Atom, Symbol, SymbolFalse, SymbolTrue, symbol_set
from mathics.core.systemsymbols import SymbolFullForm, SymbolInputForm
SymbolString = Symbol("String")
@@ -41,8 +41,17 @@ def atom_to_boxes(self, f, evaluation):
inner = str(self.value)
if f in SYSTEM_SYMBOLS_INPUT_OR_FULL_FORM:
- inner = '"' + inner.replace("\\", "\\\\") + '"'
- return _boxed_string(inner, **{"System`ShowStringCharacters": SymbolTrue})
+ inner = inner.replace("\\", "\\\\")
+ inner = inner.replace('"', '\\"')
+ inner = f'"{inner}"'
+ return _boxed_string(
+ inner,
+ **{
+ "System`NumberMarks": SymbolTrue,
+ "System`ShowSpecialCharacters": SymbolFalse,
+ "System`ShowStringCharacters": SymbolTrue,
+ },
+ )
return String('"' + inner + '"')
def do_copy(self) -> "String":
diff --git a/mathics/core/builtin.py b/mathics/core/builtin.py
index 09d001408..dc8a9ac0e 100644
--- a/mathics/core/builtin.py
+++ b/mathics/core/builtin.py
@@ -347,7 +347,7 @@ def contextify_form_name(f):
"""Handle adding 'System`' to a form name, unless it's ""
(meaning the rule applies to all forms).
"""
- return "" if f == "" else ensure_context(f)
+ return f if f in ("", "_MakeBoxes") else ensure_context(f)
if isinstance(pattern, tuple):
forms, pattern = pattern
@@ -383,6 +383,9 @@ def contextify_form_name(f):
formatvalues[form].append(
Rule(pattern, parse_builtin_rule(replace), system=True)
)
+
+ formatvalues.setdefault("_MakeBoxes", []).extend(box_rules)
+
for form, formatrules in formatvalues.items():
formatrules.sort(key=lambda x: x.pattern_precedence)
@@ -434,10 +437,6 @@ def contextify_form_name(f):
else:
definitions.builtin[name] = definition
- makeboxes_def = definitions.builtin["System`MakeBoxes"]
- for rule in box_rules:
- makeboxes_def.add_rule(rule)
-
# This method is used to produce generic argument mismatch errors
# (tags: "argx", "argr", "argrx", "argt", or "argtu") for builtin
# functions that define this as an eval method. e.g. For example
diff --git a/mathics/core/load_builtin.py b/mathics/core/load_builtin.py
index dfff80c10..418a7527d 100644
--- a/mathics/core/load_builtin.py
+++ b/mathics/core/load_builtin.py
@@ -133,11 +133,8 @@ def definition_contribute(definitions):
Load the Definition objects associated to all the builtins
on `Definitions`
"""
- # let MakeBoxes contribute first
- _builtins["System`MakeBoxes"].contribute(definitions)
for name, item in _builtins.items():
- if name != "System`MakeBoxes":
- item.contribute(definitions)
+ item.contribute(definitions)
from mathics.core.definitions import Definition
from mathics.core.expression import ensure_context
diff --git a/mathics/doc/documentation/1-Manual.mdoc b/mathics/doc/documentation/1-Manual.mdoc
index f3f6ac18e..433a65c38 100644
--- a/mathics/doc/documentation/1-Manual.mdoc
+++ b/mathics/doc/documentation/1-Manual.mdoc
@@ -912,14 +912,13 @@ In a similar way, in the CLI, we can ask for TraditionalForm explicitly
= c
'MakeBoxes' for another form:
-
>> MakeBoxes[TeXForm[b], form_] = "d";
>> b // TeXForm
= ...
You can cause a much bigger mess by overriding 'MakeBoxes' than by sticking to 'Format', e.g. generate invalid XML:
- >> MakeBoxes[MathMLForm[c], form_] = "> MakeBoxes[MathMLForm[c], form_] := "> c // MathMLForm //StandardForm
= RadicalBox[3, StandardForm]
+ if not lhs.has_form("MakeBoxes", 2):
+ evaluation.message("MakeBoxes", "argrx", Integer(len(lhs.elements)))
+ raise AssignmentException(lhs, None)
+ target, form = lhs.elements
+ # Check second argument
+
makeboxes_rule = Rule(lhs, rhs, system=False)
+ tags = [] if tags is None else tags
+ if upset:
+ tags = tags + [target.get_lookup_name()]
+ else:
+ if not tags:
+ tags = ["System`MakeBoxes"]
+
definitions = evaluation.definitions
- definitions.add_rule("System`MakeBoxes", makeboxes_rule, "downvalues")
- # makeboxes_defs = evaluation.definitions.builtin["System`MakeBoxes"]
- # makeboxes_defs.add_rule(makeboxes_rule)
+ for tag in tags:
+ if is_protected(tag, definitions):
+ evaluation.message(self.get_name(), "wrsym", Symbol(tag))
+ return False
+ definitions.add_format(tag, makeboxes_rule, "_MakeBoxes")
return True
diff --git a/mathics/eval/lists.py b/mathics/eval/lists.py
index 130d9ffb1..f20173ed6 100644
--- a/mathics/eval/lists.py
+++ b/mathics/eval/lists.py
@@ -1,4 +1,3 @@
-from mathics.builtin.box.layout import RowBox
from mathics.core.atoms import String
from mathics.core.convert.expression import to_expression
from mathics.core.exceptions import PartDepthError, PartRangeError
@@ -61,6 +60,8 @@ def get_tuples(items):
def list_boxes(items, f, evaluation, open=None, close=None):
+ from mathics.builtin.box.layout import RowBox
+
result = [
Expression(SymbolMakeBoxes, item, f).evaluate(evaluation) for item in items
]
diff --git a/mathics/format/box/__init__.py b/mathics/format/box/__init__.py
index 42d3f798c..48688dd37 100644
--- a/mathics/format/box/__init__.py
+++ b/mathics/format/box/__init__.py
@@ -6,9 +6,7 @@
from mathics.format.box.makeboxes import (
_boxed_string,
eval_generic_makeboxes,
- eval_makeboxes,
eval_makeboxes_fullform,
- eval_makeboxes_outputform,
format_element,
to_boxes,
)
@@ -36,9 +34,7 @@
"eval_baseform",
"eval_generic_makeboxes",
"eval_infix",
- "eval_makeboxes",
"eval_makeboxes_fullform",
- "eval_makeboxes_outputform",
"eval_mathmlform",
"eval_postprefix",
"eval_tableform",
diff --git a/mathics/format/box/makeboxes.py b/mathics/format/box/makeboxes.py
index 2090080c4..e365570a7 100644
--- a/mathics/format/box/makeboxes.py
+++ b/mathics/format/box/makeboxes.py
@@ -9,49 +9,41 @@
from typing import List
from mathics.core.atoms import Complex, Rational, String
-from mathics.core.element import BaseElement, BoxElementMixin
+from mathics.core.element import BaseElement, BoxElementMixin, EvalMixin
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
from mathics.core.symbols import (
Atom,
Symbol,
+ SymbolFalse,
SymbolFullForm,
SymbolList,
SymbolMakeBoxes,
+ SymbolTrue,
)
from mathics.core.systemsymbols import ( # SymbolRule, SymbolRuleDelayed,
+ SymbolAborted,
SymbolComplex,
SymbolRational,
SymbolStandardForm,
SymbolTraditionalForm,
)
+from mathics.eval.lists import list_boxes
from mathics.format.box.formatvalues import do_format
from mathics.format.box.precedence import parenthesize
BOX_FORMS = {SymbolStandardForm, SymbolTraditionalForm}
+PRINT_FORMS_CALLBACK = {}
-def to_boxes(x, evaluation: Evaluation, options={}) -> BoxElementMixin:
- """
- This function takes the expression ``x``
- and tries to reduce it to a ``BoxElementMixin``
- expression using an evaluation object.
- """
- if isinstance(x, BoxElementMixin):
- return x
- if isinstance(x, Atom):
- x = x.atom_to_boxes(SymbolStandardForm, evaluation)
- return to_boxes(x, evaluation, options)
- if isinstance(x, Expression):
- if x.has_form("MakeBoxes", None):
- x_boxed = x.evaluate(evaluation)
- else:
- x_boxed = eval_makeboxes(x, evaluation)
- if isinstance(x_boxed, BoxElementMixin):
- return x_boxed
- if isinstance(x_boxed, Atom):
- return to_boxes(x_boxed, evaluation, options)
- return eval_makeboxes_fullform(x, evaluation)
+def is_print_form_callback(head_name: str):
+ """Decorator for register print form callbacks"""
+
+ def _register(func):
+ PRINT_FORMS_CALLBACK[head_name] = func
+ return func
+
+ return _register
# this temporarily replaces the _BoxedString class
@@ -61,10 +53,86 @@ def _boxed_string(string: str, **options):
return StyleBox(String(string), **options)
+@is_print_form_callback("System`StandardForm")
+def eval_makeboxes_standard_form(expr, evaluation):
+ from mathics.builtin.box.layout import FormBox, TagBox
+
+ boxed = apply_makeboxes_rules(expr, evaluation, SymbolStandardForm)
+ boxed = FormBox(boxed, SymbolStandardForm)
+ boxed = TagBox(boxed, SymbolStandardForm, **{"System`Editable": SymbolTrue})
+ return boxed
+
+
+@is_print_form_callback("System`TraditionalForm")
+def eval_makeboxes_traditional_form(expr, evaluation):
+ from mathics.builtin.box.layout import FormBox, TagBox
+
+ boxed = apply_makeboxes_rules(expr, evaluation, SymbolTraditionalForm)
+ boxed = FormBox(boxed, SymbolTraditionalForm)
+ boxed = TagBox(boxed, SymbolTraditionalForm, **{"System`Editable": SymbolTrue})
+ return boxed
+
+
+def apply_makeboxes_rules(
+ expr: BaseElement, evaluation: Evaluation, form: Symbol = SymbolStandardForm
+) -> BoxElementMixin:
+ """
+ This function takes the definitions provided by the evaluation
+ object, and produces a boxed fullform for expr.
+
+ Basically: MakeBoxes[expr, form]
+ """
+ assert form in BOX_FORMS, f"{form} not in BOX_FORMS"
+
+ def yield_rules():
+ # Look
+ for lookup in (expr.get_lookup_name(), "System`MakeBoxes"):
+ definition = evaluation.definitions.get_definition(lookup)
+ for rule in definition.formatvalues.get("_MakeBoxes", []):
+ yield rule
+
+ mb_expr = Expression(SymbolMakeBoxes, expr, form)
+ boxed = mb_expr
+ for rule in yield_rules():
+ try:
+ boxed = rule.apply(mb_expr, evaluation, fully=False)
+ except OverflowError:
+ evaluation.message("General", "ovfl")
+ boxed = mb_expr
+ continue
+ if boxed is mb_expr or boxed is None or boxed.sameQ(mb_expr):
+ continue
+ if boxed is SymbolAborted:
+ return String("Aborted")
+ if isinstance(boxed, EvalMixin):
+ return boxed.evaluate(evaluation)
+ if isinstance(boxed, BoxElementMixin):
+ return boxed
+ return eval_generic_makeboxes(expr, form, evaluation)
+
+
# TODO: evaluation is needed because `atom_to_boxes` uses it. Can we remove this
# argument?
+@is_print_form_callback("System`FullForm")
def eval_makeboxes_fullform(
- element: BaseElement, evaluation: Evaluation
+ element: BaseElement, evaluation: Evaluation, **kwargs
+) -> BoxElementMixin:
+ from mathics.builtin.box.layout import StyleBox, TagBox
+
+ result = eval_makeboxes_fullform_recursive(element, evaluation, **kwargs)
+ style_box = StyleBox(
+ result,
+ **{
+ "System`ShowSpecialCharacters": SymbolFalse,
+ "System`ShowStringCharacters": SymbolTrue,
+ "System`NumberMarks": SymbolTrue,
+ },
+ )
+ return TagBox(style_box, SymbolFullForm)
+
+
+def eval_makeboxes_fullform_recursive(
+ element: BaseElement, evaluation: Evaluation, **kwargs
) -> BoxElementMixin:
"""Same as MakeBoxes[FullForm[expr_], f_]"""
from mathics.builtin.box.expression import BoxExpression
@@ -90,7 +158,7 @@ def eval_makeboxes_fullform(
head, elements = expr.head, expr.elements
boxed_elements = tuple(
- (eval_makeboxes_fullform(element, evaluation) for element in elements)
+ (eval_makeboxes_fullform_recursive(element, evaluation) for element in elements)
)
# In some places it would be less verbose to use special outputs for
# `List`, `Rule` and `RuleDelayed`. WMA does not that, but we do it for
@@ -106,7 +174,7 @@ def eval_makeboxes_fullform(
result_elements = [left]
else:
left, right, sep = (String(ch) for ch in ("[", "]", ","))
- result_elements = [eval_makeboxes_fullform(head, evaluation), left]
+ result_elements = [eval_makeboxes_fullform_recursive(head, evaluation), left]
if len(boxed_elements) > 1:
arguments: List[BoxElementMixin] = []
@@ -121,32 +189,24 @@ def eval_makeboxes_fullform(
return RowBox(*result_elements)
-def eval_makeboxes_outputform(
- expr: BaseElement, evaluation: Evaluation, form: Symbol, **kwargs
-):
- """
- Build a 2D representation of the expression using only keyboard characters.
- """
- from mathics.builtin.box.layout import PaneBox
- from mathics.format.form.outputform import render_output_form
-
- text_outputform = str(render_output_form(expr, evaluation, **kwargs))
- elem1 = PaneBox(String('"' + text_outputform + '"'))
- return elem1
-
-
def eval_generic_makeboxes(expr, f, evaluation):
"""MakeBoxes[expr_,
f:TraditionalForm|StandardForm]"""
from mathics.builtin.box.layout import RowBox
+ assert f in BOX_FORMS, f"{f} not in BOX_FORMS"
if isinstance(expr, BoxElementMixin):
expr = expr.to_expression()
if isinstance(expr, Atom):
return expr.atom_to_boxes(f, evaluation)
+ if expr.has_form("List", None):
+ return RowBox(*list_boxes(expr.elements, f, evaluation, "{", "}"))
else:
head = expr.head
elements = expr.elements
+ printform_callback = PRINT_FORMS_CALLBACK.get(head.get_name(), None)
+ if printform_callback is not None:
+ return printform_callback(elements[0], evaluation)
f_name = f.get_name()
if f_name == "System`TraditionalForm":
@@ -170,6 +230,7 @@ def eval_generic_makeboxes(expr, f, evaluation):
"System`InputForm",
"System`OutputForm",
):
+ raise ValueError
sep = ", "
else:
sep = ","
@@ -194,41 +255,41 @@ def eval_generic_makeboxes(expr, f, evaluation):
return RowBox(*result)
-def eval_makeboxes(
- expr, evaluation: Evaluation, form=SymbolStandardForm
-) -> BoxElementMixin:
- """
- This function takes the definitions provided by the evaluation
- object, and produces a boxed fullform for expr.
-
- Basically: MakeBoxes[expr // form]
- """
- # This is going to be reimplemented. By now, much of the formatting
- # relies in rules of the form `MakeBoxes[expr, OutputForm]`
- # which is wrong.
- if form is SymbolFullForm:
- return eval_makeboxes_fullform(expr, evaluation)
- if form not in BOX_FORMS:
- # print(form, "not in", BOX_FORMS)
- expr = Expression(form, expr)
- form = SymbolStandardForm
- mb_expr = Expression(SymbolMakeBoxes, expr, form)
- # print(" evaluate", mb_expr)
- return mb_expr.evaluate(evaluation)
-
-
def format_element(
element: BaseElement, evaluation: Evaluation, form: Symbol, **kwargs
) -> BoxElementMixin:
"""
Applies formats associated to the expression, and then calls Makeboxes
"""
- if form is SymbolFullForm:
- return eval_makeboxes_fullform(element, evaluation)
-
evaluation.is_boxing = True
formatted_expr = do_format(element, evaluation, form)
- result_box = eval_makeboxes(formatted_expr, evaluation, form)
+ if form not in BOX_FORMS:
+ formatted_expr = Expression(form, formatted_expr)
+ form = SymbolStandardForm
+ result_box = apply_makeboxes_rules(formatted_expr, evaluation, form)
if isinstance(result_box, BoxElementMixin):
return result_box
- return eval_makeboxes_fullform(element, evaluation)
+ return eval_makeboxes_fullform_recursive(element, evaluation)
+
+
+def to_boxes(x, evaluation: Evaluation, options={}) -> BoxElementMixin:
+ """
+ This function takes the expression ``x``
+ and tries to reduce it to a ``BoxElementMixin``
+ expression using an evaluation object.
+ """
+ if isinstance(x, BoxElementMixin):
+ return x
+ if isinstance(x, Atom):
+ x = x.atom_to_boxes(SymbolStandardForm, evaluation)
+ return to_boxes(x, evaluation, options)
+ if isinstance(x, Expression):
+ if x.has_form("MakeBoxes", 1, 2):
+ x_boxed = x.evaluate(evaluation)
+ if isinstance(x_boxed, BoxElementMixin):
+ return x_boxed
+ if isinstance(x_boxed, Atom):
+ return to_boxes(x_boxed, evaluation, options)
+ else:
+ return apply_makeboxes_rules(x, evaluation)
+ return eval_makeboxes_fullform_recursive(x, evaluation)
diff --git a/mathics/format/box/outputforms.py b/mathics/format/box/outputforms.py
index a653ee5f8..60d187f4d 100644
--- a/mathics/format/box/outputforms.py
+++ b/mathics/format/box/outputforms.py
@@ -1,18 +1,33 @@
import re
from mathics.core.atoms import Integer, String
+from mathics.core.element import BaseElement, BoxElementMixin
+from mathics.core.evaluation import Evaluation
from mathics.core.expression import BoxError, Expression
from mathics.core.list import ListExpression
-from mathics.core.symbols import SymbolFalse, SymbolFullForm, SymbolList
-from mathics.core.systemsymbols import SymbolRowBox, SymbolTraditionalForm
+from mathics.core.symbols import (
+ Symbol,
+ SymbolFalse,
+ SymbolFullForm,
+ SymbolList,
+ SymbolTrue,
+)
+from mathics.core.systemsymbols import (
+ SymbolMathMLForm,
+ SymbolTeXForm,
+ SymbolTraditionalForm,
+)
from mathics.eval.testing_expressions import expr_min
-from mathics.format.box.makeboxes import format_element
+from mathics.format.box.makeboxes import format_element, is_print_form_callback
MULTI_NEWLINE_RE = re.compile(r"\n{2,}")
-def eval_mathmlform(expr, evaluation) -> Expression:
+@is_print_form_callback("System`MathMLForm")
+def eval_mathmlform(expr: BaseElement, evaluation: Evaluation) -> BoxElementMixin:
"MakeBoxes[MathMLForm[expr_], form_]"
+ from mathics.builtin.box.layout import InterpretationBox
+
boxes = format_element(expr, evaluation, SymbolTraditionalForm)
try:
mathml = boxes.boxes_to_mathml(evaluation=evaluation)
@@ -34,14 +49,23 @@ def eval_mathmlform(expr, evaluation) -> Expression:
mathml = '%s' % mathml
mathml = '' % mathml # convert_box(boxes)
- return Expression(SymbolRowBox, ListExpression(String(mathml)))
+ return InterpretationBox(
+ String(f'"{mathml}"'),
+ Expression(SymbolMathMLForm, expr),
+ **{"System`AutoDelete": SymbolTrue, "System`Editable": SymbolTrue},
+ )
-def eval_tableform(self, table, f, evaluation, options):
+def eval_tableform(
+ self, table: BaseElement, f: Symbol, evaluation: Evaluation, options
+):
"""MakeBoxes[TableForm[table_], f_]"""
from mathics.builtin.box.layout import GridBox
from mathics.builtin.tensors import get_dimensions
+ if not isinstance(table, Expression):
+ return format_element(table, evaluation, f)
+
dims = len(get_dimensions(table, head=SymbolList))
depth = self.get_option(options, "TableDepth", evaluation, pop=True)
options["System`TableDepth"] = depth
@@ -93,7 +117,10 @@ def transform_item(item):
return result
-def eval_texform(expr, evaluation) -> Expression:
+@is_print_form_callback("System`TeXForm")
+def eval_texform(expr: BaseElement, evaluation: Evaluation) -> BoxElementMixin:
+ from mathics.builtin.box.layout import InterpretationBox
+
boxes = format_element(expr, evaluation, SymbolTraditionalForm)
try:
# Here we set ``show_string_characters`` to False, to reproduce
@@ -114,4 +141,8 @@ def eval_texform(expr, evaluation) -> Expression:
Expression(SymbolFullForm, expr).evaluate(evaluation),
)
tex = ""
- return Expression(SymbolRowBox, ListExpression(String(tex)))
+ return InterpretationBox(
+ String(f'"{tex}"'),
+ Expression(SymbolTeXForm, expr),
+ **{"System`AutoDelete": SymbolTrue, "System`Editable": SymbolTrue},
+ )
diff --git a/mathics/format/render/latex.py b/mathics/format/render/latex.py
index e432992ca..a24ee0447 100644
--- a/mathics/format/render/latex.py
+++ b/mathics/format/render/latex.py
@@ -17,6 +17,7 @@
from mathics.builtin.box.graphics import GraphicsBox
from mathics.builtin.box.graphics3d import Graphics3DBox
from mathics.builtin.box.layout import (
+ FormBox,
FractionBox,
GridBox,
InterpretationBox,
@@ -663,8 +664,9 @@ def graphics3dbox(self, elements=None, **options) -> str:
add_conversion_fn(Graphics3DBox, graphics3dbox)
-def tag_box(self, **options):
+def tag_and_form_box(self, **options):
return lookup_conversion_method(self.boxed, "latex")(self.boxed, **options)
-add_conversion_fn(TagBox, tag_box)
+add_conversion_fn(FormBox, tag_and_form_box)
+add_conversion_fn(TagBox, tag_and_form_box)
diff --git a/mathics/format/render/mathml.py b/mathics/format/render/mathml.py
index d48a2eb6f..e229e0c18 100644
--- a/mathics/format/render/mathml.py
+++ b/mathics/format/render/mathml.py
@@ -13,6 +13,7 @@
from mathics.builtin.box.graphics import GraphicsBox
from mathics.builtin.box.graphics3d import Graphics3DBox
from mathics.builtin.box.layout import (
+ FormBox,
FractionBox,
GridBox,
InterpretationBox,
@@ -371,8 +372,9 @@ def graphics3dbox(self, elements=None, **options) -> str:
add_conversion_fn(Graphics3DBox, graphics3dbox)
-def tag_box(self, **options):
+def tag_and_form_box(self, **options):
return lookup_conversion_method(self.boxed, "mathml")(self.boxed, **options)
-add_conversion_fn(TagBox, tag_box)
+add_conversion_fn(FormBox, tag_and_form_box)
+add_conversion_fn(TagBox, tag_and_form_box)
diff --git a/mathics/format/render/text.py b/mathics/format/render/text.py
index 59e9236c2..49a71a510 100644
--- a/mathics/format/render/text.py
+++ b/mathics/format/render/text.py
@@ -7,6 +7,7 @@
from mathics.builtin.box.graphics import GraphicsBox
from mathics.builtin.box.graphics3d import Graphics3DBox
from mathics.builtin.box.layout import (
+ FormBox,
FractionBox,
GridBox,
InterpretationBox,
@@ -235,8 +236,9 @@ def graphics3dbox(self, elements=None, **options) -> str:
add_conversion_fn(Graphics3DBox, graphics3dbox)
-def tag_box(self, **options):
+def tag_and_form_box(self, **options):
return boxes_to_text(self.boxed, **options)
-add_conversion_fn(TagBox, tag_box)
+add_conversion_fn(FormBox, tag_and_form_box)
+add_conversion_fn(TagBox, tag_and_form_box)
diff --git a/test/builtin/box/test_custom_boxexpression.py b/test/builtin/box/test_custom_boxexpression.py
index d3b36fdcb..aaac0e8d2 100644
--- a/test/builtin/box/test_custom_boxexpression.py
+++ b/test/builtin/box/test_custom_boxexpression.py
@@ -6,6 +6,7 @@
from mathics.core.builtin import Predefined
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
+from mathics.core.rules import BaseRule, FunctionApplyRule, Rule
from mathics.core.symbols import Symbol
SymbolCustomGraphicsBox = Symbol("CustomGraphicsBox")
@@ -42,12 +43,28 @@ class CustomAtom(Predefined):
"N[System`CustomAtom]": "37",
}
- def eval_to_boxes(self, evaluation):
- "System`MakeBoxes[System`CustomAtom, StandardForm|TraditionalForm|OutputForm]"
+ # Since this is a Mathics3 Module which is loaded after
+ # the core symbols are loaded, it is safe to assume that `MakeBoxes`
+ # definition was already loaded. We can add then rules to it.
+ # This modified `contribute` method do that, adding specific
+ # makeboxes rules for this kind of atoms.
+ def contribute(self, definitions, is_pymodule=True):
+ super().contribute(definitions, is_pymodule)
+ # Add specific MakeBoxes rules
+ name = self.get_name()
+
+ for pattern, function in self.get_functions("makeboxes_"):
+ mb_rule = FunctionApplyRule(
+ name, pattern, function, None, attributes=None, system=True
+ )
+ definitions.add_format("System`MakeBoxes", mb_rule, "_MakeBoxes")
+
+ def makeboxes_general(self, evaluation):
+ "System`MakeBoxes[System`CustomAtom, StandardForm|TraditionalForm]"
return CustomBoxExpression(evaluation=evaluation)
- def eval_to_boxes_inputform(self, evaluation):
- "System`MakeBoxes[InputForm[System`CustomAtom], StandardForm|TraditionalForm|OutputForm]"
+ def makeboxes_inputform(self, evaluation):
+ "System`MakeBoxes[InputForm[System`CustomAtom], StandardForm|TraditionalForm]"
return CustomBoxExpression(evaluation=evaluation)
@@ -57,6 +74,22 @@ class CustomGraphicsBox(BoxExpression):
options = GRAPHICS_OPTIONS
attributes = A_HOLD_ALL | A_PROTECTED | A_READ_PROTECTED
+ # Since this is a Mathics3 Module which is loaded after
+ # the core symbols are loaded, it is safe to assume that `MakeBoxes`
+ # definition was already loaded. We can add then rules to it.
+ # This modified `contribute` method do that, adding specific
+ # makeboxes rules for this kind of BoxExpression.
+ def contribute(self, definitions, is_pymodule=True):
+ super().contribute(definitions, is_pymodule)
+ # Add specific MakeBoxes rules
+ name = self.get_name()
+
+ for pattern, function in self.get_functions("makeboxes_"):
+ mb_rule = FunctionApplyRule(
+ name, pattern, function, None, attributes=None, system=True
+ )
+ definitions.add_format("System`MakeBoxes", mb_rule, "_MakeBoxes")
+
def init(self, *elems, **options):
self._elements = elems
self.evaluation = options.pop("evaluation", None)
@@ -65,16 +98,15 @@ def init(self, *elems, **options):
def to_expression(self):
return Expression(SymbolCustomGraphicsBox, *self.elements)
- def eval_box(self, expr, evaluation: Evaluation, options: dict):
+ def makeboxes_graphics(self, expr, evaluation: Evaluation, options: dict):
"""System`MakeBoxes[System`Graphics[System`expr_, System`OptionsPattern[System`Graphics]],
- System`StandardForm|System`TraditionalForm|System`OutputForm]"""
+ System`StandardForm|System`TraditionalForm]"""
instance = CustomGraphicsBox(*(expr.elements), evaluation=evaluation)
return instance
- def eval_box_outputForm(self, expr, evaluation: Evaluation, options: dict):
+ def makeboxes_outputForm(self, expr, evaluation: Evaluation, options: dict):
"""System`MakeBoxes[System`OutputForm[System`Graphics[System`expr_, System`OptionsPattern[System`Graphics]]],
System`StandardForm|System`TraditionalForm]"""
- print("MakeBoxes OutputForm")
instance = CustomGraphicsBox(*(expr.elements), evaluation=evaluation)
return instance
diff --git a/test/format/format_tests.yaml b/test/format/format_tests.yaml
index a94ae3af1..b25b9c1f3 100644
--- a/test/format/format_tests.yaml
+++ b/test/format/format_tests.yaml
@@ -23,6 +23,7 @@
# because we use both in documentation and in the web interface.
#
+
'"-7.32"':
msg: A String with a number
latex:
@@ -813,6 +814,8 @@ TableForm[{{a,b},{c,d}}]:
System`OutputForm: 'α'
System`StandardForm: "α"
System`TraditionalForm: "α"
+
+
a:
msg: A Symbol
latex:
@@ -867,3 +870,47 @@ a^4:
System`OutputForm: a ^ 4
System`StandardForm: a^4
System`TraditionalForm: a^4
+
+
+Optional[x__]:
+ msg: Optional with one argument
+ latex:
+ System`OutputForm: '\text{x\_\_.}'
+ System`StandardForm: '\text{x\_\_.}'
+ mathml:
+ System`OutputForm: 'x__.'
+ System`StandardForm: 'x__.'
+ text:
+ System`InputForm: '(x__.)'
+ System`OutputForm: 'x__.'
+ System`StandardForm: 'x__.'
+ System`TraditionalForm: 'x__.'
+
+
+Optional[x__, a+b]:
+ msg: Optional with two arguments
+ latex:
+ System`OutputForm: ' \text{x\_\_ : a + b}'
+ System`StandardForm: '\text{x\_\_}:a+b'
+ mathml:
+ System`OutputForm: 'x__ : a + b'
+ text:
+ System`InputForm: 'x__ : a + b'
+ System`OutputForm: 'x__ : a + b'
+ System`StandardForm: 'x__:a+b'
+ System`TraditionalForm: 'x__:a+b'
+
+
+a+PrecedenceForm[b+c,10]:
+ msg: "PrecedenceForm"
+ latex:
+ System`OutputForm: '\text{a + (b + c)}'
+ System`StandardForm: 'a+\left(b+c\right)'
+ mathml:
+ System`OutputForm: 'a + (b + c)'
+ System`StandardForm: 'a + ( b + c )'
+ text:
+ System`InputForm: 'a + (PrecedenceForm[b + c, 10])'
+ System`OutputForm: 'a + (b + c)'
+ System`StandardForm: 'a+(b+c)'
+ System`TraditionalForm: 'a+(b+c)'
diff --git a/test/format/makeboxes_tests.yaml b/test/format/makeboxes_tests.yaml
index 23d2e5990..4363450bb 100644
--- a/test/format/makeboxes_tests.yaml
+++ b/test/format/makeboxes_tests.yaml
@@ -65,10 +65,10 @@
Basic Forms:
Arithmetic:
FullForm:
- expect: TagBox[StyleBox[RowBox[{"Plus", "[", RowBox[{"a", ",", RowBox[{"Times", "[", RowBox[{RowBox[{"-", "1"}], ",", "b"}], "]"}]}], "]"}], ShowSpecialCharacters-> False, ShowStringCharacters -> True, NumberMarks -> True], FullForm]
+ expect: 'TagBox[StyleBox[RowBox[{"Plus", "[", RowBox[{"a", ",", RowBox[{"Times", "[", RowBox[{RowBox[{"-", "1"}], ",", "b"}], "]"}]}], "]"}], System`ShowSpecialCharacters-> False, System`ShowStringCharacters -> True, System`NumberMarks -> True], FullForm]'
expr: MakeBoxes[a-b//FullForm]
InputForm:
- expect: InterpretationBox[StyleBox["a - b", ShowStringCharacters -> True, NumberMarks-> True], InputForm[a - b], Editable -> True, AutoDelete -> True]
+ expect: InterpretationBox[StyleBox["a - b", System`ShowStringCharacters -> True, NumberMarks-> True], InputForm[a - b], Editable -> True, AutoDelete -> True]
expr: MakeBoxes[a-b//InputForm]
OutputForm:
expect: InterpretationBox[PaneBox["\"a - b\""], OutputForm[a - b], Editable-> False]
@@ -87,10 +87,10 @@ Basic Forms:
expect: TagBox[FormBox[RowBox[List["F", "(", "x", ")"]], TraditionalForm], TraditionalForm, Editable-> True]
expr: MakeBoxes[F[x]//TraditionalForm]
FullForm:
- expect: TagBox[StyleBox[RowBox[{"F", "[", "x", "]"}], ShowSpecialCharacters-> False, ShowStringCharacters -> True, NumberMarks -> True], FullForm]
+ expect: TagBox[StyleBox[RowBox[{"F", "[", "x", "]"}], ShowSpecialCharacters-> False, System`ShowStringCharacters -> True, System`NumberMarks -> True], FullForm]
expr: MakeBoxes[F[x]//FullForm]
InputForm:
- expect: InterpretationBox[StyleBox["F[x]", ShowStringCharacters -> True, NumberMarks-> True], InputForm[F[x]], Editable -> True, AutoDelete -> True]
+ expect: InterpretationBox[StyleBox["F[x]", System`ShowStringCharacters -> True, NumberMarks-> True], InputForm[F[x]], Editable -> True, AutoDelete -> True]
expr: MakeBoxes[F[x]//InputForm]
OutputForm:
expect: InterpretationBox[PaneBox["\"F[x]\""], OutputForm[F[x]], Editable ->False]
@@ -103,10 +103,10 @@ Basic Forms:
expr: MakeBoxes[F[x]//TeXForm]
Integer_negative:
FullForm:
- expect: TagBox[StyleBox[RowBox[{"-", "14"}], ShowSpecialCharacters-> False, ShowStringCharacters -> True, NumberMarks -> True], FullForm]
+ expect: TagBox[StyleBox[RowBox[{"-", "14"}], ShowSpecialCharacters-> False, System`ShowStringCharacters -> True, System`NumberMarks -> True], FullForm]
expr: MakeBoxes[-14//FullForm]
InputForm:
- expect: InterpretationBox[StyleBox["-14", ShowStringCharacters -> True, NumberMarks -> True], InputForm[-14], Editable -> True, AutoDelete -> True]
+ expect: InterpretationBox[StyleBox["-14", System`ShowStringCharacters -> True, System`NumberMarks -> True], InputForm[-14], Editable -> True, AutoDelete -> True]
expr: MakeBoxes[-14//InputForm]
OutputForm:
expect: InterpretationBox[PaneBox["\"-14\""], OutputForm[-14], Editable -> False]
@@ -119,10 +119,10 @@ Basic Forms:
expr: MakeBoxes[-14//TeXForm]
Integer_positive:
FullForm:
- expect: TagBox[StyleBox["14", ShowSpecialCharacters -> False, ShowStringCharacters-> True, NumberMarks -> True], FullForm]
+ expect: TagBox[StyleBox["14", System`ShowSpecialCharacters -> False, System`ShowStringCharacters-> True, System`NumberMarks -> True], FullForm]
expr: MakeBoxes[14//FullForm]
InputForm:
- expect: InterpretationBox[StyleBox["14", ShowStringCharacters -> True, NumberMarks-> True], InputForm[14], Editable -> True, AutoDelete -> True]
+ expect: InterpretationBox[StyleBox["14", System`ShowStringCharacters -> True, NumberMarks-> True], InputForm[14], Editable -> True, AutoDelete -> True]
expr: MakeBoxes[14//InputForm]
OutputForm:
expect: InterpretationBox[PaneBox["\"14\""], OutputForm[14], Editable -> False]
@@ -135,12 +135,12 @@ Basic Forms:
expr: MakeBoxes[14//TeXForm]
PrecisionReal:
FullForm:
- expect: TagBox[StyleBox[RowBox[{"-", "14.`3."}], ShowSpecialCharacters -> False, ShowStringCharacters-> True, NumberMarks -> True], FullForm]
+ expect: TagBox[StyleBox[RowBox[{"-", "14.`3."}], System`ShowSpecialCharacters -> False, System`ShowStringCharacters-> True, System`NumberMarks -> True], FullForm]
expr: MakeBoxes[-14.`3//FullForm]
msg: "In Mathics3, precision is always an integer number."
InputForm:
expr: MakeBoxes[-14.`3//InputForm]
- expect: InterpretationBox[StyleBox["-14.`3.", ShowStringCharacters -> True, NumberMarks-> True], InputForm[-14.`3], Editable -> True, AutoDelete -> True]
+ expect: InterpretationBox[StyleBox["-14.`3.", System`ShowStringCharacters -> True, NumberMarks-> True], InputForm[-14.`3], Editable -> True, AutoDelete -> True]
OutputForm:
expect: InterpretationBox[PaneBox["\"-14.\""], OutputForm[-14.0], Editable-> False]
expr: MakeBoxes[-14.0//OutputForm]
@@ -153,10 +153,10 @@ Basic Forms:
-> True]
Symbol:
FullForm:
- expect: TagBox[StyleBox["x", ShowSpecialCharacters -> False, ShowStringCharacters-> True, NumberMarks -> True], FullForm]
+ expect: TagBox[StyleBox["x", System`ShowSpecialCharacters -> False, System`ShowStringCharacters-> True, System`NumberMarks -> True], FullForm]
expr: MakeBoxes[x//FullForm]
InputForm:
- expect: InterpretationBox[StyleBox["x", ShowStringCharacters -> True, NumberMarks-> True], InputForm[x], Editable -> True, AutoDelete -> True]
+ expect: InterpretationBox[StyleBox["x", System`ShowStringCharacters -> True, NumberMarks-> True], InputForm[x], Editable -> True, AutoDelete -> True]
expr: MakeBoxes[x//InputForm]
OutputForm:
expect: InterpretationBox[PaneBox["\"x\""], OutputForm[x], Editable -> False]
diff --git a/test/format/test_makeboxes.py b/test/format/test_makeboxes.py
index e4a1386b1..31b39a6bf 100644
--- a/test/format/test_makeboxes.py
+++ b/test/format/test_makeboxes.py
@@ -28,8 +28,8 @@ def makeboxes_basic_forms_iterator(block):
for key, tests in MAKEBOXES_TESTS[block].items():
for form, entry in tests.items():
msg = f"{key}, {form}"
- expr = entry["expr"]
- expect = entry["expect"]
+ expr = entry["expr"] + "//InputForm"
+ expect = entry["expect"] + "//InputForm"
yield expr, expect, msg
@@ -44,7 +44,7 @@ def test_makeboxes_basic_forms(str_expr, str_expected, fail_msg):
str_expected,
to_string_expr=True,
to_string_expected=True,
- hold_expected=True,
+ hold_expected=False,
failure_message=fail_msg,
)
@@ -62,7 +62,7 @@ def test_makeboxes_real(str_expr, str_expected, msg):
str_expected,
to_string_expr=True,
to_string_expected=True,
- hold_expected=True,
+ hold_expected=False,
failure_message=msg,
)
diff --git a/test/helper.py b/test/helper.py
index f9df14b31..0baa2205c 100644
--- a/test/helper.py
+++ b/test/helper.py
@@ -126,10 +126,10 @@ def check_evaluation(
print(time.asctime())
if failure_message:
- print(f"got: {result}, expect: {expected} -- {failure_message}")
+ print(f"got: \n{result}\nexpect:\n{expected}\n -- {failure_message}")
assert result == expected, failure_message
else:
- print(f"got: {result}, expect: {expected}")
+ print(f"got: \n{result}\nexpect:\n{expected}\n --")
if isinstance(expected, re.Pattern):
assert expected.match(result)
else: