The syntax that you have written means that the arrow has to be called with two arguments. So even if you don't have anything below the arrow, you still need to say \myrightarrow{}{above}
. To get an optional argument, define the command as:
\newcommand*{\myrightarrow}[2][]{\xrightarrow[#1]{\mathmakebox[\arrow]{#2}}}
However, this treats the two arguments differently. To see this, try putting a really long text in the upper and lower arguments. The arrow will stretch for the lower one but not for the upper one. To ensure equal treatment, we need to put both arguments in a \mathmakebox
. However, for spacing reasons we should only put the lower one in a box if it is defined. So we test for that. Here's one way to do it, probably not the most elegant (but then I'm not know for the elegance of my code!).
\def\empty{}
\newcommand*{\myrightarrow}[2][]{%
\def\temp{#1}%
\ifx\temp\empty
\def\mycmd{\xrightarrow}%
\else
\def\mycmd{\xrightarrow[{\mathmakebox[\arrow]{#1}}]}%
\fi
\mycmd{\mathmakebox[\arrow]{#2}}%
}
What this does is the following: the #1
is a placeholder for our first argument. We want to test if this is empty, which we do by defining a temporary macro (\temp
) to hold it and testing that against a pre-defined \empty
macro (note to TeXperts: I'm deliberately avoiding @
s). If it is empty, we define a temporary command to be just \xrightarrow
. If it is not, we add in the lower part with the surrounding \mathmakebox
. Then whatever that was set to, we execute it together with the command for the upper code.
\myrightarrow{below}{above}
. Note the curly brackets for both arguments. If you want the first argument to be optional (as for\xrightarrow
) then you need to use:\newcommand*{\myrightarrow}[2][]{\xrightarrow[#1]{\mathmakebox[\arrow]{#2}}}
. It still has slightly different behaviour with the upper and lower labels (try really long words to see what I mean). Do you want something that fixes that as well?\usepackage{mathtools}
in your preamble.\newcommand
reference.