Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic implementation of DisplayForm #604

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ New Builtins
#. ``Accuracy``
#. ``ClebschGordan``
#. ``Curl`` (2-D and 3-D vector forms only)
#. ``DisplayForm``
mmatera marked this conversation as resolved.
Show resolved Hide resolved
#. ``Kurtosis``
#. ``PauliMatrix``
#. ``Remove``
Expand Down Expand Up @@ -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
-----

Expand Down
44 changes: 44 additions & 0 deletions mathics/builtin/forms/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,50 @@ def apply_makeboxes(self, expr, n, f, evaluation):
)


class DisplayForm(FormBaseClass):
"""
mmatera marked this conversation as resolved.
Show resolved Hide resolved
<dl>
<dt>'DisplayForm[$obj$]'
<dd>is a form that shows low-level box structures as the correspoding
mmatera marked this conversation as resolved.
Show resolved Hide resolved
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):
Copy link
Member

Choose a reason for hiding this comment

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

apply -> eval in new code please.

"""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>
Expand Down
4 changes: 4 additions & 0 deletions mathics/builtin/makeboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,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:
Copy link
Member

@rocky rocky Nov 13, 2022

Choose a reason for hiding this comment

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

Can this be handled by some sort of HoldForm attribute?

I know DisplayForm doesn't have the HoldForm attribute, but if the attribute mechanism were hooked into somehow we wouldn't need to add a special flag and test.

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 don't think so. In the first place, I guess that in WMA , it does not have that attribute for a reason. But, I also tried to avoid the new attribute, and I could not figure out how to do that without changing more parts of the code.

Copy link
Member

Choose a reason for hiding this comment

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

Ok - I'd like to check on this. Doing this kind of thing feels weird.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking about it again, one alternative would be to set a symbol in a private context, and then instead of looking at that property, look at the value of the symbol. This could have the advantage to make easy to replace the Python code that implements MakeBoxes by WL code. But in the end, it would be the same idea.

Copy link
Member

@rocky rocky Nov 13, 2022

Choose a reason for hiding this comment

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

To start out, I believe we should be following the way that can be written in WL. This keeps us from inventing mechanisms, and flags and so on. Also, since WL follows a certain logic, makes it more likely we will go with the natural flow here, without having to consider specially edge cases. They are probably the ones that WL has set up.

If later we need to get things faster then starting with the logical flow is better than some guessed version.

Copy link
Member

@rocky rocky Nov 15, 2022

Choose a reason for hiding this comment

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

As I think I mentioned on the other PR, TagBox might be used by DisplayForm and that is probably a mechanism by which we get special behavior.

See https://reference.wolfram.com/language/ref/TraditionalForm.html

return expr
expr = expr.to_expression()
if isinstance(expr, Atom):
return expr.atom_to_boxes(f, evaluation)
Expand Down
3 changes: 3 additions & 0 deletions mathics/core/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down