15

I have the following MNWE and don't understand why this fails.

\documentclass{article}
\usepackage{amsmath}
\begin{document}
$\dots \left. \right.$
\end{document}

Understanding the relevant code in amsmath proves to be rather difficult and I can't find a mention anywhere that this is somehow not OK to do. Of course I can use some of the more specialized dot commands to get rid of the guessing \dots does. I would be extra grateful for an explanation of what the trick with \uppercase in all the helper definitions(\striplong@...) and using \meaning in \mdots is.

  • it's a bug, hang on I'll see what it's doing.... – David Carlisle May 8 '16 at 20:47
  • Who's planted it? ;-) It works with TL2014. – egreg May 8 '16 at 20:53
  • @egreg yes but long macros (like amsmath defined arrows don't work in 2014:-) – David Carlisle May 8 '16 at 20:57
  • Another reason not to use \left/\right... – Andrew Swann May 11 '16 at 7:10
16

UPDATE this is fixed in release 2.15d (sent to ctan today, 2016-06-28, so will be reaching distributions is a few days.)


This is a bug (sorry ask @egreg who did it:-) until a fix is made available you can use

 $\dots\relax \left. a \right.$

Rather than change the document, you can fix the definition of \striplong@ as follows

\documentclass{article}
\usepackage{amsmath}
{\catcode`\@=11 \uccode`9=`\l \uccode`8=`\o %
 \uppercase{\gdef\striplong@#1#2#3#4\relax{%
  \ifx9#2\ifx8#3\@xp\@xp\@xp\@xp\@xp\@xp\@xp\zap@to@space\fi\fi}}}

\begin{document}
a$x$

$\dots \left. a \right)$
\end{document}

UPDATE

There are other cases that can trigger the same error (probably less likely to occur except in test files) basically any primitive starting with l so I think this is a better fix. It looks complicated as it is patching a largeish macro but the actual suggested change here is a singe space character being added (. ......... instead of ..........)

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\def\mdots@@{\gdef\thedots@{\dotso@}%
 \ifx\@let@token\boldsymbol 
   \gdef\thedots@\boldsymbol{\boldsymboldots@}%
 \else
   \ifx,\@let@token \gdef\thedots@{\dotsc}%
   \else
     \ifx\not\@let@token
       \gdef\thedots@{\dotsb@}%
     \else
       \keybin@
       \ifgtest@ % if \keybin@ test
         \gdef\thedots@{\dotsb@}%
       \else
%    \end{macrocode}
% The space below ensures that |\zap@to@space| never gets a runaway argument.
% (If |\meaning@| is |\left|, |\long|, |\looseness| in which case later tests will see |.|
% and choose |\ldots| as required.)
%    \begin{macrocode}
         \xdef\meaning@{\meaning\@let@token. .........}%
%    \end{macrocode}
% In previous versions \verb|\long| macros were not seen.
% Bad as this file uses \verb|\(re)newcommand| for \verb|\implies| etc.
%    \begin{macrocode}
         \xdef\meaning@@{\@xp\striplong@\meaning@\relax\meaning@}%
%    \end{macrocode}
%    \begin{macrocode}
         \@xp\math@\meaning@\math@
         \ifgtest@ % if \mathxxx test
           \@xp\mathch@\meaning@\mathch@
           \ifgtest@ % if \mathchar
             \@xp\getmathch@\meaning@\getmathch@
           \fi % end if \mathchar
         \else  % \not \mathxxx
%    \end{macrocode}
% Test for \verb|\Umathchar| added.
%    \begin{macrocode}
             \@xp\Umathch@\meaning@"0"\Umathch@
             \ifgtest@ % if \Umathchar
             \else % else not \Umathcar
%    \end{macrocode}
%    \begin{macrocode}
           \@xp\macro@\meaning@@\macro@
           \ifgtest@ % if macro test
             \@xp\not@\meaning@\not@
             \ifgtest@ % if macro starts \not test
               \gdef\thedots@{\dotsb@}%
             \else% else not \not
               \@xp\DOTS@\meaning@\DOTS@
               \ifgtest@ % \if DOTS
                 \ifcase\number\DOTSCASE@ %ifcase dots
                   \gdef\thedots@{\dotsb@}%
                 \or\gdef\thedots@{\dotsi}\else
                 \fi % endifcase dots
               \else % not macro starts \DOTS
                 \@xp\math@\meaning@\math@
                 \ifgtest@ % \if macro starts \mathxxxx
                   \@xp\mathbin@\meaning@\mathbin@
                   \ifgtest@ % if macro starts \mathbin
                     \gdef\thedots@{\dotsb@}%
                   \else % not macro starting \mathbin
                     \@xp\mathrel@\meaning@\mathrel@
                     \ifgtest@ % if macro starts \mathrel
                       \gdef\thedots@{\dotsb@}%
                     \fi % endif macro starts \mathrel (no else)
                   \fi % endif macro starts \mathbin
                 \fi % endif macro starts with \mathxxx (no else)
               \fi % endif macro starts \DOTS else
             \fi % end macro  starting \not \ifgtest@ test (no else)
%    \end{macrocode}
% Additional test for a catcode 12 character.
%    \begin{macrocode}
             \else
               \@xp\thecharacter@\meaning@\thecharacter@
%    \end{macrocode}
%    \begin{macrocode}
             \fi % end macro \ifgtest@ test (no else)
           \fi % end if \Umathchar test
         \fi % end \math@   \ifgtest@ 
       \fi % end \keybin@ \ifgtest@ test (no else)
     \fi % end if \not (no else)
   \fi % end if comma (no else)
 \fi % end if boldsymbol (no else)
 \thedots@}
\makeatother

\begin{document}
a$x$

$.\dots \left. a \right)$


$.\dots \long\def\zzz{} x$


$.\dots \looseness=1 x$

$.\dots \longrightarrow x$


$.\dots + x$


\end{document}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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