# Construct a function with subindices

I'm constructing a function that gives me subindices in output.
The function is HAt.

For example:

HAt[u == u0, t -> 0]


The function is constructed following:

HAt/:MakeBoxes[HAt[eq_, x_-> n_], StandardForm]:=
RowBox[
{SubscriptBox[
RowBox[{"", ToBoxes[eq[[1]]], ")"}],
RowBox[{ToBoxes[x], "=", ToBoxes[n]}]],
"\[Equal]",
SubscriptBox[
RowBox[{"(", ToBoxes[eq[[2]]], ")"}],
RowBox[{ToBoxes[x],"=",ToBoxes[n]}]]}]


So, the problema is when the right-hand (or left-hand) of my equation is a number. For example, if I put:

HAt[u == 0, t -> 0]


But I want some like this:

I think the ideia is put some condition at eq[[2]] when this term is a numerical term, some like that:

HAt/:MakeBoxes[HAt[eq_, x_ -> n_] /; eq[[2]]_Numeric, StandardForm] :=
RowBox[
{SubscriptBox[
RowBox[{"(",ToBoxes[eq[[1]]],")"}],
RowBox[{ToBoxes[x], "=", ToBoxes[n]}]],
"\[Equal]",
ToBoxes[eq[[2]]]}]


But the above doesn't work. How do I write the condition I want to enforce correctly?

• Why not do this with PatternTest? Also Numeric isn't a thing... NumericQ is though. Jan 29 '19 at 21:01
• Solved, thank you @b3m2a1 Jan 29 '19 at 21:20

When playing with typesetting the most important thing is to keep your input unevaluated. In cases like Hold @ HAt[...] MakeBoxes won't know that Hold is there.

There are several things that can cause evaluation leaks:

• ToBoxes[x] will evaluate x, use MakeBoxes

• eq[[1]] will evaluate eq, use lhs_ == rhs_ to match your equations

• ?NumericQ will evaluate as well as opposed to e.g. _Real but the latter is not general enough. Fortunately there is SystemDumpHeldNumericQ :)

Here is how I'd do this:

HAt // ClearAll;
HAt /: MakeBoxes[HAt[lhs_ == rhs_, x_ -> n_], fmt : StandardForm] := With[
{ subscript = SubscriptBox[RowBox[{"(", #, ")"}], RowBox[{MakeBoxes[x, fmt], "=", MakeBoxes[n, fmt]}]] &
}
, RowBox[{
subscript @ MakeBoxes[lhs, fmt]
, "\[Equal]"
, If[SystemDumpHeldNumericQ[rhs], Identity, subscript] @ MakeBoxes[rhs, fmt]
}]
]