Why does MakeBoxes mess up RowBox ordering?
When I see this right, then the evil function is TraditionalFormDump`ordplus
. This seems to change the order. The arguments can be extracted from a Trace
TraditionalForm[a + b]; (* Dummy call *)
TraditionalFormDump`ordplus[{{"+", "b"}, {"+", "a"}}, {}]
(* {2,1} *)
If we change this to give a sorted list, then your arguments are not reordered
ClearAll[TraditionalFormDump`ordplus]
TraditionalFormDump`ordplus[l1_, _] := Range[Length[l1]]
MakeBoxes[x, form_] = RowBox[{"b", "+", "a"}];
MakeBoxes[x, StandardForm]
MakeBoxes[x, TraditionalForm]
(*
RowBox[{"b", "+", "a"}]
RowBox[{"b", "+", "a"}]
*)
halirutan gave a very nice explanation why this only happens in TraditionalForm
and not in StandardForm
. For completeness I will add the workaround that Rojo mentioned: Associate the definition to x
and not to MakeBoxes
using UpSet
:
MakeBoxes[x, form_] ^= RowBox[{"b", "+", "a"}];
Association with TraditionalForm
also works:
Unprotect[TraditionalForm];
TraditionalForm /: MakeBoxes[x, TraditionalForm] = RowBox[{"b", "+", "a"}];