1

I have defined my own command allowing me to number and reference a single line in a starred multiline equation environment, rather than using an un-starred environment and entering \nonumber at the end of every other line. The command is this: \newcommand{\TAG}[1]{\stepcounter{equation}\tag{\theequation}\label{#1}}

Then, I'm using \labelcref to reference multiple equations with a single command. For equations labelled the 'usual' way (with \label), the command works as expected; they are always printed in numerical order regardless of the order they are referenced in.

However, I run into problems when I use \labelcref for equations labelled using \TAG. Essentially, the references aren't ordered numerically anymore; usual \label references are printed first, in numerical order, and then any \TAG references are printed, in the order they're referenced. labelcref also doesn't include \TAG equations when printing (x) to (y), even when they are the last equations, numerically.

The examples in my MWE show what I mean. Hopefully.

I'd rather use my command once than use \nonumber many times, especially for environments with lots of lines. How might I get it to work?

\documentclass{article}
\usepackage{amsmath, amssymb, amsthm}
\usepackage{showlabels}
\usepackage{cleveref}
\usepackage{pifont}
\usepackage{fullpage}

\newcommand{\TAG}[1]{\stepcounter{equation}\tag{\theequation}\label{#1}}

\begin{document}

\begin{equation}\label{e:test1}
    y = x
\end{equation}
\begin{equation}\label{e:test2}
    y = x
\end{equation}
\begin{equation}\label{e:test3}
    y = x
\end{equation}
\begin{equation}\label{e:test4}
    y = x
\end{equation}
\verb+\labelcref+ gives `\labelcref{e:test3,e:test4,e:test2,e:test1}' no matter the order, because \verb+\label+ is used every time \ding{51}

\begin{align*}
    y &= x + x\\
    &= 2x\TAG{e:test5}
\end{align*}
\begin{equation}\label{e:test6}
    y = x
\end{equation}
\verb+\labelcref+ gives `\labelcref{e:test5,e:test6}' no matter the order, because test5 uses \verb+\TAG+ and so it always goes last \ding{55}

\begin{align*}
    y &= x + x\\
    &= 2x\TAG{e:test7}
\end{align*}
\begin{gather*}
    y = x + x\\
    \Rightarrow y = 2x\TAG{e:test8}
\end{gather*}
\verb+\labelcref{e:test8,e:test7}+ gives `\labelcref{e:test8,e:test7}', while \verb+\labelcref{e:test7,e:test8}+ gives `\labelcref{e:test7,e:test8}'; since both equations use \verb+\TAG+, the order of reference is printed \ding{55}

\begin{equation}\label{e:test9}
    y = x
\end{equation}
\begin{gather*}
    y = x + x\\
    \Rightarrow y = 2x\TAG{e:test10}
\end{gather*}
\begin{equation}\label{e:test11}
    y = x
\end{equation}
\verb+\labelcref+ gives `\labelcref{e:test9,e:test11,e:test10}' no matter the order; the two \verb+\label+ equations get printed first, in numerical order, and then the \verb+\TAG+ equation is printed last \ding{55}

\begin{equation}\label{e:test12}
    y = x
\end{equation}
\begin{equation}\label{e:test13}
    y = x
\end{equation}
\begin{equation}\label{e:test14}
    y = x
\end{equation}
\begin{gather*}
    y = x + x\\
    \Rightarrow y = 2x\TAG{e:test15}
\end{gather*}
\verb+\labelcref+ gives `\labelcref{e:test12,e:test14,e:test15,e:test13}' no matter the order; the \verb+\TAG+ equation doesn't get included in the `to' \ding{55}

\end{document}
0
1

Cross-referencing basically works as follows:

Commands like \section, \subsection etc internally call a macro whose name is \refstepcounter. This macro increments the associated counter and redefines macros whose names begin with \@current..., e.g., \@currentlabel, \@currentHref, etc. The purpose of these \@current...-macros is to always hold some piece of data wich belongs to that item of sectioning whose counter was incremented via \refstepcounter as the last one. The command \label places entries of the form \newlabel... into the .aux-file and hereby uses the expansion of these \@current...-macros for providing the data wich belongs to that item of sectioning whose counter was incremented via \refstepcounter as the last one. In the next LaTeX-run the .aux-file is read at the beginning and macros \r@<name of referencing label> get defined from these \newlabel-entries. Referencing-commands like \ref in turn expand these \r@<name of referencing label>-macros and from the expansion extract the piece of data they need.

I tried to elaborate in detail on the cross-referencing-mechanism of LaTeX 2e in my answer to the question "How to prevent reference to enumeration inside new environment?"


cleveref uses its own mechanism for writing data for its own referencing-labels that are needed for internal purposes to the .aux-file in terms of \newlabel-entries.

Usually that mechanism ensures that (benath other things) the value of the counter that was incremented via \refstepcounter as the last one "is placed into the definition" of the macro \cref@currentlabel which in turn is used by the cleveref-package for writing a \newlabel-entry for internal purposes into the .aux-file.

Hereby cleveref needs to handle situations where no counter is associated. By default this is the case with environments like align* and gather*. With such environments cleveref redefines the macros \make@df@tag@@ and \make@df@tag@@@, which internally are called by amsmath's \tag-command, in a way which leads to cleveref's \cref@currentlabel delivering a default-value which causes cleveref, when doing things like \labelcref, to treat that reference in special ways when forming/calculating the phrases for ranges of references of the same type.

When you look at the .aux-file which results from compiling your example, you find this:

\relax 
\newlabel{e:test1}{{1}{1}}
\newlabel{e:test1@cref}{{[equation][1][]1}{[1][1][]1}}
\newlabel{e:test2}{{2}{1}}
\newlabel{e:test2@cref}{{[equation][2][]2}{[1][1][]1}}
\newlabel{e:test3}{{3}{1}}
\newlabel{e:test3@cref}{{[equation][3][]3}{[1][1][]1}}
\newlabel{e:test4}{{4}{1}}
\newlabel{e:test4@cref}{{[equation][4][]4}{[1][1][]1}}
\newlabel{e:test5}{{{5}}{1}}
\newlabel{e:test5@cref}{{[equation][2147483647][]{5}}{[1][1][]1}}
\newlabel{e:test6}{{6}{1}}
\newlabel{e:test6@cref}{{[equation][6][]6}{[1][1][]1}}
\newlabel{e:test7}{{{7}}{1}}
\newlabel{e:test7@cref}{{[equation][2147483647][]{7}}{[1][1][]1}}
\newlabel{e:test8}{{{8}}{1}}
\newlabel{e:test8@cref}{{[equation][2147483647][]{8}}{[1][1][]1}}
\newlabel{e:test9}{{9}{1}}
\newlabel{e:test9@cref}{{[equation][9][]9}{[1][1][]1}}
\newlabel{e:test10}{{{10}}{1}}
\newlabel{e:test10@cref}{{[equation][2147483647][]{10}}{[1][1][]1}}
\newlabel{e:test11}{{11}{1}}
\newlabel{e:test11@cref}{{[equation][11][]11}{[1][1][]1}}
\newlabel{e:test12}{{12}{1}}
\newlabel{e:test12@cref}{{[equation][12][]12}{[1][1][]1}}
\newlabel{e:test13}{{13}{1}}
\newlabel{e:test13@cref}{{[equation][13][]13}{[1][1][]1}}
\newlabel{e:test14}{{14}{1}}
\newlabel{e:test14@cref}{{[equation][14][]14}{[1][1][]1}}
\newlabel{e:test15}{{{15}}{1}}
\newlabel{e:test15@cref}{{[equation][2147483647][]{15}}{[1][1][]1}}

The entries

\newlabel{e:test5@cref}{{[equation][2147483647][]{5}}{[1][1][]1}}
\newlabel{e:test7@cref}{{[equation][2147483647][]{7}}{[1][1][]1}}
\newlabel{e:test8@cref}{{[equation][2147483647][]{8}}{[1][1][]1}}
\newlabel{e:test10@cref}{{[equation][2147483647][]{10}}{[1][1][]1}}
\newlabel{e:test15@cref}{{[equation][2147483647][]{15}}{[1][1][]1}}

are definitely not correct in your scenario (where inside environments like align* and gather* you wish the equation-counter to be associated rather than no counter being associated) and they come from what cleveref does when the \tag-command is carried out within environments align* and gather*.

You can resolve this by redefining these macros in a way where they deliver data to \cref@currentlabel in the same way as is done for references of type "equation".

Perhaps like this:

\documentclass{article}
\usepackage{amsmath, amssymb, amsthm}
%\usepackage{showlabels}
%\usepackage{hyperref}
\usepackage{cleveref}
\usepackage{pifont}
\usepackage{fullpage}

\makeatletter
\newcommand*\my@make@df@tag@@[1]{%
  \cref@old@make@df@tag@@{#1}%
  \let\cref@old@df@tag\df@tag
  \expandafter\gdef\expandafter\df@tag\expandafter{%
    \cref@old@df@tag
    \def\cref@currentlabel{%
      [equation][\theequation][]#1%
    }%
  }%
}%
\newcommand*\my@make@df@tag@@@[1]{%
  \cref@old@make@df@tag@@@{#1}%
  \let\cref@old@df@tag\df@tag
  \expandafter\gdef\expandafter\df@tag\expandafter{%
    \cref@old@df@tag
    \toks@\@xp{\p@equation{#1}}%
    \edef\cref@currentlabel{[equation][\theequation][]\the\toks@}%
  }%
}%
\newcommand{\TAG}[1]{%
  \refstepcounter{equation}%
  \begingroup
  \let\make@df@tag@@\my@make@df@tag@@
  \let\make@df@tag@@@\my@make@df@tag@@@
  \tag{\theequation}%
  \endgroup
  \label{#1}%
}%
\makeatother

\begin{document}

\begin{equation}\label{e:test1}
    y = x
\end{equation}
\begin{equation}\label{e:test2}
    y = x
\end{equation}
\begin{equation}\label{e:test3}
    y = x
\end{equation}
\begin{equation}\label{e:test4}
    y = x
\end{equation}
\verb+\labelcref{e:test3,e:test4,e:test2,e:test1}+ yields `\labelcref{e:test3,e:test4,e:test2,e:test1}' \ding{51}

\begin{align*}
    y &= x + x\\
    &= 2x\TAG{e:test5}
\end{align*}
\begin{equation}\label{e:test6}
    y = x
\end{equation}
\verb+\labelcref{e:test5,e:test6}+ yields `\labelcref{e:test5,e:test6}' \ding{51}

\begin{align*}
    y &= x + x\\
    &= 2x\TAG{e:test7}
\end{align*}
\begin{gather*}
    y = x + x\\
    \Rightarrow y = 2x\TAG{e:test8}
\end{gather*}
\verb+\labelcref{e:test8,e:test7}+ yields `\labelcref{e:test8,e:test7}', while \verb+\labelcref{e:test7,e:test8}+ yields `\labelcref{e:test7,e:test8}' \ding{51}

\begin{equation}\label{e:test9}
    y = x
\end{equation}
\begin{gather*}
    y = x + x\\
    \Rightarrow y = 2x\TAG{e:test10}
\end{gather*}
\begin{equation}\label{e:test11}
    y = x
\end{equation}
\verb+\labelcref{e:test9,e:test11,e:test10}+ yields `\labelcref{e:test9,e:test11,e:test10}' \ding{51}

\begin{equation}\label{e:test12}
    y = x
\end{equation}
\begin{equation}\label{e:test13}
    y = x
\end{equation}
\begin{equation}\label{e:test14}
    y = x
\end{equation}
\begin{gather*}
    y = x + x\\
    \Rightarrow y = 2x\TAG{e:test15}
\end{gather*}
\verb+\labelcref{e:test12,e:test14,e:test15,e:test13}+ yields `\labelcref{e:test12,e:test14,e:test15,e:test13}' \ding{51}

\begin{verbatim}
\labelcref{e:test1,e:test2,e:test3,e:test4,e:test5,e:test6,e:test7,%
           e:test8,e:test9,e:test10,e:test11,e:test12,e:test13,e:test14,e:test15}
\end{verbatim}
yields 
`\labelcref{e:test1,e:test2,e:test3,e:test4,e:test5,e:test6,e:test7,%
            e:test8,e:test9,e:test10,e:test11,e:test12,e:test13,e:test14,e:test15}' \ding{51}

\end{document}

enter image description here

4
  • Incredible, thanks! Do you know what the problem was? Is obviously some intricacy in how cleveref works... – jonnybolton16 May 23 '20 at 18:24
  • @jonnybolton16 I edited my answer in an attempt of adding some explanation. ;-) – Ulrich Diez May 26 '20 at 9:08
  • Cool. How LaTeX works is definitely outside of my knowledge haha – jonnybolton16 May 26 '20 at 10:47
  • @jonnybolton16 In case you are one of those who are not just urged to use LaTeX for a few pieces of work while still in university and who will never use it again afterwards but are interested in how LaTeX works, I suggest the commented sources of LaTeX 2e - https://ctan.org/pkg/source2e. Besides this the usenet-newsgroup comp.text.tex and TeX-LaTeX-StackExchange are good places to ask in case you need explanation on how some snippet of TeX-code/LaTeX-code works. – Ulrich Diez May 26 '20 at 18:21

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.