Skip to content

Conversation

@mmatera
Copy link
Contributor

@mmatera mmatera commented Jan 21, 2026

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, MakeBoxes rules are not Downvalues, of the MakeBoxes symbol, but are stored as FormatValues of the corresponding symbols. Rules in MakeBoxes are now restricted to call the format_element function, and return a Box expression that represents its input. Hence, in loading definitions, MakeBoxes is 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.

summary_text = "format as a matrix"

def eval_makeboxes_matrix(self, table, form, evaluation, options):
def eval_makeboxes(self, table, form, evaluation, options):
Copy link
Contributor Author

@mmatera mmatera Jan 21, 2026

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):
Copy link
Contributor Author

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")
Copy link
Contributor Author

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.


items = items.get_sequence()
return RowBox(*list_boxes(items, f, evaluation, "{", "}"))
# def eval_makeboxes(self, items, f, evaluation):
Copy link
Contributor Author

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):
Copy link
Contributor Author

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):
Copy link
Contributor Author

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
Copy link
Contributor Author

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.

@mmatera
Copy link
Contributor Author

mmatera commented Jan 21, 2026

@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 mathics -f makeboxes_test.m. The results obtained are now much closer to the ones in WS, where the reference values were collected.

Read json
Found 4 expressions to test.

        Basic Forms
        ===========

          Arithmetic
          ==========
    MakeBoxes[a-b//FullForm] //FullForm   [OK]
    MakeBoxes[a-b//InputForm] //InputForm   [Failed]
      expr    = MakeBoxes[a-b//InputForm]
      result  = InterpretationBox[StyleBox[a - b, NumberMarks → True, ShowStringCharacters → True], a - b, AutoDelete → True, Editable → True]
      expected= InterpretationBox[StyleBox[a - b, NumberMarks → True, ShowStringCharacters → True], a - b, AutoDelete → True, Editable → True]
    MakeBoxes[a-b//OutputForm] //OutputForm   [Failed]
      expr    = MakeBoxes[a-b//OutputForm]
      result  = InterpretationBox[PaneBox["a - b"], a - b, Editable → False]
      expected= InterpretationBox[PaneBox["a - b"], a - b, Editable → False]
    MakeBoxes[a-b] //StandardForm   [OK]
    MakeBoxes[a-b//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[a-b//TeXForm]
      result  = InterpretationBox[a-b, a-b, AutoDelete → True, Editable → True]
      expected= InterpretationBox["a-b", a-b, AutoDelete → True, Editable → True]

          Expression
          ==========
    MakeBoxes[Format[F[x], StandardForm]] //Format   [Failed]
      expr    = MakeBoxes[Format[F[x], StandardForm]]
      result  = RowBox[{Format, [, RowBox[{RowBox[{F, [, x, ]}], ,, StandardForm}], ]}]
      expected= TagBox[FormBox[RowBox[{F, [, x, ]}], StandardForm], Format[#1, StandardForm]&]
    MakeBoxes[F[x]//TraditionalForm] //TraditionalForm   [Failed]
      expr    = MakeBoxes[F[x]//TraditionalForm]
      result  = TagBox[FormBox[RowBox[{F, (, x, )}], TraditionalForm], TraditionalForm, Editable → True]
      expected= TagBox[FormBox[RowBox[{F, (, x, )}], TraditionalForm], TraditionalForm, Editable → True]
    MakeBoxes[F[x]//FullForm] //FullForm   [OK]
    MakeBoxes[F[x]//InputForm] //InputForm   [OK]
    MakeBoxes[F[x]//OutputForm] //OutputForm   [OK]
    MakeBoxes[F[x]] //StandardForm   [OK]
    MakeBoxes[F[x]//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[F[x]//TeXForm]
      result  = InterpretationBox[F\left(x\right), F\left(x\right), AutoDelete → True, Editable → True]
      expected= InterpretationBox["F(x)", F\left(x\right), AutoDelete → True, Editable → True]

          Integer_negative
          ================
    MakeBoxes[-14//FullForm] //FullForm   [OK]
    MakeBoxes[-14//InputForm] //InputForm   [OK]
    MakeBoxes[-14//OutputForm] //OutputForm   [OK]
    MakeBoxes[-14] //StandardForm   [OK]
    MakeBoxes[-14//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[-14//TeXForm]
      result  = InterpretationBox[-14, -14, AutoDelete → True, Editable → True]
      expected= InterpretationBox["-14", -14, AutoDelete → True, Editable → True]

          Integer_positive
          ================
    MakeBoxes[14//FullForm] //FullForm   [OK]
    MakeBoxes[14//InputForm] //InputForm   [OK]
    MakeBoxes[14//OutputForm] //OutputForm   [OK]
    MakeBoxes[14] //StandardForm   [OK]
    MakeBoxes[14//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[14//TeXForm]
      result  = InterpretationBox[14, 14, AutoDelete → True, Editable → True]
      expected= InterpretationBox["14", 14, AutoDelete → True, Editable → True]

          PrecisionReal
          =============
    MakeBoxes[-14.`3//FullForm] //FullForm   [OK]
    MakeBoxes[-14.`3//InputForm] //InputForm   [OK]
    MakeBoxes[-14.0//OutputForm] //OutputForm   [OK]
    MakeBoxes[-14.`3] //StandardForm   [OK]
    MakeBoxes[-14.`3//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[-14.`3//TeXForm]
      result  = InterpretationBox[-14., -14., AutoDelete → True, Editable → True]
      expected= InterpretationBox["-14.0", -14., AutoDelete → True, Editable → True]

          Symbol
          ======
    MakeBoxes[x//FullForm] //FullForm   [OK]
    MakeBoxes[x//InputForm] //InputForm   [OK]
    MakeBoxes[x//OutputForm] //OutputForm   [OK]
    MakeBoxes[x] //StandardForm   [OK]
    MakeBoxes[x//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[x//TeXForm]
      result  = InterpretationBox[x, x, AutoDelete → True, Editable → True]
      expected= InterpretationBox["x", x, AutoDelete → True, Editable → True]

        Numbers
        =======

          MachineReal, positive
          =====================
    MakeBoxes[1.4`] //StandardForm   [OK]
    MakeBoxes[1.4`//OutputForm] //OutputForm   [OK]

          MachineReal, negative
          =====================
    MakeBoxes[-1.4`] //StandardForm   [OK]
    MakeBoxes[-1.4`//OutputForm] //OutputForm   [OK]

          MachineReal, Large
          ==================
    MakeBoxes[34.*^3] //StandardForm   [OK]

          MachineReal, Very Large
          =======================
    MakeBoxes[34.*^9] //StandardForm   [Failed]
      expr    = MakeBoxes[34.*^9]
      result  = RowBox[{3.4`, *^, 10}]
      expected= 3.4`*^10

          PrecisionReal, Few Digits
          =========================
    MakeBoxes[3.142`3] //StandardForm   [OK]
    MakeBoxes[OutputForm[3.142`3]] //OutputForm   [Failed]
      expr    = MakeBoxes[OutputForm[3.142`3]]
      result  = InterpretationBox[PaneBox["3.14"], 3.14, Editable → False]
      expected= InterpretationBox[PaneBox["3.14"], 3.14, Editable → False]

          PrecisionReal, Many Digits
          ==========================
    MakeBoxes[1.4`20] //StandardForm   [OK]

          PrecisionReal, Many Accuracy
          ============================
    MakeBoxes[1.5``20] //StandardForm   [Failed]
      expr    = MakeBoxes[1.5``20]
      result  = 1.5`20.
      expected= 1.5`20.176091259055685

          PrecisionReal, Zero_LowPrec
          ===========================
    MakeBoxes[0.`3] //StandardForm   [OK]

          PrecisionReal, Zero_LargePrec
          =============================
    MakeBoxes[0.`30] //StandardForm   [OK]

          PrecisionReal, Zero_Accuracy
          ============================
    MakeBoxes[0.``30] //StandardForm   [Failed]
      expr    = MakeBoxes[0.``30]
      result  = RowBox[{0.`30., *^, -30}]
      expected= 0``30.

        Graphics
        ========

          Disk
          ====
    MakeBoxes[Graphics[{Disk[{0,0}, 1]}]] //StandardForm   [Failed]
      expr    = MakeBoxes[Graphics[{Disk[{0,0}, 1]}]]
      result  = GraphicsBox[{DiskBox[{0, 0}, 1]}, AlignmentPoint → Center, AspectRatio → Automatic, Axes → False, AxesLabel → None, AxesOrigin → Automatic, AxesStyle → {}, Background → Automatic, BaseStyle → {}, BaselinePosition → Automatic, ContentSelectable → Automatic, CoordinatesToolOptions → Automatic, Epilog → {}, FormatType → TraditionalForm, Frame → False, FrameLabel → None, FrameStyle → {}, FrameTicks → Automatic, FrameTicksStyle → {}, GridLines → None, GridLinesStyle → {}, ImageMargins → 0., ImagePadding → All, ImageSize → Automatic, LabelStyle → {}, LogPlot → False, Method → Automatic, PlotLabel → None, PlotRange → Automatic, PlotRangeClipping → False, PlotRangePadding → Automatic, PlotRegion → Automatic, PreserveImageOptions → Automatic, Prolog → {}, RotateLabel → True, Ticks → Automatic, TicksStyle → {}]
      expected= GraphicsBox[{DiskBox[{0, 0}, 1]}]
    MakeBoxes[Graphics[{Disk[{0,0}, 1]}]//OutputForm] //OutputForm   [OK]

          Sphere
          ======
    MakeBoxes[Graphics3D[{Sphere[{0,0,0}, 1]}]] //StandardForm   [Failed]
      expr    = MakeBoxes[Graphics3D[{Sphere[{0,0,0}, 1]}]]
      result  = Graphics3DBox[{Sphere3DBox[{0, 0, 0}, 1]}, AlignmentPoint → Center, AspectRatio → Automatic, Axes → False, AxesEdge → Automatic, AxesLabel → None, AxesOrigin → Automatic, AxesStyle → {}, Background → Automatic, BaseStyle → {}, BaselinePosition → Automatic, BoxRatios → Automatic, BoxStyle → {}, Boxed → True, ClipPlanes → None, ClipPlanesStyle → Automatic, ContentSelectable → Automatic, ControllerLinking → False, ControllerPath → Automatic, CoordinatesToolOptions → Automatic, Epilog → {}, FaceGrids → None, FaceGridsStyle → {}, FormatType → TraditionalForm, Frame → False, FrameLabel → None, FrameStyle → {}, FrameTicks → Automatic, FrameTicksStyle → {}, GridLines → None, GridLinesStyle → {}, ImageMargins → 0., ImagePadding → All, ImageSize → Automatic, LabelStyle → {}, Lighting → Automatic, LogPlot → False, Method → Automatic, PlotLabel → None, PlotRange → Automatic, PlotRangeClipping → False, PlotRangePadding → Automatic, PlotRegion → Automatic, PreserveImageOptions → Automatic, Prolog → {}, RotateLabel → True, RotationAction → Fit, SphericalRegion → Automatic, Ticks → Automatic, TicksStyle → {}, TouchscreenAutoZoom → False, ViewAngle → Automatic, ViewCenter → Automatic, ViewMatrix → Automatic, ViewPoint → {1.3, -2.4, 2.}, ViewProjection → Automatic, ViewRange → All, ViewVector → Automatic, ViewVertical → {0., 0., 1.}]
      expected= Graphics3DBox[{SphereBox[{0, 0, 0}, 1]}]
    MakeBoxes[Graphics3D[{Sphere[{0,0,0}, 1]}]//OutputForm] //OutputForm   [OK]

        Parsing string form
        ===================

          RowBox
          ======
    \( a, b \) //StandardForm   [OK]

          FractionBox
          ===========
    \(x \/ y + z\) //StandardForm   [OK]

          FractionBox bracket
          ===================
    \(x \/ (y + z)\) //StandardForm   [Failed]
      expr    = \(x \/ (y + z)\)
      result  = RowBox[{FractionBox[x, (], y, +, z, )}]
      expected= FractionBox[x, RowBox[{(, RowBox[{y, +, z}], )}]]

          SqrtBox
          =======
    \( \@ a + b \) //StandardForm   [OK]

          FormBox
          =======
    \(TraditionalForm \` a + b\) //StandardForm   [Failed]
      expr    = \(TraditionalForm \` a + b\)
      result  = RowBox[{FormBox[a, TraditionalForm], +, b}]
      expected= FormBox[RowBox[{a, +, b}], TraditionalForm]
Done

"""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)
Copy link
Contributor Author

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
Copy link
Contributor Author

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"]
Copy link
Contributor Author

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";
Copy link
Contributor Author

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.

@rocky
Copy link
Member

rocky commented Jan 21, 2026

@rocky, there are several other things to do in order to complete the refactor, but most of them are adjustments to this scheme.

Great news!

To see the progress....

Read json
Found 4 expressions to test.

        Basic Forms
        ===========

          Arithmetic
          ==========
    MakeBoxes[a-b//FullForm] //FullForm   [OK]
    MakeBoxes[a-b//InputForm] //InputForm   [Failed]
      expr    = MakeBoxes[a-b//InputForm]
      result  = InterpretationBox[StyleBox[a - b, NumberMarks → True, ShowStringCharacters → True], a - b, AutoDelete → True, Editable → True]
      expected= InterpretationBox[StyleBox[a - b, NumberMarks → True, ShowStringCharacters → True], a - b, AutoDelete → True, Editable → True]
...

I don't see a difference here. What's up?

@mmatera
Copy link
Contributor Author

mmatera commented Jan 21, 2026

result = InterpretationBox[StyleBox[a - b, NumberMarks → True, ShowStringCharacters → True], a - b, AutoDelete → True, Editable → True]

This is the output when I run the test in master:

Read json
Found 4 expressions to test.

        Basic Forms
        ===========

          Arithmetic
          ==========
    MakeBoxes[a-b//FullForm] //FullForm   [OK]
    MakeBoxes[a-b//InputForm] //InputForm   [OK]
    MakeBoxes[a-b//OutputForm] //OutputForm   [OK]
    MakeBoxes[a-b] //StandardForm   [Failed]
      expr    = MakeBoxes[a-b]
      result  = RowBox[{Plus, [, RowBox[{a, ,, RowBox[{Times, [, RowBox[{RowBox[{-, 1}], ,, b}], ]}]}], ]}]
      expected= RowBox[{a, -, b}]
    MakeBoxes[a-b//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[a-b//TeXForm]
      result  = RowBox[{a-b}]
      expected= InterpretationBox["a-b", a-b, AutoDelete → True, Editable → True]

          Expression
          ==========
    MakeBoxes[Format[F[x], StandardForm]] //Format   [Failed]
      expr    = MakeBoxes[Format[F[x], StandardForm]]
      result  = RowBox[{Format, [, RowBox[{RowBox[{F, [, x, ]}], ,, StandardForm}], ]}]
      expected= TagBox[FormBox[RowBox[{F, [, x, ]}], StandardForm], Format[#1, StandardForm]&]
    MakeBoxes[F[x]//TraditionalForm] //TraditionalForm   [Failed]
      expr    = MakeBoxes[F[x]//TraditionalForm]
      result  = RowBox[{F, (, x, )}]
      expected= TagBox[FormBox[RowBox[{F, (, x, )}], TraditionalForm], TraditionalForm, Editable → True]
    MakeBoxes[F[x]//FullForm] //FullForm   [OK]
    MakeBoxes[F[x]//InputForm] //InputForm   [OK]
    MakeBoxes[F[x]//OutputForm] //OutputForm   [OK]
    MakeBoxes[F[x]] //StandardForm   [OK]
    MakeBoxes[F[x]//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[F[x]//TeXForm]
      result  = RowBox[{F\left(x\right)}]
      expected= InterpretationBox["F(x)", F\left(x\right), AutoDelete → True, Editable → True]

          Integer_negative
          ================
    MakeBoxes[-14//FullForm] //FullForm   [OK]
    MakeBoxes[-14//InputForm] //InputForm   [OK]
    MakeBoxes[-14//OutputForm] //OutputForm   [OK]
    MakeBoxes[-14] //StandardForm   [OK]
    MakeBoxes[-14//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[-14//TeXForm]
      result  = RowBox[{-14}]
      expected= InterpretationBox["-14", -14, AutoDelete → True, Editable → True]

          Integer_positive
          ================
    MakeBoxes[14//FullForm] //FullForm   [OK]
    MakeBoxes[14//InputForm] //InputForm   [OK]
    MakeBoxes[14//OutputForm] //OutputForm   [OK]
    MakeBoxes[14] //StandardForm   [OK]
    MakeBoxes[14//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[14//TeXForm]
      result  = RowBox[{14}]
      expected= InterpretationBox["14", 14, AutoDelete → True, Editable → True]

          PrecisionReal
          =============
    MakeBoxes[-14.`3//FullForm] //FullForm   [OK]
    MakeBoxes[-14.`3//InputForm] //InputForm   [OK]
    MakeBoxes[-14.0//OutputForm] //OutputForm   [OK]
    MakeBoxes[-14.`3] //StandardForm   [OK]
    MakeBoxes[-14.`3//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[-14.`3//TeXForm]
      result  = RowBox[{-14.}]
      expected= InterpretationBox["-14.0", -14., AutoDelete → True, Editable → True]

          Symbol
          ======
    MakeBoxes[x//FullForm] //FullForm   [OK]
    MakeBoxes[x//InputForm] //InputForm   [OK]
    MakeBoxes[x//OutputForm] //OutputForm   [OK]
    MakeBoxes[x] //StandardForm   [OK]
    MakeBoxes[x//TeXForm] //TeXForm   [Failed]
      expr    = MakeBoxes[x//TeXForm]
      result  = RowBox[{x}]
      expected= InterpretationBox["x", x, AutoDelete → True, Editable → True]

        Numbers
        =======

          MachineReal, positive
          =====================
    MakeBoxes[1.4`] //StandardForm   [OK]
    MakeBoxes[1.4`//OutputForm] //OutputForm   [OK]

          MachineReal, negative
          =====================
    MakeBoxes[-1.4`] //StandardForm   [OK]
    MakeBoxes[-1.4`//OutputForm] //OutputForm   [OK]

          MachineReal, Large
          ==================
    MakeBoxes[34.*^3] //StandardForm   [OK]

          MachineReal, Very Large
          =======================
    MakeBoxes[34.*^9] //StandardForm   [Failed]
      expr    = MakeBoxes[34.*^9]
      result  = RowBox[{3.4`, *^, 10}]
      expected= 3.4`*^10

          PrecisionReal, Few Digits
          =========================
    MakeBoxes[3.142`3] //StandardForm   [OK]
    MakeBoxes[OutputForm[3.142`3]] //OutputForm   [Failed]
      expr    = MakeBoxes[OutputForm[3.142`3]]
      result  = InterpretationBox[PaneBox["3.14"], 3.14, Editable → False]
      expected= InterpretationBox[PaneBox["3.14"], 3.14, Editable → False]

          PrecisionReal, Many Digits
          ==========================
    MakeBoxes[1.4`20] //StandardForm   [OK]

          PrecisionReal, Many Accuracy
          ============================
    MakeBoxes[1.5``20] //StandardForm   [Failed]
      expr    = MakeBoxes[1.5``20]
      result  = 1.5`20.
      expected= 1.5`20.176091259055685

          PrecisionReal, Zero_LowPrec
          ===========================
    MakeBoxes[0.`3] //StandardForm   [OK]

          PrecisionReal, Zero_LargePrec
          =============================
    MakeBoxes[0.`30] //StandardForm   [OK]

          PrecisionReal, Zero_Accuracy
          ============================
    MakeBoxes[0.``30] //StandardForm   [Failed]
      expr    = MakeBoxes[0.``30]
      result  = RowBox[{0.`30., *^, -30}]
      expected= 0``30.

        Graphics
        ========

          Disk
          ====
    MakeBoxes[Graphics[{Disk[{0,0}, 1]}]] //StandardForm   [Failed]
      expr    = MakeBoxes[Graphics[{Disk[{0,0}, 1]}]]
      result  = GraphicsBox[{DiskBox[{0, 0}, 1]}, AlignmentPoint → Center, AspectRatio → Automatic, Axes → False, AxesLabel → None, AxesOrigin → Automatic, AxesStyle → {}, Background → Automatic, BaseStyle → {}, BaselinePosition → Automatic, ContentSelectable → Automatic, CoordinatesToolOptions → Automatic, Epilog → {}, FormatType → TraditionalForm, Frame → False, FrameLabel → None, FrameStyle → {}, FrameTicks → Automatic, FrameTicksStyle → {}, GridLines → None, GridLinesStyle → {}, ImageMargins → 0., ImagePadding → All, ImageSize → Automatic, LabelStyle → {}, LogPlot → False, Method → Automatic, PlotLabel → None, PlotRange → Automatic, PlotRangeClipping → False, PlotRangePadding → Automatic, PlotRegion → Automatic, PreserveImageOptions → Automatic, Prolog → {}, RotateLabel → True, Ticks → Automatic, TicksStyle → {}]
      expected= GraphicsBox[{DiskBox[{0, 0}, 1]}]
    MakeBoxes[Graphics[{Disk[{0,0}, 1]}]//OutputForm] //OutputForm   [OK]

          Sphere
          ======
    MakeBoxes[Graphics3D[{Sphere[{0,0,0}, 1]}]] //StandardForm   [Failed]
      expr    = MakeBoxes[Graphics3D[{Sphere[{0,0,0}, 1]}]]
      result  = Graphics3DBox[{Sphere3DBox[{0, 0, 0}, 1]}, AlignmentPoint → Center, AspectRatio → Automatic, Axes → False, AxesEdge → Automatic, AxesLabel → None, AxesOrigin → Automatic, AxesStyle → {}, Background → Automatic, BaseStyle → {}, BaselinePosition → Automatic, BoxRatios → Automatic, BoxStyle → {}, Boxed → True, ClipPlanes → None, ClipPlanesStyle → Automatic, ContentSelectable → Automatic, ControllerLinking → False, ControllerPath → Automatic, CoordinatesToolOptions → Automatic, Epilog → {}, FaceGrids → None, FaceGridsStyle → {}, FormatType → TraditionalForm, Frame → False, FrameLabel → None, FrameStyle → {}, FrameTicks → Automatic, FrameTicksStyle → {}, GridLines → None, GridLinesStyle → {}, ImageMargins → 0., ImagePadding → All, ImageSize → Automatic, LabelStyle → {}, Lighting → Automatic, LogPlot → False, Method → Automatic, PlotLabel → None, PlotRange → Automatic, PlotRangeClipping → False, PlotRangePadding → Automatic, PlotRegion → Automatic, PreserveImageOptions → Automatic, Prolog → {}, RotateLabel → True, RotationAction → Fit, SphericalRegion → Automatic, Ticks → Automatic, TicksStyle → {}, TouchscreenAutoZoom → False, ViewAngle → Automatic, ViewCenter → Automatic, ViewMatrix → Automatic, ViewPoint → {1.3, -2.4, 2.}, ViewProjection → Automatic, ViewRange → All, ViewVector → Automatic, ViewVertical → {0., 0., 1.}]
      expected= Graphics3DBox[{SphereBox[{0, 0, 0}, 1]}]
    MakeBoxes[Graphics3D[{Sphere[{0,0,0}, 1]}]//OutputForm] //OutputForm   [OK]

        Parsing string form
        ===================

          RowBox
          ======
    \( a, b \) //StandardForm   [OK]

          FractionBox
          ===========
    \(x \/ y + z\) //StandardForm   [OK]

          FractionBox bracket
          ===================
    \(x \/ (y + z)\) //StandardForm   [Failed]
      expr    = \(x \/ (y + z)\)
      result  = RowBox[{FractionBox[x, (], y, +, z, )}]
      expected= FractionBox[x, RowBox[{(, RowBox[{y, +, z}], )}]]

          SqrtBox
          =======
    \( \@ a + b \) //StandardForm   [OK]

          FormBox
          =======
    \(TraditionalForm \` a + b\) //StandardForm   [Failed]
      expr    = \(TraditionalForm \` a + b\)
      result  = RowBox[{RowBox[{FormBox, [, RowBox[{"a", ,, TraditionalForm}], ]}], +, b}]
      expected= FormBox[RowBox[{a, +, b}], TraditionalForm]
Done

And this is the diff:

<     MakeBoxes[a-b//InputForm] //InputForm   [OK]
<     MakeBoxes[a-b//OutputForm] //OutputForm   [OK]
<     MakeBoxes[a-b] //StandardForm   [Failed]
<       expr    = MakeBoxes[a-b]
<       result  = RowBox[{Plus, [, RowBox[{a, ,, RowBox[{Times, [, RowBox[{RowBox[{-, 1}], ,, b}], ]}]}], ]}]
<       expected= RowBox[{a, -, b}]
---
>     MakeBoxes[a-b//InputForm] //InputForm   [Failed]
>       expr    = MakeBoxes[a-b//InputForm]
>       result  = InterpretationBox[StyleBox[a - b, NumberMarks → True, ShowStringCharacters → True], a - b, AutoDelete → True, Editable → True]
>       expected= InterpretationBox[StyleBox[a - b, NumberMarks → True, ShowStringCharacters → True], a - b, AutoDelete → True, Editable → True]
>     MakeBoxes[a-b//OutputForm] //OutputForm   [Failed]
>       expr    = MakeBoxes[a-b//OutputForm]
>       result  = InterpretationBox[PaneBox["a - b"], a - b, Editable → False]
>       expected= InterpretationBox[PaneBox["a - b"], a - b, Editable → False]
>     MakeBoxes[a-b] //StandardForm   [OK]
18c21
<       result  = RowBox[{a-b}]
---
>       result  = InterpretationBox[a-b, a-b, AutoDelete → True, Editable → True]
29c32
<       result  = RowBox[{F, (, x, )}]
---
>       result  = TagBox[FormBox[RowBox[{F, (, x, )}], TraditionalForm], TraditionalForm, Editable → True]
37c40
<       result  = RowBox[{F\left(x\right)}]
---
>       result  = InterpretationBox[F\left(x\right), F\left(x\right), AutoDelete → True, Editable → True]
48c51
<       result  = RowBox[{-14}]
---
>       result  = InterpretationBox[-14, -14, AutoDelete → True, Editable → True]
59c62
<       result  = RowBox[{14}]
---
>       result  = InterpretationBox[14, 14, AutoDelete → True, Editable → True]
70c73
<       result  = RowBox[{-14.}]
---
>       result  = InterpretationBox[-14., -14., AutoDelete → True, Editable → True]
81c84
<       result  = RowBox[{x}]
---
>       result  = InterpretationBox[x, x, AutoDelete → True, Editable → True]
187c190
<       result  = RowBox[{RowBox[{FormBox, [, RowBox[{"a", ,, TraditionalForm}], ]}], +, b}]
---
>       result  = RowBox[{FormBox[a, TraditionalForm], +, b}]

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"
Copy link
Contributor Author

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,
Copy link
Contributor Author

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.

@mmatera mmatera marked this pull request as ready for review January 22, 2026 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants