# How can I make amsmath's \dots look ahead after macro expansion?

As explained by egreg, "amsmath redefines \dots so that it can do a lookahead in order to establish what kind of dots to use." However, I noticed that this feature of \dots doesn't work when I define macros in place of commands that \dots would otherwise recognize. For example,

\documentclass[12pt]{report}
\usepackage{amsmath}
\newcommand{\by}{\times}

\begin{document}

\begin{gather*}
A = A_1 \times \dots \times A_n \\
B = B_1 \by \dots \by B_m
\end{gather*}

\end{document}


produces the output

The dots between the pairs of \times are in the correct position, whereas the dots between the pairs of \by are not. I'm guessing this is because \dots did a lookahead before macro expansion? Is there a way to fix this?

• \let\by=\times – egreg Sep 9 '15 at 16:25
• – moewe Sep 9 '15 at 16:42

\documentclass[12pt]{report}
\usepackage{amsmath}
\newcommand{\by}{\times}
\let\olddots\dots
\def\dots{\expandafter\olddots\romannumeral\^^@}

\begin{document}

\begin{gather*}
A = A_1 \times \dots \times A_n \\
B = B_1 \by \dots \by B_m
\end{gather*}

\end{document}

• This breaks when \boldsymbol{\times}\dots\boldsymbol{\times} is tried. – egreg Sep 9 '15 at 16:37
• @egreg true but it does what was asked, do the test after expansion. – David Carlisle Sep 9 '15 at 18:22

The standard way with amsmath is using \DOTSB inside the macro (\dots looks ahead for \DOTSB).

Note: I don't know why it's important that the macro is not \long so it works, hence the asterisk in \newcommand* is mandatory (which is correct anyways).

\documentclass{scrartcl}

\usepackage{mathtools}
\newcommand*{\by}{\DOTSB\times}

\begin{document}

\begin{gather*}
A = A_1 \times \dots \times A_n \\
B = B_1 \by \dots \by B_m
\end{gather*}

\end{document}


To make the AMS test skip over \long :

\documentclass{scrartcl}

\usepackage{mathtools}
\newcommand{\by}{\DOTSB\times}

\makeatletter
{\uccode5=m \uccode6=a \uccode7=c
\uccode8=\\ \uccode9=l \uccode+=o
\uppercase{\gdef\macro@#1#2#3#4\macro@{\gtest@false
\ifx 5#1\ifx 6#2\ifx 7#3\gtest@true
\xdef\meaning@{\macro@@#4\macro@@}\fi\fi
\else
\ifx 8#1\ifx 9#2\ifx +#3\gtest@true
\xdef\meaning@{\macro@@#4\macro@@}\fi\fi\fi
\fi}}}
\makeatother
\begin{document}

\begin{gather*}
A = A_1 \times \dots \times A_n \\
B = B_1 \by  \dots \by B_m
\end{gather*}

\end{document}

• amsmath 2.15 released this week includes a similar code that makes it ignore \long` – David Carlisle Mar 4 '16 at 9:22