Here is one possible solution:
Note: I'll be using ⊕
/⊖
(respectively oplus
/ominus
) to recreate the effect of +
/-
- change operators/symbols as necessary
First, use InfixNotation
to get the foundation:
InfixNotation[ParsedBoxWrapper["⊕"], oplus]
InfixNotation[ParsedBoxWrapper["⊖"], ominus]
Attributes[oplus] = {Flat, OneIdentity};
Attributes[ominus] = {Flat, OneIdentity};
This gets us to here:
a⊕b⊖c⊖c⊕d // FullForm
(* oplus[a,ominus[b,c,c],d] *)
Next, transform ominus[…]
into something more similar to Plus[a,Times[-1,b]]
:
ominus[a_, b__] := oplus[a, Sequence @@ Map[oinv, {b}]]
Giving us:
a⊕b⊖c⊖c⊕d // FullForm
(* oplus[a,b,oinv[c],oinv[c],d] *)
So input is already working. Output formatting still has some issues though:
oplus[a,b,oinv[c],oinv[c],d]
(* a⊕b⊕oinv[c]⊕oinv[c]⊕d *)
Basically, we need to replace ⊕oinv[…]
with ⊖…
. The following should achieve this (hopefully) robustly:
NotationMakeBoxes[oplus[arg1_, args__], StandardForm] /; MemberQ[$ContextPath, "Global`"]:=
RowBox@Riffle[
List @@ (
FixedPoint[
Replace[
HoldComplete[pre___, unproc@bef_, Longest[inv : unproc@oinv[_] ..], post___] :>
HoldComplete[pre, ominus[bef, inv], post]
],
unproc /@ HoldComplete[arg1, args]
] //. HoldPattern@ominus[pre___, unproc@oinv[inv_], post___] :>
ominus[pre, inv, post]
/. om_ominus :> MakeBoxes[om, StandardForm]
/. unproc@arg_ :> Parenthesize[arg, StandardForm, CirclePlus]
),
"⊕"
]
First, lets verify that it works:
oplus[a,b,oinv[c],oinv[c],d]
(* a⊕b⊖c⊖c⊕d *)
How it works
The basic idea is to override the formatting rule put in place by InfixNotation
and replace it with something that knows how to handle oinv[…]
:
- First wrap the args in
HoldComplete
and wrap all arguments in unproc
, to keep track of which arguments need processing at the end.
- Then, we replace argument sequences of the form
unproc@arg1,unproc@oinv[arg2],unproc@oinv[arg3],…
with ominus[arg1,unproc@oinv@arg2,unproc@oinv@arg3,…]
(since we are within HoldComplete
this is not reverted)
- Then, we remove the
unproc@oinv@
wrappers within all ominus
- Then, we call the existing (thanks to
InfixNotation
) formatter for ominus
- And finally, we format the remain
unproc
arguments using the default formatting routine
b
andc
? $\endgroup$a op1 b c op1 d
will be equivalent toop1[a,b*c,d]
, or am I missing something? Or should it not be possible to input anything using this notation? $\endgroup$