0

When I want to iterate a counter using \stepcounter inside \mathllap , \mathclap or \mathrlap the counter iterates by 4 instead of by 1. E.g, the following MWE

\documentclass{article}
\usepackage{mathtools}
\newcounter{mycounter}


\begin{document}
$\mathclap{\stepcounter{mycounter}xyz}$

\arabic{mycounter}
\end{document}

outputs

xyz
  4

while

\documentclass{article}
\usepackage{mathtools}
\newcounter{mycounter}


\begin{document}
\stepcounter{mycounter}$\mathclap{xyz}$

\arabic{mycounter}
\end{document}

outputs the desired

xyz
  1

as expected.

In this simple example the second MWE is an easy work-around, but how can I deal with this problem in a more elegant ways, when it is not so easy to move the \stepcounter outside of the \mathclap like in the following MWE:

\documentclass{article}
\usepackage{mathtools}
\newcounter{mycounter}
\newcommand{\printMyNextCounter}{\stepcounter{mycounter}\arabic{mycounter}}


\begin{document}
$\mathclap{\printMyNextCounter xyz}$

\printMyNextCounter
\end{document} 

outputs

2xyz
   5

I think this can be almost seen as a bug. Would it be possible to fix this bug?

3
  • it isn't a bug mathclap content is always evaluated 4 times – David Carlisle Jul 30 '20 at 22:21
  • I personally think it would be more user-friendly if mathclap would only effect the spacing and not stuff like counters. Probably it was much easier to implement mathclap such that it is internally evaluated 4 times, but for the end-user the side-effects of the four evaluations are not beneficial but rather annoying. Or would you tell me that if both implementations were equally easy and would result in exactly the same spacing behavior, you would still prefer that everything is evaluated four times? Maybe someone has an idea for a future implementation that does not need 4 times evaluation? – Jakob Jul 30 '20 at 22:49
  • You need 4 evaluations that;s the way tex works (you would see the same with \textrm{..} and lots of other commands, what is possible (but somewhat costly) is to save and restore all counters at each evaluation (tabularx does that when doing trial layouts) It is really very rare to be doing anything more complicated than x=0 in a \mathclap certainly counters I have never seen. If you separate out your increment and printing and only have the printing part in the mathclap then it will work better, if you really need the set reset all counters version I could post an answer later probably – David Carlisle Jul 30 '20 at 23:11
3

You can inject in \mathclap the same trickery that amsmath uses for avoiding the issue within \text and related commands such as \textrm and similar.

\documentclass{article}
\usepackage{mathtools}

\MHInternalSyntaxOn
%%% original definitions
%\def\MT_mathllap:Nn #1#2{{}\llap{$\m@th#1{#2}$}}
%\def\MT_mathrlap:Nn #1#2{{}\rlap{$\m@th#1{#2}$}}
%\def\MT_mathclap:Nn #1#2{{}\clap{$\m@th#1{#2}$}}
%%% modified definitions
\def\MT_mathllap:Nn #1#2{{}\llap{$\check@choice{#1}\m@th#1{#2}$}}
\def\MT_mathrlap:Nn #1#2{{}\rlap{$\check@choice{#1}\m@th#1{#2}$}}
\def\MT_mathclap:Nn #1#2{{}\clap{$\check@choice{#1}\m@th#1{#2}$}}
\MHInternalSyntaxOff

\makeatletter
\def\check@choice#1{\ifx#1\displaystyle\firstchoice@true\else\firstchoice@false\fi}
\makeatother

\newcounter{mycounter}

\begin{document}

$\mathclap{\stepcounter{mycounter}xyz}$

\arabic{mycounter}

\end{document}

enter image description here

3
  • +1 and you'll probably get the tick which is so depressing – David Carlisle Jul 31 '20 at 8:52
  • Would you recommend me using this by default in all my LaTeX documents or do you think this slows down the compilation significantly or do you see any danger of incompatibilities? – Jakob Aug 5 '20 at 15:54
  • @Jakob I'm not sure I'd increment a counter inside \mathclap, actually. The slow down is not significant. – egreg Aug 5 '20 at 16:33
4

You can arrange the counter is reset in each of the four evaluations

enter image description here

\documentclass{article}
\usepackage{mathtools}
\newcounter{mycounter}
\newcounter{mycounterx}
\newcommand{\printMyNextCounter}{\stepcounter{mycounter}\arabic{mycounter}}
\newcommand\mymathclap[1]{%
\setcounter{mycounterx}{\value{mycounter}}%
\mathclap{\setcounter{mycounter}{\value{mycounterx}}#1}%
}

\begin{document}
$\mymathclap{\printMyNextCounter xyz}$

\printMyNextCounter
\end{document}

The four evaluations come from the \mathchoice primitive and you see the same with most box commands in math mode that needs to react to being in a subscript and change size, \sqrt, \phantom etc would all have the same issue as \mathclap here.

2
  • 1
    \text and \textrm don't have the problem. – egreg Jul 31 '20 at 8:24
  • @egreg you know something told me that was wrong but I was tired:-) I'll delete those two, thanks – David Carlisle Jul 31 '20 at 8:50
2

The dirty trick follows. The TeX primitive \mathchoice is redefined:

\let\orimathchoice=\mathchoice
\def\mathchoice#1#2#3#4{\orimathchoice{#1}{\noadvance#2}{\noadvance#3}{\noadvance#4}}
\def\noadvance{\def\stepcounter##1{}}

% your code:

\documentclass{article}
\usepackage{mathtools}
\newcounter{mycounter}
\newcommand{\printMyNextCounter}{\stepcounter{mycounter}\arabic{mycounter}}

\begin{document}
$\mathclap{\printMyNextCounter xyz}$

\printMyNextCounter
\end{document} 
5
  • Why is this trick dirty? I don't really understand it? Does it locally define \stepcounter to have no effect inside \mathchoice? How can you guarantee that \stepcounter has exactly once an effect? – Jakob Aug 5 '20 at 15:59
  • @Jakob Yes, \stepcounter is locally re-defined in T, S and SS branches. Moreover, \stepcounter is processed only once in D branch of the \mathchoice. The \mathchoice TeX primitive creates four math lists \mathchoice{D}{T}{S}{SS} and uses only one in the second step of math processing. The \mathclap macro uses the \matchoice primitive and copies its parameter four times to the parameters of \mathchoice. This is reason of your problems: the \matchoice processes all its four parameters. – wipet Aug 5 '20 at 16:44
  • Do you know what are the pros and cons compared to egreg's solution: tex.stackexchange.com/a/556803/128042 I think your solution would generalize to \sqrt, \phantom and so on? egreg's solution would also work with other iterators instead of \stepcounter? – Jakob Aug 5 '20 at 16:52
  • 1
    The advantage of my solution (as all my solutions in stack.exchange) is that it is LaTeX independent. It does not use any package and not depends on LaTeX macros. My solution uses low-level approach: TeX primitives. Disadvantage: this solution solves only usage of \stepcounter macro in parameters of macros which are using \mathchoice. And the \stepcounter must be used before printing the counter in such parameter. The reverse usage: \mathclap{print counter, step counter} needs to keep SS branch and do redefinition in D, T and S branches. – wipet Aug 5 '20 at 17:17
  • 1
    You are true that this problem is something like bug. I'v reported (to TeX implementors) that \mathchoice idea is not so good idea by D. Knuth and that this problem can be solved much better. But this needs a deep re-implementation of TeX. Moreover, all \mathchioce dance is here only because of atypical syntax of fractions and generalized fractions (\over primitive etc.) which is generally not used by LaTeX users (they are using \frac macro). – wipet Aug 5 '20 at 17:26

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.