6

I know that amsmath typesets at least twice its material, the first one for measurement and that it takes measures (sic) to avoid some counters being updated twice.

Is there a switch a macro writer could use to inform LaTeX not to update counters (which are global in LaTeX) when it is needed to typeset some unknown contents #1 inside a box, which will be discarded later?


update from info gathered from egreg's answer and a (belated) look in the sources. It is not as I said above that amsmath avoids for some counters to be updated; it avoids it for all, because it uses a list of all counter names which is kept up-to-date by the latex kernel, and designed to allow anyone using it to do things with all these names. The conclusion is thus that amsmath defines the macro pair \savecounters@/\restorecounters@ because it needs the functionality, but that anyone can copy their definitions (\savecounters@ defines what \restorecounters@ will do) and use them with the same effect without having to load amsmath or even any portion of it. Just replace \@nx by \noexpand.

  • \ifmeasuring@ is true in the first step and false during actual typesetting. However subtle problems can arise, if the counter's value changes from one to two digits. Can you give an example? – egreg Sep 27 '13 at 20:12
  • @egreg I mentioned amsmath for background, I am asking for a switch provided by the LaTeX kernel. I have not looked at what exactly amsmath does to avoid counters being updated twice, I am asking if LaTeX provides now a way to do that. – user4686 Sep 27 '13 at 20:18
  • @egreg the reason I am asking is that I just worked on this anwer and my method uses two preliminary renderings of the unknown argument, which may contain macros updating counters. – user4686 Sep 27 '13 at 20:20
6

This is basically what amsmath does for avoiding the problem of stepping counters twice when measuring. The changes to the counters' values should take place during the measuring phase, or there's the risk that a change from one to two digits ruins the measures made.

\documentclass{article}

\usepackage{amsmath,xcolor}

\newcounter{xyz}
\newcommand{\doxyz}{\stepcounter{xyz}--\thexyz--}

\makeatletter
\newdimen\jfbu@width
\newcommand{\processtwice}[1]{%
  \begingroup
  \savecounters@
  % here we do the measurement
  \sbox\z@{#1}%
  \global\jfbu@width=2\wd\z@
  % and we restore the counters' values
  \restorecounters@
  \endgroup
  \colorbox{yellow}{\makebox[\jfbu@width]{#1}}%
}
\makeatother

\begin{document}

\processtwice{\doxyz}

\processtwice{\doxyz}

\end{document}

As you see, #1 is evaluated twice, but the counter is stepped only the right number of times.

enter image description here

  • ok, so I ended up looking in amsmath and latex and I am very surprised that amsmath just uses the \cl@@ckpt thing in a simple way; it didn't have to tap into \newcounter etc... surprising really that \savecounters@ and restorecounters@ are provided by amsmath, and not from the latex kernel itself. The good news is thus that a macro writer only has to steal the macros from amsmath. – user4686 Sep 27 '13 at 20:57

Your Answer

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