3
$\begingroup$

I'd like to format the output of certain operators with Infix-style formatting to have lower precedence than Times.

Let's say I define foo to format as CenterDot :

Format[x_foo]:=CenterDot@@foo

The following prints with no parentheses (as expected) :

a * foo[x,y]
(* a x \[CenterDot] y *)

This is the sort of output I want :

a*PrecedenceForm[ foo[x,y], 395 ]
(* a (x \[CenterDot] y) *)

However, I'd like to abstract this away a bit more. I'd like to instead do something like

Format[x_foo]:=PrecedenceForm[CenterDot @@ x, 395]

so that this is handled entirely at the output level. However, the PrecedenceForm doesn't seem to do anything:

a*foo[x,y]
(* a x \[CenterDot] y *)

Of course, I'm just as interested in why this doesn't work as I am in solving the problem of inserting parentheses.

$\endgroup$

2 Answers 2

2
$\begingroup$

\I would suggest to use lower level formatting commands like this

MakeBoxes[foo[arg1_Symbol, arg2_Symbol], StandardForm] := 
 With[{arg1b = MakeBoxes[arg1], arg2b = MakeBoxes[arg2]},
  TemplateBox[{arg1, arg2}, "foo", 
   DisplayFunction :> (RowBox[{"(", 
        RowBox[{arg1b, "\[CenterDot]", arg2b}], ")"}] &)]]

a (x \[CenterDot] y)

Using TemplateBox approach will allow you to convert output into desired input form. If you need only to output, just explicitly form the boxes.

You can add conditions as well, for example, the special formatting will occur only if first argument of bar is 1

MakeBoxes[bar[a__, foo[arg1_Symbol, arg2_Symbol]], StandardForm] :=

 With[{replBox = 
     RowBox[{"(", 
       RowBox[{MakeBoxes[arg1], "\[CenterDot]", MakeBoxes[arg2]}], 
       ")"}]},
   RowBox[{MakeBoxes[bar], "[", MakeBoxes[a], ",",replBox, "]"}]] /; 
  First[{a}] === 1


bar[1, foo[x, y]]

bar[1, (x\[CenterDot]y)]

$\endgroup$
1
  • $\begingroup$ This is good, but I'd really like the parentheses to show up only under certain conditions. Let's say I want the parentheses when foo[...] appears as the first argument of some head bar which satisfies some condition conditionQ[bar]. Then I can imagine I'd do something like MakeBoxes[bar_?conditionQ[a__, foo[arg1_Symbol, arg2_Symbol]], StandardForm] := ??? -- what would go on the right hand side? I'm unsure how to include the existing formatting of bar and its other arguments within MakeBoxes. $\endgroup$
    – jjc385
    Commented Mar 3, 2015 at 0:36
2
$\begingroup$

I think you're looking for SyntaxForm. For example:

foo /: MakeBoxes[foo[x,y], StandardForm] := TemplateBox[
    {MakeBoxes[x], MakeBoxes[y]},
    "foo",
    DisplayFunction->(RowBox[{#1, "\[CenterDot]", #2}]&),
    SyntaxForm->Star
]

I used Star for the SyntaxForm since its precedence is 390, as requested, in between the precedences for Plus and Times:

Precedence /@ {Plus, Star, Times}

{310., 390., 400.}

Then:

a + foo[x, y]
a * foo[x, y]

enter image description here

$\endgroup$

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.