[Tex/LaTex] Define a math symbol relative to font size

fontsizemath-modesymbolstikz-pgf

Idea

All characters, including the new defined symbol (here an arrow), should scale related to the current font size, e.g. here 12pt.

Implementation

I would like to define an arrow similar to here. The arrow should scale with the font size. The current MWE of my definition is:

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc,decorations.pathmorphing,shapes}

\newcounter{sarrow}
\newcommand\xrsquigarrow[1]{%
\mathrel{\begin{tikzpicture}[baseline={($(current bounding box.south)+(0,-0.5ex)$)}]
\node[inner sep=.5ex] (\thesarrow) {$\scriptstyle #1$};
\draw[<-,decorate,decoration={snake,amplitude=0.7pt,segment length=1.2mm,pre=lineto,pre length=4pt}] (\thesarrow.south east) -- (\thesarrow.south west);
\end{tikzpicture}}%
}

\begin{document}

$A\xrsquigarrow{f}B$

\end{document}

How does the definition have to look like in order to get dependent on the font size (from the document class)?

Best Answer

Define, as already suggested, the macro with "relative units":

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc,decorations.pathmorphing,shapes}

\newcounter{sarrow}
\newcommand\xrsquigarrow[1]{\mathrel{%
  \begin{tikzpicture}[baseline={($(current bounding box.south)+(0,-0.5ex)$)}]
    \node[inner sep=.5ex] (\thesarrow) {$\scriptstyle #1$};
    \draw[<-,decorate,
          decoration={snake,amplitude=0.135ex,segment length=0.34em,pre=lineto,pre length=0.4em}] 
         (\thesarrow.south east) -- (\thesarrow.south west);
  \end{tikzpicture}
}}

\begin{document}

$A\xrsquigarrow{f}B$

{\large$A\xrsquigarrow{f}B$\par}

{\Large$A\xrsquigarrow{f}B$\par}

{\LARGE$A\xrsquigarrow{f}B$\par}

{\small$A\xrsquigarrow{f}B$\par}

{\footnotesize$A\xrsquigarrow{f}B$\par}

\end{document}

enter image description here

In order to get automatic scaling for subscripts and superscripts (or \scriptstyle declarations), one has to work harder:

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc,decorations.pathmorphing,shapes}

\makeatletter
\newcommand\xrsquigarrow[1]{\mathrel{\mathchoice
  {\hbox{\fontsize{\tf@size}{\tf@size}\selectfont\@xrsquigarrow\scriptstyle{#1}}}
  {\hbox{\fontsize{\tf@size}{\tf@size}\selectfont\@xrsquigarrow\scriptstyle{#1}}}
  {\hbox{\fontsize{\sf@size}{\sf@size}\selectfont\@xrsquigarrow\scriptscriptstyle{#1}}}
  {\hbox{\fontsize{\ssf@size}{\ssf@size}\selectfont\@xrsquigarrow\scriptscriptstyle{#1}}}
}}
\newcommand\@xrsquigarrow[2]{%
  \begin{tikzpicture}[baseline={($(current bounding box.south)+(0,-0.5ex)$)}]
    \node[inner sep=.5ex] (A) {$#1#2$};
    \draw[<-,decorate,
          decoration={snake,amplitude=0.135ex,segment length=0.34em,pre=lineto,pre length=0.4em}] 
         (A.south east) -- (A.south west);
  \end{tikzpicture}%
}

\begin{document}

$A\xrsquigarrow{f}B_{A\xrsquigarrow{f}B}$

{\large$A\xrsquigarrow{f}B$\par}

{\Large$A\xrsquigarrow{f}B$\par}

{\LARGE$A\xrsquigarrow{f}B$\par}

{\small$A\xrsquigarrow{f}B$\par}

{\footnotesize$A\xrsquigarrow{f}B$\par}

\end{document}

enter image description here

Beware that this is slow, because for each instance of \xrsquigarrow all the four variants need to be typeset.

Note. I've removed \thesarrow that does nothing more than provide a node name.


\mathchoice requires four arguments: what's to be typeset in display, text, first level sub/superscript and second level sub/superscript styles respectively. All four text will be typeset and then TeX will decide which one to use. So we set four boxes in which the font is chosen to be of size \tf@size for display and text styles, \sf@size and \ssf@size for the other two styles (these sizes are automatically computed by LaTeX when a formula is being typeset).

The box then contains \@xrsquigarrow which has two arguments: the style to be applied for the label and the label itself. This style should be \scriptstyle when the arrow is in display or text styles, \scriptscriptstyle in the other cases.

The definition of \@xrsquigarrow, apart from the additional parameter, is just the same as the one proposed before.