5

I'm looking for a way to place some text flushed to the right margin (like \tag*{…} does) at the end of each line of an equation. The equation has multiple columns, and I need to control the alignment (right, center or left) of each column. Furthermore, I don't want the environment to add extra space before the first column, after the last column or between columns.

I tried the following, which does not work because only a single \tag{…} is allowed for the whole equation.

\documentclass{article}
\usepackage{amsmath}
\begin{document}
\[
\begin{array}{@{}r@{}c@{}l@{}}
  a&bbbbb&c \tag*{a, b and c} \\
  x&y&z    \tag*{other stuff}\\
\end{array}
\]
\end{document}

Screenshot of the desired outcome.

It would be cool if I could also do this for sub-cases (lines after a big opening brace), like numcases does (but numcases does not support \tag, and adds extra spaces everywhere).

Things I tried (after browsing through quite a few questions here):

  • equationarray from the eqnarray package looks promissing, but it does not support the \tag{…} command, only \notag (I tried and failed to manually call the internals of what \tag{…} does). align adds extra space between
  • align and empheq do not support rcl column specifications and add extra space
  • alignat* has everything except rcl column specification (it is hardcoded to be rlrlrl…)

Right now my best bet is to put a marker with tikz and draw the label as an overlay (I am not extremely interested in precise \label/\ref references, I can make all labels point to the whole multi-line equation if needed, so drawing with tikz is a crude, but viable solution).

1
  • I added a less hackish solution.
    – egreg
    Jul 19, 2017 at 20:29

5 Answers 5

2

You can abuse IEEEtrantools (but I recommend not pushing material that belongs in the equation to the right margin, which should be reserved for reference marks or numbers).

Note that you are responsible for avoding overlaps.

\documentclass{article}
\usepackage{amsmath}
\usepackage{IEEEtrantools}
\usepackage{showframe}

\begin{document}

\begin{IEEEeqnarray*}{r-c-l+r-}
a&bbbbb&c &\makebox[0pt][r]{a, b and c} \\
x&y&z     &\makebox[0pt][r]{other stuff}
\end{IEEEeqnarray*}

\begin{equation}
abbbbbc
\end{equation}

\end{document}

enter image description here

Original answer for reference

\documentclass{article}
\usepackage{amsmath}
\usepackage{IEEEtrantools}

\renewcommand\theIEEEsubequationdis{\theIEEEsubequation}
\newcommand{\IEEEtag}[1]{%
  \IEEEyessubnumber
  \gdef\theIEEEsubequation{#1}%
}

\begin{document}

\begin{IEEEeqnarray}{r-c-l}
a&bbbbb&c \IEEEtag{a, b and c} \\
x&y&z     \IEEEtag{other stuff}
\end{IEEEeqnarray}

\begin{equation} % just for checking the number has not advanced
a
\end{equation}

\end{document}

enter image description here

4

Here you are, with alignat and eqparbox:

\documentclass{article}
\usepackage{amsmath}
\usepackage{eqparbox}
\newcommand{\eqmathbox}[2][M]{\eqmakebox[#1]{$\displaystyle#2$}}

\begin{document}

\begin{alignat}{3}\label{rcl-eq}
  aa & & \eqmathbox{bbbbb} & & & c \tag*{a, b and c} \\
  x & &\eqmathbox{ y} & & & zzz \tag*{other stuff}
\end{alignat}

\end{document} 

enter image description here

4

The rl alignment is not that deeply embedded in the amsmath code and so it is easy to use alignat (or any of the AMS alignments) with different settings. Here I provide a command that lets you specify a string such as clr that will be repeated as often as necessary, just like the standard rl

enter image description here

\documentclass{article}

\usepackage{amsmath}
\makeatletter
\def\align@preamble@r{%
\hfil
    \strut@
    \setboxz@h{\@lign$\m@th\displaystyle{##}$}%
    \ifmeasuring@\savefieldlength@\fi
    \set@field
    \tabskip\z@skip}
\def\align@preamble@l{%
\strut@
\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
    \ifmeasuring@\savefieldlength@\fi
    \set@field
    \hfil
    \tabskip\alignsep@}
\def\align@preamble@c{%
\hfil
    \strut@
\setboxz@h{\@lign$\m@th\displaystyle{{}##}$}%
    \ifmeasuring@\savefieldlength@\fi
    \set@field
    \hfil
    \tabskip\alignsep@
}


\def\setalignpreamble#1{\def\align@preamble{}\x@setalignpreamble#1\relax}
\def\x@setalignpreamble#1{%
\ifx\relax#1\else
\edef\align@preamble{%
\unexpanded\expandafter{\align@preamble}%
&\span\expandafter\noexpand\csname align@preamble@#1\endcsname}%
\expandafter\x@setalignpreamble
\fi}



\begin{document}

default (rl)
\begin{alignat}{2}
  a&b&c&d\\
www& xxx&yyy&zzz
\end{alignat}

rl \setalignpreamble{rl}
\begin{alignat}{2}
  a &b&c&d\\
www& xxx&yyy&zzz
\end{alignat}

c \setalignpreamble{c}
\begin{alignat}{2}
  a &b&c&d\\
www& xxx&yyy&zzz
\end{alignat}


ccrr \setalignpreamble{ccrr}
\begin{alignat}{2}
  a &b&c&d\\
www& xxx&yyy&zzz
\end{alignat}

lcrc \setalignpreamble{lcrc}
\begin{alignat}{2}
  a &b&c&d\\
www& xxx&yyy&zzz
\end{alignat}

\end{document}
5
  • I have never seen ## used alone before, except in ##1 and other escaped parameters. Could you give us a concise explanation of what dark magic is at work here? Great solution by the way! Jul 20, 2017 at 8:26
  • @GeorgesDupéron there is no special meaning for ##1 in tex, it is just that in definitions, ## is replaced by # in just the same way as #1 is replaced by the first argument. so ##1 if used in a definition is replaced by #1 because ## is replaced by # and 1 is just 1. Jul 20, 2017 at 8:28
  • But what is the role of this single # (after expansion) here? I don't see a number appended to it, and \[\displaystyle{#}\] (with one or two #) obviously produces an error. Is it part of the syntax matched by \m@th, or something like that? Jul 20, 2017 at 8:32
  • 1
    @GeorgesDupéron that is the syntax of Tex's \halign primitive that underlies all these environments using & a centred column is specified as &\hfil#\hfil& where # is replaced by the cell contents. Jul 20, 2017 at 8:34
  • @Skillmon done. Jun 3, 2022 at 9:20
2

This is a complete kludge, that strongly depends on the height of the math involved.

\documentclass{article}
\usepackage{amsmath,tabstackengine}
\begin{document}
\begin{align}
&\tag*{a, b and c}\\&{\setstackgap{L}{1\baselineskip}\setstacktabulargap{0pt}
\ensureTABstackMath{\smash{\tabularLongstack{rcl}{aa&bbbbb&cc\\x&y&z }}}}
\tag*{other stuff}
\end{align}
\end{document}

enter image description here

3
  • @GeorgesDupéron There were some updates in the last 6 months or so. You can get the new .sty file and PDF at ctan.org/pkg/tabstackengine Jul 19, 2017 at 16:36
  • That was it, updating tabstackengine.sty, listofitems.sty and listofitems.tex fixed the Use of \\smash doesn't match its definition. error. Jul 19, 2017 at 16:44
  • @GeorgesDupéron The upgrade to using the listofitems parser was indeed a big upgrade. That is a package worth investigating on its own. Jul 19, 2017 at 16:47
1

Here's a somewhat comprehensive implementation using TikZ and overlay,remember picture of \tikztag{text}.

The starred version \tikztag*{text} omits the parentheses surrounding text. When a single optional argument is given, it gives the name of the label, e.g. \tikztag[eq:foo]{Foo} will place a label such that \ref{eq:foo} uses Foo as the “ref” text. When a second optional argument is given, it chooses the text for the “ref”, e.g. \tikztag*[eq:foo][Short]{Blah blah (Short)} will reference the equation as Short but will include a bit more Blah Blah to the right of the equation.

References made with \ref{…} point to the correct sub-equation when hyperref is loaded.

To use it, simply copy everything between \makeatletter and \makeatother in your preamble (or in an .sty, removing the \makeatletter and \makeatother lines). Then, use \begin{taggableequationstar}…\end{{taggableequationstar} in place of \begin{equation*}…\end{equation*} for the equations containing uses of \tikztag.

Screenshot of the resulting document.

% This code is released under the CC0 license (i.e. in the Public Domain
% or under a very permissive license if your country does not recognise
% dedications to the Public Domain.
\documentclass{article}
\makeatletter
\usepackage{amsmath, tikz, array, hyperref, lipsum}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parse options into:
%    \if@tikztag@star
%    \if@tikztag@label@
%    \@tikztag@label
%    \if@tikztag@labeltext@
%    \@tikztag@label
\newif\if@tikztag@star@
\newif\if@tikztag@label@
\newif\if@tikztag@labeltext@
\def\tikztag{\@ifstar\@tikztag@star\@tikztag@nostar}
\def\@tikztag@star{\@tikztag@star@true\expandafter\@tikztag@common}
\def\@tikztag@nostar{\@tikztag@star@false\expandafter\@tikztag@common}
\def\@tikztag@common{\@ifnextchar[{%
    \@tikztag@label@true\@tikztag@get@label%
  }{%
    \@tikztag@label@false\@tikztag%
  }}
\def\@tikztag@get@label[#1]{\def\@tikztag@label{#1}\expandafter\@tikztag@get@maybe@labeltext}
\def\@tikztag@get@maybe@labeltext{\@ifnextchar[{%
    \@tikztag@labeltext@true\@tikztag@get@labeltext%
  }{%
    \@tikztag@labeltext@false\@tikztag%
  }}
\def\@tikztag@get@labeltext[#1]{\def\@tikztag@labeltext{#1}\expandafter\@tikztag}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Implementation:
\edef\tikztagnumber{0}
\newcommand{\@tikztag}[1]{%
  % place the marker:
  \pgfmathtruncatemacro{\tikztagnumber}{\tikztagnumber+1}%
  \xdef\tikztagnumber{\tikztagnumber}%
  \tikz[remember picture]\coordinate(tikztagmarker\tikztagnumber){};%
  % dispatch given the options
  \expandafter\gdef\csname @tikztag@tag@\tikztagnumber\endcsname{#1}%
  \if@tikztag@label@%
    \if@tikztag@labeltext@%
      \if@tikztag@star@%
        \edef\@@tikztag{\noexpand\@@@tikztag{\expandafter\noexpand\@tikztag@label}{\expandafter\noexpand\@tikztag@labeltext}{\expandafter\noexpand\csname @tikztag@tag@\tikztagnumber\endcsname}{\tikztagnumber}{\noexpand\@firstoftwo}}%
      \else%
        \edef\@@tikztag{\noexpand\@@@tikztag{\expandafter\noexpand\@tikztag@label}{\expandafter\noexpand\@tikztag@labeltext}{(\expandafter\noexpand\csname @tikztag@tag@\tikztagnumber\endcsname)}{\tikztagnumber}{\noexpand\@firstoftwo}}%
      \fi%
    \else%
      \if@tikztag@star@%
        \edef\@@tikztag{\noexpand\@@@tikztag{\expandafter\noexpand\@tikztag@label}{\expandafter\noexpand\csname @tikztag@tag@\tikztagnumber\endcsname}{\expandafter\noexpand\csname @tikztag@tag@\tikztagnumber\endcsname}{\tikztagnumber}{\noexpand\@firstoftwo}}%
      \else%
        \edef\@@tikztag{\noexpand\@@@tikztag{\expandafter\noexpand\@tikztag@label}{\expandafter\noexpand\csname @tikztag@tag@\tikztagnumber\endcsname}{(\expandafter\noexpand\csname @tikztag@tag@\tikztagnumber\endcsname)}{\tikztagnumber}{\noexpand\@firstoftwo}}%
      \fi%
    \fi%
  \else%
    \if@tikztag@star@%
      \edef\@@tikztag{\noexpand\@@@tikztag{no label}{no label text}{\expandafter\noexpand\csname @tikztag@tag@\tikztagnumber\endcsname}{\tikztagnumber}{\noexpand\@secondoftwo}}%
      \else%
      \edef\@@tikztag{\noexpand\@@@tikztag{no label}{no label text}{(\expandafter\noexpand\csname @tikztag@tag@\tikztagnumber\endcsname)}{\tikztagnumber}{\noexpand\@secondoftwo}}%
    \fi%
  \fi%
  \@@tikztag%
}
\newcommand{\@@@tikztag}[5]{%
  \g@addto@macro\accumulatetikztag{\@@@@tikztag{#1}{#2}{#3}{#4}{#5}}%
}
% #1=label #2=label text #3=text #4=\tikztagnumber #5=\@firstoftwo or \@secondoftwo to use label or not
\newcommand{\@@@@tikztag}[5]{%
  \tikz[overlay,remember picture]%
    \node[anchor=base east, inner xsep=0pt]%
      at (tikztagmarker#4 -| current line right)%
      {#3};%
  #5{%
    \tikz[overlay,remember picture]%
      \node[anchor=base east, inner xsep=0pt]%
        at (tikztagmarker#4 -| current line left)%
        {\phantomsection\edef\@currentlabel{#2}\label{#1}};%
  }{}
}
\newenvironment{taggableequationstar}{%
  \noindent\tikz[remember picture]\coordinate(current line left){};%
  \tikz[overlay,remember picture]%
    \coordinate[xshift=\linewidth] (current line right) at (current line left){};%
  \xdef\accumulatetikztag{}%
  \begin{equation*}%
}{%
  \end{equation*}%
  \accumulatetikztag
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatother
\begin{document}

\newcolumntype{R}{>{\displaystyle}r}
\newcolumntype{C}{>{\displaystyle}c}
\newcolumntype{L}{>{\displaystyle}l}

\lipsum[2]
\begin{equation*}
  \begin{array}{@{}R@{}C@{}L@{}}
    a&bbbbb&c  \\
    x&y&z      \\
  \end{array}
\end{equation*}
\lipsum[2]
\begin{taggableequationstar}
  \begin{array}{@{}R@{}C@{}L@{}}
    a&bbbbb&c \tikztag[eq:foo][abc]{a, b and c} \\
    x&y&z     \tikztag[eq:bar]{other stuff}\\
    x&y&z     \tikztag{more stuff}\\
  \end{array}
\end{taggableequationstar}
Foo: \ref{eq:foo}. Bar: \ref{eq:bar}. Baz: \ref{eq:baz}. Quux: \ref{eq:quux}.
\lipsum[2]
\begin{taggableequationstar}
  \begin{array}{@{}R@{}C@{}L@{}}
    \frac{a}{i}&bbbbb&c \tikztag*[eq:baz][baz]{a, b and c (baz)} \\
    x&y&z     \tikztag*[eq:quux]{other stuff 2}\\
    x&y&z     \tikztag*{more stuff 2}\\
  \end{array}
\end{taggableequationstar}

\end{document}
2
  • 1
    using array means that the entries are set in textstyle not displaystyle as is normally the case for displayed equations. Jul 20, 2017 at 8:33
  • @DavidCarlisle Good point. I updated the example code to use >{\displaystyle}r and so on. Jul 20, 2017 at 9:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .