5

This took me hours to track down, partially because I am fairly new to TeX. I want to understand why the custom counter eqpart in the following code fails to increment properly when using mathclap. The counter jumps from a to d. The first equation only has the right counter because it is not wrapped in mathclap. Removing mathclap from ubrace gives the correct count which is b.

\documentclass[10pt]{article}

\usepackage{unicode-math}
\usepackage{mathtools}
\usepackage{xcolor}

\newcounter{eqpart}[section]
\setcounter{eqpart}{0}
\renewcommand{\theeqpart}{\alph{eqpart}}

\newcommand*{\ubrace}[3][black]{
\colorlet{current}{.}
\color{#1}
\underbrace{#2}_{ \mathclap{ #3 } }
\color{current}
}

\makeatletter
\newcommand{\tageqpart}[1]{%
\ifmeasuring@\else
\refstepcounter{eqpart}
\displaystyle(\theeqpart)
\fi
\@bsphack
\protected@write\@auxout{}
{\string\newlabel{#1}{{(\theeqpart)}{\thepage}}}
\@esphack
}
\makeatother

\begin{document}
  \begin{align*}
    \underbrace{x + y}_{ \tageqpart{test1} } = 0
  \end{align*}
  \begin{align*}
    \ubrace{x + z}{\tageqpart{test2}} = 0
  \end{align*}
\end{document}

EDIT: Heeding the advice of David Carlisle I have refined the \ubrace command as:

\newcommand*{\ubrace}[3][black]{
  \begingroup
    \color{#1}
    \overbrace{#2}^{#3}
  \endgroup
}
arynhard
  • 149
  • 1
    \mathclap like any command using \mathchoice typesets its arguments 4 times display,text,script and scriptscript with the final version only being chosen later when the math list is finished. In classic TeX you can not detect this. Also why do you use \colorlet and explicitly save/restore the colour rather than simply using a group? – David Carlisle Jan 14 '15 at 10:58
  • To learn about \mathchoice and its implications, see http://tex.stackexchange.com/questions/43978/proper-use-of-mathchoice – Steven B. Segletes Jan 14 '15 at 11:25
  • @DavidCarlisle Thank you for the explanation of \mathcoice. To answer your question I am not familiar with TeX. After learning more about a group I can see why it is a better choice. Thank you for the tip. – arynhard Jan 14 '15 at 14:57
  • Is there any way to make this work using \mathclap? – arynhard Jan 14 '15 at 15:04
  • possibly you can set a global flag to avoid incrementing the counter (you'd need to \write in all cases though as only one will be used) I may look later – David Carlisle Jan 14 '15 at 15:11

1 Answers1

1

I suggest you

  • replace \mathclap{#3} with \makebox[0pt]{$#3$} -- the latter method doesn't mess with the counter eqpart; (Aside: Any "advantage" the \mathclap method may have, in terms of auto-sizing the result via \mathchoice, is illusory since #3 is set in \displaystyle anyway, according to a subsequent part of your code.)

  • add parentheses to the definition of \theeqpart, and simplify some of the subsequent code that involves \theeqpart;

  • apply David Carlisle's suggestion and surround the substantive instructions of the \ubrace macro with \begingroup and \endgroup -- letting you get rid of the \colorlet{current}{.} and \color{current} instructions.

enter image description here

% !TEX TS-program = xelatex
\documentclass[10pt]{article}

\usepackage{unicode-math}
\usepackage{mathtools}
\usepackage{xcolor}

\newcounter{eqpart}[section]
\setcounter{eqpart}{0}
\renewcommand{\theeqpart}{(\alph{eqpart})}

\newcommand*{\ubrace}[3][black]{%
   \begingroup
   \color{#1}
   \underbrace{#2}_{ \makebox[0pt]{$#3$} }
   \endgroup
}
\makeatletter
\newcommand{\tageqpart}[1]{%
  \ifmeasuring@\else
     \refstepcounter{eqpart}
     \displaystyle\theeqpart
  \fi
  \@bsphack
  \protected@write\@auxout{}
    {\string\newlabel{#1}{\theeqpart\thepage}}
  \@esphack
}
\makeatother

\begin{document}
  \begin{align*}
    \underbrace{x + y}_{ \tageqpart{test1} } &= 0\\
    \ubrace{x + z}{ \tageqpart{test2} }      &= 0
    \end{align*}
\end{document}
Mico
  • 506,678