Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question
    
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 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 at 20:35

3 Answers 3

up vote 3 down vote accepted

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}

enter image description here

share|improve this answer
    
If it's a bug I expect a bug report to Jazos :-) –  Joseph Wright Mar 22 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}

Result

\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}
share|improve this answer
    
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 at 20:52
    
Also, I would really love to understand why the texdef command returns \relax. –  Zii8roZi Mar 22 at 20:53
    
@shilluc: Make a minimal example that shows the problem. –  Heiko Oberdiek Mar 22 at 20:53
1  
@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 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}

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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