# Custom-length arrows, text over and under

Expanding on this question I'd like to know if it's possible to modify this macro to allow for text under the arrow as well, as the \xrightarrow[below]{under}. I don't have any experience with macros but using the answer to the aforementioned question I tried this to no effect

\newlength{\arrow}
\settowidth{\arrow}{\scriptsize$1000$}
\newcommand*{\myrightarrow}[2]{\xrightarrow[#1]{\mathmakebox[\arrow]{#2}}}


What would be the right way to do this?

-
When you say 'to no effect' what do you mean? It works okay for me, but as you've defined it then it has to be used with \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? – Loop Space Sep 5 '11 at 13:03
Yep, works as Andrew staed. Also don't forget to add \usepackage{mathtools} in your preamble. – Peter Grill Sep 5 '11 at 15:48
@Andrew Stacey : Yep this seems to work. So the extra square brackets tell the compiler argument 2 can be ignored? (before I had instances where the first argument wasn't present and the code didn't compile) – Jóhann Sep 5 '11 at 16:56
@Johann: That's correct. See the \newcommand reference. – Werner Sep 5 '11 at 16:57
I've expanded my comment into an answer. – Loop Space Sep 5 '11 at 18:41

Here is a \xxrightarrow that has a first mandatory argument, the desired subscript to which the arrow should adapt (see the examples in the test document below).

\documentclass[a4paper]{article}
\usepackage{amsmath,mathtools}
\makeatletter
\newlength\min@xx
\newcommand*\xxrightarrow[1]{\begingroup
\settowidth\min@xx{$\m@th\scriptstyle#1$}
\@xxrightarrow}
\newcommand*\@xxrightarrow[2][]{
\sbox8{$\m@th\scriptstyle#1$}  % subscript
\ifdim\wd8>\min@xx \min@xx=\wd8 \fi
\sbox8{$\m@th\scriptstyle#2$} % superscript
\ifdim\wd8>\min@xx \min@xx=\wd8 \fi
\xrightarrow[{\mathmakebox[\min@xx]{\scriptstyle#1}}]
{\mathmakebox[\min@xx]{\scriptstyle#2}}
\endgroup}
\makeatother

\begin{document}
$A\xxrightarrow{1000}{1}A$

$A\xxrightarrow{1000}{1000}A\xrightarrow{1000}A$

$A\xxrightarrow{1000}[1]{1}A\xrightarrow[1]{1}A$

\end{document}


So you call it as

\xxrightarrow{<sample>}[<below>]{<above>}


where <below> is optional.

-

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.

-