7

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?

  • 2
    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
  • 1
    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
7

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.

  • Thank you for your solution. Do you know why \xxrightarrow needs more vertical space than \xrightarrow, and how to avoid this? I mean, it seams to incrase \linespread.. – Heinrich Ody Apr 29 '17 at 14:11
  • @HeinrichOdy That's how \mathop does, which is used internally by \xrightarrow – egreg Apr 29 '17 at 14:19
  • Ah, it might be that the space below the arrow always is reserved, regardless of whether the optional parameter is given. Which might be the reason for the other answer.. my bad – Heinrich Ody May 2 '17 at 8:07
2

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.

0

This answer takes the ideas in the two other answers and combines them. The code is mostly copied from @egreg. When there is no subscript given, there will not be reserved space below the arrow. This causes the lines to be more compact, if there is no subscript given.

\documentclass[a4paper]{article}
\usepackage{amsmath,mathtools,xparse}
\makeatletter
\newlength\min@xx
\DeclareDocumentCommand\xxrightarrow{ m o m }{%
    \IfNoValueTF%
    {#2}
    {%
        \begingroup
        \settowidth\min@xx{$\m@th\scriptstyle#1$}
        \sbox8{$\m@th\scriptstyle#3$} % superscript
        \ifdim\wd8>\min@xx \min@xx=\wd8 \fi
        \xrightarrow{\mathmakebox[\min@xx]{\scriptstyle#3}}
        \endgroup
    }%
    {%
        \begingroup
        \settowidth\min@xx{$\m@th\scriptstyle#1$}
        \sbox8{$\m@th\scriptstyle#2$}  % subscript
        \ifdim\wd8>\min@xx \min@xx=\wd8 \fi
        \sbox8{$\m@th\scriptstyle#3$} % superscript
        \ifdim\wd8>\min@xx \min@xx=\wd8 \fi
        \xrightarrow[{\mathmakebox[\min@xx]{\scriptstyle#2}}]
        {\mathmakebox[\min@xx]{\scriptstyle#3}}
        \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$

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.