4

I'd like to reduce the vertical space between the arrow and the symbol above it in the \xrightarrow command.

Of course, "hard-coding" a value leads to unfortunate results:

\documentclass{article}
\usepackage{mathtools}
\newcommand\myxrightarrow[1]{
    \xrightarrow{\raisebox{-.5ex}[0pt][0pt]{\ensuremath{\scriptstyle#1}}}
}
\begin{document}
\(A \myxrightarrow{\theta} B\)

\(A \myxrightarrow{\theta_D'} B\)

\end{document}

gives

enter image description here

where the "D" is on the arrow line.

How can I adaptatively reduce this spacing?

I have read the documentation of the calc package and tried various formulas using heightof, but none was satisfactory (to say the least…).

This question is related to, but not solved by, https://tex.stackexchange.com/a/231918/34551.

egreg
  • 1,121,712
Clément
  • 5,591

3 Answers3

4

You can pretend that the arrow is less high than it is. Since TeX uses the height of the symbol it attaches limits to, we'll get a lower upper limit.

Note: \xrightarrow basically does

\mathrel{\mathop{<extended arrow>}\limits_{<lower label>}^{<upper label>}}}

but we just need to adapt the existing macros to our purpose.

\documentclass{article}
\usepackage{mathtools}

\makeatletter %% straight copy from \xrightarrow in amsmath.sty %% with \rightarrowfill replaced \NewDocumentCommand{\myxrightarrow}{m}{% \ext@arrow 0359\smashed@rightarrowfill@{}{#1}% } %% we want to define \smashed@rightarrowfill %% like amsmath.sty does for \rightarrowfill %% but with \smashed@arrow instead of \rightarrow \newcommand{\smashed@rightarrowfill@}{% \arrowfill@\relbar\relbar\smashed@rightarrow } %% now define \smashed@rightarrow %% we need \mathpalette \newcommand{\smashed@rightarrow}{\mathrel{\mathpalette\smashed@@rightarrow\relax}} %% we use \raisebox to assign a height %% the height is that of the formula axis %% stored in \fontdimen22 <font>2 %% where <font> is one of \textfont, \scriptfont or \scriptscript font \newcommand{\smashed@@rightarrow}[2]{% \raisebox{0pt}[\fontdimen22\smashed@font{#1}2]{$\m@th#1\rightarrow$}% } %% here we use the current style to select the right font %% among the three we identified earlier \newcommand{\smashed@font}[1]{% \ifx#1\displaystyle\textfont\else \ifx#1\textstyle\textfont\else \ifx#1\scriptstyle\scriptfont\else \scriptscriptfont\fi\fi\fi } \makeatother

\begin{document}

(A \myxrightarrow{\theta} B) (A \xrightarrow{\theta} B)

(A \myxrightarrow{\theta_D'} B) (A \xrightarrow{\theta_D'} B)

\end{document}

enter image description here

egreg
  • 1,121,712
  • That's very creative, thanks a lot. Is there a "squigarrowfill" to substitute for the "\arrowfill"? I couldn't find anything documenting the various types of "\arrowfill" unfortunately. – Clément Dec 07 '23 at 23:10
  • @Clément you can do it with TikZ, I believe there’s somoon the site – egreg Dec 08 '23 at 12:04
  • This answer doesn't explain how the code works: what does mean the curious constant 0359, why we need to read \fontdimen22, etc. – wipet Dec 08 '23 at 12:20
  • @wipet Are you happier now? The “curious constant” is actually four independent tokens, as defined in amsmath.sty. I'm sure you will understand it as soon as you read the source. – egreg Dec 08 '23 at 17:01
  • @egreg Thanks a lot for commenting out your solution so nicely. Many interesting elements in there! – Clément Dec 08 '23 at 19:37
4

The easiest solution is to use \height and \depth to avoid overlaps.

\documentclass{article}
\usepackage{mathtools}

\newcommand\myxrightarrow[1]{ \xrightarrow{\raisebox{-0.4ex}[\dimexpr \height-0.4ex][\depth]{\ensuremath{\scriptsize#1}}} } \begin{document} (A \myxrightarrow{\theta} B)

\(A \myxrightarrow{\theta_D'} B\)

\end{document}

demo

John Kormylo
  • 79,712
  • 3
  • 50
  • 120
2

The positioning a box x over relation symbol is implemented using Op math atom with \limits, which is described in rule 13a of appendix G in TeXbook. We can read here that the depth of the box x is subtracted when the vertical space between the box and the relation symbol box is calculated, see the expression max(\xi_9,\xi_{11}-d(x)) here. This calculation keeps the baseline of x at constant distance if d(x) isn't too big.

Your solution creates the box x where its depth is zero and its material is shifted down with respect to its baseline and extends below the box boundary. The material of box x overlaps the relation symbol because its real depth isn't used in the calculation. Your shifting of box x can be rewritten in primitive TeX language:

\setbox0=\hbox{\lower.5ex\hbox{$\scriptstyle x$}}\wd0=0 \box0

A simple solution of your problem is to create a box with depth zero and the material shifted down with respect to its bottom. It can be done by

\vbox{\hbox{$\scriptstyle x$}\kern-.5ex}

Now the box is shifted but its original depth isn't ignored and its new depth is zero.

You can try:

\def\mybuildrel #1\over{\buildrel \vbox{\hbox{$\scriptstyle#1$}\kern-.4ex}\over}

test: $$ A \mybuildrel \theta \over \rightarrow B, \quad A \mybuildrel \theta'_D \over \longrightarrow B $$ \bye

Viola, it works.

wipet
  • 74,238
  • How does this solve the OP's problem? Try $\xrightarrow{\theta}$ and $\buildrel\theta\over\rightarrow$ and you'll get the same output. Which is not what the OP wants. – egreg Dec 07 '23 at 22:23
  • Yes indeed I'm not sure I see any change using that command. – Clément Dec 07 '23 at 22:46
  • 1
    @Clément I rewrote my answer, I explain, what is bad in your macro. – wipet Dec 08 '23 at 07:45