# Typesetting for different powers

Suppose that I want to typeset an object such that it looks differently for different powers. The simplest example would be a three vector. For odd powers I want it to look like $$|\vec{v}|^n,$$ while for even powers it should be just $$\vec{v}^n.$$

The naive approach

myvec /: MakeBoxes[myvec[x_], TraditionalForm] :=
RowBox[{"|", OverscriptBox[ToBoxes[x], "\[RightArrow]"], "|"}]
SuperscriptBox[
RowBox[{"|", OverscriptBox[ToBoxes[x], "\[RightArrow]"], "|"}],
ToBoxes[n]] /; OddQ[n]
SuperscriptBox[OverscriptBox[ToBoxes[x], "\[RightArrow]"],
ToBoxes[n]] /; EvenQ[n]


obviously doesn't work, because the tag is too deep. A "dirty" hack is to use

Unprotect[Power];
RowBox[{"|", OverscriptBox[ToBoxes[x], "\[RightArrow]"], "|"}];
Power /: MakeBoxes[Power[myvec[x_], n_], TraditionalForm] :=
SuperscriptBox[
RowBox[{"|", OverscriptBox[ToBoxes[x], "\[RightArrow]"], "|"}],
ToBoxes[n]] /; OddQ[n];
Power /: MakeBoxes[Power[myvec[x_], n_], TraditionalForm] :=
SuperscriptBox[OverscriptBox[ToBoxes[x], "\[RightArrow]"],
ToBoxes[n]] /; EvenQ[n];
Protect[Power];


This works fine but involves redefining protected functions, which is something I'd really like to avoid. So, is there a safer and more elegant way to achieve the desired result?

Tags (e.g. Power /:) are not necessary here. So

MakeBoxes[myvec[x_], TraditionalForm] :=
TemplateBox[{OverscriptBox[ToBoxes[x], "→"]}, "Abs"];
SuperscriptBox[
TemplateBox[{OverscriptBox[ToBoxes[x], "→"]}, "Abs"],
ToBoxes[n]] /; OddQ[n];

$\left| \vec{v}\right| ^3+\left| \vec{v}\right| +\vec{v}^2$
Here I use TemplateBox[{...}, "Abs"] to omit additional parentheses (see here). If you are interested in TeXForm and get redundant \left\left and \right\right see here.
• @vsht It is good idea to use tags when you can. For example, it helps you to clear certain definitions with ClearAll[yourTag]. – ybeltukov Feb 2 '15 at 1:08