jbezos / enumitem

Customize enumerate, itemize and description
MIT License
48 stars 5 forks source link

\value* works in label= but not in ref= #36

Open FrankMittelbach opened 2 years ago

FrankMittelbach commented 2 years ago

Here is an example:

\documentclass{article}

\usepackage{pifont,color,enumitem} 

\setlist[itemize]{label=\ding{43}} 
\setlist[enumerate,1]{start=172,
   ref=\ding{\value*}, 
% using \arabic* would work, but it isn't quite right ..   
%   ref=\ding{\arabic*},
%
% however, with label= \value gives the right results: 
    label=\textcolor{blue}{\ding{\value*}}
  }

\begin{document}

\begin{enumerate} 
\item Altering \texttt{enumerate} is easy:\label{x1}
  \begin{itemize} 
  \item Just load a font with nice digits. 
  \item Select the starting point if necessary.
  \end{itemize} 
\item For \texttt{itemize} select the symbol in
  the \texttt{label}.\label{x2} 
\item Cross-referencing still works.\label{x3} 
\end{enumerate} 

x1=\ref{x1} x2=\ref{x2} x3=\ref{x3}  % we get 3 times the same reference when using \value* in ref=

\end{document}

The fact that \value* can be used in label= (as documented) makes it a bit surprising that it can't be used also in a ref= setting, which is a bit of a pity, and I would rather prefer to be able to document it as working in both cases.

muzimuzhi commented 2 years ago

An expansion problem (as can be smelled from .aux).

\newlabel{x1}{{{\ding {\c@enumi }}}{1}}
\newlabel{x2}{{{\ding {\c@enumi }}}{1}}
\newlabel{x3}{{{\ding {\c@enumi }}}{1}}

\arabic is expandable, but \value is not. Hence when used in \the<counter>, \value{<counter>} should be prepended with \the.

This makes differences for \enit@normlabel, the common internal called by options label and ref. https://github.com/jbezos/enumitem/blob/1bdcad0987823b3716c86b126b3863f895ea9c4a/enumitem.sty#L911-L918

The following attempt patches \enit@normlabel so that

\documentclass{article}

\usepackage{pifont,color,enumitem} 

\setlist[itemize]{label=\ding{43}} 
\setlist[enumerate,1]{start=172,
   ref=\protect\ding{\value*}, 
% using \arabic* would work, but it isn't quite right ..   
%   ref=\ding{\arabic*},
%
% however, with label= \value gives the right results: 
    label=\textcolor{blue}{\protect\ding{\value*}}
  }

\usepackage{xpatch}
\makeatletter
\xpatchcmd\enit@normlabel
  {\def\value{\enit@refstar@i\value}}
  {\def\value{\enit@refstar@ii\value}}
  {}{\PatchFailed}

\def\enit@refstar@ii#1#2{%
  \if*#2\@empty
    \noexpand\the\noexpand#1{\@enumctr}% <- added \noexpand\the
                                       %    compared to \enit@refstar@ii
  \else
    \noexpand#1{#2}%
  \fi}
\makeatother

\begin{document}

\begin{enumerate} 
\item Altering \texttt{enumerate} is easy:\label{x1}
  \begin{itemize} 
  \item Just load a font with nice digits. 
  \item Select the starting point if necessary.
  \end{itemize} 
\item For \texttt{itemize} select the symbol in
  the \texttt{label}.\label{x2} 
\item Cross-referencing still works.\label{x3} 
\end{enumerate} 

x1=\ref{x1} x2=\ref{x2} x3=\ref{x3}  % now we get circled 1, 2, and 3, respectively

\end{document}

image