From 562bcafdc50d3366300ad71c301ed43682e87479 Mon Sep 17 00:00:00 2001 From: mmatera <matera@fisica.unlp.edu.ar> Date: Thu, 10 Nov 2022 14:26:22 -0300 Subject: [PATCH 1/5] basic implementation of DisplayForm --- CHANGES.rst | 4 +++- mathics/builtin/makeboxes.py | 45 ++++++++++++++++++++++++++++++++++++ mathics/core/evaluation.py | 3 +++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 836d64e9d..c7428cde4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,6 +15,7 @@ New Builtins #. ``Accuracy`` #. ``ClebschGordan`` #. ``Curl`` (2-D and 3-D vector forms only) +#. ``DisplayForm`` #. ``Kurtosis`` #. ``PauliMatrix`` #. ``Remove`` @@ -57,7 +58,8 @@ 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`` + 5.0.2 ----- diff --git a/mathics/builtin/makeboxes.py b/mathics/builtin/makeboxes.py index bc8ec6bbc..27c533d52 100644 --- a/mathics/builtin/makeboxes.py +++ b/mathics/builtin/makeboxes.py @@ -325,6 +325,47 @@ class BoxForms_(Predefined): summary_text = "the list of box formats" +class DisplayForm(Builtin): + """ + <dl> + <dt>'DisplayForm[$obj$]' + <dd>is a form that shows low-level box structures as the correspoding + print form. + </dl> + + 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 + + """ + + def apply_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. + evaluation.in_display_form = True + try: + result = MakeBoxes(expr, f).evaluate(evaluation) + except: + pass + evaluation.in_display_form = False + return result + + class MakeBoxes(Builtin): """ <dl> @@ -394,6 +435,10 @@ def apply_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 3c1dfa174..5576d2f77 100644 --- a/mathics/core/evaluation.py +++ b/mathics/core/evaluation.py @@ -256,6 +256,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 From 44b3efe18922f30da5bba324e46f03d17606c782 Mon Sep 17 00:00:00 2001 From: mmatera <matera@fisica.unlp.edu.ar> Date: Thu, 10 Nov 2022 14:32:51 -0300 Subject: [PATCH 2/5] adding summary_text. Moving to mathics.builtin.forms --- mathics/builtin/forms/output.py | 44 +++++++++++++++++++++++++++++++++ mathics/builtin/makeboxes.py | 41 ------------------------------ 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/mathics/builtin/forms/output.py b/mathics/builtin/forms/output.py index b516e0b06..c71b73d80 100644 --- a/mathics/builtin/forms/output.py +++ b/mathics/builtin/forms/output.py @@ -149,6 +149,50 @@ def apply_makeboxes(self, expr, n, f, evaluation): ) +class DisplayForm(FormBaseClass): + """ + <dl> + <dt>'DisplayForm[$obj$]' + <dd>is a form that shows low-level box structures as the correspoding + print form. + </dl> + + 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 apply_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. + evaluation.in_display_form = True + try: + result = MakeBoxes(expr, f).evaluate(evaluation) + except: + pass + evaluation.in_display_form = False + return result + + class FullForm(FormBaseClass): """ <url> diff --git a/mathics/builtin/makeboxes.py b/mathics/builtin/makeboxes.py index 27c533d52..84d504c1a 100644 --- a/mathics/builtin/makeboxes.py +++ b/mathics/builtin/makeboxes.py @@ -325,47 +325,6 @@ class BoxForms_(Predefined): summary_text = "the list of box formats" -class DisplayForm(Builtin): - """ - <dl> - <dt>'DisplayForm[$obj$]' - <dd>is a form that shows low-level box structures as the correspoding - print form. - </dl> - - 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 - - """ - - def apply_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. - evaluation.in_display_form = True - try: - result = MakeBoxes(expr, f).evaluate(evaluation) - except: - pass - evaluation.in_display_form = False - return result - - class MakeBoxes(Builtin): """ <dl> From 7aedfc1448d28dc86ea1d9969a2b7690970800aa Mon Sep 17 00:00:00 2001 From: mmatera <matera@fisica.unlp.edu.ar> Date: Thu, 10 Nov 2022 22:41:08 -0300 Subject: [PATCH 3/5] add URL. Fix typo. Fix Manifest --- SYMBOLS_MANIFEST.txt | 1 + mathics/builtin/forms/output.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/SYMBOLS_MANIFEST.txt b/SYMBOLS_MANIFEST.txt index 7a9a64774..9c3987010 100644 --- a/SYMBOLS_MANIFEST.txt +++ b/SYMBOLS_MANIFEST.txt @@ -316,6 +316,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 c71b73d80..666f29b1f 100644 --- a/mathics/builtin/forms/output.py +++ b/mathics/builtin/forms/output.py @@ -151,9 +151,13 @@ def apply_makeboxes(self, expr, n, f, evaluation): class DisplayForm(FormBaseClass): """ + <url> + :WMA link: + https://reference.wolfram.com/language/ref/DisplayForm.html</url> + <dl> <dt>'DisplayForm[$obj$]' - <dd>is a form that shows low-level box structures as the correspoding + <dd>is a form that shows low-level box structures as the corresponding\ print form. </dl> From 371a4c3768936af2892ac1fbab088491b068ae98 Mon Sep 17 00:00:00 2001 From: mmatera <matera@fisica.unlp.edu.ar> Date: Thu, 10 Nov 2022 22:44:50 -0300 Subject: [PATCH 4/5] support nested displayform --- mathics/builtin/forms/output.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mathics/builtin/forms/output.py b/mathics/builtin/forms/output.py index 666f29b1f..cedcfa275 100644 --- a/mathics/builtin/forms/output.py +++ b/mathics/builtin/forms/output.py @@ -188,12 +188,12 @@ def apply_makeboxes(self, expr, f, evaluation): # 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. - evaluation.in_display_form = True + previous_df, evaluation.in_display_form = evaluation.in_display_form, True try: result = MakeBoxes(expr, f).evaluate(evaluation) except: pass - evaluation.in_display_form = False + evaluation.in_display_form = previous_df return result From 3aea3456fc167d82fc0533ea851164d4a1bdb3c2 Mon Sep 17 00:00:00 2001 From: mmatera <matera@fisica.unlp.edu.ar> Date: Sun, 13 Nov 2022 12:43:21 -0300 Subject: [PATCH 5/5] apply -> eval --- mathics/builtin/forms/output.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mathics/builtin/forms/output.py b/mathics/builtin/forms/output.py index cedcfa275..bdbb28f8e 100644 --- a/mathics/builtin/forms/output.py +++ b/mathics/builtin/forms/output.py @@ -115,7 +115,7 @@ class BaseForm(Builtin): "basf": "Requested base `1` must be between 2 and 36.", } - def apply_makeboxes(self, expr, n, f, evaluation): + def eval_makeboxes(self, expr, n, f, evaluation): """MakeBoxes[BaseForm[expr_, n_], f:StandardForm|TraditionalForm|OutputForm]""" @@ -181,7 +181,7 @@ class DisplayForm(FormBaseClass): in_outputforms = True summary_text = "render low-level box structures" - def apply_makeboxes(self, expr, f, evaluation): + def eval_makeboxes(self, expr, f, evaluation): """MakeBoxes[DisplayForm[expr_], f_]""" # This is a paratemer needed to remember if @@ -692,7 +692,7 @@ def default_NumberFormat(man, base, exp, options): else: return man - def apply_list_n(self, expr, n, evaluation, options) -> Expression: + def eval_list_n(self, expr, n, evaluation, options) -> Expression: "NumberForm[expr_List, n_, OptionsPattern[NumberForm]]" options = [ Expression(SymbolRuleDelayed, Symbol(key), value) @@ -705,7 +705,7 @@ def apply_list_n(self, expr, n, evaluation, options) -> Expression: ] ) - def apply_list_nf(self, expr, n, f, evaluation, options) -> Expression: + def eval_list_nf(self, expr, n, f, evaluation, options) -> Expression: "NumberForm[expr_List, {n_, f_}, OptionsPattern[NumberForm]]" options = [ Expression(SymbolRuleDelayed, Symbol(key), value) @@ -718,7 +718,7 @@ def apply_list_nf(self, expr, n, f, evaluation, options) -> Expression: ], ) - def apply_makeboxes(self, expr, form, evaluation, options={}): + def eval_makeboxes(self, expr, form, evaluation, options={}): """MakeBoxes[NumberForm[expr_, OptionsPattern[NumberForm]], form:StandardForm|TraditionalForm|OutputForm]""" @@ -743,7 +743,7 @@ def apply_makeboxes(self, expr, form, evaluation, options={}): return number_form(expr, py_n, None, evaluation, py_options) return Expression(SymbolMakeBoxes, expr, form) - def apply_makeboxes_n(self, expr, n, form, evaluation, options={}): + def eval_makeboxes_n(self, expr, n, form, evaluation, options={}): """MakeBoxes[NumberForm[expr_, n_?NotOptionQ, OptionsPattern[NumberForm]], form:StandardForm|TraditionalForm|OutputForm]""" @@ -763,7 +763,7 @@ def apply_makeboxes_n(self, expr, n, form, evaluation, options={}): return number_form(expr, py_n, None, evaluation, py_options) return Expression(SymbolMakeBoxes, expr, form) - def apply_makeboxes_nf(self, expr, n, f, form, evaluation, options={}): + def eval_makeboxes_nf(self, expr, n, f, form, evaluation, options={}): """MakeBoxes[NumberForm[expr_, {n_, f_}, OptionsPattern[NumberForm]], form:StandardForm|TraditionalForm|OutputForm]"""