diff --git a/CHANGES.rst b/CHANGES.rst index c233ec27a..c7de7f12c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -122,6 +122,7 @@ New Builtins #. ``ClebschGordan`` #. ``ComplexExpand`` (@yzrun) #. ``Curl`` (2-D and 3-D vector forms only) +#. ``DisplayForm`` #. ``DiscretePlot`` #. ``Kurtosis`` #. ``ListLogPlot`` @@ -206,11 +207,10 @@ Enhancements #. Better handling of comparisons with finite precision numbers. #. Improved implementation for ``Precision``. #. Infix operators, like ``->`` render with their Unicode symbol when ``$CharacterEncoding`` is not "ASCII". +#. Basic implementation of ``DisplayForm`` #. ``Grid`` compatibility with WMA was improved. Now it supports non-uniform list of lists and lists with general elements. #. Support for BigEndian Big TIFF - - 5.0.2 ----- diff --git a/SYMBOLS_MANIFEST.txt b/SYMBOLS_MANIFEST.txt index 43c6e2162..d384a3885 100644 --- a/SYMBOLS_MANIFEST.txt +++ b/SYMBOLS_MANIFEST.txt @@ -319,6 +319,7 @@ System`Disk System`DiskBox System`DiskMatrix System`Dispatch +System`DisplayForm System`Divide System`DivideBy System`Divisible diff --git a/mathics/builtin/forms/output.py b/mathics/builtin/forms/output.py index be995cd8a..c9e26da70 100644 --- a/mathics/builtin/forms/output.py +++ b/mathics/builtin/forms/output.py @@ -150,6 +150,54 @@ def eval_makeboxes(self, expr, n, f, evaluation: Evaluation): ) +class DisplayForm(FormBaseClass): + """ + + :WMA link: + https://reference.wolfram.com/language/ref/DisplayForm.html + +
+
'DisplayForm[$obj$]' +
is a form that shows low-level box structures as the corresponding\ + print form. +
+ + By default, box structures are shown without a format: + >> box = MakeBoxes[Infix[{a, b}," + "], StandardForm] + = RowBox[{a, + , b}] + Wrapping the box structure in a $DisplayForm$ ensures to render the expression: + >> DisplayForm[box] + = a + b + + The same is valid if the box is nested into an expression: + >> DisplayForm[F[box]] + = F[a + b] + + If the argument does not have a box structure, `DisplayForm` is ignored: + >> DisplayForm[a + b] + = a + b + + """ + + in_outputforms = True + summary_text = "render low-level box structures" + + def eval_makeboxes(self, expr, f, evaluation): + """MakeBoxes[DisplayForm[expr_], f_]""" + + # This is a paratemer needed to remember if + # MakeBoxes is formatting an expression inside a DisplayForm. + # Hopefully, this is temporal and it is not going to be + # needed after the Format/MakeBoxes refactor. + previous_df, evaluation.in_display_form = evaluation.in_display_form, True + try: + result = MakeBoxes(expr, f).evaluate(evaluation) + except: + pass + evaluation.in_display_form = previous_df + return result + + class FullForm(FormBaseClass): """ diff --git a/mathics/builtin/makeboxes.py b/mathics/builtin/makeboxes.py index afdd32408..071a85f68 100644 --- a/mathics/builtin/makeboxes.py +++ b/mathics/builtin/makeboxes.py @@ -390,6 +390,10 @@ def eval_general(self, expr, f, evaluation): """MakeBoxes[expr_, f:TraditionalForm|StandardForm|OutputForm|InputForm|FullForm]""" if isinstance(expr, BoxElementMixin): + # If we are inside a DisplayForm block, + # BoxElementMixin are not processed. + if evaluation.in_display_form: + return expr expr = expr.to_expression() if isinstance(expr, Atom): return expr.atom_to_boxes(f, evaluation) diff --git a/mathics/core/evaluation.py b/mathics/core/evaluation.py index 3d132a5dc..19f7bae18 100644 --- a/mathics/core/evaluation.py +++ b/mathics/core/evaluation.py @@ -174,6 +174,9 @@ def __init__( self.quiet_all = False self.format = format + + # See comment in mathics.builtin.makeboxes.DisplayForm + self.in_display_form = False self.catch_interrupt = catch_interrupt self.SymbolNull = SymbolNull