-
-
Notifications
You must be signed in to change notification settings - Fork 64
Makeboxes overhault #1642
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
base: formbox
Are you sure you want to change the base?
Makeboxes overhault #1642
Conversation
| summary_text = "format as a matrix" | ||
|
|
||
| def eval_makeboxes_matrix(self, table, form, evaluation, options): | ||
| def eval_makeboxes(self, table, form, evaluation, options): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method must have the same name as in the superclass. Otherwise, the rule generated by the method in the superclass hides this definition.
| in_printforms = False | ||
| summary_text = "format expression in underlying M-Expression representation" | ||
|
|
||
| def eval_makeboxes(self, expr, fmt, evaluation): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rules of these OutputForms were removed, in favor of a dispatch table which does not pass thorugh the standar evaluation method (see bellow).
| # TeXForm by default uses `TraditionalForm` | ||
|
|
||
| return eval_texform(expr, evaluation) | ||
| @is_print_form_callback("System`InputForm") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of defining (MakeBoxes) format rules, the default implementation of the builtin PrintForms is now registered and processed as callback functions. This default behavior can be modified from the CLI by defining customized Format/MakeBoxes rules, or from a client by overwriting these callback functions.
mathics/builtin/list/constructing.py
Outdated
|
|
||
| items = items.get_sequence() | ||
| return RowBox(*list_boxes(items, f, evaluation, "{", "}")) | ||
| # def eval_makeboxes(self, items, f, evaluation): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rule is now implemented at the level of the generic MakeBoxes evaluation. Again, the behaviour can be modified from inside the CLI by defining convenient rules (see the example in 1-Manual.mdoc).
| # MakeBoxes[CubeRoot, StandardForm] := RadicalBox[3, StandardForm] | ||
| # rather than: | ||
| # MakeBoxes[CubeRoot, StandardForm] -> RadicalBox[3, StandardForm] | ||
| if not lhs.has_form("MakeBoxes", 2): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, MakeBoxes does not allow new Downvalues to be defined. Any assignment to MakeBoxes is stored as a FormatValue.
| yield [item] + rest | ||
|
|
||
|
|
||
| def list_boxes(items, f, evaluation, open=None, close=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably this function does not belong here anymore.
|
|
||
| def eval_to_boxes(self, evaluation): | ||
| "System`MakeBoxes[System`CustomAtom, StandardForm|TraditionalForm|OutputForm]" | ||
| # Since this is a Mathics3 Module which is loaded after |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example shows one way to implement Mathics3 modules that overwrite the default formatting process. This could be useful for example, for Pymathics-Matplotlib.
|
@rocky, there are several other things to do in order to complete the refactor, but most of them are adjustments to this scheme. To see the progress, this is the output of |
| """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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation of this rule now is just the function we use to format elements.
| Load the Definition objects associated to all the builtins | ||
| on `Definitions` | ||
| """ | ||
| # let MakeBoxes contribute first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed anymore.
| else: | ||
| definitions.builtin[name] = definition | ||
|
|
||
| makeboxes_def = definitions.builtin["System`MakeBoxes"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we do not need to make references to the MakeBoxes definition from other symbols anymore.
| You can cause a much bigger mess by overriding 'MakeBoxes' than by sticking to 'Format', e.g. generate invalid XML: | ||
|
|
||
| >> MakeBoxes[MathMLForm[c], form_] = "<not closed"; | ||
| >> MakeBoxes[MathMLForm[c], form_] := "<not closed"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example is not very good, but gives the idea about how to reimplement a PrintForm from inside a Mathics3 session.
Great news!
I don't see a difference here. What's up? |
This is the output when I run the test in master: And this is the diff: A few more tests are now OK, but many of the others produce a closer result. |
| msg = f"{key}, {form}" | ||
| expr = entry["expr"] | ||
| expect = entry["expect"] | ||
| expr = entry["expr"] + "//InputForm" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
InputForm seems to be easier to compare.
| to_string_expr=True, | ||
| to_string_expected=True, | ||
| hold_expected=True, | ||
| hold_expected=False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To allow the evaluation makes that the expected expression be converted to Box elements, which are easier to compare, since options are sorted.
This PR does the largest step so far in making the formatting process in Mathics compatible with the one in WMA.
The main change is in the sequence of formatting. Now,
MakeBoxesrules are notDownvalues, of theMakeBoxessymbol, but are stored asFormatValuesof the corresponding symbols. Rules inMakeBoxesare now restricted to call theformat_elementfunction, and return a Box expression that represents its input. Hence, in loading definitions,MakeBoxesis not a special symbol anymore.Also, the default implementation for formatting basic elements like symbols, expressions, and lists does not pass through the evaluation process until explicit rules are set by the user.