6
$\begingroup$

Why HoldForm do this?

enter image description here

HoldForm[a/b \[Integral]f[x] \[DifferentialD]x]

Output is this ugly looking formula: $$\frac{a \int f(x) \, dx}{b}$$

I want the output to look exactly same as I typed it: $$\frac{a}{b} \int f(x) \, dx$$

What is the purpose of HoldForm when it does not hold the form of expression as it has been typed?

It always rearranges fractions from $\frac{a}{b} c$ to $\frac{a c}{b}$.

$\endgroup$
2

3 Answers 3

7
$\begingroup$

(The basic idea is from this answer by xzczd.)

Try this:

MakeBoxes[Times[a_, b_], StandardForm] := RowBox[{MakeBoxes@a, MakeBoxes@b}]
MakeBoxes[Times[a_, Power[b_, -1]], StandardForm] := MakeBoxes[Divide[a, b]]

Now

Hold[a/b  \[Integral]f[x] \[DifferentialD]x]

screenshot

$\endgroup$
3
  • $\begingroup$ While this will not preserve the input box structure exactly, it seems to be surprisingly robust and is very simple. Nice! $\endgroup$
    – Lukas Lang
    Commented May 8, 2022 at 13:19
  • $\begingroup$ @LukasLang Yes, technically this method doesn't do what was requested in the question: it does not hold the form of expression "as it has been typed". It just produces the formatting the OP wished to get. $\endgroup$ Commented May 8, 2022 at 13:39
  • $\begingroup$ @LukasLang The only simple way to get exactly the form in which the expression was typed is to take the box form of the expression directly from the cell when the expression was typed. Then wrap the extracted boxes with RawBoxes for producing the output. $\endgroup$ Commented May 8, 2022 at 13:45
9
$\begingroup$

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:

enter image description here

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[...]:

enter image description here

$\endgroup$
1
  • $\begingroup$ Interesting but rather complicated. If nobody comes with a simpler method I will accept your answer. $\endgroup$ Commented May 8, 2022 at 13:14
3
$\begingroup$

It is just enough to wrap a/b. Try this:

enter image description here

Have fun!

$\endgroup$
2
  • $\begingroup$ What is the point of your answer? If I have complex expression that contains several compound fractions I will not rewrite it with lots of HoldForm inside in appropriate positions. For such a manual work I would use rather Latex than Mathematica. HoldForm is simply not doing what it claims it should do. And that is the problem, not that I would not know how to do it manually. $\endgroup$ Commented May 8, 2022 at 11:52
  • $\begingroup$ @azerbajdzan What is the point of your comment? 1. Mma is just constructed in such a way as it is. It is not arranged to return results in a beautiful form. It is not a Latex. 2. If you have a "complex expression that contains several compound fractions " you should write this directly in your question. I must not guess what exactly do you have in mind. $\endgroup$ Commented May 8, 2022 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.