7
$\begingroup$

How can I create mathematical expressions (just for the looks) which have correct spacing around the operator? I want to use display these in arbitrary places, such as labels in a GUI, tick labels or within Text/Inset in Graphics, etc.


Here's an example of entering $a\times b$ in an input cell as a \[Times] b. The spacing is perfect, and automatically determined.

If I enter the same in a string or create it with Row, then the spacing is too small.

enter image description here

How can I assemble this expression given an arbitrary a and b (say, $a = 5$ and $b = 10^{6}$), and maintain correct spacing around the operator? In some cases HoldForm helps, but multiplication isn't always formatted with \[Times] so I cannot use it in this case.

I can adjust the spacing in Row manually in several ways, but I don't want to do this. I want to let Mathematica determine the spacing automatically, and have it consistent with expressions I type into an input cell.


When I type $a\times b$ into an input cell, the underlying representation is just RowBox[{"a", "\[Times]", "b"}]. There is something about the "Input" cell style that causes the front end to interpret \[Times] as an operator and create the correct spacing. What is it? It doesn't happen for all cells style (e.g. not for "Code").

$\endgroup$
  • $\begingroup$ It seems the key is AutoSpacing. Now I have to figure out how to use this to create a display that can be inserted anywhere in the notebook, including graphics. $\endgroup$ – Szabolcs Oct 11 '16 at 9:52
  • $\begingroup$ In my system (I haven't messed with autospacing) Row[...] and a \[Times] b have the same spacing: i.stack.imgur.com/mQiSR.png $\endgroup$ – gpap Oct 11 '16 at 13:15
  • $\begingroup$ @gpap What version of M do you have? Let me try that again. $\endgroup$ – Szabolcs Oct 11 '16 at 13:25
  • $\begingroup$ @gpap I see your screenshot, but I can't get any M between 9 and 11 to behave that way. I'm on OS X. $\endgroup$ – Szabolcs Oct 11 '16 at 13:27
  • $\begingroup$ osx 10.10.5 and MMA 10.3.0.0 - I got distracted by an email and forgot to write that :D $\endgroup$ – gpap Oct 11 '16 at 13:27
4
$\begingroup$

I am not quite sure, if I correctly understuud your ultimate aim. I take it that you will only use the expressions for demonstration in a notebook or as a part of an image (say, graphics). If this is true, may be using Spacer may help. Let us take your example with and without the spacer:

    Row[{"a", "\[Times]", "b"}]
    Row[{"a", Spacer[2.5], "\[Times]", Spacer[2], "b"}]

it yields

enter image description here

the second example has somewhat larger spaces between the symbols. One can do the same also by using the BoxLanguage:

  StyleBox[RowBox[{"a", Spacer[2.5], "\[Times]", Spacer[1], "b"}], 
  SpanMaxSize -> Infinity] // DisplayForm

enter image description here

I hope it helps. Have fun!


You can also use the option you mentioned, AutoSpacing. This is an option for Cell, so we must use DisplayForm to show the result in the notebook:

DisplayForm[
 Cell[BoxData@RowBox[{4, "\[Times]", SuperscriptBox[10, 5]}], AutoSpacing -> True]
]

enter image description here

$\endgroup$
  • $\begingroup$ Actually I explicitly asked not to put in the space manually. I need the spacing to be as determined by the front end. So Spacer is not an acceptable solution. But DisplayForm (which I wasn't aware of) combined with AutoSpacing does solve the problem! Thank you. DisplayForm[ Cell[BoxData@RowBox[{4, "\[Times]", SuperscriptBox[10, 5]}], AutoSpacing -> True]]. $\endgroup$ – Szabolcs Oct 11 '16 at 10:50
  • $\begingroup$ I went ahead and edited this into your answer so I can feel content accepting it :-) I hope you don't mind about the edit. It can always be undone. $\endgroup$ – Szabolcs Oct 11 '16 at 13:31
  • $\begingroup$ @Szabolcs I do not mind, by I do not deserve it: I did not know about such an option. Even more, when I tried to evaluate ` Options[DisplayForm]` Mma returnd an empty list. $\endgroup$ – Alexei Boulbitch Oct 11 '16 at 16:06
1
$\begingroup$

The cell created when you enter a \[Times] b can be examined by using Cell | Show Expression on the input cell:

Cell[BoxData[ RowBox[{"a", "\[Times]", "b"}]], "Input", CellChangeTimes->{{3.764961916060225*^9, 3.764961918981412*^9}}]

Alternatively, consider the boxes generated for typical binary operations:

a.b //ToBoxes

RowBox[{"a", ".", "b"}]

a+b //ToBoxes

RowBox[{"a", "+", "b"}]

So, to get the nice front end spacing you observe, you need to construct a similar structure. One way to do this is to use Row with a second argument of None:

Row[{a, "\[Times]", b}, None]

enter image description here

Let's see what the underlying box structure is for the above:

ToBoxes @ Row[{a, "\[Times]", b}]

TemplateBox[{"a", "\"\[Times]\"", "b"}, "RowDefault"]

Oops, we get a TemplateBox. Let's use an internal function to convert this to ordinary boxes:

BoxForm`TemplateBoxToDisplayBoxes @ ToBoxes@Row[{a, "\[Times]", b},None]

RowBox[{"a", "\"\[Times]\"", "b"}]

To be even more similar to how things like a + b are converted to boxes, you can use RawBoxes. Basically, ToBoxes @ RawBoxes[boxes] returns boxes. So:

BoxForm`TemplateBoxToDisplayBoxes@ ToBoxes@Row[{a, RawBoxes@"\[Times]", b},None]

RowBox[{"a", "\[Times]", "b"}]

An alternative to using Row is to actually create a format:

MakeBoxes[times[a_, b_], StandardForm] ^:= RowBox @ {
    MakeBoxes[a, StandardForm], "\[Times]", MakeBoxes[b, StandardForm]
}

Then:

times[a, b]
ToBoxes @ %

enter image description here

RowBox[{"a", "\[Times]", "b"}]

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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