Why it happens
When you enter an expression and evaluate it in Mathematica, MakeExpression
is used to convert the box expression (i.e. the description of the exact input you entererd) into an expression. For example, when you enter f[a]
into a Notebook, what Mathematica sees is RowBox[{"f","[","a","]"}]
(you can use Cell > Show expression to see this). Only after MakeExpression
is applied, is it actually converted to f[a]
.
Similar conversions happen for all other types of valid input. In particular, this process removes certain kinds of information from the input. For example, a+b
, a+(b)
, Plus[a,b]
are all converted to a+b
. At this point, it is too late to tell how a+b
was entered. Something similar is happening in your case, only that Times
and Plus
have some additional simplification rules that are applied during these early phases. To prevent this from happening, we have to interfere with this process at or before the MakeExpression
step, see below for an example of how to do that.
Workaround
Here's a solution similar to what the Notation`
paclet does:
HoldBoxesTemplate[t_] :=
TemplateBox[{t}, "HoldBoxes", DisplayFunction -> (# &)]
MakeExpression[TemplateBox[{b_}, "HoldBoxes", ___], frm_] :=
HoldComplete@HoldBoxes[b, frm]
MakeBoxes[HoldBoxes[b_, _], _] ^:=
HoldBoxesTemplate[b]
Normal@HoldBoxes[b_, frm_] ^:=
ReleaseHold@MakeExpression[b, frm]
AppendTo[CurrentValue[EvaluationNotebook[], InputAliases],
"hb" -> HoldBoxesTemplate["\[Placeholder]"]];
You can now press EschbEsc to insert a placeholder that will keep its contents in exactly the same shape:
The trick is to have an invisible TemplateBox
around your expression that ensures the box structure is preserved through MakeExpression
, rather than being converted into a normal expression (at which point there expression has already been "canonicalized", so that it's no longer possible to reconstruct the original shape). The expression returned is of the form HoldBoxes[...]
: