20

In my document, I have made an enumerate with several items I will need to reference to. They are numbered with a simple (1), (2)... , but I need a (2') as well. To reference nicely, I was using enumitem, this fails upon changing one label:

\documentclass{article}
\usepackage{enumitem}
\begin{document}

\begin{enumerate}[label=\textnormal{(\arabic*)}]
    \item text1\label{itm:1}.
    \item text2\label{itm:2}.
    \item[(2')] manually different label\label{itm:2b}.
    \item text3\label{itm:3}.
\end{enumerate}
Referencing to \ref{itm:1}\ref{itm:2}\ref{itm:2b}\ref{itm:3}.

\end{document}

This produces, as a final line, the following:

Referencing to (1)(2)(2)(3).

How could I fix this?

16

You could define it like this:

\documentclass{article}
\usepackage{enumitem}
\makeatletter
\newcommand{\mylabel}[2]{#2\def\@currentlabel{#2}\label{#1}}
\makeatother
\begin{document}
\begin{enumerate}[label=\textnormal{(\arabic*)}]
    \item text1\label{itm:1}.
    \item text2\label{itm:2}.
    \item[\mylabel{itm:2b}{(2')}] manually different label.
    \item text3\label{itm:3}.
\end{enumerate}
Referencing to \ref{itm:1}\ref{itm:2}\ref{itm:2b}\ref{itm:3}.

\end{document}

enter image description here

  • 1
    The problem is that it does not update automatically when the label is changed inside [ ]. – Sigur Jul 6 '15 at 10:21
  • @Sigur Yes, whatever we give inside the \mylabel command (here) is printed. Thought it was going to be a rare single case :) – Ambika Vanchinathan Jul 6 '15 at 10:24
  • 1
    You can change the command to print the label and use it inside the []. \newcommand{\mylabel}[2]{#2\def\@currentlabel{#2}\label{#1}} and \item[\mylabel{itm:2b}{(2')}] manually... – Sigur Jul 6 '15 at 10:25
  • 1
    @Sigur edited to incorporate your idea. Thanks. – Ambika Vanchinathan Jul 6 '15 at 10:50
  • 1
    This solution does not work correctly with hyperref - a link to (2') with still link to (2). – bers Nov 26 '16 at 17:06
1

You can do it dynamically like this, and not have to input the "2" yourself; you just pass a suffix, such as ', as an argument. This solution works with and without hyperref, cleveref, and enumitem, basically relying on the new \labelsuffix command:

\documentclass{article}
\usepackage{xpatch}

\usepackage{hyperref}
\usepackage{cleveref}
\usepackage{enumitem}

% latex.ltx
% \def\item{ 
% - sets \@noitemargtrue if no argument
% - calls \@item
% \def\@item[#1]{
% - checks \if@noitemarg
% - calls \refstepcounter only if true
% ==> \item[] does not call \refstepcounter
% \def\refstepcounter#1{\stepcounter{#1}
% - defines \@currentlabel
% \def\label#1{\@bsphack
% - uses \@currentlabel
% ==> need to set \@currentlabel manually before calling label

% cleveref.sty
% \item looks unchanged (no mention)
% \refstepcounter is changed!
% \def\refstepcounter{%
% - calls \refstepcounter@optarg or \refstepcounter@noarg
% - basically the same flow, both call the old \refstepcounter
% - same problem: call to \refstepcounter was skipped; 
% we have set \@currentlabel manually, and need to do similarly for \cref@currentlabel

\makeatletter
\newcommand{\labelsuffix}[2]{%
    % this is required for hyperref:
    \addtocounter{\@listctr}{-1}%
    \refstepcounter{\@listctr}%

    % fix for \ref:
    \edef\@currentlabel{\@currentlabel#2}%

    % fix for \cref (if you need to, load hyperref *before* cleveref):
    % TODO: this ignores prefixes and counter aliases!
    % TODO: to fix, copy/patch additional parts from \refstepcounter@noarg (from cleveref.sty)
    \global\def\cref@currentlabel{[\@listctr][\arabic{\@listctr}][]\@currentlabel}%

    % fix without enumitem
    \expandafter\edef\csname the\@listctr\endcsname{\csname the\@listctr\endcsname#2}%

    % fix with enumitem: label\@listctr does not contain the\@listctr, but c@\@listctr directly.
    % so we patch; silently fails when enumitem is not loaded.
    % https://tex.stackexchange.com/questions/340620/
    \expandafter\def\expandafter\label@listctr\expandafter{\csname label\@listctr\endcsname}%
    \expandafter\def\expandafter\c@@listctr\expandafter{\csname c@\@listctr\endcsname}%

    \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter%
    \xpatchcmd\expandafter\expandafter\expandafter%
    \label@listctr\expandafter\expandafter\expandafter%
        {\expandafter\expandafter\expandafter%
            {\expandafter%
                \c@@listctr\expandafter%
            }\expandafter%
        }\expandafter%
        {\expandafter%
            {\c@@listctr}#2%
        }{}{err}%

    \csname label\@listctr\endcsname%
    \label{#1}%
}
\makeatother

\begin{document}
    \begin{enumerate}
    \item\label{item:A}

    \item\label{item:Aa}
    \begin{enumerate}

        \item\label{item:B}

        \item[\labelsuffix{item:C}{'}]

        \item[\labelsuffix{item:D}{*}]

        \item\label{item:E}
    \end{enumerate}

    \item[\labelsuffix{item:F}{'}]

    \item\label{item:G}

    \item[\labelsuffix{item:H}{*}]

    \end{enumerate}

    items \ref{item:A}, \ref{item:Aa}, \ref{item:B}, \ref{item:C}, \ref{item:D}, \ref{item:E}, \ref{item:F}, \ref{item:G} and \ref{item:H}

    \cref{item:A,,item:Aa,,item:B,,item:C,,item:D,,item:E,,item:F,,item:G,,item:H}

    (cref does not sort items in different levels correctly -- I have filed that as a bug with the developer.)

\end{document}
1

If one is using hyperref, the easiest way to print the prime and have a link pointing to the right item is to modify slightly the solution by Ambika Vanchinathan by adding a dummy counter (that is, adding \newcounter{dummy} in the preamble and \refstepcounter{dummy} inside the definition of \mylabel).

However, personally I would rather redefine \item (instead of \label) through:

\makeatletter
\newcommand\myitem[1][]{\item[#1]\refstepcounter{dummy}\def\@currentlabel{#1}}
\makeatother

With this definition, manual-labeled items should be introduced as

\myitem[(2')]\label{itm:2b}

That is, changes are minimal with respect to the usual way of introducing things, so that the new definition is easier to remember. I would also define a math-mode prime through

\newcommand*{\mprime}{\ensuremath{'}}

Complete MWE:

\documentclass{article}
\newcounter{dummy}
\usepackage{hyperref}
\usepackage{enumitem}
\makeatletter
\newcommand\myitem[1][]{\item[#1]\refstepcounter{dummy}\def\@currentlabel{#1}}
\makeatother
\newcommand*{\mprime}{\ensuremath{'}}

\begin{document}
\begin{enumerate}[label=\textnormal{(\arabic*)}]
    \item text1\label{itm:1}.
    \item text2\label{itm:2}.
    \myitem[(2\mprime)]\label{itm:2b} manually different label.
    \item text3\label{itm:3}.
\end{enumerate}
Referencing to \ref{itm:1}\ref{itm:2}\ref{itm:2b}\ref{itm:3}.

\end{document}

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.