[Tex/LaTex] amsmath aligned environment: correct positioning of equation number on the last line with tbtags

alignamsmathnumberingpositioningtags

tl;dr

How to place the equation number on the last line of an {aligned}[t] environment?
(Similar questions have been asked in Equation number in aligned environment after last line and How can I position the tag of a "nested" aligned environment?, but the situation I describe here is more complicated and not easily solved by the answers posted there.)

The situation

Consider the following situation: The tbtags option for the amsmath package is in use, i.e., tags on the right hand side should always be placed on the bottommost line of each eqution. I have multiple equations in a single align environment. All the relation symbols need to be aligned. In each equation I may need additional alignment points. (In the following example the opening parentheses will be aligned.) The secondary alignment points will not be at the same horizontal position. (I.e., alignat can't be used here.) The equations are typeset by nesting aligned inside split and align.

The example

\documentclass{article}
\usepackage[tbtags]{amsmath}
\begin{document}
\begin{align}
 x &= 1234[\!\begin{aligned}[t]
          &(a+b)\\
          &(c+d+e)\\
          &(f+g)]\end{aligned}\\
\begin{split}
 y &= 5[(h+i)+j]\\
   &= 6[\!\begin{aligned}[t]
       &(k+l)\\
       &(m+n+o)]\end{aligned}
\end{split}
\end{align}
\end{document}

compiled example

In the image the black font shows the output when compiling the example code. The equations themselves are typeset exactly as I want, but I disagree with the position of the equation numbers. The red numbers show where I want the tags to be positioned.

The problem

The equation numbers are not placed on what would mathematically be considered the last line of the equations, i.e., lines 3 and 6. Instead they are placed on lines 1 and 5. (I think this happens because LaTeX-internally only lines 1, 4 and 5 are actually considered lines.)

The solution?

  1. Don't use aligned at all. (Don't use split either.) Use \notag on lines 1, 2, 4 and 5. Use something like \hphantom{{}=prefactor[} on lines 2, 3 and 6.
  2. Put each equation in a split and use something like \end{aligned}\\[-XXpt]&\end{split}\\[YYpt], thus introducing a new line that LaTeX considers worthy of a number but move it upwards so that the printed tag appears not on its own line but the previous one.
  3. I hate soultions 1 and 2. Solution 1 requires duplication the prefactor many times (The best I can do is store it in a macro for each equation and call that on every line that needs the leading whitespace), solution 2 requires finetuning the vertical spaces XX and YY (I have no idea whether those could be measured and inserted automatically). Both are tedious, might have unintended side effects that I don't know of, it will be very annoying when typesetting a large number of equations, and it might fail if a tag has to be moved from its default position because of a long line.

Can anyone think of a better, more automatic or more elegant solution?

Bonus question

If you have a good solution for the problem above then you might also be able to answer this: How to solve the same problem when cases is used (instead of aligned), i.e., how to place the tag on the line with the last case? In this situation solution 1 cannot be used and the calculation for solution 2 becomes more complicated.

Bonus bonus question

How to tackle the same problem if you have aligned inside cases inside split inside align?

Best Answer

This uses tikz to place (overlay) the tag, consequently it takes two runs to position the tags correctly.

It ignores whether the equation is too wide, since it may not be too wide where the tag is. \taghere does provide an optional argument to apply additional vertical offset.

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}

\makeatletter
\newif\iftag@here

\newcommand*{\taghere}[1][0pt]% #1 = additional vertical offset (optional)
{\ifmeasuring@\else% do not expand until displayed
  \global\tag@heretrue
  \tikz[remember picture,overlay]{\coordinate (taghere) at (0pt,#1);}%
\fi}

\def\place@tag{%
    \iftagsleft@
      \kern-\tagshift@
      \iftag@here
        \global\tag@herefalse
        \tikz[remember picture,overlay]%
          {\path (taghere) -| node[anchor=base]{\rlap{\boxz@}} (0pt,0pt);}%
      \else
        \if1\shift@tag\row@\relax
            \rlap{\vbox{%
                \normalbaselines
                \boxz@
                \vbox to\lineht@{}%
                \raise@tag
            }}%
        \else
            \rlap{\boxz@}%
        \fi
        \kern\displaywidth@
      \fi% end of \iftag@here
    \else
      \kern-\tagshift@
      \iftag@here
        \global\tag@herefalse
        \tikz[remember picture,overlay]%
          {\path  (taghere) -|  node[anchor=base]{\llap{\boxz@}} (0pt,0pt);}%
      \else
        \if1\shift@tag\row@\relax
            \llap{\vtop{%
                \raise@tag
                \normalbaselines
                \setbox\@ne\null
                \dp\@ne\lineht@
                \box\@ne
                \boxz@
            }}%
        \else \llap{\boxz@}%
        \fi
      \fi% end of \iftas@here
    \fi
}
\makeatother

\begin{document}
\begin{align}
 x &= 1234[\!\begin{aligned}[t]
          &(a+b)\\
          &(c+d+e)\\
          &(f+g)\taghere]
          \end{aligned}\\
\begin{split}
 y &= 5[(h+i)+j]\\
   &= 6[\!\begin{aligned}[t]
       &(k+l)\\
       &(m+n+o)\taghere]
      \end{aligned}
\end{split}\\
z &= \begin{cases}
       1 & x>0\\
       0 & \textrm{otherwise}\taghere
    \end{cases}
\end{align}

\end{document}

demo