# Define a \dots-aware command

edit: changed the MWE to show the problem with french babel

So, I was wondering about in TeX.sx and came upon this question How do magic \dots work in amsmath?, I wanted to do the same thing (have a \dots-aware macro).

\documentclass{minimal}

\usepackage{amsmath}
\usepackage{xparse}
\usepackage[french]{babel}

\renewcommand*{\to}{%
\DOTSB
\myto
}
\NewDocumentCommand{\myto}{o}{%
\IfValueTF{#1}{%
\xrightarrow{#1}%
}{%
% default latex \to
\mathchar"3221
}%
}

\begin{document}
$$t\to[s]\dots\to[b]a$$
\end{document}


but the dots don't adapt. I did:

texdef -t latex -p amsmath DOTSB


and apparently \DOTSB is \relax, and the amsmath.sty file confirm this. Does anyone have a solution for this?

edit: I went with @egreg solution, because the other two conflicted with the split environment of amsmath.

-
That is because texdef is (like TeX itself) case sensitive: texdef -t latex -p amsmath dotsb yields \dotsb: macro:->\protect \cdots –  Henri Menke Mar 22 '14 at 20:30
\dotsb is a semantic macro for 'dots for binary operator', I was talking about \DOTSB wich is (if I understood right) a macro used in amsmath.sty to define commands wich make \dots behave like \cdots –  Zii8roZi Mar 22 '14 at 20:35

There's a bug in the french module of babel. The \dots command is redefined to be

\relax\csname\ifmmode M\else T\fi dots@\endcsname


so in math mode \Mdots@ is executed, which expands to \@xp\mdots@, which is wrong: it should simply be \mdots@. Indeed, patching \dots gives the expected result:

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}
\usepackage[french]{babel}
\usepackage{xpatch}

% the redefinition of \dots happens at begin document
% we simply remove one step: instead of the faulty
% \Mdots@ we do \mdots@
\AtBeginDocument{\xpatchcmd{\dots}{M}{m}{}{}}

\renewcommand*{\to}{%
\DOTSB
\myto
}
\NewDocumentCommand{\myto}{o}{%
\IfValueTF{#1}{%
\xrightarrow{#1}%
}{%
% default latex \to
\rightarrow
}%
}

\begin{document}
$$t\to[s]\dots\to[b]a$$
\end{document}


-
If it's a bug I expect a bug report to Jazos :-) –  Joseph Wright Mar 22 '14 at 21:52

\dots of amsmath checks the next token and also checks the meaning of the next macro if necessary, if it starts with \DOTSB. The parsing for an optional argument prevents this detection, because it is implemented by more than one macro (mainly because of \futurelet). Therefore \dots does not see \DOTSB, the marker used by \dots. The example splits the macro in an expandable part for \DOTSB and the other part for the arrow and the optional argument:

\documentclass{minimal}

\usepackage{amsmath}
\usepackage{xparse}

\renewcommand*{\to}{%
\DOTSB
\myto
}
\NewDocumentCommand{\myto}{o}{%
\IfValueTF{#1}{%
\xrightarrow{#1}%
}{%
% default latex \to
\mathchar"3221
}%
}

\begin{document}
$$t\to[s]\dots\to[b]a$$
\end{document}


## \usepackage[french]{babel}

This does not work for frenchb.ldf, because it redefines \dots and the definition of amsmath is gone.

The following example restores the \dots macro of amsmath inside math mode:

\documentclass{minimal}

\usepackage{letltxmacro}
\usepackage{amsmath}
\LetLtxMacro\amsmathdots\dots

\usepackage{xparse}
\usepackage[french]{babel}

\AtBeginDocument{%
\LetLtxMacro\frenchdots\dots
\everymath{\LetLtxMacro\dots\amsmathdots}%
\everydisplay{\LetLtxMacro\dots\amsmathdots}%
}

\renewcommand*{\to}{%
\DOTSB
\myto
}
\NewDocumentCommand{\myto}{o}{%
\IfValueTF{#1}{%
\xrightarrow{#1}%
}{%
% default latex \to
\mathchar"3221
}%
}

\begin{document}
$$t\to[s]\dots\to[b]a$$
\end{document}

-
Your solution worked perfectly with the MWE, but when I tried it with the acctual document, it didn't. Apparently, there is a conflict with french babel, do you have any idea on how to fix it? –  Zii8roZi Mar 22 '14 at 20:52
Also, I would really love to understand why the texdef command returns \relax. –  Zii8roZi Mar 22 '14 at 20:53
@shilluc: Make a minimal example that shows the problem. –  Heiko Oberdiek Mar 22 '14 at 20:53
@shilluc: \DOTSB is just used as marker for the previous \dots command. It does not need to do anything just sitting at the begin of the macro. –  Heiko Oberdiek Mar 22 '14 at 20:54

A solution without xparse:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{letltxmacro,amsmath}
\LetLtxMacro\amsdots\dots
\usepackage[french]{babel}
\AtBeginDocument{%
\LetLtxMacro\frenchdots\dots
\everymath{\LetLtxMacro\dots\amsdots}%
\everydisplay{\LetLtxMacro\dots\amsdots}%
}
\renewcommand*\to{\DOTSB\myto}
\newcommand*\myto[1][]{\if$#1$\dots\else\xrightarrow{#1}\fi}

\begin{document}
$$t\to[s]\dots\to[b]a \to$$
\end{document}


-